/* ══════════════════════════════════════════════════════════════════
   alpha desk · SHARED DESIGN SYSTEM · V2
   ──────────────────────────────────────────────────────────────────
   V2 upgrades (all backward-compatible with V1 class names):
     • Animated aurora background (breathing multi-color glow)
     • Faint dot-grid + subtle grain texture
     • Scroll-aware sticky nav (shrinks + glows on scroll)
     • New Aurora theme replaces Oxide (6 themes total)
     • Smooth theme crossfade (no instant swap)
     • Shimmer skeleton loader utility
     • Toast notification system
     • Command palette (⌘K) modal shell
     • Number counter utility (kc-count-up)
     • Richer card hover (lift + glow)
     • Prefers-reduced-motion respected throughout
   ══════════════════════════════════════════════════════════════════ */

/* ─── CROSS-DOCUMENT VIEW TRANSITIONS ──────────────────────────
   index / scanners / store / chat are separate documents, so every nav
   is a hard reload that white-flashes between pages. This opts the whole
   site into the browser's cross-document view-transition: the outgoing
   page is snapshotted and cross-faded into the incoming one, so a click
   reads as a smooth swap instead of a flash + heavy repaint. Chromium 126+
   honors it; Safari/Firefox ignore the at-rule and navigate normally (no
   regression). Kept short so it feels snappy, not sluggish, and fully
   disabled under reduced-motion. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 170ms;
  animation-timing-function: ease;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ─── THEMES ────────────────────────────────────────────────── */
/* Three Razor variants are the platform default. The :root block below
   defaults to `razor-pewter` so a page that paints before localStorage
   resolves (or for users with no saved theme) gets the correct identity
   from first paint — eliminating the brief kolhub-easy flicker that
   would otherwise occur. Theme blocks only override palette tokens;
   font weights, font-family defaults, and weight-scale modifiers live
   in :root and stay theme-independent so the Font tab keeps working
   unchanged. Legacy theme blocks (kolhub*, dusk*, graphite*) remain
   below for back-compat — they still apply to users whose
   localStorage.kc_theme points at one of them. The picker filters
   them via THEME_FAMILIES[].hiddenFromPicker in shared.js.
   ────────────────────────────────────────────────────────────── */
:root,
html[data-theme="razor-pewter"] {
  /* ── DEFAULTS that apply regardless of theme ── */
  /* Radar uses these as elevated-surface tokens; aliased to existing tokens
     so radar panels match the rest of the theme. Previously undefined →
     panels rendered transparent. */
  --panel: var(--card);
  --bg-elev: var(--surface);
  /* Global UI display font — Space Grotesk. Set once here so every
     `var(--kc-font-ui, 'Space Grotesk')` declaration in the codebase
     picks up the same family. (Legacy 'Syne' fallbacks were swept in
     the May 2026 polish pass — kept the fallback shape in case any
     stray declarations remain that we missed.) */
  --kc-font-ui: 'Space Grotesk', sans-serif;
  /* Legacy alias for setup-wizard h1; mirrors --kc-font-ui so the
     font picker affects it consistently. */
  --font-display: var(--kc-font-ui);
  /* Mono font family. Used widely as `var(--font-mono, 'Space Mono', monospace)`
     with explicit fallback, but ALSO used in `font:` shorthand declarations
     in the wallet block without a fallback (e.g. `font: var(--w-bold) 13px/1 var(--font-mono)`).
     CSS spec: if a var() in a shorthand resolves to nothing AND has no fallback,
     the entire shorthand is dropped — falling back to inherited body font (16px).
     Defining it here once makes those shorthand declarations work as intended. */
  --font-mono: 'Space Mono', monospace;
  /* ── FONT WEIGHTS — light mode subtracts 100 from each ──────────
     All font-weight declarations across this file and the per-page
     <style> blocks have been converted to use these vars. When the
     user toggles "Light" in the Appearance menu, html gets
     data-font-weight="light" and every var drops by 100 in one shot.
     Caveat: Chakra Petch has no 300 weight on Google Fonts — it
     stays at 400 in Light mode while everything else goes 300.
     ─────────────────────────────────────────────────────────────── */
  --w-regular:  400;
  --w-medium:   500;
  --w-semibold: 600;
  --w-bold:     700;
  --w-extra:    800;

  /* Shared mobile primitive: the iOS home-indicator / gesture-bar
     inset. Used wherever a viewport-tall surface pins content to the
     bottom (sidebar foot, chat composer) so it clears the safe area.
     Pair with the dvh height pattern: `height: calc(100vh - …)` as a
     fallback, then `height: calc(100dvh - … - var(--kc-safe-b))`. */
  --kc-safe-b: env(safe-area-inset-bottom, 0px);

  /* ── RAZOR · PEWTER palette (default for new users) ── */
  --bg: #0b0a09;
  --surface: #121110;
  --border: #2a2b30;
  --border2: #3a3b42;
  --accent:  #d4a335;        /* brass */
  --accent2: #b88b1f;        /* darker brass */
  --accent3: #8a96a3;        /* pewter — third color */
  --up: #6dd99c;             /* sage green — gains role split from brass (2026-05) */
  --red: #a83232;            /* oxblood */
  --down: var(--red);
  --blue: #8a96a3;           /* locked/waiting/bet — fixed at pewter across all razor variants */
  --yellow: #e8c560;         /* highlight (kept distinct from --accent) */
  --text: #f1ece1;
  --text-bright: #faf6ec;
  --text-mid: #c8c2b4;
  --muted: #8a857a;
  --card: #171513;
  --card2: #100f0d;
  --nav-bg: rgba(11,10,9,0.86);
  --glow-bg-1: rgba(212,163,53,0.045);
  --glow-bg-2: rgba(168,50,50,0.025);
  --glow-bg-3: rgba(138,150,163,0.018);
  --grid-dot: rgba(255,250,240,0.018);

  /* ── TYPED-DATA TOKENS — theme-independent, never re-themed ──────
     These five tokens identify the kind of data on screen, regardless
     of theme variant. They live in :root so they apply to all themes
     equally — like the family-dot palette, they are functional, not
     decorative. The utility classes (.kc-cashtag / .kc-handle / etc.)
     are defined further down in the file. */
  --type-cashtag:  #7dc4d4;        /* cool cyan — $BTC, $ETH, ticker symbols */
  --type-handle:   #a89cd0;        /* soft violet — @elonmusk, KOL handles */
  --type-price-up: #6dd99c;        /* gain green — for prices that need a value-independent up color */
  --type-price-dn: #e08896;        /* loss pink — for prices that need a value-independent down color */
  --type-ca:       #c8b67e;        /* aged ivory — contract addresses (0xab12…) */
  /* Sizes for the typed-data roles above - one source of truth so
     cashtags / handles / tickers render at a consistent size on every
     page. Contexts needing a different size override locally. */
  --type-handle-size:  12px;
  --type-cashtag-size: 12px;
  --type-cashtag-lg:   18px;
}

/* Legacy default (kept for back-compat — existing users with
   localStorage.kc_theme = 'kolhub-easy' still get this exact theme).
   Hidden from the picker via THEME_FAMILIES[].hiddenFromPicker. */
html[data-theme="kolhub-easy"] {
  --bg: #0f0e1a;
  --surface: #161522;
  --border: #25233a;
  --border2: #322f4d;
  --accent:  #4dd99a;        /* desaturated emerald */
  --accent2: #b693f5;        /* desaturated violet */
  --accent3: #5dd5e8;        /* desaturated cyan */
  --up: #6dd99c;
  --red: #f06b80;
  --down: var(--red);          /* alias used by .wl-* / .cp-* (wallet + compete) */
  --blue: #8caaff;             /* used by .wl-* / .cp-* (locked / bet / waiting hues) */
  --yellow: #f5d97a;
  --text: #d8d6e4;
  --text-bright: #f0eef8;
  --text-mid: #c8c6d8;
  --muted: #8a87a0;
  --card: #161522;
  --card2: #110f1c;
  --nav-bg: rgba(15,14,26,0.84);
  --glow-bg-1: rgba(168,85,247,0.06);
  --glow-bg-2: rgba(77,217,154,0.035);
  --glow-bg-3: rgba(93,213,232,0.025);
  --grid-dot: rgba(255,255,255,0.018);
}

html[data-font-weight="light"] {
  --w-regular:  300;
  --w-medium:   400;
  --w-semibold: 500;
  --w-bold:     600;
  --w-extra:    700;
}
/* Appearance B (2026-10): Medium = every weight +100. Light stays above for
   back-compat but is no longer offered (stored 'light' is dropped on read). */
html[data-font-weight="medium"] {
  --w-regular:  500;
  --w-medium:   600;
  --w-semibold: 700;
  --w-bold:     800;
  --w-extra:    800;
}

/* Optional utility classes for new code — same vars as inline weights */
.fw-regular  { font-weight: var(--w-regular); }
.fw-medium   { font-weight: var(--w-medium); }
.fw-semibold { font-weight: var(--w-semibold); }
.fw-bold     { font-weight: var(--w-bold); }
.fw-extra    { font-weight: var(--w-extra); }

/* ── TYPED-DATA UTILITY CLASSES ────────────────────────────────────
   Colors that identify what kind of data is on screen, never themed.
   Apply by class:  <span class="kc-cashtag">$BTC</span>
   Or as a parent style:  .my-row .sym { color: var(--type-cashtag) }
   These read consistently across all theme variants because the
   underlying tokens live in :root.
   ────────────────────────────────────────────────────────────────── */
.kc-cashtag  { color: var(--type-cashtag); font-weight: var(--w-semibold); font-size: var(--type-cashtag-size); }
.kc-handle   { color: var(--type-handle);  font-weight: var(--w-medium); font-size: var(--type-handle-size); }
.kc-price-up { color: var(--type-price-up); }
.kc-price-dn { color: var(--type-price-dn); }
.kc-ca       { color: var(--type-ca); font-family: var(--font-mono, 'Space Mono', monospace); }

/* ── KOLHUB FAMILY — emerald + violet + cyan, your signature ── */
html[data-theme="kolhub"] {
  --bg: #08070d;
  --surface: #0d0c14;
  --border: #1c1a2c;
  --border2: #2a2740;
  --accent:  #1fd687;
  --accent2: #a855f7;
  --accent3: #22d3ee;
  --up: #34d399;
  --red: #f43f5e;
  --yellow: #facc15;
  --text: #e9e8f0;
  --text-bright: #ffffff;
  --text-mid: #c8c6d4;
  --muted: #7a7790;
  --card: #0f0e17;
  --card2: #0b0a12;
  --nav-bg: rgba(8,7,13,0.85);
  --glow-bg-1: rgba(168,85,247,0.10);
  --glow-bg-2: rgba(31,214,135,0.05);
  --glow-bg-3: rgba(34,211,238,0.04);
  --grid-dot: rgba(255,255,255,0.025);
}

html[data-theme="kolhub-calm"] {
  --bg: #16152a;
  --surface: #1d1c33;
  --border: #2c2a44;
  --border2: #3a3858;
  --accent:  #7eddb0;        /* mint */
  --accent2: #c4a8f0;        /* lavender */
  --accent3: #8dd0d8;        /* dusty cyan */
  --up: #8dd5a8;
  --red: #e08896;
  --yellow: #e8d490;
  --text: #c8c6d8;
  --text-bright: #e6e3f2;    /* never pure white */
  --text-mid: #b8b6c8;
  --muted: #908ea8;
  --card: #1d1c33;
  --card2: #181628;
  --nav-bg: rgba(22,21,42,0.86);
  --glow-bg-1: rgba(196,168,240,0.04);
  --glow-bg-2: rgba(126,221,176,0.025);
  --glow-bg-3: rgba(141,208,216,0.018);
  --grid-dot: rgba(255,255,255,0.012);
}

/* ── DUSK FAMILY — warm charcoal + amber, editorial ── */
html[data-theme="dusk"] {
  --bg: #1a1816;
  --surface: #211e1b;
  --border: #2a2724;
  --border2: #36322d;
  --accent:  #d99a5b;        /* desaturated amber */
  --accent2: #7eb8a8;        /* sage teal */
  --accent3: #a896c4;        /* dusty lavender */
  --up: #8db895;
  --red: #d97a7a;
  --yellow: #d9c074;
  --text: #d8d2c5;
  --text-bright: #ede6d4;
  --text-mid: #c4bfae;
  --muted: #8a857a;
  --card: #211e1b;
  --card2: #1c1916;
  --nav-bg: rgba(26,24,22,0.85);
  --glow-bg-1: rgba(217,154,91,0.06);
  --glow-bg-2: rgba(126,184,168,0.04);
  --glow-bg-3: rgba(168,150,196,0.03);
  --grid-dot: rgba(255,250,240,0.022);
}

html[data-theme="dusk-easy"] {
  --bg: #23211d;
  --surface: #2a2723;
  --border: #36322d;
  --border2: #423d36;
  --accent:  #c89060;
  --accent2: #7fa896;
  --accent3: #9d8eb6;
  --up: #85a48a;
  --red: #c47474;
  --yellow: #c8b074;
  --text: #cec8b8;
  --text-bright: #e0d9c4;
  --text-mid: #b8b1a0;
  --muted: #969080;
  --card: #2a2723;
  --card2: #25221e;
  --nav-bg: rgba(35,33,29,0.85);
  --glow-bg-1: rgba(200,144,96,0.04);
  --glow-bg-2: rgba(127,168,150,0.025);
  --glow-bg-3: rgba(157,142,182,0.018);
  --grid-dot: rgba(255,250,240,0.015);
}

html[data-theme="dusk-calm"] {
  --bg: #2c2925;
  --surface: #332f2a;
  --border: #3d3933;
  --border2: #494438;
  --accent:  #b8865c;
  --accent2: #7e9c8a;
  --accent3: #9387a8;
  --up: #85a08a;
  --red: #b87878;
  --yellow: #b8a474;
  --text: #c4bfb0;
  --text-bright: #d6cfba;     /* never pure white */
  --text-mid: #aea895;
  --muted: #9e9888;
  --card: #332f2a;
  --card2: #2e2a26;
  --nav-bg: rgba(44,41,37,0.86);
  --glow-bg-1: rgba(184,134,92,0.025);
  --glow-bg-2: rgba(126,156,138,0.018);
  --glow-bg-3: rgba(147,135,168,0.012);
  --grid-dot: rgba(255,250,240,0.010);
}

/* ── GRAPHITE FAMILY — cool slate + sky, data-tool clarity ── */
html[data-theme="graphite"] {
  --bg: #15171c;
  --surface: #1c1f25;
  --border: #262932;
  --border2: #323641;
  --accent:  #6ba6e8;        /* cool sky blue */
  --accent2: #6dc5b3;
  --accent3: #b39ce0;
  --up: #7ec092;
  --red: #d97585;
  --yellow: #e0c074;
  --text: #c8ccd6;
  --text-bright: #f1f3f8;
  --text-mid: #b0b4c0;
  --muted: #7a8090;
  --card: #1c1f25;
  --card2: #16191e;
  --nav-bg: rgba(21,23,28,0.85);
  --glow-bg-1: rgba(107,166,232,0.05);
  --glow-bg-2: rgba(109,197,179,0.035);
  --glow-bg-3: rgba(179,156,224,0.025);
  --grid-dot: rgba(200,204,214,0.022);
}

html[data-theme="graphite-easy"] {
  --bg: #1b1d24;
  --surface: #22252d;
  --border: #2c2f39;
  --border2: #3a3d49;
  --accent:  #7eaee0;
  --accent2: #7fc1b3;
  --accent3: #b1a0d6;
  --up: #84bd96;
  --red: #cb7c8a;
  --yellow: #d4be7a;
  --text: #bdc1cc;
  --text-bright: #e3e6ed;
  --text-mid: #a7abb6;
  --muted: #838998;
  --card: #22252d;
  --card2: #1d2027;
  --nav-bg: rgba(27,29,36,0.85);
  --glow-bg-1: rgba(126,174,224,0.035);
  --glow-bg-2: rgba(127,193,179,0.025);
  --glow-bg-3: rgba(177,160,214,0.018);
  --grid-dot: rgba(200,204,214,0.016);
}

html[data-theme="graphite-calm"] {
  --bg: #22242a;
  --surface: #282b32;
  --border: #33353e;
  --border2: #41434d;
  --accent:  #92b6d8;
  --accent2: #8bbcb1;
  --accent3: #aea3cc;
  --up: #8cb89b;
  --red: #c4818e;
  --yellow: #c8b67e;
  --text: #b6bac4;
  --text-bright: #d8dbe4;     /* never pure white */
  --text-mid: #a0a4ae;
  --muted: #888d9b;
  --card: #282b32;
  --card2: #23262c;
  --nav-bg: rgba(34,36,42,0.86);
  --glow-bg-1: rgba(146,182,216,0.022);
  --glow-bg-2: rgba(139,188,177,0.015);
  --glow-bg-3: rgba(174,163,204,0.012);
  --grid-dot: rgba(200,204,214,0.012);
}

/* ── RAZOR FAMILY — brass + oxblood + third color, the platform identity ──
   Three variants share the same brass-and-oxblood DNA but differ on the
   third color (used for tracked / pending / informational surfaces) and
   on the saturation of yellow + red. --blue is held fixed at pewter
   across all three variants so locked / waiting / bet states remain
   visually consistent regardless of variant. Family dots used in scanner
   tiles (Pattern cyan, Levels amber, Momentum violet, Imbalance mint)
   are functional identifiers and are NOT theme tokens — they live in
   per-page CSS.
   ───────────────────────────────────────────────────────────────────── */
/* razor-pewter is defined at the top of this file alongside :root —
   it is the platform default and lives there so first-paint matches
   the active theme even before localStorage resolves. */

html[data-theme="razor-steel"] {
  --bg: #0a0a0a;
  --surface: #141413;
  --border: #2a2d36;
  --border2: #3a3e4a;
  --accent:  #f5c518;        /* hazard yellow */
  --accent2: #d6a90e;        /* darker hazard */
  --accent3: #5a7a92;        /* steel blue */
  --up: #5fcfa4;             /* cool sage — gains role split from hazard (2026-05) */
  --red: #ff3b30;            /* signal red */
  --down: var(--red);
  --blue: #8a96a3;           /* fixed pewter */
  --yellow: #ffd060;
  --text: #ebe9e0;
  --text-bright: #f7f4ea;
  --text-mid: #c4c1b6;
  --muted: #88857c;
  --card: #1a1a18;
  --card2: #121210;
  --nav-bg: rgba(10,10,10,0.86);
  --glow-bg-1: rgba(245,197,24,0.05);
  --glow-bg-2: rgba(255,59,48,0.03);
  --glow-bg-3: rgba(90,122,146,0.022);
  --grid-dot: rgba(220,230,240,0.015);
}

html[data-theme="razor-verdigris"] {
  --bg: #0d0d0a;             /* very faint warm tint */
  --surface: #13140f;
  --border: #2c2d22;
  --border2: #3c3d30;
  --accent:  #ffd400;        /* pure yellow */
  --accent2: #d9b300;        /* darker pure */
  --accent3: #4a7a6e;        /* verdigris */
  --up: #8dd9a0;             /* warm sage — gains role split from yellow (2026-05) */
  --red: #c44141;            /* bright oxblood */
  --down: var(--red);
  --blue: #8a96a3;           /* fixed pewter */
  --yellow: #ffe040;
  --text: #f1ece1;
  --text-bright: #fbf6e8;
  --text-mid: #c8c2b0;
  --muted: #8a8576;
  --card: #171810;
  --card2: #0f1009;
  --nav-bg: rgba(13,13,10,0.86);
  --glow-bg-1: rgba(255,212,0,0.045);
  --glow-bg-2: rgba(196,65,65,0.028);
  --glow-bg-3: rgba(74,122,110,0.02);
  --grid-dot: rgba(245,250,225,0.020);
}

/* ── RAZOR · GASLIGHT / FOUNDRY / MIDNIGHT (2026-10) ──────────────
   Free variants (not in KCUnlocks DEFAULT_UNLOCKS). Same 23-token
   palette shape as Steel / Verdigris; --blue stays fixed at pewter.
   --red is a readable down colour on purpose (used as text too). */
html[data-theme="razor-gaslight"] {
  --bg: #0b1413;             /* teal dusk */
  --surface: #101c1a;
  --border: #26433d;
  --border2: #345750;
  --accent:  #e9c45a;        /* gas-lamp yellow */
  --accent2: #c9a23c;
  --accent3: #5fb5a0;        /* lamp-lit teal */
  --up: #62c796;
  --red: #e47a63;            /* warm coral */
  --down: var(--red);
  --blue: #8a96a3;           /* fixed pewter */
  --yellow: #f0d27a;
  --text: #e4ece8;
  --text-bright: #f3f8f5;
  --text-mid: #bfcdc8;
  --muted: #7f9a94;
  --card: #152420;
  --card2: #0e1917;
  --nav-bg: rgba(11,20,19,0.86);
  --glow-bg-1: rgba(233,196,90,0.045);
  --glow-bg-2: rgba(95,181,160,0.03);
  --glow-bg-3: rgba(228,122,99,0.018);
  --grid-dot: rgba(220,240,232,0.018);
}

html[data-theme="razor-foundry"] {
  --bg: #0e0a08;             /* soot */
  --surface: #15100d;
  --border: #352720;
  --border2: #47352b;
  --accent:  #ff8a3d;        /* molten orange */
  --accent2: #d96a20;
  --accent3: #ffb866;        /* ember */
  --up: #7ccc84;
  --red: #e8607c;            /* cool crimson — kept off the orange accent */
  --down: var(--red);
  --blue: #8a96a3;           /* fixed pewter */
  --yellow: #ffc861;
  --text: #f1e6dc;
  --text-bright: #fbf3ea;
  --text-mid: #cdbfb2;
  --muted: #9a8577;
  --card: #1c1511;
  --card2: #120d0a;
  --nav-bg: rgba(14,10,8,0.86);
  --glow-bg-1: rgba(255,138,61,0.05);
  --glow-bg-2: rgba(232,96,124,0.025);
  --glow-bg-3: rgba(255,184,102,0.02);
  --grid-dot: rgba(255,240,225,0.018);
}

html[data-theme="razor-midnight"] {
  --bg: #090d18;             /* navy ink */
  --surface: #0e1424;
  --border: #26324d;
  --border2: #34425f;
  --accent:  #c9ab6c;        /* brass */
  --accent2: #a88a4c;
  --accent3: #7c9bd0;        /* steel blue */
  --up: #58bfa6;
  --red: #e37a80;            /* rose */
  --down: var(--red);
  --blue: #8a96a3;           /* fixed pewter */
  --yellow: #e2c47e;
  --text: #e3e8f2;
  --text-bright: #f3f6fb;
  --text-mid: #bcc4d4;
  --muted: #8090b2;
  --card: #131b2e;
  --card2: #0c1220;
  --nav-bg: rgba(9,13,24,0.86);
  --glow-bg-1: rgba(201,171,108,0.045);
  --glow-bg-2: rgba(124,155,208,0.03);
  --glow-bg-3: rgba(227,122,128,0.018);
  --grid-dot: rgba(220,230,250,0.018);
}

/* ── MARKET COLOURS · blue / orange (Appearance B · 2026-10) ────────
   Colour-blind-safe up/down. Must sit AFTER every theme block: same
   specificity as html[data-theme=…], so source order decides. Swaps the
   shared up/down tokens, so success/error UI that reuses --up / --red
   follows too (accepted trade-off). Hard-coded hexes are not covered. */
html[data-market="bo"] {
  --up: #5b9cf0;
  --red: #f0a040;
  --down: var(--red);
  --type-price-up: #5b9cf0;
  --type-price-dn: #f0a040;
}

/* ─── BASE ──────────────────────────────────────────────────── */
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  transition: background-color 0.4s ease, color 0.4s ease;
}
html {
  min-height: 100vh;
  min-height: 100dvh;
  /* Reserve space for the vertical scrollbar on every page so navigating
     between short pages (no scrollbar) and long pages (scrollbar) doesn't
     cause a horizontal layout shift. Supported in all modern browsers
     (Chrome 94+, Firefox 97+, Safari 16+). On older browsers this is a
     silent no-op — the historical jumpy behavior is preserved. */
  scrollbar-gutter: stable;
}
/* body's min-height is divided by font-scale so the zoomed body still
   fills the viewport at scale < 1 (otherwise at 0.85 there's a 15vh
   gap of html background showing under the page content). */
body  { min-height: calc(100vh / var(--kc-font-scale, 1)); min-height: calc(100dvh / var(--kc-font-scale, 1)); }

body {
  padding: 0 0 60px;
  position: relative;
  overflow-x: hidden;
  /* Font-size scale + line-height (set by Appearance picker). Zoom scales
     the whole app proportionally so layouts don't break. Default 1 = 100%.
     Firefox 126+ (early 2025) and all Chromium / WebKit browsers support
     `zoom`. For very old Firefox we silently skip scaling — content still
     renders at 100%. A transform-based fallback would break position:sticky
     on the nav, so we prefer a graceful no-op over a broken layout. */
  zoom: var(--kc-font-scale, 1);
  line-height: var(--kc-line-height, 1.5);
}

/* Static brass vignette (2026-05 polish pass) — replaces the breathing
   aurora that previously animated three radial glows on a 28s loop.
   Motion on a page background is restless, and Peaky interiors should
   feel still — the drama lives in the foreground. One soft brass wash
   from the top-left corner anchors the room without competing for
   attention. The pseudo-element keeps the same fixed-position, z-index,
   pointer-events shape so any rules that rely on body::before stacking
   still work; only the paint changes. `--glow-bg-1` is still consumed
   so each theme's atmospheric tint flows through (brass on pewter,
   hazard on steel, pure yellow on verdigris).

   A second 1px brass line painted at the very top of the viewport
   gives every page the same "we are inside the building" signal —
   visible across the content area and softly faded toward both ends
   so it doesn't hard-clip against the sidebar's --nav-bg paint. The
   line uses a non-themed brass hex on purpose: it's an identity mark
   for the platform as a whole, not a per-theme atmosphere cue. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse 70% 55% at 12% -8%, var(--glow-bg-1) 0%, transparent 60%),
    linear-gradient(90deg, transparent 0%, rgba(212,163,53,0.32) 30%, rgba(212,163,53,0.32) 70%, transparent 100%);
  background-size: 100% 100%, 100% 1px;
  background-position: 0 0, 0 0;
  background-repeat: no-repeat, no-repeat;
}

/* Dot-grid texture — tightened from the V2 era. 22px spacing at lower
   opacity reads as fine grain rather than a regular punched-tin
   pattern. The mask still concentrates the texture toward the middle
   of the viewport, but with a softer fall-off than before. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px);
  background-size: 22px 22px;
  opacity: 0.55;
  mask-image: radial-gradient(ellipse 80% 70% at 50% 30%, black 30%, transparent 90%);
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 30%, black 30%, transparent 90%);
}

/* kcAurora keyframes retained for safety — there are page-local
   styles that reference this name (busy spinners, hero badge dots).
   The old body::before no longer consumes it, so the keyframes are
   effectively dead from the background's point of view. Leaving the
   block intact avoids breaking those local consumers and keeps the
   diff minimal. */
@keyframes kcAurora {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
  25%      { transform: translate3d(-2%, 1%, 0) scale(1.04); opacity: 0.92; }
  50%      { transform: translate3d(1%, -2%, 0) scale(1.02); opacity: 1; }
  75%      { transform: translate3d(2%, 2%, 0) scale(1.03); opacity: 0.95; }
}

/* ══════════════════════════════════════════════════════════════════
   SIDEBAR (replaces the v1 sticky top nav)
   ──────────────────────────────────────────────────────────────────
   Default = COLLAPSED (56px, icons only).
   Mouse near the left edge → PEEK (240px, floats over content,
   does not push layout).
   Click chevron → LOCKED OPEN (240px, pushes content rightward via
   body padding-left). Choice persists in localStorage as
   `kc_sidebarLocked` ('1' / '0').
   Below 900px: sidebar disappears, hamburger appears in a slim mobile
   topbar. Tapping it slides the sidebar in from the left over a scrim.
   ══════════════════════════════════════════════════════════════════ */

/* Body offset so locked-open sidebar pushes page content. Collapsed
   (default) reserves 56px. JS toggles `data-sb-locked` on <html> for
   the wider 240px reserve. Mobile (<=900px) collapses both to 0. */
:root { --kc-sb-w: 56px; }
html[data-sb-locked="1"] { --kc-sb-w: 240px; }
@media (max-width: 900px) { :root { --kc-sb-w: 0px !important; } }

body.kc-page {
  padding: 0 0 60px !important;
  /* The sidebar now renders at the GLOBAL scale (see .kc-sidebar), but this
     padding lives on the body which is zoomed by the effective/per-page
     scale — so we pre-scale by global/effective to keep the content's left
     edge flush against the sidebar's right edge under any per-page override.
     Rendered = (sb-w * global/effective) * effective = sb-w * global, exactly
     the sidebar's rendered width. No-op when no override is active. */
  padding-left: calc(var(--kc-sb-w) * var(--kc-font-scale-global, 1) / var(--kc-font-scale, 1)) !important;
  transition: padding-left 0.18s ease;
}

/* Mobile only: leave room for the slim top bar (48px). */
@media (max-width: 900px) {
  body.kc-page { padding-top: 48px !important; }
}

/* On narrow viewports, give page content breathing room at edges
   (excluding sidebar/drawer/toasts/scrim). */
@media (max-width: 1140px) {
  body.kc-page > *:not(.kc-sidebar):not(.kc-sb-scrim):not(.kc-mobile-topbar):not(.kc-nav-drawer):not(.kc-toast-host):not(.kc-cmdk-overlay):not(.kc-dock-wrap):not(.kc-dock-sheet-overlay) {
    padding-left: 16px;
    padding-right: 16px;
  }
}

/* ══ SIDEBAR SHELL ═══════════════════════════════════════════════ */
.kc-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  /* Shared chrome: the sidebar rides the GLOBAL text scale, never a page's
     per-page size override, so switching to a page that resolves a different
     scale never resizes the nav. Body applies `zoom: var(--kc-font-scale)`
     (the effective/per-page scale) to all its children including this fixed
     sidebar, so we counter-zoom by global/effective to land the sidebar's
     NET render scale on the global scale. When no per-page override is active
     the two are equal and this is `zoom: 1` — a no-op. */
  zoom: calc(var(--kc-font-scale-global, 1) / var(--kc-font-scale, 1));
  /* Height divided by the sidebar's net scale (global) so `100vh` still
     renders exactly viewport-tall — otherwise the foot (theme + settings
     buttons) drifts off-screen at non-1 scales. Was --kc-font-scale; now
     --kc-font-scale-global to match the counter-zoom above. */
  height: calc(100vh / var(--kc-font-scale-global, 1));
  height: calc(100dvh / var(--kc-font-scale-global, 1));
  width: 56px;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 900;
  transition: width 0.18s ease, transform 0.22s ease, box-shadow 0.18s ease;
  box-shadow: inset -1px 0 0 rgba(255,255,255,0.02);
}

/* Peek (transient, hover-driven) — floats over content, does not
   push layout. Same visual width as locked-open. */
.kc-sidebar.kc-sb-peek {
  width: 240px;
  box-shadow:
    inset -1px 0 0 rgba(255,255,255,0.03),
    8px 0 28px -8px rgba(0,0,0,0.55),
    0 0 0 1px var(--border2);
}

/* Locked-open — sidebar reserves 240px in layout (body padding handles
   the offset; the element itself is still fixed-position). */
html[data-sb-locked="1"] .kc-sidebar { width: 240px; }

/* Edge hover zone: an invisible 12px-wide strip on the very left.
   Mouse entering it triggers peek. Sits behind the sidebar in z-order
   when sidebar is wider, so the sidebar's own mouseleave fires
   correctly when mouse exits to the right. */
.kc-sb-edge {
  position: fixed;
  top: 0;
  left: 0;
  width: 12px;
  /* Compensate for body zoom (see `.kc-sidebar` for the explanation). */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  z-index: 899;
  pointer-events: auto;
}
@media (max-width: 900px) { .kc-sb-edge { display: none; } }
html[data-sb-locked="1"] .kc-sb-edge { pointer-events: none; }

/* ══ SECTIONS ════════════════════════════════════════════════════ */
.kc-sb-section {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 14px 6px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  opacity: 1;
  transition: opacity 0.12s ease;
}
.kc-sb-section::before {
  content: '';
  width: 12px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15));
  flex-shrink: 0;
}
/* Hide section labels in collapsed state (no peek, no lock). */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-section { opacity: 0; }

/* Brand row — logo + lock toggle */
.kc-sb-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 12px 12px 14px;
  height: 54px;
  box-sizing: border-box;
  flex-shrink: 0;
  position: relative;
}
.kc-sb-brand::after {
  content: '';
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.07), transparent);
}
.kc-sb-logo {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  position: relative;
  background: #0a0a0a;
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent),
    0 2px 12px color-mix(in srgb, var(--accent) 18%, transparent);
  flex-shrink: 0;
  /* Razor Alpha mark — layered "A" razor blade. Brass on near-black,
     so the image's own black ground blends into the box (#0a0a0a) and
     the brass inset ring frames it. 84% size leaves breathing room
     inside the ring. Base64 PNG, 96x96 source. */
  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAIAAABt+uBvAAABCGlDQ1BJQ0MgUHJvZmlsZQAAeJxjYGA8wQAELAYMDLl5JUVB7k4KEZFRCuwPGBiBEAwSk4sLGHADoKpv1yBqL+viUYcLcKakFicD6Q9ArFIEtBxopAiQLZIOYWuA2EkQtg2IXV5SUAJkB4DYRSFBzkB2CpCtkY7ETkJiJxcUgdT3ANk2uTmlyQh3M/Ck5oUGA2kOIJZhKGYIYnBncAL5H6IkfxEDg8VXBgbmCQixpJkMDNtbGRgkbiHEVBYwMPC3MDBsO48QQ4RJQWJRIliIBYiZ0tIYGD4tZ2DgjWRgEL7AwMAVDQsIHG5TALvNnSEfCNMZchhSgSKeDHkMyQx6QJYRgwGDIYMZAKbWPz9HbOBQAAAyJ0lEQVR42q29d5xcZ5EuXPW+J3XuCT05Ko5ylizJsi3nKBsbs3uBBXtZWMMCH8vi3b0buJfPXjBwwSxcYMGkxQvYCIwTDjhJcpAsWZKVrDCSR3EkTZ5OJ7/1/XHO6T7dMyMLvu2fmN946Dl9Tr1VT1U9FQbjkTT8CS8kICz/FyIR/QmX8a6B9F6fVXrrxdzYxbx5qreFb4UQACT473hNIp2Lu1Gki5biZNec5GAuUo4X+bYpBYQAGHxHABOfP/wBk775ou9gcmlOOMlJr/mnqO1FqljwhikERKVnBkCAi7+NC7z5AncW+mGllBD+219/pKlOpUHonQ8SAQIgVivRpE8rLiRI8kQefEEiwveQPFVYIAa/WDrD4PP/ZMQpXXfqS0lVcDvxNyfXi8pfQboYJaPSVQnoj1cO8v5HiCF50R+N4hNERiWIEFNhEFIZQQDQuwMKHpwq5RO+m9JpEoYFStWHH35KqhD9n+LjqFrk4fe9tzZhCEbCzzI5PkjVuoA4EQLfCwv9XxEX4ZOw6hv/MKj6GagkzP9ucAECRALE8IfSlIcmXZTPnlpF0deXi4JvQMAwvGBwjlj1oORpM1LIfBGBpjDlqZzg5A4hANXqN5RBiC4goD/WcdJ7KgsiTmbcHkJjRURTBprQJcpOHpAQkACr7tI3NKSLjLKIaHL/iAAlb0QXjoMuVqlpIqB712a+sYqy/ypJjIDKT4NAgIiO7XCJAbHKp6IJx0HM0y8CABRV4D8Vek0MoCaeLE2OQexPFE31pXw7QwSGwDw3DkTegQMDYOCrNgPkvp4DABBj5AinsSHBEIGJSrkgIkNkAYQyAOZfEwGQGAJDYsGj+VYTDizD/1k6H6SJP0EvTKHqZ+OKok4KUGG0nsL5V/zMu9eQPyg9UkVmAFgCrsAuEMi1fv+be8+PGLv3HInHIkQCAL3XJKfsCQTLXscTYSASvAgwRAg+oCoVmPhiVULxfmdS6fjnET5fAAbI0LP/kr6E//mBS/hpEQgRAREQuMyyOeMTdy5dvrbzX7740WQiZrsuMMYYCz8qY8gYIBIiIaPAtiDQKSAERPI0F5AIid7LpRJNokdV/wiBK7JWkumFHChWy5WVA9tAU4hBpWR9/cbJDZkx1A1rdnfdj+6/jlzePmeRYxjPv7A9GokJ4V4Q9z2Je98AASuFN4gltEaE9wi5PI2e3DIIvftmEw11ovqEVIc8rQHP51bFD1iyYApOmwEigZezkP8NCkIBKBDJdd0vfXptXZI7Drnm+Be+8P5li2fnC0XGGaEARoDCC7uDS7NKsy1pKIQtGpEQRUgRiEp6UWGxYoKDqZAGTQrS7+XpCVAQesEzq0YZ/+a8yAUEEDBARogldPQvLnEcyxp3XjP3lis7h8fyiXiMCYrE+f954K4QWgJ65+U9LRPICMvXKsF/GB8QgJeU7IKOBSogowrOA4F6JkaTmJgHnyHjYlg6Kw8kWZULYwjIEDw/jIC++0EARlSBTYhoO1Sfivzw/10fkZxkuvbxP/QmatLJuNbd03rm+NDr2w7GojFyCZEBAaPAqMDzjyVx4ySgihBWpWqrxzJMAxKyCRkzUkhBkSuyNjmMY5WTqgoSsNo9MQBWjnR9sPdFU311ibNc3rrvkyuvWdNkO3A+r3z60z+0Cublt6wSeX3VypmPbHwjm9MliVVos2DB4VCgMoTVyTYiAwQg8qPlKlVC76iwFBde2E0jV5XIJAEolvJAQC/QKFuvpxYMglwDmac86LtnYB4EVWd5QB6uSxLLFs0rljff/9kVuVwhmWm6/2vP1cZpz9u9PTO726c3xtLRTDKy8fGt0agmiFgAMVgKOKlse8FZEFEgCMJAiL7+eMGoZ/0UmAteFMWJXJUjFaqFMMHxEzHvQ9nE8IT5rpUCl1WywgmhB3reBgSRyvE//ue6+hSLJRMvvXH2hadf+48ffHJoKPvoI5tv/8B6ZhYWL5u2e+fxve+cikVVEuR5QoGeDIKsLhT0+HdVoiUCSSIG1ApCpVNDvKgoDxmVTC4A8JJzQgjQg/x4NZRsCi/iE0heahMAlH8RDEMdI2ACAIlQYiyXs/7qfT0LZsX1ol6wlJ/99MW7P7S6NhP7xF9fOzpw/sf/93EWj5JpfPW+O9OJqO24EPghD52JBRBHAAJAlBlrxHLK6d1gkE8zIAQQiIIFyfHkCXbJiwUWwGVFrc7c0IPkijPBMmFEnp0HMbGPzhVaynyZQWWgwRkWTWfB9PRX/2aZrucyLU0P/fwtSRQ/fvdlRsGo62pKR+TvfPupq9cvramNZtpSZNrPvLgvFlcFEVQl3mHHQmVt8g7KD7/8gJuCL1hCjUkCv0k9FZTTAz9Y8PJcDCIaXzXK3osACRlRwDchlQko8p0x+E66bM/+WQt0Eejev5ivymY0oh04nN/+5v6P37XOti0BYGf1W9+/dtH8pi/f91+AzB3Jfe6TVy1f1JXLG5xNlXz7n4KAIAIABj+wCAgNRATGvWDKhyREgV54VbrIxKzNR1yayhJ9IWAoDvZTp8lCiiC2DfmSKrTjPJtz71zfsWZhcmzMkGM1P/uvLe+7dnZLa6pQMCWJCyEQ6N7Pb9i788ATj27mEUVT4Zv/ewO7AKmCAVpjoNUh8GDMR0afW0cALzwtZYQwWQRU+eKKHKmCboYlCGIVsRZ6MBBolA/JofimzNixMHdAwBDQspzWOu3+e+aTbWQyNc9uOjHUf+4jH1xd1E0uM92AaCzu2kZTR8bMFv/z4c033bBUlahrdtP5M9kt247GYpqYoiiAgVsL0NPTdwHVyTNgIDIM/eYkhoYlLoqqz5lVUA1YQT34YR+DctTn5xClEJm8jBUEgADfbzEAQgaWI+65fUZdgiPicAG2bNn/oTuWCiLXcaOK/N3vv/iHF/dqyaiVL37k7svSUfbtbz3BVdUZH/tfX7h6ele9YdiMsUlzK/JZp5IDQz8j8oRWEU8ShoAGQbD3Sv6DZLWcKJTYABbW5JKDQAobUkCLYphiFiWs9sNChrmCdcWSxntu6xzPGi2tzb94bM/86cmlyzqKBTMZ197a3X/ixEBf3+Dihd1RlUcS0Yb62A8fenFeT2dnZyYal5pqEo88tScaUYjEZDTIpJRFGaHRU2esSDkwVIuq5MrLl2KAXJG1QBEpbDAhdgKQeZWNquiZSrzKRLkTMCKfzbKFm9Ckf/3orJhMqVT04Ltjx4/2337LAtN0ZQZ53dm27ej+fvfcQF4la8mKaYVscUZP+7u9Z55/Ye+NNy0jw1y4oPXAofO7DvTHIqogqmRzSnojJqSWoYAIICCS/N+l6tho0gcJaVAIY0Nv9QNWj+BkHr55ihOYL07kzoJYFgGIcSgUxd03dFy6IK3rVjSRfPLZfTdfOzMSkVzLVWPKW7tOnhkwfvbKgEU8YecbmjOtrSlhu7NnNm787TbX4StWz7BNa/n81l89sc+0XcawTENXRaXVxadSISuUXYQfsJwGTcmZcVnR0CewCIABMQzbpUc4EMPAuoMfQimIDxcrPEgu57cMi4ZYMC31qQ2d2bze2lK7eevxlkxk3uxMsWhrmnTmXO7MqbEnd+ePnsnmDEhGuNDHlyydZVt6Y2MNA/rFI6+vXDGzJh3JNCUkzp564VA05sXWZQ45RAyGea+y6iD5aIxlOyDEgJwM1yIxfB0Az8RC51CR2fkSKHmrifG4x7GXvF6gw6FyLMoo/vb27ro4qZoyXhCHj5679rLphaLJEImxg4fO9w3jIy+dmtbZ6Aj3/LjRoLiKyufPbc/ljVmzW3a82btrz5nrr1qoFwqrFnds2XGi98SopiokWIhXhBD0ihBe+1hBPocZsjqkqnqYH3CXjdSXFldlFX1yp0SN+u4pCNsDjSJE5iOvH1H6IE0+NVOJURJned25ZXXm6sXpXMFoaEht3nps3fIOibuOC1pEOdo3qOvw4z8MDA6P/vZX/5JMSH94aVcsnpQL49Nmt8WjkqJKLU3pX//m9XRNat6cZiJ7dnfDo08dAM4QQFCJAPL0iCFiJcpScHMlGxM+80BY9nHEJs9aEcCjXEsJICt5rpKREoXUB7GsuowAvAwrkHoFGHAGpi066pS/ur7JtJxMfby3byQVU6d3pXN5W1V4seCMDBff6HOfe+3on9225gv//OcL5rT9+jfbjvZnW9ModGvhkmn5XLGzo2F0eOyp5/dddulczmBmV3p03Hhl68lYTCFRsrBy4Qer2Z8yb0XEsMpnYSnH9h9qQgwKXFVUPx0FVr44C2gd4iF7EqXavR8MlnQHWBUBgIi2Kz5yZVN7vSwAIprW2ze0blXn0EiecybL0snTI7oTe/C3xzRV/sWPP02u3dDcXJfWNv72VYtFa3kxXZtqa0ubpj1rRvOWzfvOni9cunpWIV9ctaTj+c3vnhvWFaXEoQZOqZoyxnDnBcOSl6YKawOswB2q+J6rilqugkA4kYdJqLZQUhFYO04spHBkBdO5ZHbqhmU143mjozm979C5JfPbHMe0bFeT+eBIXpWjD28Z2nvo1D9+6ro77rrittu+Njaa/8Tf3Pnqlt073j6ZqYsxPTt7Tpfr2IlULBWTH3vira6u5pbmVFRhjZnoxmcPKarkMyEe0TRlmQqxqt0rkBigAAQGvFTQxbJClTBIURGw7LrKKIMl4yQUyMrOIkhlvVCQVx0dAtgCUlH+kSsaAJ10IlIomCgp3W2p84PjqswdF3TdODWqfXfj/tkzWx7+0ceff2L7/d98cv/BU3d96PJLls/4+S83DWRFdxoQxOxZzbmc3tnZePrk2a3b3730kpmGac6f1fDuyfG3DpyPRxXyGlD8MI6VQxYsqweFbdBjWn3sZkAIjIBRwBdQKaXy3byqqJWBj1cAJ59oRqgq21QqMAtLx2P7GUPTcTasqJ/Vopq225SJ9Z4YWb286+TpIZlxWeIjY/lkTeNXfnVkYDj30wc+MHNO820f+YFh0dBQLp/N/+U9d4ydO/fCpr1yNJHCfENzfTKuCsCO1rqXXn67qOPiRe2Gbi6d2/zUS7053WGswrVOSK6qOkZK0TOGQQd9aqYcNWGoshoJ+XYRkDglWCkDc2XEEfCDYd1BZIi6LWa3RG5ckswXjbbG+PGTY7PntFvFYlG3ZJkXdCNTm3xud+HJVw7detW8L9634YF/+/3Gp9+OaJqsyjt2Hrt6Teedd6x+dOObB0+MTstoYBRmzm7XdbO2Pimh++xL+2bPbE3E5bq0Fo2oT28+FonIfv7nlb0rfUoFZhMFZHGpA0CUAhL0iSL0+yx9jEauKBpDFg6dw8Q/QIimm6IqW+U4ZA63r6qJqaBpnAhdJk3vqOnrG9Q0SQCCcCjW+MWHdimy9Mi37syP5j967+8IWWMmwThm8/o7B8586lNXtySkRx5/K+8qnWlistLeli4Ujc6OpnePnX7n0ODyZV2FvLFoTmbPoaEjfaOaKhFV9KHhZNRX4OzLeRmVMLRMYFBYxr6AArXw8ifPS7FQERMqC98ExMJiK4E7Ryza7mU98UVdkaLhNGeSJ8+Pr1k2o/doP+OMM17I6zNmd377N317Dp3+7IdXffB/LPn4F57cfficsN2ffO393d1NL2853H92tC4i3f2Z63du7d26q68hk064heaWJs5AkqWmTGLTq++oaqy7o861nTnT6p985ZhLExG6kqcJSH+vbSq4YapIQMrlDgr/lKtqBMO5PJbKfxT8UJRSjBArXu1TGaLlOM0p+eYladNy6mqig6PZnultlmkMjeZVWbZMu7kp2Tca+cbPd0zryjz8lRtf2NT7pe++LjF53ZLMP3985fI1Cx57atd4wd655/iHb1l+xaruh3+z4/iAMa8tYpvFru6mYrFYX5dyLXPz1t45PW2Mi/bGuGXTph1nohGZBIV1ZSpS3qfLqBzKlJWo1NlWIjMQuKpEgryDfAmF+UJGFQGFL+rJjAsBBFy/pKY+DoAsqoDlSj2zmvYdPhVTVEAUrjNtZtc/fHfn0GjhG59bO39O5sP3PjuYNeJR5V/umt/YmGjs6ayLaI8/syenu0NnRz726auNofHnNr0jZK0zBWo0UpPSDMttbkodPnTqdP/4onlt2YKxaHbD63v6+4d0RcYQcz15ZacUEmOIKi5jNitlH+XeNzZZq1IVp43v2U6GiKZF89ujXQ0sW7RrUtKZgfzSJV2HDp2WUCKAfF6fP7fzsTcGDx7tv/qSjg9eP/OBH27be2wQiTZc2jyrRbWZJrKFP79z4Q3rZzMGv/r97hcf2/EPn7lq3szmN/YPnh4Rfb0nDQss05I1bf26Ob3Hzry9/xwik5n43AcXcXABWUUNvKwLk3RdIjAQpcCYyt23oT7ckpuPVJVIgcIE5cQmrGr0AQQhKKHBdQsT4IpYXNGLZkdHoyZh38mRiCpZjlOb0uJNXX//jS2Konz33kuGs8bnvr6VkNrq4/fc3N7WkXnhlf0uKB1zWue2xB99cq/h0P53+j/xFytba6Mbn9k/UHCXdERMh5oa08WiVVuf1PP5t/aemTOr1bbdGW2JwVFj56HBqCaJcjv2BaE6iJfKp44T62WIfmW1ungd4g2qe+vKPGEIfchy4NKeWEsdOjbVJmXdwuWLp7+566imSYioG8alaxc/8Iv9ew6evOvmnj+7Zvrnv/HmgROjDNmHr25dMDMJkhZTnJ07jy9aMKO9q2Z8RH9tx/GzQ9kIsk98bN3be0+8setMTW0soznRRFJRmBDQkEkcPnR6PG9On5YpFMz5MzKbd54eLwguBXQhlq2sFIX4HVwUbrKmkKP3cn8Mj4dcfAseTdVhYzjUleE9TUqhIOpSyvmh4qqlM945fFK4AIS5gjFnRuOB0/aTLx2c3t74iQ3dv3n53T+8dUaWpfmdiQVdUUWLWPrYlVcu626NPPvE68Ckz921cnZ3jcT5//nJGwf3nb7vM1el09rv3xwYLVLvkVMEpBd1VdPWruo+fKT/xPERIag2hh/f0GNaNqskFUsiqCjPT4kZFcbl6RpXVS0odUM5Pvc1iaoIuonBIQDKHNb3JGUZVAXBpfrG2obaxNsHjscimgBX5rRi1aLPP/jGyKj++Q/OmtYS+/v/+3ZWdxUZ77y0sas1XlcXbahPSApMm9b2wvPbOtq6WtpSSY0/8eJh3XZOnRr97N2rxkbzL289Lpgyt4VbDtSkIoZppdPRQjZ7sHdo5vRMUbdndtT2nR4/cjqrKbwMNROkExhW4K1ZZetOuBwUtIn8/3gh2La7oF2pjaNp2XGVZw2xeMG0N3f1KprmAssWzNUren696eyBI6cvWVh/7dLG/3j82NH+AgKumJ5oSkt1NdHammgyxo2iEYloa1dOf/6ZVxyL7rhqxvXrpjHgz73a+8vH9/zdXZfMmV67Zc+54yM0eHY4p1uu41o2LZrfJmxj557TnDPL1D926+xUTLJdgRfRt01V/b5TVAdZKeHyLTMY6pgAQBO7GcFxqSHFe5q1omEnYvLQaGHV8pl9J8/mi6aETDfN1kwSYpnv/WpbIhn/8JWtB/vGf7PplKJKNXG+oF1NJtTmxkQsGdWLOYnLhbwxf8E0ZuV27zmixZR/+NglqZgsOL//+6+ScO69awUI97evnpM4P/7uADIwTVvSoksXtfT29g8MFgxDtGW0P7+qq6g7lcQNUvCapAYi2KSjLaVWMVaRzdF79D5UngByFIvbNU4CGIJt19bXZeoS+/efimiqEGQaxuq1C//90b3jWf36pQ3dzdGHnu3LW4DgLu+OxCPSzOk1yYa0WRgj8hJdclyxctXs3W+8PZp1Fs6qu+vWOa5Dh06OfuXH2+68pue6NV1HTw5vPWpw1xkYKCII3XAaG+umtad27D4BSGPj+s1rWhZNTxYMh1WwyO85vzFlZMkqh2mmKsL6hcBwbGQ5NL1ByySxYLoJTRotWKsvmbF1xyGUJCDIFwqL53cePQ+/e35fa3P6xmW1m3cP7Dg0pkqsrVZtTUkdrcmuGa2WaViFAmOMS8g42LZb35BuqYvteWs/IX70ljmzO9Myl372+P6d75z7wkeX1qSjj205VSRpeGjUssGxHcMSc3sahW0feXeYcwASH71xhiKhG27RD6jkshKxMMHGQo36iBhmGUu9qhUNn5M2tlXomhCQ0mBOs2TbIqpJ2fHCkoWzhofyZ/pHZQltV2gKX7hk/gM/eo1z6YaldQLFrzefQ+Qyo3ktkURMXrGsQ4rFsgPnuSQzzo4e6bctwSWwLXv23LZzp/tHRrOZ2sinPjAXwc0V7X97aPucrrq7burJ5oq/fX2gNqH2948xhpbluoIvWdDce3SgUHSKht3THrthVUuxaHkcF4UnEMKjPhfqzCzrAQsZXGVKPNGmRDk4F0LMa1UVCR2BEiM1Fp81vfH17Ycj0aggNpYtXLlu0eOvntp76My8ruSyafGntw2dHLYYg+6MGpXF/Ln1LTPaB071C9thnNkmOZZ7vK9fkyXhgixLbR0N7+w7SohXLm28bFkrIntl98lHnzvyl7f2zJ/ZsGnn2XeHhER2NmcJ4eSKTiqpdTbH3953lnOeK5gb1rV2NsRMS/gOK5hQKUsBg6ws/Lg4SVMGK5OQ9J6G6n+1XWqtkVpTkm6KeJSPZ/V1q3t2vH3UtoGQdN3uaq+LN7d+6+db44nEFXOTJwb0V/aNKxKPKdiaYo01yuq1s8byRrb/nKwqtu0IgO4ZbSNDY4MjeVXhtuM2NKRNwzh3dlBR+V03TU9GJM6k723cZ1rOJ2+bJXP6yXPH06n4yOCoEEiuO5q1Zs2s1Yv6yTPjABhX4APr24Rwq0IbT0ZlyMbqkl44OAiKfOXH9+gmmkrxPLN0CTQJehplSwiJc6OoT5/RBiTeOdKvahIJNCz9+uvXfPPnu8bHi4u6og0J+fe7hnTHBYDOWsbJvWJdd6qt6/i+Y1xiQhAIjMTTn31gWzQRP/XuOUBOAK4Qra31fX2nXJRmdqQ2XNYuXNF3Pvv9X+9fv6LlypXtx06MPL9nJFOjnh/ME4LpiLzuLl3YeOjIOdty8wVz+azatfPqiqbDOEyecyAEdG2oCOg194SUjpV0gybToUoHgAggXJrRIEdksBxXkQUBX7aoa9PrByIRFYiy2cLaVXN7z4nfPPN2U0NiUZu663i+t9/knNVEISnB7Gnp1VctO3boVHF0RFYVy3JaW+qf3HzusZfeeXrrUE1Kfvf4QESVHJc0TY5GtYGz51VVumVtR3dTTJL4xk3Hdx0Z/qtbZtalo7964YSJEWGZuiGIaCxrpZOR9pbY/sPnZUkyTON9a5tr45LjEkyWjxFd1GxHCMdCnfNTsbq2oPo4a0txwwJNYflsce0lPYeP9I+NmxJy26F4TFq1asH933tZUvj8Vk24sLU3x5BJQE1JSZXZ+26ZV3SVI7v2a9GobTvpVHREVx74yY5EKv2jje8M69rYyJiuCwnBsZ36mmR2bBzIqU/Jt1/eAS7olvj+xgOdjZHbr+rK561fvHiqu712cHCcCIjo1Pn84nmtY+PFgaGi7VJtSrplZaNpuiVXFB6GIr/xjSaUCyuaZli4cQYn9A2HTIwEkcRwRkYmEsDIte3mlvr62viOPX2xmEaA2Wx+ww0rH9t8cv/h052Nifa0tOtEcbRAwKAhISuOuW5545wVi7Zt2i0cC5EJV3R3tX3zv/adOpsn4Yzq1oO/3NfWUtd79KwmK0TgCJFKxYYHR6IxacmsxLLZKYZ8+6GRJ7ecfv/lHT3Tki9uP9M76NQnlbFxAwQaujs8YqxZ1rrn0FkEzBXMNfPrFnTFDMPByQB40smCingyaALyGwHCUxETbc0V0FHLkio3HYzIzLScyy6Zs/mNw4xzAVAoWjOnNaebp33jx1sSyXh3LQ5mrUPnLImhxrFWdRtqtTvev/Lo8eyJA8ei0ZhpWJ0ddbuP5X76u0NqVPr7v75xWnv62S19e/v0mCrOj+RkiTmug5wREQk7EVc2XNIa04hL0n89f9Q07Q9d2SVL7KGnjjW1ZYrZouMQAJ48O15TE21rih/uHVSZ7LrOhjUtmsRcMXn7EIaQuyJTq8CgC4aYRIQAjgspBdvTiuW4iszzeX3lkpkDI+N9p4cUWSECyzRu3bDuwYffyGaL7WlJk3B/vyEEEIrmOHLHvema6TXd019++jVZk11XqBq2tLbc94Pd+Xz+ujXT//UrG/7i9jVCWF9/eF+msfl8/yAyjsB0w45EVL1o1SQjHY3q+kUNLrlnRqxfPNu3cm7tukWZ3r6BF98a6JlZd344J4gQ5YO9w+tWdJ4dKY7mLdsSHfXa+kUZw3Rwym4yvEC+xi4iIfVCUeqqkziQAGDkJpKRnlmNL716OBaNCxJj44XLL51/fEg8+tTuTH2yPgLnRs2hvEsIaZXFkKZ1JK69cfnmVw4OnBnUVNUyi4sXdj/12vAzW46l0/H7/+4aMZb9fz519bw5nfsOnnn05ZNtjclTp4cVhSOwfN6JaDKSG08oa+am22sjksSee+vsvmNjt13aXFsT/89njrJIMqJgQbcFOGN55/xQ/rJVHXsPnZWYlCualy+s6cxE/LDIp4XYBPZj8q41NmkXG1W2LTouNcblVJRZjogoLF/Ur71s0dYd7xqWTUCOg7G4vO7y5fd950VZ4Q2aICFOjAnBJI5UH0WFw603zSqy5ObnticTUUO3GjLRaLL2Sz94Q7j2Zz68asHyNmskX9Oc+NIXbpa4/P2N+wssauumabqcM902dMNljGrS0dq4vH5xHZIwHPzVS8cbUpEbljfl8uZPn3536cLW0dEiCZQ47j8y1NlaW18XO3Z6hCHKyK5fkQEUZTLDHzsPhzx+E73AUA9PdbMuThJFu4JpCraluesKzqig6wtmtRE6Ow+c0VSZgEbGs3922+VPvXp87+GTDelIUqGzedIdBKJMhElC9MyIr7h82dOPbzeKOnDuuPYlq+b+4LEj+w71z53V+nd/fambNbSo4owV77hj+Y3XLhgaHv3er3u7uzKn+0dkmclcHhwtIueyhLWZaE+zNrcjDkj7T+Q2vX3+8kW1szrTz71x4sQwzehIjowXPDjZuef01VfMOd4/ZlhuwbRmNUdXzEwVLcdLyatCxynTWd/EqFR0Jb+7N7gIAgC5rWlZksghQmQMcc3K6c+98k5UVUhAoWDNm9nS1NH59YdeSSQSDYowHBjUCRA1LpIqajLdfMO8EwPOzq17E6lYsWgvnNM0bsnf+NlOxqX//ZkrUhkNhTsyZiIQCPe+e29Mp5OPv9y794SRikpj4xZjiCAGhgqqKtUl5URSWTM7EZUROPv9m+cKunX9sjpV5v++8cC8+Z226ViOy1A6czZXGC+svWT63kODkiQVdXP9/Pr6hGS7/qwbIpYmN0MpCAU5l1/vZxcYm0MkV0BNhNdqaNkkc57NFq5aM2ff4XNnhwpMkoiYZRr/4wNXfONnr49n9UycKxKeK5JDCEQNEc5csbgnPXfF0icffVWWFSFIVWjt6llffmj3+cHhm6/suXPDPJEzdBtu/shDew8OgCsWLm2758Nrbct88Jf7a+vqhwdHGTLO+eh4sai7akRtbYxmkvKy6XEgMZB1n98+2NMWWdqTOnJs6NkdA2tXdg0M5gU4sspf3XZ0UU+LEuFnz+cEsZjGrlqQcVwRajmnyZRmUrqj3MGKpR5WApQYNSUlIYABmpbV0ZpuaqzZtO1IIhIRBCPjhWvWLz81Do8+vTNTF69RKGeIvEUAkJQxKrOY5tx084ode04fO3g8EdP0gnn1mo49xwq/fGpfKpW8/3NXkOuwhPqdn27buvvw/Q8+DZyLnHHv31wzZ2bz7gNnn91+tq0pNTiUkxjKTDp+alhV5HRKra+PzG1JNKc1xnH74dGj/cX1C2rra2M/eHR/oiZdl1YLeYcEGA5s33ns1usWHjk+TAC66czris1pi+uWYFhq6Q4jjAiq0qKUW7EJqVqZNHMFNca5JoEjBOfMsuyrLlvw/KvvEHAAsh03ldCuuXb5Fx/8g6Swek0A4ZkiOoScqC7CUdgrFzdnujufePTlWDKmm05zvdI9vflvvvxa0Sh89iOXLFjcQiSOHBj56kNbUum63z2z+3eP7WIRpbZe+9LnbwCgrz28d6gArmGalssY6YZ95mwuloh1NEbTSWn59CS47ohBT7w5FJPZ2p5UtmB969GD69fOGR7NkwBFkg4cOi9csXBB54GjA4rMbdtePz8dVcAVMEW/dYla9QURGqgrt88jEgqiuIrNSZmEyznLFfRLl3dLMt+8rTce1xiD0ZHsJ//y6v1HR3775Pa2TCzBsOgIQRiRWI0GEYmlVPvuv7pm82tHet85kUxFLcu+7ZppRQt6T45decnMf/n0eoVcFond80+P7zpwLh7VHCH2HDj9F3eskIQzb1aTY+QjaNen1K7WaL5gMc4QcWi40NiYVriwTHs8a8ZUntC4xkmTsK1GGdPF2++cW7+qOxnFd0+NKApHgOMnh264et6W7X1xTeGcxaPIBD/cn5clRmWmhwVCYcHQJ/PHoTQ1WpmHAAISIWPQnpJlDsAYA6pNRq+5fO7vfv+2rCgMmWFZ8+e0XXf1qge++VhtQo1yJAJJwpSCSRU1zpCcG6+e1djesvFXm2tqko7tzp9Rc+1l0zK16oYr2m+/fp6qRFgi8tSzh7747y+lUzHHcaOqfOL0sCYp66+bR4XiFava5zdb7Y0RQcC45AoEABKsUDQ7u5okYY2NW3EVZzZHpzVGOANk0JSSTd3qOzH0wfct23PgJGcScpbNmZrCFy3q3rTtaHdLynGorV47M2wN5w3OeXXLOWF5pNH7Phmv8f9/5ufzRETEJAYRGQQRR3QE1aeiioT9QwVFZUBo205bS40r2IlTA4qqCFFK5fx8jjHR0VqTzeu5rKEoMgm3riaWTEbGRgs3XDb9S/94A5imScrqO354pG84osneFYQgieO2pz8/Y1otIHzv+89/5z9fS6dilu2WKsmu6yZTUWHbuiHyBRsZkPBWCiBDzBtOsWhN66gpFk3TshEJgVkCprXWHD05HI9InCNDyBVoMGdxXiptML9dl4J9SRQWkJdPlPt+/YVJgoBQeB7RcQUIkBUUJIA4ILdsG4BURREksNSajaViHVqWwzlyzry7cF2yHcHA3fbrv166IIOafP/XX/nXb71YW5NwHL/jmUt8bLzw/hsX/fond4tCfmjMWnrTt8+cG9c0RYSIG9cRiMgYMs5ICAr5JM4YR9QtR2LE/cktRsgsy9EUcL2BQwLGQWaBdydWmm6jYGNDSUBckSNBssrKDXoegHv7HhgigsRQkrwfMo4AjBRJkiUOQMwfj0IM5hQRkSGoMuecIQBH5IgRVSoWzP95z7oP//lisKwjvaMf+6cnZVUpF0ARBEE0ouw+cHppT2vP3OZYXOpuSG58dk8iEeEMFc5lziSOqsIViUucMQTOUGLIGXrfeJLSJMY5IAPG0LthTSEGXOIoMSZz5IC+zyIGEIqdqbQnxbMIrJ5Ww2CXAWPIOJYn6zDU3+orit9DPdU/Km0cQ2AMc0V7envN5z66zBrNoqJ+8cFXxvOmJHFRQS8AAUiy/M9ff6aQNZ1cccONPTdeNmtkJMcZEpRAAAiISEzcXxj66FIXJQMgT8uJgAQRAOfMaxis6P0IMa2hYRZVASoxh+S65LpAAEWDdN3kMncFCcFcAS4JV5ArSARfhSAhQAhwBbgCBJErQBAIQgEkyPsegEAQ2Lb90y/fsPiSLh6LP/3kgS9+Z1M6GXEFYal5MrhHTZNOnByKquoVNy1kiJcv6vzFU3tyhsM5Ly+wIRB+FIwCvI/2tliQ99UlEoQuoSAiAkFAAlwXCcEw3UKxIMkSAQqBLBis83c3eZOEwdQXxuNJIJ8YQhCZhKzKzLCcOV01zc3pTVuPc46MAQDz7YfKfJEgEEFY7nF6obVnIWqTgCEyVVm9uBUBUZI27zh5diinypLfFSYqmG+G6AoRVaXrLp/FSEiKvGP3yZHhURLCY5I91Q3GjpEBYTBtw/yEPTARCnV4EyBwyzZnTmuZP7/rid+/6biuxPhoUdiCIXpqJrxlH6XWakzEkgSIyFxBDUlpQbPsAktF4D+/ev1vXzz5zZ+9VZ+OcA6KxGUZFYlxLiTGZIlxhpwjZ8E3HDjjjAFnyDiwABcQQeboEv/m4ydOnisCQxAQjSmKxAUFzX2VAvIeXAjK5Q3vcDWZf/nTKxbMTuXHdeG6jiMc13Vs13GEbTuOI2xb2LZj2a5tC8sm03Jtx/V/7pLtkOm4tkOOgKJh1qXijzz8jy+9sPWxjS/XpWN9g+YTb43KnBG5QYNrSaNR8pvnBKkStKVQF0LPFz/zgaXnR42v/Wi7FFGKlqNwJPK6H5mnkYyDJKEio6agInFV4YqMiiKrMpNlpshclZBLKEsSIGVqIj977syZIbuuNu5pnBAeFOBURTgiYAxr0jEA4AxGs/pLuwf+9rNrRa5o265l2pZpGYalFw3DsAq6UyhYhYJV0O2ibuWLbl53dN0xTEc3BVmOAy4KJsC1XIFcOXh06H/d98t/+/rdQ2dOnzp57rLWzIkh662j2ajGXFEdW3NVVoGBENCellNRKV+0l85IffajS/7hG28eOZ1NRhSGwDlyhowjR+SccYacMeY5WkTGPEcXtFcTAZAAIEGuEKqMR88YDzzyLpcYEInKJoIpN19hmQl1BUVUZe/Bs82p+PIF9UNDOdO09KKp67ahu7ru6LqlF23DcHXTMQzHsoRpOabtWrZwbNd2yXHIdckR4LjgOkJR1d37+5b0dK5Zu3Dbtj1AbmdDbG9f1nTK/E+ogQqZSyypUjrCLJu4695zZ8+Lb5x6ccepmqQG5Jm3pzqeKICVlxv5LVvgez3wJhY8B+HZF5eln//hTMFwJQ6TSwermo0JJrDornAjUe2BH715+mwxEpEAETlHhsg9KGKMeYfGOPPcE+PIGLLgxZFzxhjnnDHOOJNV7asP/i5VX3fV+hVjWb02wa9aXG861a0e3noclQO0pBRZovG8devahpU96Y99Zfto3hEuWrZwbGE5wnaE6whHuMIlQSQEuURChJbvBIEQA/+GCVgqLr+2f/yXL52ORRQx1UJUTzqI4e7iiTqmyOzcQMF2xE3r2sZG87ZtGYZp6qaum3reKBSMQl4vFIr5fDGfM3K5YjZXyOcLubyez+vZXCGXK3r/8jl9PFu0TeudY8P6ePZDf3lT74HewcGx7pbE2QGjf8ySpYrCF2qRZCaOzXHJtKEzIz30hbkjOfuN/aNRVRbgJWJ+CwljiCgkhswfmyeOyLBkYMgwtFmTiHEsWvS3P+w7PVLQZOYSh/famfWetW/Xtl/40YdWr+kycxYhuoJcgY4DjgBbgCuYK8gRzHbBcYVL3k/AdoUrQJBwXBACXJdccoVDDKxbNqwePHrkJ995mAEM5/A/njnheHODwcFLEQlrVe664LhuXTLx+OtDwqFoTDZtIiABQgASARITPrgIIUAIAvKqboyIhBBEKEgIQiFIuOAKN67x1w4Vjw/qcU11ycHyYATSHyGmIPZHYohFW/zTt1/7JxNM3QTGERGYRIjeoitgMjLub8FBxpjkrR9h3FsbhzISU5EjMGQMBBB/5amXkSCeTA2eG26ujaxbkHpm+0g8KpUzm7kt9VHukang2mRaLqEfvnlK4RW2OSCiQIZB8sEYCv8t/gQdIIIH3ogocyrY8NYpg0mSN2vkz/9SeTSrlD1PuTkdw3tt/Xy0WLQWNbOuRsmwhBBAAlzhCpdcAcIF1zst4Y88MwRJQlkGmTNFApkzWeGaIikKUyWuyFxTJMYwGovKMpcYyZL8vWdOHzlbVGXu5WWS4ZBhezstgCMyifvTp8EGBfS3tCEF4vLXiQBj/uAhUWl1R9CqLzM8n7MZA06u8IJ9f9aPQp0Q5WtVd6ZWZAChqrEQmiadLWJU10gIAUTCvz1gHkVYClf9lgWbocWAI3IiLhi3UXKR20xiyJBzRsiIBgpepBhReH1aOXquUG71iEZTQSNIeZEqTlpBRFEa7/NZ2dKNVO4X9bafMUTOXKruY6va7UiTdbMFfTlEE2stCCAIXDGxBRPDXdFE5K928QXmr9Ui18sjBQAI4OVdeCXQYShL5VXBEkeESXbiUnVvR3mTSRC/BwtJoaJ1NrywWVBF5TY0ogdVQwA4lYlN3IXuZcier4GJ3T1YfpNPWbDyPA8RASuHFeTPcla0ApOAcP4sVfc3lMd2g12sfjMsASEyRkgEAgiZ35HupYLM21oWOtPwVlYW0hoKPUppJTBW6U5pJn6qoHLiMugA3Zi39qi0Wxm9fJb8bVmerxDA/IX0F9jBjwgAUnXx2bfjciyL3qoZKC3hFf6nUmmhJJu6PVRUDvaVSlLw3/PyCw+hYwjKM97K4fI+9QCYqnrxylu2qDxPF25nkJCq/zQFQXhbNSfyploEoCAPg/x6G2Gwb9KjE0sjEJV0TMWiP6wYYKyqNbFqQyqvUZjCEgPRlHtWiTDYIhhu56FSddTTnXCzS+W0YoWR+8lqGW4n/wMrJBAZCy7geiRi1R5nCnY8BeOeAtGDv9J0O0223ZcmVz0UkzQNhLZElwmMSft9gt5Ueq/U78K6Cd7C7fIWivAdE5YPlahyy5o/3wzMjwT8VWEUmo0k76C8RxJYYohKuj7lLGzZXqhiAKk09Vdarws48fcwtJeDEESJFA08mh+OTfFHTiYKqKJNc2LQRhWt9QCIobMlIgwWYvhD9kThzShUMf9HodEST6YiGJENNhh5MvWxgFjJ9/pvodLK06ot5FUBh6c34bX+ZdD5I/9ehTTlhgXCys5YqEBvBgACPD/grdZB4e+YE6HO29Canor2WiRkod1/WO6R9GreXsxVLnH6QBn+IzmlAgz563qC+IuoBDJUPSDg7UOZHEcm/xsVf+RO+1JCRRRe4kbBhCJ5I9HgBbYUjqcqIlCaBD7IX7HnobxHvlfPTE6wRkIWPkoCt1x6KFliRUzwR0KSdAHzm1SnghApvKUroClFqCG51DRJgAL8Qb7yeJ/XZ4LhJrbQH4/x57ax/CdfKisOnimiPzSKxCgYFcDKbnAqr35Dupg/0jXh9f8BBtHJdfDKkfkAAAAASUVORK5CYII=");
  background-size: 84%;
  background-position: center;
  background-repeat: no-repeat;
}
.kc-sb-brand-text {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 2px;
  color: var(--text-bright);
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.kc-sb-lock {
  width: 26px;
  height: 26px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 7px;
  color: var(--muted);
  font-size: 12px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s, transform 0.22s ease, background 0.15s, box-shadow 0.15s;
  font-family: inherit;
  line-height: 1;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
}
.kc-sb-lock:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 10px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* Mobile-only close button in the drawer brand row. Hidden on desktop
   (the pin chevron is shown there instead); the mobile media query
   swaps them. Reuses the lock button's chrome for visual consistency. */
.kc-sb-close {
  display: none;
  width: 26px;
  height: 26px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 7px;
  color: var(--muted);
  font-size: 20px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-family: inherit;
  line-height: 1;
}
.kc-sb-close:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
html[data-sb-locked="1"] .kc-sb-lock {
  transform: rotate(180deg);
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 12%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 10px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* When collapsed-only, hide brand text and the lock button (the lock
   is reachable from the peek state instead). */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-brand-text,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-lock {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}

/* ══ SCROLLABLE BODY ════════════════════════════════════════════ */
.kc-sb-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
.kc-sb-scroll::-webkit-scrollbar { width: 6px; }
.kc-sb-scroll::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }
.kc-sb-scroll::-webkit-scrollbar-track { background: transparent; }

/* ══ NAV LINKS ═══════════════════════════════════════════════════ */
.kc-nav-links {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 8px 8px;
}

/* The shared liquid-glass pill — single element that physically slides
   between links on hover, then settles back on the active item when the
   cursor leaves the rail. Injected by renderNav() in shared.js, driven
   by a small bit of JS in initSidebar(). The pill IS the active/hover
   indicator — individual links no longer paint their own backgrounds
   or left-bars. */
.kc-nav-glass {
  position: absolute;
  left: 8px;
  right: 8px;
  /* `top` and `height` are set by JS (kcNavGlass.moveTo). We give them
     0 defaults so an unhydrated rail (e.g. JS disabled) just shows
     nothing rather than a pill stuck at the top. */
  top: 0;
  height: 0;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  border-radius: 7px;
  -webkit-backdrop-filter: blur(8px) saturate(1.5);
  backdrop-filter: blur(8px) saturate(1.5);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    0 0 16px color-mix(in srgb, var(--accent) 22%, transparent);
  transition:
    top 0.34s cubic-bezier(.34,1.2,.5,1),
    height 0.34s cubic-bezier(.34,1.2,.5,1),
    opacity 0.18s ease,
    background 0.2s ease,
    border-color 0.2s ease,
    box-shadow 0.2s ease;
  pointer-events: none;
  opacity: 0;
  z-index: 1;
}
.kc-nav-glass.kc-nav-glass-show { opacity: 1; }
/* Locked state = pill is sitting on the active link (cursor not in rail).
   Slightly stronger fill + glow than hover, so "where you are" reads
   stronger than "what you're considering". */
.kc-nav-glass.kc-nav-glass-locked {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 48%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.1),
    0 0 20px color-mix(in srgb, var(--accent) 28%, transparent);
}
/* Collapsed sidebar — pill hugs the icon column rather than the full width. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-glass {
  left: 6px;
  right: 6px;
  border-radius: 6px;
}

.kc-nav-link {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-radius: 5px;
  white-space: nowrap;
  transition: color 0.18s;
}
.kc-nav-link:hover {
  color: var(--text-bright);
}
.kc-nav-link.active {
  color: var(--accent);
}
.kc-nav-link.active .kc-nav-icon {
  color: var(--accent);
  /* SVG-compatible glow — the legacy text-shadow rule worked for the
     unicode-glyph icons; the new Peaky SVG set needs a filter to get the
     same brass halo on active state. drop-shadow follows the stroke
     outline, so the glow traces the icon silhouette rather than a bounding
     box. */
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 55%, transparent));
}
.kc-nav-link.external::after {
  content: ' ↗';
  color: var(--muted);
  font-size: 9px;
}

/* Icon slot — holds either the Peaky SVG set (rendered into an inner
   <svg> by KC.icon / the kc-ic auto-render) or a unicode glyph fallback
   for any nav entry that isn't in the registry. The flex centering and
   18×18 box work for both. font-family/size kept narrow so the fallback
   character lines up with the SVG visually. */
.kc-nav-link .kc-nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  font-size: 12px;
  line-height: 1;
  flex-shrink: 0;
  color: inherit;
  font-family: 'Space Mono', monospace;
  transition: color 0.18s, filter 0.18s;
}
/* SVG sub-element inherits the 18×18 box so width/height attrs on the
   <svg> are honored (KC.icon emits explicit width/height, but belt-and-
   braces in case a future caller forgets). */
.kc-nav-link .kc-nav-icon > svg {
  width: 18px;
  height: 18px;
  display: block;
}

.kc-nav-link .kc-nav-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Nav badge · small data pill on the right of a nav link ──
   Currently used by Compete to surface the user's leaderboard
   rank ("#42") next to the nav label. Designed to coexist with
   .kc-nav-link.active (the badge keeps its own muted styling so
   it never fights the active accent). The badge sits AFTER the
   label in flex order; .kc-nav-label has flex:1 so the badge is
   pushed to the right edge automatically.

   Hides in collapsed-rail state along with the label (same selector
   pattern the label hide rule uses below).                      */
.kc-nav-link .kc-nav-badge {
  flex-shrink: 0;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.4px;
  line-height: 1.4;
  padding: 1px 6px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.06);
  color: var(--text-mid, var(--muted));
  text-transform: none;     /* override the parent uppercase */
  transition: color 0.18s, background 0.18s, border-color 0.18s;
}
.kc-nav-link:hover .kc-nav-badge {
  color: var(--text-bright);
  background: rgba(255, 255, 255, 0.08);
}
.kc-nav-link.active .kc-nav-badge {
  /* Active-page badge picks up a subtle accent tint without
     becoming a second focus point — borderless, faint accent
     glow, accent-tinted text. */
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 22%, transparent);
}
/* Rank-flavoured badge — Compete uses this. Keeps the # tighter
   to the digits (no extra letter-spacing on the prefix) and uses
   a slightly tabular feel so #1 / #42 / #200 don't shift width. */
.kc-nav-link .kc-nav-badge.kc-nav-badge-rank {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2px;
}

/* Collapsed state: hide labels, center icons */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-link {
  justify-content: center;
  padding: 9px 0;
  gap: 0;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-link .kc-nav-label,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-link .kc-nav-badge,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-link.external::after {
  display: none;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-links { padding: 4px 4px 8px; }

/* Native browser tooltip is enough — JS sets `title` per link. */

/* ══ SEARCH IN SIDEBAR ═══════════════════════════════════════════ */
.kc-nav-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 4px 10px 8px;
  padding: 8px 10px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.015));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
  min-width: 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
.kc-nav-search:hover {
  border-color: rgba(255,255,255,0.1);
  background:
    linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
}
.kc-nav-search:focus-within {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 6%, rgba(255,255,255,0.04)), rgba(255,255,255,0.02));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 0 14px color-mix(in srgb, var(--accent) 18%, transparent);
}
.kc-nav-search-icon {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  color: var(--muted);
  line-height: 1;
  flex-shrink: 0;
}
.kc-nav-search input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-family: 'Space Mono', monospace;
  font-size: 11.5px;
  padding: 1px 0;
  letter-spacing: 0.3px;
}
.kc-nav-search input::placeholder { color: var(--muted); }
.kc-nav-search-kbd {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--muted);
  background: rgba(0,0,0,0.25);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 4px;
  padding: 1px 5px;
  line-height: 1;
  flex-shrink: 0;
  box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
}
.kc-nav-search:focus-within .kc-nav-search-kbd { display: none; }

/* Collapsed state — search collapses to just the icon. Click expands. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-search {
  margin: 6px 8px 8px;
  padding: 7px 0;
  justify-content: center;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-search input,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-nav-search-kbd {
  display: none;
}

/* Search results dropdown — anchored via JS getBoundingClientRect.
   Already position:fixed in original CSS, just verify here. */
.kc-search-results {
  position: fixed;
  max-height: 420px;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 6px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.45);
  padding: 6px;
  z-index: 1100;
  display: none;
}
.kc-search-results.open { display: block; }

/* ══ SIDEBAR TRACKER MINI-CARD ════════════════════════════════════
   Cross-page surface for the Signal Tracker wallet. Lives between
   Today and Ideas. Painted by renderSidebarTracker() in shared.js
   from the kc_wallet_snapshot localStorage key (written by
   scanners.html). Hidden via data-empty="1" when no snapshot exists
   yet, and entirely hidden in the collapsed (no peek, no lock)
   sidebar state — same pattern as Today + Ideas, since the 56px
   rail is too narrow for a multi-row card.                        */

/* Section header — flex row so the meta + ? button can sit on the
   right end. Mirrors .kc-sb-today-section / .kc-sb-ideas-section. */
.kc-sb-tracker-section {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.kc-sb-tracker-section[data-empty="1"] { display: none; }
.kc-sb-tracker-section[data-empty="1"] + .kc-sb-tracker-block { display: none; }

/* Hidden in collapsed sidebar (no peek, no lock) — same rule as
   Today + Ideas blocks. The 56px rail is too narrow for the card. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-tracker-section,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-tracker-block { display: none; }

/* Inline ? button inside the section header. Adds a subtle outline
   to the platform-default kc-explainer-btn so it doesn't look like a
   floating glyph next to the small "Tracker" label. */
.kc-sb-tracker-explainer {
  border: 1px solid var(--border2);
  width: 14px;
  height: 14px;
  font-size: 9px;
}
.kc-sb-tracker-explainer:hover {
  border-color: var(--accent);
}

/* Card — gradient panel with a thin accent strip on top, hover-lift
   matching .market-tile / .stat-card on dashboard. Wrapped in <a>
   so the entire card is the click target → scanners.html#tracked. */
.kc-sb-tracker-block {
  display: block;
  margin: 0 10px 8px;
  padding: 12px 13px 11px;
  background:
    radial-gradient(160% 60% at 50% 0%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 60%),
    linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.012));
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 10px;
  position: relative;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 4px 14px -8px rgba(0,0,0,0.5);
  transition: transform 0.15s cubic-bezier(0.2,0.8,0.2,1),
              border-color 0.15s ease,
              box-shadow 0.15s ease;
}
.kc-sb-tracker-block:hover {
  transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--accent) 28%, rgba(255,255,255,0.07));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 8px 22px -10px rgba(0,0,0,0.5),
    0 0 16px color-mix(in srgb, var(--accent) 12%, transparent);
}

.kc-sb-tracker-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 9px;
}
.kc-sb-tracker-diamond {
  color: var(--accent);
  font-size: 10px;
  line-height: 1;
  text-shadow: 0 0 6px color-mix(in srgb, var(--accent) 55%, transparent);
}
.kc-sb-tracker-ttl {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--muted);
  letter-spacing: 1.6px;
  text-transform: uppercase;
}

/* Live-dot — pulses green when there's live exposure AND the
   snapshot is fresh (<90s old). Otherwise dims via .idle. The
   2px outer ring gives it more presence on the glass surface. */
.kc-sb-tracker-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--up);
  margin-left: auto;
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--up) 18%, transparent),
    0 0 10px var(--up);
  animation: kc-sb-tracker-pulse 2s infinite;
  flex-shrink: 0;
}
.kc-sb-tracker-dot.idle {
  background: var(--muted);
  box-shadow: 0 0 0 2px rgba(255,255,255,0.04);
  animation: none;
  opacity: 0.5;
}
@keyframes kc-sb-tracker-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}

.kc-sb-tracker-equity {
  font-family: 'Space Mono', monospace;
  font-size: 21px;
  font-weight: var(--w-bold, 700);
  color: var(--text-bright);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.4px;
  background: linear-gradient(180deg, var(--text-bright) 0%, color-mix(in srgb, var(--text-bright) 70%, var(--muted)) 110%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.kc-sb-tracker-totalpl {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2px;
}
.kc-sb-tracker-totalpl.up {
  color: var(--up);
  text-shadow: 0 0 8px color-mix(in srgb, var(--up) 30%, transparent);
}
.kc-sb-tracker-totalpl.down { color: var(--red); }
.kc-sb-tracker-totalpl.flat { color: var(--muted); }

.kc-sb-tracker-divider {
  border-top: none;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
  margin: 10px 0 8px;
}
.kc-sb-tracker-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  margin-top: 3px;
}
.kc-sb-tracker-row:first-of-type { margin-top: 0; }
.kc-sb-tracker-row .k {
  color: var(--muted);
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.kc-sb-tracker-row .v {
  font-weight: var(--w-bold, 700);
  font-variant-numeric: tabular-nums;
}
.kc-sb-tracker-row .v.up    { color: var(--up); }
.kc-sb-tracker-row .v.down  { color: var(--red); }
.kc-sb-tracker-row .v.flat  { color: var(--muted); }
.kc-sb-tracker-row .v.muted { color: var(--text-bright); }
.kc-sb-tracker-row .v.dim   { color: var(--muted); font-weight: 400; }

/* ── TWO-BOOK SIDEBAR TRACKER (Wallet consolidation v2) ──────────
   The new sidebar mini-card stacks two compact "book" rows (Trade
   and Bet) inside the existing .kc-sb-tracker-block shell. Painter
   lives in shared.js → renderSidebarTracker(). Each book has a
   single-row head (icon + label + equity) and a P/L line below.
   Color-coded via .trade / .bet variants — green-tint for trading,
   blue-tint for betting — to mirror the .wl-book::before strip on
   the full Wallet page so the visual identity carries across.
   The legacy single-book classes above (.kc-sb-tracker-equity etc.)
   are kept intact for the backward-compat fallback path the painter
   uses when only kc_wallet_snapshot exists (no kc_compete_snapshot
   yet — i.e. before the user has visited wallet.html for the first
   time). They render harmlessly when not emitted.                 */
.kc-sb-tracker-book {
  position: relative;
  margin-top: 9px;
  padding: 7px 9px 7px 11px;
  background: rgba(255,255,255,0.025);
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 7px;
  overflow: hidden;
}
.kc-sb-tracker-book + .kc-sb-tracker-book { margin-top: 6px; }
.kc-sb-tracker-book::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px;
}
.kc-sb-tracker-book.trade::before { background: var(--up); }
.kc-sb-tracker-book.bet::before   { background: var(--blue); }

.kc-sb-tracker-book-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 3px;
}
.kc-sb-tracker-book-icon {
  width: 14px; height: 14px;
  border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: var(--w-bold, 700);
  line-height: 1;
  flex-shrink: 0;
}
.kc-sb-tracker-book.trade .kc-sb-tracker-book-icon {
  background: color-mix(in srgb, var(--up) 18%, transparent);
  color: var(--up);
}
.kc-sb-tracker-book.bet .kc-sb-tracker-book-icon {
  background: color-mix(in srgb, var(--blue) 20%, transparent);
  color: var(--blue);
}
.kc-sb-tracker-book-label {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
}
.kc-sb-tracker-book-eq {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 13px;
  font-weight: var(--w-bold, 700);
  color: var(--text-bright);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
  line-height: 1;
}
.kc-sb-tracker-book-pl {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2px;
  padding-left: 20px;     /* align under the equity, past icon+label */
}
.kc-sb-tracker-book-pl.up   { color: var(--up); }
.kc-sb-tracker-book-pl.down { color: var(--red); }
.kc-sb-tracker-book-pl.flat { color: var(--muted); }

/* ══ TODAY + IDEAS BLOCKS ═══════════════════════════════════════
   Compact, glance-able views of today's queue and unused ideas.
   Both follow the same shell: a section header with a meta count
   on the right, then a wrapper holding 2-3 small rows. Hidden in
   collapsed sidebar (peek/lock are the only states that show
   text), and hidden via [data-empty="1"] when there's nothing
   relevant to show. */

/* Section header: keep the existing styling but make it flex so the
   meta count can sit on the right. Only applies to the two new
   sections so the original "Search / Navigate" sections are unchanged. */
.kc-sb-today-section,
.kc-sb-ideas-section {
  display: flex;
  align-items: center;
  gap: 8px;
}
.kc-sb-section-meta {
  font-size: 8.5px;
  letter-spacing: 0.6px;
  text-transform: lowercase;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.04);
  border-radius: 9px;
  padding: 1px 7px;
  margin-left: auto;
  line-height: 1.4;
}

/* Hide section + block entirely when empty (no data to show) */
.kc-sb-today-section[data-empty="1"],
.kc-sb-ideas-section[data-empty="1"] { display: none; }
.kc-sb-today-section[data-empty="1"] + .kc-sb-today-block,
.kc-sb-ideas-section[data-empty="1"] + .kc-sb-ideas-block { display: none; }

/* Hide entirely when the sidebar is collapsed (no peek, no lock) —
   same pattern as the chips/labels. Saves the space + avoids
   awkward truncation in 56px-wide rail. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-today-section,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-ideas-section,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-today-block,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-ideas-block { display: none; }

/* ════════════════════════════════════════════════════════════════════
   SIDEBAR · STATUS RAIL (Razor Alpha · Variant D · 2026-05)
   ────────────────────────────────────────────────────────────────────
   Replaces four previously-stacked blocks with one unified rail:
   three KPI tiles (Tasks · Today · P/L) over a wide Wallet tile,
   followed by the (collapsable) Tasks panel mount and a thin
   Ideas footer. The renderers in shared.js → renderSidebarToday /
   renderSidebarTracker / renderSidebarIdeas + the tasks module's
   syncMeta paint into the tile values; the rail is just chrome.

   Hidden in the collapsed-rail state (no peek, no lock); shown in
   the mobile slide-over. Tiles individually hide via data-empty="1"
   so non-dashboard pages quietly drop the Tasks tile while the
   Today/P/L/Wallet tiles continue to render where they have data.
   ════════════════════════════════════════════════════════════════════ */
.kc-sb-rail {
  margin: 6px 10px 4px;
}
/* Whole rail folds when collapsed — matches the Today/Tracker/Ideas
   pattern above so the 56px rail stays clean. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-rail { display: none; }

/* ── Tasks tile · single ribbon layout (2026-05) ──
   The Today + P/L tiles were removed — Tasks now sits alone above
   the Wallet tile as a horizontal "ribbon": label + value + sub
   inline, ending with a caret that rotates when the panel is open.
   Same visual rhythm as the Wallet tile so the rail reads as a
   stacked pair rather than competing widgets. */
.kc-sb-rail-tile {
  position: relative;
  padding: 8px 11px;
  margin-bottom: 6px;
  background: rgba(255,255,255,0.025);
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  transition: border-color 0.15s ease, background 0.15s ease;
  user-select: none;
}
.kc-sb-rail-tile[data-empty="1"] { display: none; }
.kc-sb-rail-tile[data-empty="0"]:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 28%, rgba(255,255,255,0.05));
  background: rgba(255,255,255,0.04);
}
.kc-sb-rail-tile[data-empty="0"]:focus-visible {
  outline: 1px solid var(--accent, #d4a335);
  outline-offset: -2px;
}

/* Label */
.kc-sb-rail-tile-lab {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 8.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1;
  flex-shrink: 0;
}
.kc-sb-rail-tile[data-empty="0"]:hover .kc-sb-rail-tile-lab {
  color: var(--text-mid);
}

/* Compact ? button — capture-phase explainer handler stops propagation
   so clicks here never trigger the tile click toggle. */
.kc-sb-rail-tile-q {
  margin-left: 0;
  width: 13px;
  height: 13px;
  font-size: 8px;
  padding: 0;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Status dot */
.kc-sb-rail-tile-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
  background: rgba(255,255,255,0.15);
  transition: background 0.15s, box-shadow 0.15s;
}
.kc-sb-rail-tile-dot[data-state="up"] {
  background: var(--up, #4ade80);
  box-shadow: 0 0 4px color-mix(in srgb, var(--up, #4ade80) 60%, transparent);
}
.kc-sb-rail-tile-dot[data-state="down"] {
  background: var(--red, #f87171);
  box-shadow: 0 0 4px color-mix(in srgb, var(--red, #f87171) 55%, transparent);
}
.kc-sb-rail-tile-dot[data-state="amber"] {
  background: var(--accent, #d4a335);
  box-shadow: 0 0 4px color-mix(in srgb, var(--accent, #d4a335) 50%, transparent);
}
.kc-sb-rail-tile-dot[data-state="muted"] {
  background: var(--muted);
  opacity: 0.5;
}
.kc-sb-rail-tile-dot[data-state="empty"] {
  background: rgba(255,255,255,0.12);
}

/* Value (big number, e.g. "5/8") — pinned to right of label area,
   pulls toward the centre with margin-left:auto so the sub-line +
   caret can sit on the far right. */
.kc-sb-rail-tile-val {
  margin-left: auto;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text-bright);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
  flex-shrink: 0;
}
.kc-sb-rail-tile-val .den {
  font-size: 9px;
  color: var(--muted);
  font-weight: 400;
  margin-left: 1px;
}

/* Sub-line (status verb, e.g. "5 left" / "all done") */
.kc-sb-rail-tile-sub {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  color: var(--muted);
  letter-spacing: 0.4px;
  line-height: 1;
  flex-shrink: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60px;
}

/* Caret — rotates -90° when collapsed (the default per the legacy
   tasks module contract) and back to 0deg when the panel is open. */
.kc-sb-rail-tile-caret {
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  flex-shrink: 0;
  transform: rotate(0deg);
  transition: transform 0.18s ease, color 0.15s;
}
.kc-sb-rail-tile.is-collapsed .kc-sb-rail-tile-caret {
  transform: rotate(-90deg);
}
.kc-sb-rail-tile[data-empty="0"]:hover .kc-sb-rail-tile-caret {
  color: var(--text-mid);
}

/* Tasks tile · expanded variant (panel open) */
.kc-sb-rail-tile.tile-tasks:not(.is-collapsed) {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 35%, rgba(255,255,255,0.05));
  background: color-mix(in srgb, var(--accent, #d4a335) 6%, rgba(255,255,255,0.025));
}
.kc-sb-rail-tile.tile-tasks:not(.is-collapsed) .kc-sb-rail-tile-lab {
  color: var(--text-bright);
}

/* Compatibility surface: the tasks module's syncMeta() writes into
   #kcSbTasksMeta / #kcSbTasksBarDaily / #kcSbTasksCountDaily. We keep
   them in DOM but visually hidden — the ribbon val/sub mirror the
   same data. The hidden #kcSbTrackerSection wrapper for #kcSbTrackerMeta
   uses the same shape so wrappers like wireSidebarBlocks find their
   targets without rendering. */
.kc-sb-rail-tile-compat,
.kc-sb-rail-tracker-compat {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  pointer-events: none;
}

/* ── Wide Wallet tile ── */
.kc-sb-rail-wallet {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 9px 11px 10px;
  background:
    radial-gradient(160% 60% at 50% 0%, color-mix(in srgb, var(--accent, #d4a335) 7%, transparent), transparent 60%),
    rgba(255,255,255,0.025);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.06s;
  margin-bottom: 4px;
}
.kc-sb-rail-wallet:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 28%, rgba(255,255,255,0.06));
  transform: translateY(-1px);
}
.kc-sb-rail-wallet:active { transform: translateY(0); }
.kc-sb-rail-wallet[data-empty="1"],
.kc-sb-rail-wallet:empty { display: none; }

.kc-sb-rail-wallet-head {
  display: flex;
  align-items: center;
  gap: 6px;
}
.kc-sb-rail-wallet-lab {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 8.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1;
}
.kc-sb-rail-wallet:hover .kc-sb-rail-wallet-lab { color: var(--text-mid); }
/* Compact ? explainer button inside the wallet head — same shape as
   the Tasks tile ? for visual consistency. The platform-wide capture-
   phase explainer click handler stops propagation, so clicking ?
   never triggers the wrapping <a> navigation. */
.kc-sb-rail-wallet-q {
  margin-left: 0;
  width: 13px;
  height: 13px;
  font-size: 8px;
  padding: 0;
  border-radius: 50%;
  flex-shrink: 0;
}
.kc-sb-rail-wallet-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--up, #4ade80);
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--up, #4ade80) 18%, transparent),
    0 0 8px var(--up, #4ade80);
  animation: kc-sb-rail-wallet-pulse 2s infinite;
  flex-shrink: 0;
}
.kc-sb-rail-wallet-dot.idle {
  background: var(--muted);
  box-shadow: 0 0 0 2px rgba(255,255,255,0.04);
  animation: none;
  opacity: 0.5;
}
@keyframes kc-sb-rail-wallet-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}
.kc-sb-rail-wallet-chev {
  margin-left: auto;
  color: var(--muted);
  font-size: 12px;
  line-height: 1;
  transition: color 0.15s, transform 0.15s;
}
.kc-sb-rail-wallet:hover .kc-sb-rail-wallet-chev {
  color: var(--text-mid);
  transform: translateX(1px);
}

/* Inline books row: Trade · Bet · total */
.kc-sb-rail-wallet-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kc-sb-rail-wallet-book {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  color: var(--text-mid);
  font-variant-numeric: tabular-nums;
}
.kc-sb-rail-wallet-book .bk-pip {
  width: 3px;
  height: 11px;
  border-radius: 1px;
  flex-shrink: 0;
}
.kc-sb-rail-wallet-book.trade .bk-pip { background: var(--up, #4ade80); }
.kc-sb-rail-wallet-book.bet   .bk-pip { background: var(--blue, #60a5fa); }
.kc-sb-rail-wallet-book .bk-lab {
  font-size: 9px;
  color: var(--muted);
  letter-spacing: 0.6px;
}
.kc-sb-rail-wallet-book .bk-eq {
  color: var(--text-bright);
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: -0.2px;
}
.kc-sb-rail-wallet-total {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-bright);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
}

/* ── Ideas footer (single thin row, hidden when empty) ── */
.kc-sb-rail-ideas-section {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 2px 3px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 8.5px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--muted);
}
.kc-sb-rail-ideas-section[data-empty="1"] { display: none; }
.kc-sb-rail-ideas-section[data-empty="1"] + .kc-sb-ideas-block { display: none; }
.kc-sb-rail-ideas-lab { line-height: 1; }
.kc-sb-rail-ideas-section .kc-sb-section-meta {
  margin-left: auto;
}

/* Sidebar Ideas footer permanently hidden — the module has its own
   home now on the Writer → Ideas tab and the sidebar mirror was
   creating duplicate surfaces with no clear winner. The DOM nodes
   (#kcSbIdeasSection + #kcSbIdeas) are kept so renderSidebarIdeas,
   the kc:ideas-changed listeners, and the right-click context menu
   continue to operate harmlessly into invisible elements. */
.kc-sb-rail-ideas-section,
.kc-sb-ideas-block {
  display: none !important;
}

/* Mobile drawer (slide-over): force the rail visible. The default
   sidebar-collapsed hide above wins on desktop rail; the slide-over
   counts as "open" so we revert it. */
@media (max-width: 760px) {
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-rail {
    display: revert !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-rail-tile[data-empty="0"] {
    display: flex !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-rail-wallet[data-empty="0"] {
    display: flex !important;
  }
}

/* ─────────────────────────────────────────────────────────────────
   SIDEBAR TASKS BLOCK — only rendered on the dashboard (index.html).
   ─────────────────────────────────────────────────────────────────
   The full Daily / Weekly tasks panel was previously a full-page
   panel. It now mounts inside the sidebar, between Navigate and
   Today, in a compact form that mirrors the Today / Tracker / Ideas
   visual idiom (glass pane, 11px rows, dot+text). All original
   element IDs are preserved so existing renderChecklist /
   renderWeekly / switchTasksTab JS keeps working unchanged. */

/* Hide both the section header and the mount when empty (default
   for every page that isn't the dashboard). */
.kc-sb-tasks-card[data-empty="1"] { display: none; }
.kc-sb-tasks-mount[data-empty="1"] { display: none; }

/* Hide entirely when the sidebar is collapsed — same pattern as
   Today/Tracker/Ideas. Saves space + avoids awkward truncation in
   the 56px-wide rail. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-tasks-card,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-tasks-mount { display: none; }

/* ── Card shell ───────────────────────────────────────────────
   The Tasks "section header" is now a real card (mirroring the
   Tracker idiom). It carries its own border + subtle bg so it
   reads as an interactive object rather than a quiet label. Click
   anywhere on the card to fold / unfold the full panel below. */
.kc-sb-tasks-card {
  margin: 6px 12px 4px;
  padding: 9px 11px 10px;
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 10px;
  background: rgba(255,255,255,0.02);
  cursor: pointer;
  user-select: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.kc-sb-tasks-card[data-empty="0"]:hover {
  border-color: rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.035);
}
.kc-sb-tasks-card[data-empty="0"]:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: -2px;
  border-radius: 10px;
}

/* Header row — caret + label + ? + (expand hint | meta pill) */
.kc-sb-tasks-card-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--text-mid);
  margin-bottom: 7px;
}
.kc-sb-tasks-card[data-empty="0"]:hover .kc-sb-tasks-card-head {
  color: var(--text-bright);
}
.kc-sb-tasks-card-label {
  font-weight: 500;
}
.kc-sb-tasks-explainer {
  margin-left: 0;
  width: 14px;
  height: 14px;
  font-size: 9px;
}

/* "expand ›" sits to the far right when collapsed; hides when
   expanded so the inline meta pill can take its slot. */
.kc-sb-tasks-expand-hint {
  margin-left: auto;
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--muted);
  text-transform: lowercase;
  font-weight: 400;
}
.kc-sb-tasks-card:not(.is-collapsed) .kc-sb-tasks-expand-hint { display: none; }
.kc-sb-tasks-card[data-empty="0"]:hover .kc-sb-tasks-expand-hint { color: var(--text-mid); }

/* Inline meta pill — re-uses .kc-sb-section-meta look but with
   margin-left:0 since the expand-hint already burns the auto slot.
   Hidden in collapsed state (bars + counts cover the same data). */
.kc-sb-tasks-meta-inline {
  margin-left: auto !important;
}
.kc-sb-tasks-card.is-collapsed .kc-sb-tasks-meta-inline { display: none; }

/* Caret matches sibling tool-box idiom — rotates -90° collapsed. */
.kc-sb-tasks-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 10px;
  height: 10px;
  color: var(--muted);
  transition: transform 0.18s ease, color 0.15s ease;
  flex-shrink: 0;
}
.kc-sb-tasks-card.is-collapsed .kc-sb-tasks-caret {
  transform: rotate(-90deg);
}
.kc-sb-tasks-card[data-empty="0"]:hover .kc-sb-tasks-caret {
  color: var(--text-mid);
}

/* ── Progress bar ─────────────────────────────────────────────
   Single-row mini-bar block: [▆▆▆▆▆▆▆▆▆▆] 0/7 (daily only).
   Renders only in the collapsed state — when the panel is
   open, the same data is already visible inside the pane. */
.kc-sb-tasks-bars {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
/* Single-bar variant (sidebar is daily-only). Removes the column gap
   that was tuned for the old daily+weekly stack so the lone bar sits
   flush. */
.kc-sb-tasks-bars:has(> .kc-sb-tasks-bar-row:only-child) { gap: 0; }
.kc-sb-tasks-card:not(.is-collapsed) .kc-sb-tasks-bars { display: none; }
.kc-sb-tasks-bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.kc-sb-tasks-bar-tag {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.5px;
  color: var(--muted);
  width: 8px;
  text-align: left;
  flex-shrink: 0;
  text-transform: lowercase;
}
.kc-sb-tasks-bar-track {
  flex: 1;
  height: 4px;
  background: rgba(255,255,255,0.05);
  border-radius: 2px;
  overflow: hidden;
  position: relative;
}
.kc-sb-tasks-bar-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0%;
  border-radius: 2px;
  transition: width 0.25s ease, background-color 0.2s ease;
  background: var(--muted);
}
/* Per-tab default tints (matches tasks-tab-dot-daily / -weekly
   idiom inside the open panel — emerald accent / cyan accent3). */
.kc-sb-tasks-bar-row[data-tab="daily"]  .kc-sb-tasks-bar-fill { background: var(--accent); }
.kc-sb-tasks-bar-row[data-tab="weekly"] .kc-sb-tasks-bar-fill { background: var(--accent3); }
/* State tints — empty/pending = warm amber so the row reads as
   "still to do" in collapsed state; partial keeps the accent;
   done desaturates slightly. */
.kc-sb-tasks-bar-row[data-state="empty"]   .kc-sb-tasks-bar-fill { background: rgba(255,255,255,0.08); }
.kc-sb-tasks-bar-row[data-state="pending"] .kc-sb-tasks-bar-fill { background: var(--warn, #d4a017); }
.kc-sb-tasks-bar-row[data-state="pending"] .kc-sb-tasks-bar-tag,
.kc-sb-tasks-bar-row[data-state="pending"] .kc-sb-tasks-bar-count { color: var(--warn, #d4a017); }
.kc-sb-tasks-bar-row[data-state="done"]    .kc-sb-tasks-bar-tag,
.kc-sb-tasks-bar-row[data-state="done"]    .kc-sb-tasks-bar-count { color: color-mix(in srgb, var(--accent) 80%, var(--text-mid)); }
/* Pending rows still need a non-zero visual nub so 0/n doesn't
   read as a literal empty bar — fill renders min-width via CSS. */
.kc-sb-tasks-bar-row[data-state="pending"] .kc-sb-tasks-bar-fill {
  width: 100% !important;
  opacity: 0.18;
}

.kc-sb-tasks-bar-count {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.4px;
  color: var(--muted);
  min-width: 26px;
  text-align: right;
  flex-shrink: 0;
}

/* Collapse animation — max-height + opacity. The inner panel max
   covers the realistic worst case (long custom lists scroll inside
   the panel itself); we use a generous ceiling so the transition
   reads natural for any content height. */
.kc-sb-tasks-mount {
  overflow: hidden;
  max-height: 1600px;
  transition: max-height 0.22s ease, opacity 0.18s ease, margin 0.22s ease;
}
.kc-sb-tasks-mount.is-collapsed {
  max-height: 0;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════
   TASKS PANEL — base styles
   ──────────────────────────────────────────────────────────────────
   Migrated out of index.html so the panel can render on every page.
   ALL rules in this block are scoped under `.kc-sb-tasks-mount` so
   they never leak onto unrelated pages — pages like writer.html and
   kol.html define their own conflicting `.panel`, `.panel-head`,
   `.panel-body` etc. and this scope keeps them untouched.

   The compact-sidebar overrides further down (search for
   "Tab strip + actions (compact)") still win because they're equally
   specific and appear later in the cascade.
   ══════════════════════════════════════════════════════════════════ */

/* ── Panel shell (only the bits the tasks panel uses) ───────────
   Note: padding / margin / display are explicitly reset here so
   page-level `.panel` declarations on writer.html (border-radius:10px)
   and kol.html (padding:22px; margin-bottom:18px) don't leak through.
   Same with `.panel-body` — kol.html / writer.html declare flex/gap/
   padding on it that we don't want inside the tasks mount. */
.kc-sb-tasks-mount .panel {
  background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.008));
  border: 1px solid rgba(255,255,255,0.05);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
  border-radius: 6px;
  overflow: hidden;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
  /* Hard resets vs. page-level .panel rules (kol/writer) */
  padding: 0;
  margin: 0;
}
.kc-sb-tasks-mount .panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,0.02);
}
.kc-sb-tasks-mount .panel-action {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 1px;
  cursor: pointer;
  border: 1px solid var(--border);
  padding: 5px 10px;
  border-radius: 5px;
  background: none;
  transition: all 0.15s;
  text-transform: uppercase;
  line-height: 1;
  min-height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.kc-sb-tasks-mount .panel-action:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.kc-sb-tasks-mount .panel-body {
  padding: 16px 18px;
  /* Hard resets vs. page-level .panel-body rules (writer.html ships
     display:flex; flex-direction:column; gap:16px which would push the
     daily/weekly panes into a flex column with 16px gaps). */
  display: block;
  margin: 0;
  gap: 0;
}

/* ── Tasks panel: tab-driven accent borders ────────────────────── */
.kc-sb-tasks-mount .tasks-panel {
  transition: border-color 0.25s;
}
.kc-sb-tasks-mount .tasks-panel[data-active-tab="daily"]  { border-color: color-mix(in srgb, var(--accent)  18%, transparent); }
.kc-sb-tasks-mount .tasks-panel[data-active-tab="weekly"] { border-color: color-mix(in srgb, var(--accent3) 20%, transparent); }
.kc-sb-tasks-mount .tasks-panel-head {
  transition: background 0.25s;
}
.kc-sb-tasks-mount .tasks-panel[data-active-tab="daily"]  .tasks-panel-head { background: color-mix(in srgb, var(--accent)  4%, transparent); }
.kc-sb-tasks-mount .tasks-panel[data-active-tab="weekly"] .tasks-panel-head { background: color-mix(in srgb, var(--accent3) 4%, transparent); }

/* Tab strip (default sizing — sidebar overrides further down shrink it) */
.kc-sb-tasks-mount .tasks-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  background: var(--card2);
  border-radius: 7px;
}
.kc-sb-tasks-mount .tasks-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 12px;
  font-weight: var(--w-semibold, 600);
  letter-spacing: 0.02em;
  border-radius: 5px;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
  line-height: 1;
}
.kc-sb-tasks-mount .tasks-tab:hover:not(.is-active) {
  color: var(--text);
  background: rgba(255,255,255,0.03);
}
.kc-sb-tasks-mount .tasks-tab.is-active {
  color: var(--text-bright);
  background: var(--surface, var(--card));
  box-shadow: inset 0 0 0 1px var(--border2);
}
.kc-sb-tasks-mount .tasks-tab-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
.kc-sb-tasks-mount .tasks-tab-dot-daily  { background: var(--accent); }
.kc-sb-tasks-mount .tasks-tab-dot-weekly { background: var(--accent3); }
.kc-sb-tasks-mount .tasks-tab-count {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.5px;
}
.kc-sb-tasks-mount .tasks-tab.is-active .tasks-tab-count { color: var(--text-mid); }

/* Pane visibility — both stay in DOM so render functions keep working */
.kc-sb-tasks-mount .tasks-pane[hidden] { display: none; }

/* Context-aware action buttons: only show those for the active tab */
.kc-sb-tasks-mount .tasks-panel[data-active-tab="daily"]  .tasks-action-weekly { display: none; }
.kc-sb-tasks-mount .tasks-panel[data-active-tab="weekly"] .tasks-action-daily  { display: none; }

/* Weekly banner is only meaningful while Weekly tab is open */
.kc-sb-tasks-mount .tasks-panel[data-active-tab="daily"] #weeklyBanner { display: none !important; }

/* ── Daily checklist rows ──────────────────────────────────────── */
.kc-sb-tasks-mount .checklist {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.kc-sb-tasks-mount .check-item {
  display: flex;
  align-items: center;
  gap: 0;
  padding: 0;
  border-radius: 6px;
  transition: background 0.15s;
  user-select: none;
  position: relative;
}
.kc-sb-tasks-mount .check-item:hover { background: rgba(255,255,255,0.03); }

.kc-sb-tasks-mount .check-main {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  cursor: pointer;
  flex: 1;
  min-width: 0;
}
.kc-sb-tasks-mount .check-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 8px 0 4px;
  opacity: 0;
  transition: opacity 0.15s;
}
.kc-sb-tasks-mount .check-item:hover .check-actions { opacity: 1; }

.kc-sb-tasks-mount .check-action-btn {
  width: 22px;
  height: 22px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: var(--w-bold, 700);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.12s;
  padding: 0;
  line-height: 1;
}
.kc-sb-tasks-mount .check-action-btn:hover:not(:disabled) {
  color: var(--text-bright);
  border-color: var(--border2);
  background: var(--card2);
}
.kc-sb-tasks-mount .check-action-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.kc-sb-tasks-mount .check-action-btn.danger:hover:not(:disabled) {
  color: var(--red);
  border-color: var(--red);
}

.kc-sb-tasks-mount .check-item.done .check-text { text-decoration: line-through; color: var(--muted); }
.kc-sb-tasks-mount .check-item.done .check-box  { background: var(--accent2); border-color: var(--accent2); }
.kc-sb-tasks-mount .check-item.done .check-box::after { opacity: 1; }

.kc-sb-tasks-mount .check-box {
  width: 16px; height: 16px;
  border: 1.5px solid var(--border2);
  border-radius: 4px;
  flex-shrink: 0;
  position: relative;
  transition: all 0.15s;
}
.kc-sb-tasks-mount .check-box::after {
  content: '✓';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-size: 11px;
  color: var(--bg);
  font-weight: var(--w-bold, 700);
  opacity: 0;
  transition: opacity 0.15s;
}

.kc-sb-tasks-mount .check-text {
  font-size: 15px;
  font-weight: var(--w-medium, 500);
  color: var(--text-bright);
  transition: color 0.15s;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kc-sb-tasks-mount .check-time {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text-mid);
  letter-spacing: 1px;
  flex-shrink: 0;
}

.kc-sb-tasks-mount .check-add-btn {
  width: 100%;
  background: transparent;
  border: 1px dashed var(--border2);
  border-radius: 6px;
  padding: 8px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1px;
  cursor: pointer;
  margin-top: 6px;
  transition: all 0.15s;
}
.kc-sb-tasks-mount .check-add-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}

.kc-sb-tasks-mount .check-add-form {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  padding: 6px;
  background: var(--card2);
  border: 1px solid var(--border2);
  border-radius: 6px;
  flex-wrap: wrap;
}
.kc-sb-tasks-mount .check-add-text {
  flex: 1 1 160px;
  min-width: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 7px 9px;
  color: var(--text-bright);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 13px;
  outline: none;
}
.kc-sb-tasks-mount .check-add-time {
  flex: 0 0 100px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 7px 9px;
  color: var(--text-bright);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  outline: none;
}
.kc-sb-tasks-mount .check-add-text:focus,
.kc-sb-tasks-mount .check-add-time:focus { border-color: var(--accent); }
.kc-sb-tasks-mount .check-add-save,
.kc-sb-tasks-mount .check-add-cancel {
  background: var(--accent);
  border: none;
  color: var(--bg);
  padding: 7px 14px;
  border-radius: 4px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: var(--w-bold, 700);
  letter-spacing: 1px;
  cursor: pointer;
  text-transform: uppercase;
}
.kc-sb-tasks-mount .check-add-cancel {
  background: var(--card);
  color: var(--muted);
  border: 1px solid var(--border2);
}
.kc-sb-tasks-mount .check-add-save:hover { opacity: 0.85; }
.kc-sb-tasks-mount .check-add-cancel:hover { color: var(--text-bright); }

.kc-sb-tasks-mount .check-progress {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  margin-top: 12px;
  overflow: hidden;
}
.kc-sb-tasks-mount .check-progress-bar {
  height: 100%;
  background: var(--accent2);
  border-radius: 2px;
  transition: width 0.3s ease;
}
.kc-sb-tasks-mount .check-progress-bar.weekly-progress {
  background: var(--accent3);
}

/* ── Weekly checklist rows ────────────────────────────────────── */
.kc-sb-tasks-mount .check-item.weekly {
  padding: 12px 14px;
  gap: 12px;
  background: color-mix(in srgb, var(--accent3) 3%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent3) 8%, transparent);
  margin-bottom: 2px;
}
.kc-sb-tasks-mount .check-item.weekly:hover {
  background: color-mix(in srgb, var(--accent3) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent3) 20%, transparent);
}
.kc-sb-tasks-mount .check-item.weekly.done {
  background: color-mix(in srgb, var(--accent2) 4%, transparent);
  border-color: color-mix(in srgb, var(--accent2) 15%, transparent);
}
.kc-sb-tasks-mount .check-item.weekly.done .check-box {
  background: var(--accent3);
  border-color: var(--accent3);
}
.kc-sb-tasks-mount .check-item .check-icon {
  font-size: 18px;
  flex-shrink: 0;
  opacity: 0.9;
}
.kc-sb-tasks-mount .check-item.done .check-icon { opacity: 0.5; }

/* Weekly banner (the compact-sidebar override hides it, but the styles
   are kept here in case a future skin re-enables it) */
.kc-sb-tasks-mount .weekly-banner {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
  padding: 3px 8px;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--card2);
  text-transform: uppercase;
}
.kc-sb-tasks-mount .weekly-banner.active {
  color: var(--accent3);
  border-color: color-mix(in srgb, var(--accent3) 30%, transparent);
  background: color-mix(in srgb, var(--accent3) 8%, transparent);
  animation: kcTasksWeeklyPulse 2.5s ease-in-out infinite;
}
.kc-sb-tasks-mount .weekly-now { color: var(--accent3); font-weight: var(--w-bold, 700); }
.kc-sb-tasks-mount .weekly-soon { color: var(--muted); }

@keyframes kcTasksWeeklyPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent3) 30%, transparent); }
  50%      { box-shadow: 0 0 0 4px transparent; }
}

/* ── Preset chips (Standard / Custom) ─────────────────────────── */
.kc-sb-tasks-mount .preset-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
  padding: 8px 10px;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.kc-sb-tasks-mount .preset-row-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 1px;
  text-transform: uppercase;
  margin-right: 4px;
  padding: 4px 0;
  align-self: center;
}
.kc-sb-tasks-mount .preset-chip {
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-mid);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  letter-spacing: 0.3px;
}
.kc-sb-tasks-mount .preset-chip:hover {
  border-color: var(--border2);
  color: var(--text-bright);
}
.kc-sb-tasks-mount .preset-chip.active {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}
.kc-sb-tasks-mount .preset-chip.disabled {
  opacity: 0.45;
  border-style: dashed;
}
.kc-sb-tasks-mount .preset-chip.disabled:hover {
  opacity: 0.7;
}
/* ── END TASKS PANEL — base styles ───────────────────────────── */

/* Mount container — inherits the same glass-pane look as
   .kc-sb-today-block / .kc-sb-ideas-block. The .tasks-panel div
   inside it provides the data-active-tab attribute used by the
   accent-color selectors below. */
.kc-sb-tasks-mount {
  margin: 0 10px 4px;
  padding: 0;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.008));
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
  overflow: hidden;
}

/* When the panel inside is on Daily, tint the mount border emerald;
   on Weekly, tint cyan. Matches the original full-page tab accent. */
.kc-sb-tasks-mount:has(.tasks-panel[data-active-tab="daily"])  { border-color: color-mix(in srgb, var(--accent)  20%, rgba(255,255,255,0.05)); }
.kc-sb-tasks-mount:has(.tasks-panel[data-active-tab="weekly"]) { border-color: color-mix(in srgb, var(--accent3) 22%, rgba(255,255,255,0.05)); }

/* ── Tab strip + actions (compact) ───────────────────────────── */
.kc-sb-tasks-mount .tasks-panel {
  background: transparent;
  border: 0;
  border-radius: 0;
  margin: 0;
}
.kc-sb-tasks-mount .panel-head.tasks-panel-head {
  /* Tight padding so the head fits Daily + Weekly + Reset on one row
     even at 240px sidebar width (≈210px usable inside the mount). */
  padding: 4px 5px;
  background: transparent;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  min-height: 0;
  flex-wrap: nowrap;
  min-width: 0;
}
/* Right-side action group (Reset / hidden actions) — keep on one line
   and never let it shrink past intrinsic width. The left tab strip
   takes the leftover space and shrinks first if needed. */
.kc-sb-tasks-mount .panel-head.tasks-panel-head > div {
  flex-shrink: 0;
  white-space: nowrap;
}
.kc-sb-tasks-mount .tasks-tabs {
  gap: 2px;
  padding: 0;
  background: transparent;
  border: 0;
  flex-wrap: nowrap;
  flex-shrink: 1;
  min-width: 0;
}
.kc-sb-tasks-mount .tasks-tab {
  padding: 2px 6px;
  font-size: 10px;
  border-radius: 5px;
  letter-spacing: 0.2px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  flex-shrink: 0;
}
.kc-sb-tasks-mount .tasks-tab .tasks-tab-label { font-size: 10px; white-space: nowrap; }
.kc-sb-tasks-mount .tasks-tab .tasks-tab-count {
  font-size: 9px;
  font-family: 'Space Mono', monospace;
  margin-left: 1px;
  padding: 0;
  background: transparent;
  white-space: nowrap;
}
.kc-sb-tasks-mount .tasks-tab .tasks-tab-dot {
  width: 5px;
  height: 5px;
}

/* Reset / hidden Defaults — small icon-style buttons */
.kc-sb-tasks-mount .panel-action {
  font-size: 10px;
  padding: 4px 8px;
  border-radius: 5px;
  letter-spacing: 0.3px;
  white-space: nowrap;
  flex-shrink: 0;
  min-height: 26px;
}
/* The full-page CSS tints the head per active tab — kill that here so
   the sidebar mount's own border carries the accent instead. */
.kc-sb-tasks-mount .tasks-panel[data-active-tab="daily"]  .panel-head.tasks-panel-head,
.kc-sb-tasks-mount .tasks-panel[data-active-tab="weekly"] .panel-head.tasks-panel-head {
  background: transparent;
}

.kc-sb-tasks-mount .kc-explainer-btn {
  width: 14px;
  height: 14px;
  font-size: 9px;
}

/* Weekly banner — in the full-page layout this banner sits inside the
   panel head next to the action buttons. In the cramped sidebar it
   either pushes everything out of alignment or wraps into a 4-line
   vertical block (see screenshot). Hide it here; the Weekly tab pill
   itself already shows the count, and the "Monday routine" nudge isn't
   critical at this size. The element stays in DOM so render code keeps
   working — it's just visually suppressed. */
.kc-sb-tasks-mount .weekly-banner { display: none !important; }

/* The original `.tasks-panel[data-active-tab="daily"] #weeklyBanner`
   rule from index.html (display:none !important) covers Daily anyway,
   but our blanket rule above makes the layout deterministic regardless
   of tab. */

/* ── Body / panes ────────────────────────────────────────────── */
.kc-sb-tasks-mount .panel-body { padding: 0; }
.kc-sb-tasks-mount .tasks-pane { padding: 0; }

/* Top-of-pane progress bar (was bottom-of-panel before) */
.kc-sb-tasks-mount .check-progress {
  height: 2px;
  margin: 0;
  background: rgba(255,255,255,0.04);
  border-radius: 0;
  overflow: hidden;
}
.kc-sb-tasks-mount .check-progress-bar {
  height: 100%;
  background: var(--accent);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 50%, transparent);
  transition: width 0.18s;
}
.kc-sb-tasks-mount .check-progress-bar.weekly-progress {
  background: var(--accent3);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent3) 50%, transparent);
}

/* ── Preset chips (compact: just Standard + Custom) ──────────── */
.kc-sb-tasks-mount .preset-row {
  margin: 0;
  padding: 4px 7px 4px;
  background: transparent;
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid rgba(255,255,255,0.03);
  gap: 3px;
  flex-wrap: wrap;
}
.kc-sb-tasks-mount .preset-row-label {
  font-size: 8.5px;
  letter-spacing: 0.6px;
  margin-right: 2px;
  padding: 2px 0;
}
.kc-sb-tasks-mount .preset-chip {
  font-size: 9.5px;
  padding: 2px 7px;
  border-radius: 9px;
  letter-spacing: 0.2px;
}

/* ── Checklist rows (compact: dot + text instead of box + text + actions on hover) ── */
.kc-sb-tasks-mount .checklist {
  gap: 0;
  padding: 4px 9px 6px;
}
.kc-sb-tasks-mount .check-item {
  border-radius: 4px;
  padding: 0;
}
.kc-sb-tasks-mount .check-item:hover {
  background: rgba(255,255,255,0.025);
}
.kc-sb-tasks-mount .check-item + .check-item {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
}
.kc-sb-tasks-mount .check-main {
  padding: 5px 4px;
  gap: 8px;
  align-items: flex-start;
  /* Use a 2-column grid: [checkbox][text+time stacked]. The right column
     wraps text+time vertically so the task name gets the full available
     width — no fighting with check-time for horizontal space. */
  display: grid;
  grid-template-columns: auto 1fr;
}
.kc-sb-tasks-mount .check-box {
  width: 11px;
  height: 11px;
  border-width: 1px;
  border-radius: 3px;
  margin-top: 2px;
}
.kc-sb-tasks-mount .check-text {
  font-size: 10.5px;
  line-height: 1.3;
  white-space: normal;
  word-break: normal;
  overflow-wrap: break-word;
  /* No line-clamp now that text owns the full row width — most tasks
     fit on one line, longer ones wrap to two cleanly. */
  display: block;
  overflow: visible;
  min-width: 0;
}
.kc-sb-tasks-mount .check-time {
  font-size: 9px;
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.3px;
  color: var(--muted);
  /* Move time to a second line below the task text. Now lives in the
     same grid column as .check-text, just stacked underneath. */
  grid-column: 2;
  margin-top: 1px;
}
/* Hide the time line entirely when it's empty — render functions emit
   <div class="check-time"></div> for tasks with no time set, and an
   empty grid cell would still take vertical space. */
.kc-sb-tasks-mount .check-time:empty { display: none; }
.kc-sb-tasks-mount .check-box::after { font-size: 8px; }
.kc-sb-tasks-mount .check-icon {
  display: none;     /* the 16px tile icons are too heavy at this scale */
}
.kc-sb-tasks-mount .check-actions {
  padding: 0 4px 0 2px;
  gap: 1px;
}
.kc-sb-tasks-mount .check-action-btn {
  width: 18px;
  height: 18px;
  font-size: 11px;
  border-radius: 3px;
}

/* "+ Add task" / add-form — compact, stack vertically in sidebar width */
.kc-sb-tasks-mount .check-add-btn {
  font-size: 10px;
  padding: 4px 8px;
  margin-top: 4px;
}
.kc-sb-tasks-mount .check-add-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 6px;
  margin-top: 4px;
}
.kc-sb-tasks-mount .check-add-text,
.kc-sb-tasks-mount .check-add-time {
  font-size: 10.5px;
  padding: 4px 6px;
  width: 100%;
  box-sizing: border-box;
}
/* Save / Cancel sit side by side on the bottom row */
.kc-sb-tasks-mount .check-add-save,
.kc-sb-tasks-mount .check-add-cancel {
  font-size: 10px;
  padding: 4px 8px;
  flex: 1;
}

/* Weekly tab inherits sidebar accent3 for done state */
.kc-sb-tasks-mount .check-item.weekly.done .check-box {
  background: var(--accent3);
  border-color: var(--accent3);
}

/* Block container — glass card pane shared by both blocks */
.kc-sb-today-block,
.kc-sb-ideas-block {
  margin: 0 10px 4px;
  padding: 4px 10px 6px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.008));
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
}

/* ── Today: task rows ────────────────────────────────────────── */
.kc-sb-task {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 0;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-mid);
  text-decoration: none;
  position: relative;
  transition: color 0.12s, transform 0.12s;
}
.kc-sb-task + .kc-sb-task {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
}
.kc-sb-task:first-child { padding-top: 4px; }
.kc-sb-task:last-child  { padding-bottom: 4px; }
.kc-sb-task:hover { color: var(--accent); }

.kc-sb-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  position: relative;
}
.kc-sb-dot.done  {
  background: var(--accent);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 55%, transparent);
}
.kc-sb-dot.draft {
  background: var(--yellow, #f7931a);
  box-shadow: 0 0 6px color-mix(in srgb, var(--yellow, #f7931a) 45%, transparent);
}
.kc-sb-dot.idea  { background: transparent; border: 1px solid rgba(255,255,255,0.2); }

.kc-sb-task-text {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kc-sb-task-time {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--muted);
  flex-shrink: 0;
  letter-spacing: 0.4px;
  background: rgba(255,255,255,0.03);
  border-radius: 3px;
  padding: 1px 5px;
}

/* ── Ideas: idea rows ────────────────────────────────────────── */
.kc-sb-idea {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 0;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-mid);
  text-decoration: none;
  position: relative;
  transition: color 0.12s;
}
.kc-sb-idea + .kc-sb-idea {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
}
.kc-sb-idea:first-child { padding-top: 4px; }
.kc-sb-idea:last-child  { padding-bottom: 4px; }
.kc-sb-idea:hover { color: var(--accent); }

.kc-sb-tag {
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.7px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255,255,255,0.04);
  color: var(--text-dim, #8a8c9a);
  flex-shrink: 0;
  text-transform: uppercase;
}
/* Tag accent colours — match the existing dashboard idea tag palette,
   now rendered as soft glowing pills with matching borders. */
.kc-sb-tag.tag-btc {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 15%, transparent);
}
.kc-sb-tag.tag-macro {
  background: rgba(92, 211, 199, 0.14);
  color: var(--accent);
  border-color: rgba(92, 211, 199, 0.28);
  box-shadow: 0 0 8px rgba(92, 211, 199, 0.15);
}
.kc-sb-tag.tag-alt {
  background: rgba(167, 139, 250, 0.14);
  color: #a78bfa;
  border-color: rgba(167, 139, 250, 0.28);
  box-shadow: 0 0 8px rgba(167, 139, 250, 0.15);
}
.kc-sb-tag.tag-thread {
  background: rgba(56, 189, 248, 0.14);
  color: #38bdf8;
  border-color: rgba(56, 189, 248, 0.28);
  box-shadow: 0 0 8px rgba(56, 189, 248, 0.15);
}
.kc-sb-tag.tag-poll {
  background: rgba(244, 114, 182, 0.14);
  color: #f472b6;
  border-color: rgba(244, 114, 182, 0.28);
  box-shadow: 0 0 8px rgba(244, 114, 182, 0.15);
}
.kc-sb-tag.tag-hottake {
  background: rgba(239, 68, 68, 0.14);
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.28);
  box-shadow: 0 0 8px rgba(239, 68, 68, 0.15);
}
.kc-sb-tag.tag-personal {
  background: rgba(251, 191, 36, 0.14);
  color: #fbbf24;
  border-color: rgba(251, 191, 36, 0.28);
  box-shadow: 0 0 8px rgba(251, 191, 36, 0.15);
}
.kc-sb-tag.tag-data {
  background: rgba(132, 204, 22, 0.14);
  color: #84cc16;
  border-color: rgba(132, 204, 22, 0.28);
  box-shadow: 0 0 8px rgba(132, 204, 22, 0.15);
}
.kc-sb-tag.tag-reply {
  background: rgba(168, 162, 158, 0.14);
  color: #a8a29e;
  border-color: rgba(168, 162, 158, 0.28);
  box-shadow: 0 0 8px rgba(168, 162, 158, 0.12);
}

.kc-sb-idea-star {
  font-size: 9px;
  color: var(--yellow, #f7931a);
  flex-shrink: 0;
}
.kc-sb-idea-text {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Ideas: right-click context menu ────────────────────────── */
/* Source-row highlight while menu is open */
.kc-sb-idea.kc-sb-idea-ctx-active {
  color: var(--text-bright);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-radius: 4px;
}

/* Inline edit input — replaces the .kc-sb-idea-text span */
.kc-sb-idea-edit-input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  color: var(--text-bright);
  border: 1px solid var(--accent);
  border-radius: 3px;
  padding: 2px 5px;
  font: inherit;
  font-size: 11px;
  outline: none;
}
.kc-sb-idea.kc-sb-idea-editing { cursor: text; }
.kc-sb-idea.kc-sb-idea-editing:hover { color: var(--text-mid); }

/* The floating menu itself — fixed-positioned, anchored at cursor */
.kc-sb-ctx-menu {
  position: fixed;
  z-index: 9000;
  min-width: 168px;
  padding: 5px;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px color-mix(in srgb, var(--accent) 4%, transparent);
  font-family: var(--kc-font-ui);
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 0.09s ease, transform 0.09s ease;
}
.kc-sb-ctx-menu.show {
  opacity: 1;
  transform: translateY(0);
}

.kc-sb-ctx-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  background: transparent;
  border: 0;
  border-radius: 5px;
  color: var(--text);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  transition: background 0.08s, color 0.08s;
}
.kc-sb-ctx-item svg {
  flex-shrink: 0;
  color: var(--muted);
  transition: color 0.08s;
}
.kc-sb-ctx-item:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--text-bright);
}
.kc-sb-ctx-item:hover svg { color: var(--accent); }
.kc-sb-ctx-item:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: -1px;
}

.kc-sb-ctx-divider {
  height: 1px;
  margin: 4px 6px;
  background: var(--border);
}

.kc-sb-ctx-item-danger { color: var(--red); }
.kc-sb-ctx-item-danger svg { color: var(--red); }
.kc-sb-ctx-item-danger:hover {
  background: color-mix(in srgb, var(--red) 10%, transparent);
  color: var(--red);
}
.kc-sb-ctx-item-danger:hover svg { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .kc-sb-ctx-menu,
  .kc-sb-ctx-menu.show { transition: none; transform: none; }
}

/* ══ FOOTER (theme button + version) ═════════════════════════════ */
.kc-sb-foot {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 12px 12px;
  position: relative;
  flex-shrink: 0;
}
.kc-sb-foot::before {
  content: '';
  position: absolute;
  left: 14px;
  right: 14px;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.07), transparent);
}

/* Icon row — wraps the bug / inbox / palette / settings buttons.
   Was previously the .kc-sb-foot itself (a single flex row); since
   the razors pill landed at the top of the foot, the icon group
   moved into this dedicated wrapper so it stays a horizontal row
   independent of the foot's column layout. */
.kc-sb-foot-icons {
  display: flex;
  align-items: center;
  gap: 8px;
}

.kc-nav-right {
  display: contents; /* unused container — kept for JS compat */
}

.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-foot {
  /* Collapsed sidebar (56px). The pill compresses to a 30×30 tile
     and stacks above the still-vertical icon column. */
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  padding: 10px 8px 12px;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-foot-icons {
  /* Stack vertically when collapsed so both the appearance button
     and the settings gear remain visible inside the 56px-wide
     sidebar (two 32px buttons + 8px gap = 72px, which would
     overflow horizontally and get clipped by the sidebar's
     overflow:hidden). */
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-foot-text {
  display: none;
}
.kc-sb-foot-text {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.6px;
  color: var(--muted);
  text-transform: uppercase;
  margin-left: auto;
  font-feature-settings: 'tnum';
}

/* Settings gear relocation — when the gear lives inside the sidebar
   foot, override its legacy fixed-positioned 48px circular styling
   and make it visually match .kc-theme-btn (32px square, bordered,
   muted text colour, hover-to-accent). */
.kc-sidebar .settings-gear,
.kc-sb-foot .settings-gear {
  position: static !important;
  top: auto !important;
  right: auto !important;
  /* flex: lock width even inside flex parents */
  flex: 0 0 30px !important;
  width: 30px !important;
  height: 30px !important;
  min-width: 30px !important;
  font-size: 13px !important;
  border-radius: 8px !important;
  z-index: auto !important;
  animation: none !important;
  /* glass tile appearance */
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01)) !important;
  border: 1px solid rgba(255,255,255,0.06) !important;
  color: var(--text-mid) !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2) !important;
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s !important;
}
.kc-sidebar .settings-gear:hover,
.kc-sb-foot .settings-gear:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, transparent) !important;
  color: var(--accent) !important;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01)) !important;
  transform: none !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent) 18%, transparent) !important;
}

/* Theme/Appearance button */
.kc-theme-btn {
  width: 30px;
  height: 30px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  color: var(--text-mid);
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s;
  font-family: inherit;
  flex-shrink: 0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
}
.kc-theme-btn:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* ── STANDARDIZED CONFIG GEAR ──────────────────────────────
   (unchanged — used in panel headers across pages, not just nav)
   --------------------------------------------------------- */
.cfg-gear {
  --cfg-gear-size: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  padding: 0;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 4px;
  color: var(--accent);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.2s, color 0.15s;
  font-family: inherit;
  flex-shrink: 0;
  vertical-align: middle;
}
.cfg-gear::before {
  content: "";
  display: block;
  width: var(--cfg-gear-size);
  height: var(--cfg-gear-size);
  background-color: currentColor;
  -webkit-mask: var(--cfg-gear-svg) center / contain no-repeat;
          mask: var(--cfg-gear-svg) center / contain no-repeat;
}
.cfg-gear { --cfg-gear-svg: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z'/></svg>"); }
.cfg-gear:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: var(--accent);
  transform: rotate(45deg);
}
.cfg-gear:active { transform: rotate(45deg) scale(0.94); }
.cfg-gear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.cfg-gear--sm { width: 24px; height: 24px; --cfg-gear-size: 12px; }
.cfg-gear--lg { width: 32px; height: 30px; --cfg-gear-size: 16px; }

.cfg-gear--label {
  width: auto;
  height: auto;
  padding: 5px 10px 5px 8px;
  gap: 6px;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}

/* ══ THEME / APPEARANCE MENU ═════════════════════════════════════
   In the sidebar, the theme button lives at the bottom-left. The menu
   should pop UP-AND-RIGHT (not down-and-right), so it doesn't get
   clipped or overlap the page footer. We use `bottom: 100%` and
   `left: 100%` so it appears to the right of the gear, anchored at
/* ════════════════════════════════════════════════════════════════
   APPEARANCE DRAWER (Razor Alpha) — slide-in from right, stacked sections
   ────────────────────────────────────────────────────────────────
   The Appearance menu is a slide-in drawer mounted on every page,
   triggered by the .kc-theme-btn (palette icon) in the sidebar foot.
   The DOM still has #kcThemeBtn → #kcThemeMenu (for JS compatibility),
   but the menu is now wrapped in a .kc-theme-overlay scrim and styled
   as a drawer matching the Settings + Bug-report + AI-assistant chassis
   (480px desktop, full-width mobile, ESC + outside-click close).
   ════════════════════════════════════════════════════════════════ */
.kc-theme-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.kc-theme-overlay.show { display: block; }

.kc-theme-menu {
  position: fixed;
  top: 0;
  right: 0;
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
  /* Reset legacy popover styles */
  border: none;
  border-left: 1px solid var(--border2);
  border-radius: 0;
  padding: 0;
  min-width: 0;
  max-height: none;
}
.kc-theme-overlay.show .kc-theme-menu { transform: translateX(0); }
/* Legacy support: a .kc-theme-menu.open without overlay still slides in
   (e.g. if any old code path bypasses the new opener). */
.kc-theme-menu.open { transform: translateX(0); }

.kc-theme-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.kc-theme-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: var(--w-bold, 600);
  color: var(--text-bright, var(--text));
  min-width: 0;
}
.kc-theme-panel-title .kc-theme-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.kc-theme-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.kc-theme-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
}
.kc-theme-panel-close:hover {
  color: var(--text-bright, var(--text));
  background: rgba(255,255,255,0.04);
}

.kc-theme-meta {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
}

.kc-theme-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
}

/* Stacked sections (replaces tab-based show/hide) */
.kc-appear-section { margin-bottom: 22px; }
.kc-appear-section:last-child { margin-bottom: 0; }
.kc-appear-section + .kc-appear-section {
  padding-top: 22px;
  border-top: 1px solid var(--border);
}
.kc-appear-section-title {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
  font-weight: var(--w-bold, 600);
}

.kc-theme-head {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 6px 8px 4px;
}

.kc-theme-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-mid);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 13px;
  font-weight: var(--w-semibold);
  cursor: pointer;
  text-align: left;
  transition: all 0.12s;
}
.kc-theme-opt:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--text-bright);
}
.kc-theme-opt.active {
  border-color: var(--accent);
  color: var(--accent);
}
.kc-theme-swatch {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 1px solid rgba(127,127,127,0.2);
  flex-shrink: 0;
}

/* ── FAMILY / INTENSITY PICKER ─────────────────────────────────────
   New theme picker UI: 3 collapsible family cards, each containing
   3 intensity buttons. Replaces the legacy flat 7-row list. The
   legacy .kc-theme-opt rules above remain as a fallback path.
   ────────────────────────────────────────────────────────────────── */
.kc-fam-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 8px;
  background: color-mix(in srgb, var(--card2, var(--bg)) 50%, transparent);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.kc-fam-card:hover {
  background: color-mix(in srgb, var(--card2, var(--bg)) 75%, transparent);
  border-color: var(--border2);
}
.kc-fam-card.kc-fam-selected {
  border-color: color-mix(in srgb, var(--fam-color, var(--accent)) 60%, var(--border));
  background: color-mix(in srgb, var(--fam-color, var(--accent)) 6%, transparent);
}
.kc-fam-row {
  display: flex; align-items: center; gap: 10px;
}
.kc-fam-preview {
  width: 32px; height: 32px;
  border-radius: 6px;
  background: var(--fam-bg, var(--bg));
  border: 1px solid var(--fam-border, var(--border));
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}
.kc-fam-preview::after {
  content: '';
  position: absolute;
  inset: 7px;
  border-radius: 3px;
  background: linear-gradient(135deg, var(--fam-color, var(--accent)) 0%, var(--fam-color2, var(--fam-color, var(--accent))) 100%);
}
.kc-fam-info { flex: 1 1 auto; min-width: 0; }
.kc-fam-name {
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 12.5px;
  font-weight: var(--w-semibold);
  color: var(--text-bright);
  letter-spacing: -0.2px;
  margin-bottom: 1px;
}
.kc-fam-desc {
  font-size: 10.5px;
  color: var(--muted);
  line-height: 1.35;
}
.kc-fam-check {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--border2);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; line-height: 1;
  color: transparent;
}
.kc-fam-card.kc-fam-selected .kc-fam-check {
  border-color: var(--fam-color, var(--accent));
  background: var(--fam-color, var(--accent));
  color: var(--fam-bg, var(--bg));
}
.kc-fam-card.kc-fam-selected .kc-fam-check::after {
  content: '✓';
  font-weight: var(--w-bold);
}
/* ── XP-locked family cards (KCUnlocks gating) ──────────────────── */
.kc-fam-card[data-locked="1"] {
  cursor: default;
  opacity: 0.62;
}
.kc-fam-card[data-locked="1"]:hover {
  background: color-mix(in srgb, var(--card2, var(--bg)) 50%, transparent);
  border-color: var(--border);
}
.kc-fam-card[data-locked="1"] .kc-fam-preview::after { filter: grayscale(0.45); }
.kc-fam-card[data-locked="1"] .kc-fam-check { display: none; }
.kc-fam-lock {
  display: inline-flex; align-items: center; gap: 4px;
  flex-shrink: 0;
  font-family: 'Space Mono', monospace;
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: 5px; padding: 2px 6px;
  white-space: nowrap;
}
.kc-fam-lock svg { width: 11px; height: 11px; }
@keyframes kcFamBump {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}
.kc-fam-card.kc-fam-bump { animation: kcFamBump 0.28s ease; }
/* ── XP-locked flat options (fonts, and any future flat picker) ──── */
.kc-font-fam-opt[data-locked="1"] {
  opacity: 0.55;
  cursor: default;
}
.kc-font-fam-opt[data-locked="1"]:hover {
  background: transparent;
  border-color: transparent;
}
.kc-font-fam-opt[data-locked="1"] .kc-font-fam-tag { display: none; }
.kc-opt-lock {
  display: inline-flex; align-items: center; gap: 3px;
  flex-shrink: 0;
  font-family: 'Space Mono', monospace;
  font-size: 9px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 4px; padding: 1px 5px;
  white-space: nowrap;
}
.kc-opt-lock svg { width: 10px; height: 10px; }
.kc-int-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
}
/* Hide intensity row on collapsed (non-selected) family cards */
.kc-fam-card:not(.kc-fam-selected) .kc-int-row { display: none; }
.kc-int-btn {
  background: color-mix(in srgb, var(--text) 4%, transparent);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 7px 4px;
  cursor: pointer;
  text-align: center;
  transition: all 0.12s ease;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  color: var(--muted);
}
.kc-int-btn:hover {
  background: color-mix(in srgb, var(--text) 8%, transparent);
  border-color: var(--border2);
  color: var(--text);
}
.kc-int-btn.kc-int-active {
  background: color-mix(in srgb, var(--fam-color, var(--accent)) 14%, transparent);
  border-color: color-mix(in srgb, var(--fam-color, var(--accent)) 50%, var(--border));
  color: var(--fam-color, var(--accent));
}
.kc-int-preview {
  height: 20px;
  border-radius: 4px;
  margin-bottom: 5px;
  border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
  background: var(--int-bg, var(--bg));
  position: relative;
  overflow: hidden;
}
.kc-int-preview::before {
  content: '';
  position: absolute;
  top: 4px; left: 4px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--int-accent, var(--accent));
}
.kc-int-preview::after {
  content: '';
  position: absolute;
  top: 5px; left: 14px; right: 4px;
  height: 3px;
  border-radius: 2px;
  background: var(--int-accent, var(--accent));
  opacity: 0.45;
}
.kc-int-name {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: var(--w-medium);
}

/* Header pill showing the current selection in plain English */
.kc-theme-current-pill {
  display: inline-block;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.5px;
  padding: 2px 7px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
}
/* Subtle "inherited from global" hint shown on the page-scope picker
   when no per-page override is set (mirrors how the font picker
   marks inherited values). */
.kc-fam-card.kc-fam-inherited {
  opacity: 0.92;
}
.kc-fam-card.kc-fam-inherited.kc-fam-selected::before {
  content: '· inherited';
  position: absolute;
  margin-left: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--muted);
  letter-spacing: 0.4px;
}

/* The .kc-sb-foot needs `position: relative` so the absolutely-
   positioned theme menu anchors against it. */
.kc-sb-foot { position: relative; }

/* ══ MOBILE TOPBAR + DRAWER ══════════════════════════════════════ */
.kc-mobile-topbar {
  display: none;
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 48px;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  backdrop-filter: blur(16px) saturate(1.4);
  border-bottom: 1px solid var(--border);
  z-index: 850;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
}
@media (max-width: 900px) { .kc-mobile-topbar { display: flex; } }

.kc-nav-hamburger {
  display: inline-flex;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 6px;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 0;
  flex-shrink: 0;
}
.kc-nav-hamburger span {
  display: block;
  width: 14px;
  height: 1.5px;
  background: var(--text-mid);
  border-radius: 1px;
  transition: transform 0.2s, opacity 0.2s;
}
.kc-nav-hamburger.open span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.kc-nav-hamburger.open span:nth-child(2) { opacity: 0; }
.kc-nav-hamburger.open span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

.kc-mobile-topbar .kc-mobile-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--text-bright);
}
.kc-mobile-topbar .kc-sb-logo { width: 20px; height: 20px; }

.kc-mobile-topbar .kc-mobile-chip {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--accent);
  font-weight: var(--w-bold);
  font-variant-numeric: tabular-nums;
}

/* Mobile slide-over: on small screens, the sidebar transforms into
   a slide-over drawer hidden off-screen by default. Body class
   `kc-sb-mobile-open` slides it in. A scrim covers content while open. */
@media (max-width: 900px) {
  .kc-sidebar {
    width: 260px;
    transform: translateX(-100%);
    box-shadow: 8px 0 28px -8px rgba(0,0,0,0.55);
    /* Fill the *dynamic* viewport so the foot (Razors + Appearance)
       clears Safari's collapsing toolbar, then subtract the home-
       indicator inset. vh first as a fallback for engines without dvh.
       Still divided by --kc-font-scale to cancel body zoom (see the
       base .kc-sidebar rule). */
    height: calc(100vh / var(--kc-font-scale, 1));
    height: calc((100dvh - var(--kc-safe-b)) / var(--kc-font-scale, 1));
  }
  /* Pin chevron is a desktop layout affordance — meaningless in a
     slide-over. Swap it for the close button on mobile. */
  .kc-sb-lock  { display: none !important; }
  .kc-sb-close { display: inline-flex; }
  /* Keep the foot above the gesture bar. */
  .kc-sb-foot { padding-bottom: calc(12px + var(--kc-safe-b)); }
  .kc-sidebar.kc-sb-peek { width: 260px; }
  body.kc-sb-mobile-open .kc-sidebar { transform: translateX(0); }
  /* On mobile, force the "expanded" look (text + labels visible) when open. */
  body.kc-sb-mobile-open .kc-sidebar {
    /* Add the locked class behavior so labels show */
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-section,
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-brand-text,
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-link .kc-nav-label,
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-link .kc-nav-badge,
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-search input,
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-search-kbd,
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-foot-text {
    display: revert !important;
    opacity: 1 !important;
    pointer-events: auto !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-link {
    justify-content: flex-start;
    padding: 8px 10px;
    gap: 12px;
  }
  /* Tracker block on mobile: force the expanded layout (full card with
     equity, divider, rows). The collapsed-state hide rule above wins
     in the desktop-rail-only case; mobile slide-over is treated as
     "open" so we override here to keep the card visible.            */
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tracker-section,
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tracker-block {
    display: revert !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tracker-section {
    display: flex !important;
  }
  /* Same treatment for the Tasks block so Daily / Weekly remain
     reachable from the mobile drawer. The data-empty="1" gating
     still applies (so non-dashboard pages stay hidden). */
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tasks-card[data-empty="0"],
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tasks-mount[data-empty="0"] {
    display: revert !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-sb-tasks-card[data-empty="0"] {
    display: block !important;
  }
  body.kc-sb-mobile-open .kc-sidebar .kc-nav-search {
    margin: 6px 12px 8px;
    padding: 7px 10px;
    justify-content: flex-start;
  }
}

.kc-sb-scrim {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0);
  z-index: 880;
  transition: background 0.22s ease;
  pointer-events: none;
}
@media (max-width: 900px) {
  .kc-sb-scrim { display: block; }
  body.kc-sb-mobile-open .kc-sb-scrim {
    background: rgba(0,0,0,0.55);
    pointer-events: auto;
  }
}

/* Legacy nav drawer — no longer used, but keep harmless rule
   so any leftover markup just hides. */
.kc-nav-drawer { display: none !important; }

/* (Old top-nav rules removed in sidebar refactor.) */


/* ── HERO ──────────────────────────────────────────────────── */
.kc-hero {
  text-align: center;
  padding: 32px 20px 12px;
  animation: kcFadeDown 0.55s cubic-bezier(0.2,0.8,0.2,1) both;
}

@keyframes kcFadeDown {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes kcFadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* V2: staggered reveal utility — add .kc-stagger to a parent and
   .kc-stagger-child to children. They fade-up with increasing delay. */
.kc-stagger .kc-stagger-child {
  opacity: 0;
  animation: kcFadeUp 0.5s cubic-bezier(0.2,0.8,0.2,1) forwards;
}
.kc-stagger .kc-stagger-child:nth-child(1) { animation-delay: 0.04s; }
.kc-stagger .kc-stagger-child:nth-child(2) { animation-delay: 0.08s; }
.kc-stagger .kc-stagger-child:nth-child(3) { animation-delay: 0.12s; }
.kc-stagger .kc-stagger-child:nth-child(4) { animation-delay: 0.16s; }
.kc-stagger .kc-stagger-child:nth-child(5) { animation-delay: 0.20s; }
.kc-stagger .kc-stagger-child:nth-child(6) { animation-delay: 0.24s; }
.kc-stagger .kc-stagger-child:nth-child(7) { animation-delay: 0.28s; }
.kc-stagger .kc-stagger-child:nth-child(8) { animation-delay: 0.32s; }
.kc-stagger .kc-stagger-child:nth-child(n+9) { animation-delay: 0.36s; }

.kc-hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 14px 28px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent);
  font-family: 'Space Mono', monospace;
  font-size: 20px;
  font-weight: var(--w-bold);
  letter-spacing: 4px;
  text-transform: uppercase;
  border-radius: 4px;
  position: relative;
  transition: transform 0.2s, box-shadow 0.2s;
  /* V3 glow: ambient halo at rest so the page identity announces itself. */
  box-shadow: 0 0 32px -8px color-mix(in srgb, var(--accent) 35%, transparent);
}
.kc-hero-badge:hover {
  transform: translateY(-1px);
  box-shadow:
    0 10px 30px -10px color-mix(in srgb, var(--accent) 60%, transparent),
    0 0 36px -6px color-mix(in srgb, var(--accent) 45%, transparent);
}
.kc-hero-badge .dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--accent);
  /* V3 glow: deeper diffusion on the live dot. */
  box-shadow: 0 0 12px var(--accent), 0 0 24px color-mix(in srgb, var(--accent) 40%, transparent);
  animation: kcPulse 1.4s ease-in-out infinite;
}
@keyframes kcPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(0.85); }
}

.kc-hero-badge.teal {
  background: color-mix(in srgb, var(--accent2) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent2) 30%, transparent);
  color: var(--accent2);
  box-shadow: 0 0 32px -8px color-mix(in srgb, var(--accent2) 35%, transparent);
}
.kc-hero-badge.teal .dot {
  background: var(--accent2);
  box-shadow: 0 0 12px var(--accent2), 0 0 24px color-mix(in srgb, var(--accent2) 40%, transparent);
}

.kc-hero-badge.purple {
  background: color-mix(in srgb, var(--accent3) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent3) 30%, transparent);
  color: var(--accent3);
  box-shadow: 0 0 32px -8px color-mix(in srgb, var(--accent3) 35%, transparent);
}
.kc-hero-badge.purple .dot {
  background: var(--accent3);
  box-shadow: 0 0 12px var(--accent3), 0 0 24px color-mix(in srgb, var(--accent3) 40%, transparent);
}

@media (max-width: 600px) {
  .kc-hero { padding: 32px 16px 22px; }
  .kc-hero-badge { font-size: 14px; padding: 10px 18px; letter-spacing: 3px; }
  .kc-hero-badge .dot { width: 8px; height: 8px; }
}

/* Hide legacy hero text and old status bar */
.kc-hero h1,
.kc-hero .kc-hero-sub,
.kc-status-bar {
  display: none !important;
}

/* Hide the hero rectangle / badge entirely on all pages (V2 cleanup).
   Kept the markup so any JS references to .kc-hero-badge don't break. */
.kc-hero {
  display: none !important;
}

.back-to-dashboard { display: none !important; }

/* V2: hero is hidden, so its next sibling becomes the first laid-out
   element under the sticky status bar. Give it breathing room on
   every page (active-week, archive, index, kol, parser, prompts,
   radar, week-generator, writer). */
.kc-hero + * {
  padding-top: 24px;
}

/* ══════════════════════════════════════════════════════════════════
   PEAKY MOTIF #1 · HAIRLINE RULE
   ──────────────────────────────────────────────────────────────────
   A thin brass rule that fades to transparent at both ends. Drop it
   under any section label as a quiet anchor — like the chair rails
   and picture rails in period interiors. Reads as a printed-document
   detail, not chrome.

   Two utilities ship together so the common pattern is one line of
   HTML per section:

   <div class="kc-section-head">
     <div class="kc-section-head-lab"><svg/> SECTION LABEL</div>
     <div class="kc-section-head-meta">3 open · 1 waiting</div>
   </div>
   <div class="kc-hairline"></div>

   .kc-hairline is independent — any page can drop it after its own
   section title without restructuring. The .kc-section-head pair is
   a convenience for the standard "label left, meta right" pattern.

   Strength is opacity-tunable via --kc-hairline-strength (0–1).
   Default 0.55 reads clearly on warm-soot cards without shouting.
   DISABLED PLATFORM-WIDE: set to 0 below so neither the auto-paint
   (`*-head::after`) nor the manual `.kc-hairline` utility draws a
   visible brass line on any page. To bring hairlines back, raise this
   to ~0.55 (or set it per-page in that page's :root). All references
   keep the `var(…, 0.55)` fallback so nothing breaks if this is removed.
   ══════════════════════════════════════════════════════════════════ */

/* Platform-wide off switch for the brass head-hairline (see note above). */
:root { --kc-hairline-strength: 0; }

.kc-hairline {
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--accent) calc(var(--kc-hairline-strength, 0.55) * 100%), transparent) 6%,
    color-mix(in srgb, var(--accent) calc(var(--kc-hairline-strength, 0.55) * 100%), transparent) 94%,
    transparent 100%
  );
  margin-bottom: 14px;
  /* No border-radius — hairlines are functional rules, not pills. */
  /* No pointer events; sits between a label and its content. */
  pointer-events: none;
}

/* Tighter spacing variant for nested sections (sub-panels within
   a card). Keeps the same fade pattern, just less air below. */
.kc-hairline.tight {
  margin-bottom: 8px;
}

/* The .kc-section-head row pairs with .kc-hairline below it.
   Label left (mono uppercase eyebrow), meta right (mono dim).
   The icon slot before the label inherits color from the parent. */
.kc-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
}
.kc-section-head-lab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--text-bright);
  text-transform: uppercase;
  min-width: 0;
}
.kc-section-head-lab > svg,
.kc-section-head-lab > .kc-ic {
  flex-shrink: 0;
  color: var(--accent);
}
.kc-section-head-meta {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  text-align: right;
  flex-shrink: 0;
  letter-spacing: 0.3px;
}

@media (max-width: 600px) {
  /* On narrow screens, drop the right-side meta below the label
     rather than fighting for room. Hairline stays the same. */
  .kc-section-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
  .kc-section-head-meta {
    text-align: left;
  }
}

/* ── PLATFORM-WIDE AUTO-HAIRLINE ────────────────────────────────────
   Rather than inserting <div class="kc-hairline"> after every page's
   section-header markup (30+ edits across 13 pages with non-uniform
   class names), this block paints the hairline as the bottom border
   of each page's existing section-header convention.

   Naming surveyed across the codebase (2026-05):
     • wallet.html   .wl-card-head .wl-section-head
     • compete.html  .cp-card-head
     • radar.html    .module-head .rp-card-head
     • scanners.html .hm-card-head .kn-panel-head
     • kol.html      .panel-title
     • index.html    .panel-head
     • writer.html   .panel-header .history-panel-head
     • parser.html   .history-panel-head
     • prompts.html  .section-head
     • plan.html     .anl-section-title (block, not a row)
     • earn.html     .row-brief-panel-head

   The selector list is opt-in via class match — pages that don't
   use one of these conventions stay untouched. Each rule wraps the
   border in `:not(.no-hairline)` so any page-local edge case can
   opt out by adding `.no-hairline` to the element.

   The visual is rendered via ::after rather than border-bottom so
   the fade-at-ends gradient works (borders are solid only). The
   ::after sits inside the head as the last child, with negative
   bottom margin so it slots into the existing layout without
   adding height. Padding adjusts per-page if the head sits flush
   to content (most heads have natural padding already).
   ──────────────────────────────────────────────────────────────── */

.wl-card-head:not(.no-hairline),
.wl-section-head:not(.no-hairline),
.cp-card-head:not(.no-hairline),
.module-head:not(.no-hairline),
.rp-card-head:not(.no-hairline),
.hm-card-head:not(.no-hairline),
.kn-panel-head:not(.no-hairline),
.panel-title:not(.no-hairline),
.panel-head:not(.no-hairline),
.panel-header:not(.no-hairline),
.history-panel-head:not(.no-hairline),
.section-head:not(.no-hairline),
.row-brief-panel-head:not(.no-hairline),
.pulse-mod-head:not(.no-hairline),
.kpt-row:not(.no-hairline),
.pd-strip-title:not(.no-hairline),
.thr-focus-head:not(.no-hairline),
.thr-sec-head:not(.no-hairline),
.aw-day-head:not(.no-hairline),
.aw-head:not(.no-hairline),
.week-header:not(.no-hairline),
.angles-head:not(.no-hairline),
.diversity-head:not(.no-hairline),
.results-head:not(.no-hairline),
.rz-hub-stage-head:not(.no-hairline),
.rz-hub-priority-head:not(.no-hairline),
.today-head:not(.no-hairline),
.done-dock-panel-head:not(.no-hairline) {
  position: relative;
  /* Neutralize any pre-existing solid bottom border the page may have
     painted on these heads (index.html, writer.html, etc all do).
     Our ::after below paints the new fade-at-ends brass hairline in
     its place. Pages can opt out with `.no-hairline` to keep their
     original border. */
  border-bottom-color: transparent !important;
}

.wl-card-head:not(.no-hairline)::after,
.wl-section-head:not(.no-hairline)::after,
.cp-card-head:not(.no-hairline)::after,
.module-head:not(.no-hairline)::after,
.rp-card-head:not(.no-hairline)::after,
.hm-card-head:not(.no-hairline)::after,
.kn-panel-head:not(.no-hairline)::after,
.panel-title:not(.no-hairline)::after,
.panel-head:not(.no-hairline)::after,
.panel-header:not(.no-hairline)::after,
.history-panel-head:not(.no-hairline)::after,
.section-head:not(.no-hairline)::after,
.row-brief-panel-head:not(.no-hairline)::after,
.pulse-mod-head:not(.no-hairline)::after,
.kpt-row:not(.no-hairline)::after,
.pd-strip-title:not(.no-hairline)::after,
.thr-focus-head:not(.no-hairline)::after,
.thr-sec-head:not(.no-hairline)::after,
.aw-day-head:not(.no-hairline)::after,
.aw-head:not(.no-hairline)::after,
.week-header:not(.no-hairline)::after,
.angles-head:not(.no-hairline)::after,
.diversity-head:not(.no-hairline)::after,
.results-head:not(.no-hairline)::after,
.rz-hub-stage-head:not(.no-hairline)::after,
.rz-hub-priority-head:not(.no-hairline)::after,
.today-head:not(.no-hairline)::after,
.done-dock-panel-head:not(.no-hairline)::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--accent) calc(var(--kc-hairline-strength, 0.55) * 100%), transparent) 6%,
    color-mix(in srgb, var(--accent) calc(var(--kc-hairline-strength, 0.55) * 100%), transparent) 94%,
    transparent 100%
  );
  pointer-events: none;
}

/* The wallet page got a manual <div class="kc-hairline"> in the
   first round; the new auto-rule would then double up. Suppress
   the inline divs on pages that now get the auto-paint, so the
   single border under .wl-card-head stays. .kc-hairline as a
   standalone utility still works on pages that drop it in by hand
   (kept as escape hatch). */
.wl-card-head + .kc-hairline,
.wl-section-head + .kc-hairline {
  display: none;
}

/* ══════════════════════════════════════════════════════════════════
   PEAKY MOTIF #4 · WAX SEAL
   ──────────────────────────────────────────────────────────────────
   Finalization marker for moments where something is "stamped done"
   — bets settled, brief generated, threads published, trade closed.
   Sits as a brand mark, not a generic checkmark. Use sparingly: this
   is the platform's strongest visual punctuation.

   Markup pattern:
     <div class="kc-wax-seal" aria-hidden="true">
       <i class="kc-ic" data-icon="seal-razor"></i>
     </div>

   The inner <i.kc-ic> is auto-rendered by KCIcons. The container
   sets size + oxblood color + the one-shot stamp animation. Default
   size is 64px (best read at this scale); .kc-wax-seal.sm = 48px
   for inline contexts, .kc-wax-seal.lg = 88px for the dominant slot
   on a settled-bet detail card.

   Color uses var(--red) which is oxblood in all Razor themes. The
   seal is intentionally one of the few platform-wide oxblood uses
   alongside .down — its rarity is what gives it weight.
   ══════════════════════════════════════════════════════════════════ */

.kc-wax-seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  color: var(--red);
  /* The stamp animation runs once on first paint. Subsequent renders
     (e.g. React-style re-mounts) re-trigger it because the keyframe
     is set per-element. Use .kc-wax-seal.stamped if you need to play
     the animation in response to a state change — toggle the class
     to replay. */
  animation: kcWaxStamp 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.kc-wax-seal.sm { width: 48px; height: 48px; }
.kc-wax-seal.lg { width: 88px; height: 88px; }

/* The inner SVG fills the container box exactly so size scales clean
   from the wrapper. KC.icon emits explicit width/height — we
   override here so the size= opt passed to KC.icon doesn't have to
   match the wrapper. */
.kc-wax-seal > .kc-ic,
.kc-wax-seal > svg {
  width: 100%;
  height: 100%;
  display: block;
}
.kc-wax-seal > .kc-ic > svg {
  width: 100%;
  height: 100%;
}

@keyframes kcWaxStamp {
  0%   { opacity: 0; transform: scale(1.25) rotate(-3deg); }
  60%  { opacity: 1; transform: scale(0.97) rotate(0.5deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}

@media (prefers-reduced-motion: reduce) {
  .kc-wax-seal { animation: none; }
}

/* Overlay variant — transient seal that stamps over a row briefly
   then fades. Used by the platform-wide kc:bet-settled handler so
   any page rendering bet rows with [data-kc-bet-id] gets the seal
   moment for free on live settlement events. Positions itself in
   the centre of the host element via absolute positioning; the
   host is given position:relative by the JS that injects the
   seal so the anchor is correct even on cards that didn't have a
   positioning context.

   Animation sequence (2.4s total):
     0.00s → 0.55s   stamp-in (scale + fade in, slight rotate settle)
     0.55s → 1.75s   hold at full opacity
     1.75s → 2.40s   fade-out (opacity only, no scale)
   The host JS removes the element at 2.4s so the absolute overlay
   doesn't linger in the DOM. */
.kc-wax-seal--overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 5;
  /* Override the default stamp animation with the longer combined
     sequence. The single-keyframe approach simplifies removal — one
     setTimeout instead of chained animationend listeners. */
  animation: kcWaxStampOverlay 2.4s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  /* Drop-shadow under the seal so it reads as a stamp pressed onto
     the row, not a flat sticker. Oxblood-tinted shadow at low alpha. */
  filter: drop-shadow(0 4px 14px color-mix(in srgb, var(--red) 35%, transparent));
}

@keyframes kcWaxStampOverlay {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(1.35) rotate(-4deg); }
  18%  { opacity: 1; transform: translate(-50%, -50%) scale(0.96) rotate(0.8deg); }
  28%  { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); }
  73%  { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1) rotate(0); }
}

@media (prefers-reduced-motion: reduce) {
  .kc-wax-seal--overlay {
    /* Still show the seal momentarily — the motif communicates
       finality, which is information, not decoration. Drop the
       scale/rotate dynamics; keep an opacity in/out so it still
       appears and clears within the same 2.4s window. */
    animation: kcWaxStampOverlayReduced 2.4s linear both;
  }
}
@keyframes kcWaxStampOverlayReduced {
  0%, 100% { opacity: 0; }
  15%, 85% { opacity: 1; }
}

/* ══════════════════════════════════════════════════════════════════
   PEAKY MOTIF #7 · EMPTY-STATE PLATE
   ──────────────────────────────────────────────────────────────────
   A brass-bordered "name plate" used for empty states across the
   platform — Wallet with no positions, Compete with no bets, Predict
   with no tracked markets, Threads with no clusters, Earn with no
   qualifying drops. Reads as an engraved shop sign or wall plaque,
   not a "loading skeleton". The double-border (brass solid outer +
   dashed brass inset) is the giveaway detail — keep it.

   Markup pattern:
     <div class="kc-empty-plate">
       <div class="kc-empty-plate-eyebrow">— EMPTY —</div>
       <div class="kc-empty-plate-title">No positions yet</div>
       <div class="kc-empty-plate-body">
         Track a signal on Scanners to start.
       </div>
       <a class="kc-empty-plate-cta" href="scanners.html">
         OPEN SCANNERS  ↗
       </a>
     </div>

   All four inner blocks are optional — eyebrow alone, title alone,
   or body+CTA work too. The plate auto-centres in its host
   container; pages can drop it directly into a `.wl-rows` slot or
   similar without any layout wrapper. Width caps at 380px so it
   never stretches uselessly wide on a long card.

   Eyebrow uses brass; title is text-bright; body is muted; CTA
   inherits the brass eyebrow color and reads as a mono link.
   ══════════════════════════════════════════════════════════════════ */

.kc-empty-plate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  max-width: 380px;
  margin: 32px auto;
  padding: 26px 22px;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  border: 1px solid var(--accent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
  position: relative;
  text-align: center;
}

/* Dashed inset rule — the second border that sells the engraved-
   plate look. Sits 6px inside the outer border on all sides; uses
   ::before so the plate's content layout is unaffected and the
   line never interferes with hit-testing on the optional CTA. */
.kc-empty-plate::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: 0.5px dashed color-mix(in srgb, var(--accent) 30%, transparent);
  pointer-events: none;
}

.kc-empty-plate-eyebrow {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 11px;
  letter-spacing: 4px;
  color: var(--accent);
  text-transform: uppercase;
  position: relative;
  margin-bottom: 4px;
}

/* Optional decorative slot — sits above the eyebrow when the plate
   wants to use a Peaky motif element (cigar burning down, pocket
   watch face, brass key, etc) as the visual anchor of the moment.
   Sized larger than an inline icon so the artwork carries the
   plate's weight; the SVG inside should be designed for this scale
   (roughly 88×40 for landscape props, 56×56 for symmetrical ones).
   Currentcolor inherits from the plate's accent so brass tints
   automatically; oxblood and other tints are set inline per use. */
.kc-empty-plate-art {
  position: relative;
  margin-bottom: 10px;
  color: var(--accent);
  line-height: 0;
}
.kc-empty-plate-art > svg {
  display: block;
}

/* ── Cigar prop (Peaky motif extension, 2026-05) ─────────────────
   Inline SVG illustration used in empty-state plates that benefit
   from the "patience / slow burn" metaphor — primary use is the
   Wallet "Waiting positions" filter empty state. The cigar is drawn
   horizontal, brass band on the left (wrapper foil), tobacco body
   in warm brown, ember at the right tip with two wispy smoke trails
   rising. The smoke trails animate on offset breathing keyframes
   so the still illustration carries a small sign of life without
   becoming distracting.

   Used as:
     <div class="kc-empty-plate-art kc-cigar-art">
       <svg viewBox="0 0 120 60" width="120" height="60">
         ... (markup is in the page that uses it; see wallet.html)
       </svg>
     </div>

   The smoke + ember animations are scoped to descendants of
   .kc-cigar-art so adding the class to a plate auto-animates any
   <path class="kc-cigar-smoke-1/2"> and <circle class="kc-cigar-ember">
   inside the SVG. Respects prefers-reduced-motion: still drawing,
   no animation.  */
.kc-cigar-art .kc-cigar-smoke-1 {
  animation: kcCigarSmoke1 4.2s ease-in-out infinite;
  transform-origin: 100px 30px;
}
.kc-cigar-art .kc-cigar-smoke-2 {
  animation: kcCigarSmoke2 5.1s ease-in-out infinite;
  animation-delay: -1.8s;
  transform-origin: 100px 30px;
}
.kc-cigar-art .kc-cigar-ember {
  animation: kcCigarEmber 2.4s ease-in-out infinite;
  transform-origin: 100px 30px;
}

@keyframes kcCigarSmoke1 {
  0%, 100% { opacity: 0.35; transform: translateY(0) scaleX(1); }
  50%      { opacity: 0.55; transform: translateY(-2px) scaleX(1.08); }
}
@keyframes kcCigarSmoke2 {
  0%, 100% { opacity: 0.22; transform: translateY(0) scaleX(1); }
  50%      { opacity: 0.40; transform: translateY(-3px) scaleX(0.92); }
}
@keyframes kcCigarEmber {
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .kc-cigar-art .kc-cigar-smoke-1,
  .kc-cigar-art .kc-cigar-smoke-2,
  .kc-cigar-art .kc-cigar-ember {
    animation: none;
  }
}

.kc-empty-plate-title {
  font-size: 14px;
  color: var(--text-bright);
  position: relative;
}

.kc-empty-plate-body {
  font-size: 11.5px;
  color: var(--text-mid);
  line-height: 1.5;
  position: relative;
  margin-top: 2px;
}

.kc-empty-plate-cta {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--accent);
  text-transform: uppercase;
  text-decoration: none;
  position: relative;
  margin-top: 10px;
  transition: color 0.15s;
}
.kc-empty-plate-cta:hover {
  color: var(--text-bright);
}

/* Compact variant — tighter padding + smaller max-width. Used
   where the plate sits inside a small card (e.g. Compete leaderboard
   filter returns no results), so it doesn't dwarf the surrounding
   chrome. */
.kc-empty-plate.compact {
  padding: 20px 18px;
  max-width: 320px;
  margin: 18px auto;
}

/* ══════════════════════════════════════════════════════════════════
   PEAKY MOTIF #8 · MATCH-FLAME LOADER
   ──────────────────────────────────────────────────────────────────
   In-flight indicator that replaces the rotating browser spinner
   for working-state moments — scanner runs, AI generations, sync
   polls. The match-flame icon (KCIcons sprite) renders three flame
   layers + a matchstick body. This class targets those layers and
   animates them on offset opacity + transform loops so the flame
   reads as a flicker, not a uniform pulse.

   Markup patterns:
     Inline at a label:
       <span class="kc-flame-loader">
         <i class="kc-ic" data-icon="match-flame" data-size="14"></i>
       </span>
       Generating…

     Centred card spinner:
       <div class="kc-flame-loader kc-flame-loader--card">
         <i class="kc-ic" data-icon="match-flame" data-size="28"></i>
         <span class="kc-flame-loader-label">Reading the radar…</span>
       </div>

   Color: inherits currentColor so themes can override. Default ramp
   is brass via parent context (most loading badges use --accent
   already). For oxblood flame on critical alerts, set color:var(--red)
   on the wrapper.

   The animation respects prefers-reduced-motion — falls back to a
   subtle opacity throb so the loading state still communicates
   "working" without the flicker. Empty animation would be worse:
   a static flame doesn't read as "in flight".
   ══════════════════════════════════════════════════════════════════ */

.kc-flame-loader {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Establish a containing block for the SVG transform-origin so
     the flame wobble is centred. Without this the wobble would
     drift around an arbitrary anchor. */
  line-height: 1;
}

/* Centred variant — wraps the icon + an optional label in a column,
   used for whole-card loading states (radar Your Read, scanner
   running, etc.). The card variant scales the icon up 1.8x via
   transform so the flame reads as a "moment" loader at any size. */
.kc-flame-loader--card {
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 24px 16px;
}
.kc-flame-loader--card > .kc-ic,
.kc-flame-loader--card > svg {
  transform-origin: 50% 80%;
}

.kc-flame-loader-label {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--muted);
  text-transform: uppercase;
}

/* The flame body sits inside an <svg> the kc-ic registry renders.
   Target each layer (.kc-flame-outer / .kc-flame-mid / .kc-flame-wick)
   inside any descendant <svg> of the loader wrapper. */
.kc-flame-loader .kc-flame-outer {
  animation: kcFlameOuter 1.5s ease-in-out infinite;
  transform-origin: 50% 100%;
}
.kc-flame-loader .kc-flame-mid {
  animation: kcFlameMid 1.3s ease-in-out infinite;
  animation-delay: -0.4s;
  transform-origin: 50% 100%;
}
.kc-flame-loader .kc-flame-wick {
  animation: kcFlameWick 0.9s ease-in-out infinite;
  animation-delay: -0.15s;
  transform-origin: 50% 100%;
}

@keyframes kcFlameOuter {
  0%, 100% { opacity: 0.92; transform: scaleY(1) scaleX(1); }
  35%      { opacity: 0.78; transform: scaleY(0.92) scaleX(1.04); }
  65%      { opacity: 1;    transform: scaleY(1.06) scaleX(0.97); }
}
@keyframes kcFlameMid {
  0%, 100% { opacity: 0.85; transform: scaleY(1); }
  50%      { opacity: 0.65; transform: scaleY(0.88); }
}
@keyframes kcFlameWick {
  0%, 100% { opacity: 1;    transform: scaleY(1); }
  40%      { opacity: 0.85; transform: scaleY(1.12); }
  70%      { opacity: 1;    transform: scaleY(0.96); }
}

@media (prefers-reduced-motion: reduce) {
  /* No flicker — single slow opacity pulse on the whole svg so the
     loading state still communicates motion. The 3-layer offset
     dance is decorative; one slow pulse is informational. */
  .kc-flame-loader .kc-flame-outer,
  .kc-flame-loader .kc-flame-mid,
  .kc-flame-loader .kc-flame-wick {
    animation: none;
  }
  .kc-flame-loader > .kc-ic,
  .kc-flame-loader > svg {
    animation: kcFlameReduced 1.8s ease-in-out infinite;
  }
}
@keyframes kcFlameReduced {
  0%, 100% { opacity: 0.7; }
  50%      { opacity: 1; }
}

/* ── SUB-NAV STRIP ─────────────────────────────────────────
   Unified pill-style page-group toggle used to switch between
   sibling pages/tabs that share a sidebar entry. Used by:
     • plan.html       — Generate / This week / Archive
     • prompts.html    — Prompt library / Parse response
     • parser.html     — Prompt library / Parse response
   Both <button> and <a> variants are supported. The active
   item carries aria-current="page".

   Note: uses margin-top rather than relying on .kc-hero + *'s
   padding-top, because the strip's own `padding: 4px` shorthand
   would wipe an inherited padding-top. Margin survives that. */
.kc-subnav-strip {
  display: flex;
  gap: 4px;
  align-items: center;
  margin: 28px auto 16px;
  padding: 4px;
  max-width: var(--kc-page-maxw, 1200px);
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 10px;
  width: fit-content;
}
.kc-subnav-btn {
  appearance: none;
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted, #aaa);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 8px 18px;
  border-radius: 7px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: color 0.18s, background 0.18s, border-color 0.18s;
}
.kc-subnav-btn:hover {
  color: var(--text-bright, #fff);
  background: rgba(255,255,255,0.04);
}
.kc-subnav-btn[aria-current="page"] {
  color: var(--accent, #1fd687);
  background: color-mix(in srgb, var(--accent, #1fd687) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent, #1fd687) 38%, transparent);
}
@media (max-width: 700px) {
  .kc-subnav-strip { width: auto; margin: 16px 12px 12px; }
  .kc-subnav-btn { flex: 1; padding: 8px 10px; font-size: 10px; letter-spacing: 1.0px; text-align: center; }
}

/* Main utilities */
.kc-main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* ── BUTTON CENTERING UTILITY ─────────────────────────────── */
/* Wrap a primary CTA in <div class="btn-center"> to horizontally
   center it within its container. Required because the primary CTA
   rule below uses inline-flex, which does not honor margin:auto. */
.btn-center {
  display: flex;
  justify-content: center;
}

/* ── UNIFIED PRIMARY CTA BUTTONS ──────────────────────────── */
.kc-btn-primary,
.gen-btn,
.generate-btn {
  display: inline-flex;
  align-items: center !important;
  justify-content: center !important;
  gap: 10px !important;
  padding: 14px 24px !important;
  border: none !important;
  border-radius: 6px !important;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif !important;
  font-size: 14px !important;
  font-weight: var(--w-extra) !important;
  letter-spacing: 0.5px !important;
  cursor: pointer;
  transition: all 0.18s cubic-bezier(0.2,0.8,0.2,1) !important;
  text-transform: none;
  position: relative;
  overflow: hidden;
}
.kc-btn-primary:hover:not(:disabled),
.gen-btn:hover:not(:disabled),
.generate-btn:hover:not(:disabled) {
  filter: brightness(1.12);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -10px rgba(0,0,0,0.4);
}
.kc-btn-primary:active:not(:disabled),
.gen-btn:active:not(:disabled),
.generate-btn:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
}
.kc-btn-primary:disabled,
.gen-btn:disabled,
.generate-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* Secondary outlined buttons */
.kc-btn-secondary,
.radar-bar-btn,
.refresh-all-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  padding: 8px 14px !important;
  background: transparent !important;
  color: var(--text-mid) !important;
  border: 1px solid var(--border2) !important;
  border-radius: 6px !important;
  font-family: 'Space Mono', monospace !important;
  font-size: 11px !important;
  font-weight: var(--w-bold) !important;
  letter-spacing: 1px !important;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.15s !important;
}
.kc-btn-secondary:hover,
.radar-bar-btn:hover,
.refresh-all-btn:hover {
  border-color: var(--accent) !important;
  color: var(--accent) !important;
  transform: translateY(-1px);
}
.refresh-all-btn {
  background: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  color: var(--accent) !important;
  border-color: color-mix(in srgb, var(--accent) 35%, transparent) !important;
}
.refresh-all-btn:hover {
  background: color-mix(in srgb, var(--accent) 20%, transparent) !important;
}

/* ── UNIFIED ACTION BUTTON (kc-action-btn) ──────────────────
   Single visual language for the platform's "trigger work" buttons:
   Scan All (radar), Refresh All (pulse), Generate week plan
   (week-generator), Generate tweets (writer), Open Grok (prompts),
   Generate (parser). Earn-style tinted bg + accent border + accent
   text. Two sizes: large (default, 14px Grotesk) for primary page
   CTAs, compact (.compact, 11px Mono) for toolbar contexts. Both
   share the exact same color recipe so the language reads unified
   regardless of size.
   ──────────────────────────────────────────────────────────── */
.kc-action-btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  padding: 14px 24px !important;
  background: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  color: var(--accent) !important;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent) !important;
  border-radius: 6px !important;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif !important;
  font-size: 14px !important;
  font-weight: var(--w-extra) !important;
  letter-spacing: 0.5px !important;
  text-transform: none;
  cursor: pointer;
  transition: all 0.15s !important;
  text-decoration: none;
  box-shadow:
    0 0 18px color-mix(in srgb, var(--accent) 20%, transparent),
    inset 0 0 12px color-mix(in srgb, var(--accent) 8%, transparent) !important;
}
.kc-action-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 20%, transparent) !important;
  border-color: color-mix(in srgb, var(--accent) 55%, transparent) !important;
  transform: translateY(-1px);
  box-shadow:
    0 0 26px color-mix(in srgb, var(--accent) 35%, transparent),
    0 6px 20px -6px color-mix(in srgb, var(--accent) 40%, transparent),
    inset 0 0 14px color-mix(in srgb, var(--accent) 12%, transparent) !important;
}
.kc-action-btn:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
}
.kc-action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none !important;
}
/* Compact variant — toolbar contexts (radar Scan All, pulse Refresh
   All, prompts Open Grok). Same color recipe, smaller padding/font,
   uppercase Mono for toolbar visual rhythm. */
.kc-action-btn.compact {
  gap: 6px !important;
  padding: 8px 14px !important;
  font-family: 'Space Mono', monospace !important;
  font-size: 11px !important;
  font-weight: var(--w-bold) !important;
  letter-spacing: 1px !important;
  text-transform: uppercase;
}
/* Icon sizing inside kc-action-btn: large = 16px, compact = 13px.
   Override the default kc-ic sizing so they sit cleanly with the
   text baseline at each size. */
.kc-action-btn .kc-ic { width: 16px; height: 16px; }
.kc-action-btn.compact .kc-ic { width: 13px; height: 13px; }

/* ── V2: SHIMMER SKELETON LOADER ───────────────────────────── */
.kc-skeleton {
  position: relative;
  background: linear-gradient(
    90deg,
    var(--card) 0%,
    color-mix(in srgb, var(--card) 50%, var(--border2)) 40%,
    var(--card) 80%
  );
  background-size: 200% 100%;
  animation: kcShimmer 1.4s ease-in-out infinite;
  border-radius: 6px;
  color: transparent !important;
  pointer-events: none;
  user-select: none;
}
@keyframes kcShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.kc-skeleton-text {
  height: 0.9em;
  display: inline-block;
  min-width: 60px;
  vertical-align: middle;
}
.kc-skeleton-block {
  height: 80px;
  width: 100%;
  display: block;
}

/* ── V2: TOAST SYSTEM ──────────────────────────────────────── */
.kc-toast-host {
  position: fixed;
  top: 70px;
  right: 20px;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  /* Divide vw by font-scale so the cap stays inside the viewport under
     body `zoom` (otherwise 100vw becomes 120vw visual at scale 1.2). */
  max-width: min(340px, calc((100vw - 40px) / var(--kc-font-scale, 1)));
}
.kc-toast {
  pointer-events: auto;
  background: var(--card);
  color: var(--text-bright);
  border: 1px solid var(--border2);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 10px 14px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 13px;
  font-weight: var(--w-semibold);
  box-shadow: 0 10px 30px -8px rgba(0,0,0,0.5);
  animation: kcToastIn 0.24s cubic-bezier(0.2,0.8,0.2,1) forwards;
  display: flex;
  align-items: center;
  gap: 10px;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.kc-toast.ok    { border-left-color: var(--accent2); }
.kc-toast.err   { border-left-color: var(--red); }
.kc-toast.warn  { border-left-color: var(--yellow); }
.kc-toast.info  { border-left-color: var(--accent3); }
.kc-toast .kc-toast-ic {
  flex-shrink: 0;
  font-size: 14px;
  line-height: 1;
}
.kc-toast .kc-toast-body {
  flex: 1;
  line-height: 1.3;
}
.kc-toast.hiding {
  animation: kcToastOut 0.2s ease forwards;
}
@keyframes kcToastIn {
  from { opacity: 0; transform: translateX(30px) scale(0.96); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
@keyframes kcToastOut {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(30px) scale(0.96); }
}

@media (max-width: 600px) {
  .kc-toast-host { top: 64px; right: 12px; left: 12px; max-width: none; }
}

/* ── V2: NUMBER COUNT-UP UTILITY ──────────────────────────── */
.kc-count-up {
  font-variant-numeric: tabular-nums;
  display: inline-block;
}

/* ── SCROLLBAR ─────────────────────────────────────────────── */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--accent); }

/* ── ACCESSIBILITY: REDUCED MOTION ─────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  body::before { animation: none; }
}

/* ══════════════════════════════════════════════════════════════════
   APPEARANCE DRAWER CONTENT — Theme / Font / Layout sections.
   Drawer chassis (.kc-theme-overlay + .kc-theme-menu) is defined above
   in the THEME / APPEARANCE MENU block. The classes below style the
   inner content: .kc-font-cols (Global / This page side-by-side),
   the family/size/lh/weight/maxw controls.

   Tabs (.kc-appear-tabs / .kc-appear-tab / .kc-appear-panel) are
   intentionally not styled — the drawer stacks all three sections
   vertically. Legacy CSS for those classes was removed; if any caller
   still emits .kc-appear-panel markup, it will simply render as a
   plain block (no show/hide), which is the desired stacked behavior.
   ══════════════════════════════════════════════════════════════════ */

/* Font panel: two columns ("All pages" / "This page") */
.kc-font-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.kc-font-col {
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px;
}
.kc-font-col-head {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 2px 4px 6px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}
.kc-font-col-head strong {
  color: var(--text);
  font-weight: var(--w-bold);
}
.kc-font-reset {
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.8px;
  padding: 3px 6px;
  cursor: pointer;
  transition: all 0.12s;
  text-transform: uppercase;
}
.kc-font-reset:hover {
  border-color: var(--red);
  color: var(--red);
}
.kc-font-reset:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

/* Section label (for Family / Size / Line-height sub-sections) */
.kc-font-label {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 8px 4px 4px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.kc-font-label:first-child { margin-top: 2px; }
.kc-font-label .kc-font-value {
  color: var(--accent);
  font-weight: var(--w-bold);
  letter-spacing: 0.5px;
}

/* Family picker buttons */
.kc-font-family-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.kc-font-fam-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 5px 8px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  color: var(--text-mid);
  font-size: 13px;
  font-weight: var(--w-semibold);
  cursor: pointer;
  text-align: left;
  transition: all 0.12s;
}
.kc-font-fam-opt:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--text-bright);
}
.kc-font-fam-opt.active {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.kc-font-fam-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kc-font-fam-tag {
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.8px;
  color: var(--muted);
  text-transform: uppercase;
  padding: 2px 4px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  flex-shrink: 0;
}

/* Sliders (size + line-height) */
.kc-font-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  background: var(--border2);
  border-radius: 2px;
  outline: none;
  margin: 6px 0 2px;
  cursor: pointer;
}
.kc-font-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  background: var(--accent);
  border-radius: 50%;
  border: 2px solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent);
  cursor: pointer;
}
.kc-font-slider::-moz-range-thumb {
  width: 12px;
  height: 12px;
  background: var(--accent);
  border-radius: 50%;
  border: 2px solid var(--bg);
  cursor: pointer;
}

/* Size − / + steppers flanking the slider */
.kc-size-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 6px 0 2px;
}
.kc-size-row .kc-font-slider {
  flex: 1;
  margin: 0;
}
.kc-size-step {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: all 0.12s;
  user-select: none;
}
.kc-size-step:hover { color: var(--accent); border-color: var(--accent); }
.kc-size-step:active { transform: scale(0.94); }

/* Line-height pip buttons (discrete choices) */
.kc-lh-pips {
  display: flex;
  gap: 3px;
  margin-top: 4px;
}
.kc-lh-pip {
  flex: 1;
  padding: 5px 4px;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  cursor: pointer;
  transition: all 0.12s;
}
.kc-lh-pip:hover { color: var(--text); border-color: var(--border2); }
.kc-lh-pip.active {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--w-bold);
}

/* Page max-width pips (Layout panel) — share the line-height pip
   visual language but render 4-digit pixel values, so they want a
   little more breathing room. The unit hint sits in the section
   label as a small muted suffix. */
.kc-maxw-pips {
  display: flex;
  gap: 4px;
  margin-top: 4px;
}
.kc-maxw-pip {
  flex: 1;
  padding: 6px 4px;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.4px;
  cursor: pointer;
  transition: all 0.12s;
}
.kc-maxw-pip:hover { color: var(--text); border-color: var(--border2); }
.kc-maxw-pip.active {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--w-bold);
}
.kc-maxw-unit {
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 1px;
  color: var(--muted);
  opacity: 0.65;
  text-transform: uppercase;
}

/* Weight toggle pills (Regular / Light) */
.kc-weight-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.kc-weight-reset-mini {
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
  transition: all 0.12s;
}
.kc-weight-reset-mini:hover:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent);
}
.kc-weight-reset-mini:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.kc-weight-pills {
  display: flex;
  gap: 4px;
  margin-top: 4px;
}
.kc-weight-opt {
  flex: 1;
  padding: 7px 8px;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: var(--w-medium);
  cursor: pointer;
  transition: all 0.12s;
  letter-spacing: 0.3px;
}
.kc-weight-opt:hover { color: var(--text); }
.kc-weight-opt.active {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: var(--w-semibold);
}
.kc-weight-opt.kc-font-inherited { opacity: 0.55; }

/* Override badge on the per-page column title when override is active */
.kc-font-col.has-override .kc-font-col-head strong {
  color: var(--accent);
}
.kc-font-col.has-override .kc-font-col-head::after {
  content: '●';
  color: var(--accent);
  margin-left: 4px;
}

/* ── Scope toggle (All pages / This page) — single-column drawer ───
   The drawer renders BOTH scope columns; [data-scope] on .kc-theme-menu
   shows one at a time. Fallback (attr absent) shows both — old layout. */
.kc-theme-menu[data-scope="global"] [data-theme-col="page"],
.kc-theme-menu[data-scope="global"] [data-font-col="page"],
.kc-theme-menu[data-scope="global"] [data-layout-col="page"],
.kc-theme-menu[data-scope="page"] [data-theme-col="global"],
.kc-theme-menu[data-scope="page"] [data-font-col="global"],
.kc-theme-menu[data-scope="page"] [data-layout-col="global"] { display: none; }

/* Single column + content. Drawer width stays at its base 480px (parity
   with .ka-panel / .kbr-panel and Appearance's own non-scoped default) —
   the scope toggle hides one column rather than shrinking the chassis. */
/* minmax(0,1fr) + min-width:0 — block grid min-content blowout: nowrap
   font names/tags otherwise force tracks (and the whole column) wider
   than the drawer, clipping the right edge. */
.kc-theme-menu[data-scope] .kc-font-cols { grid-template-columns: minmax(0, 1fr); }
.kc-theme-menu[data-scope] .kc-font-col { min-width: 0; }

/* Column heads: the toggle already names the scope, so the per-column
   "All pages / This page" title is redundant — hide just the <strong>;
   the current-theme pill, override dot (::after) and Reset stay. */
.kc-theme-menu[data-scope] .kc-font-col-head strong { display: none; }

/* Compact: font families fold to a 2-col grid, theme cards tighten. */
.kc-theme-menu[data-scope] .kc-font-family-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px;
}
.kc-theme-menu[data-scope] .kc-font-fam-opt { min-width: 0; }
.kc-theme-menu[data-scope] .kc-fam-card { padding: 8px; margin-bottom: 6px; }
.kc-theme-menu[data-scope] .kc-fam-preview { width: 26px; height: 26px; }
.kc-theme-menu[data-scope] .kc-fam-preview::after { inset: 6px; }

.kc-scope-toggle {
  display: flex;
  gap: 3px;
  padding: 3px;
  margin-bottom: 16px;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.kc-scope-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 4px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: var(--w-bold, 600);
  cursor: pointer;
  transition: all 0.12s;
}
.kc-scope-tab:hover { color: var(--text); }
.kc-scope-tab.active {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}
.kc-scope-pill {
  font-size: 8px;
  letter-spacing: 0.8px;
  padding: 1px 5px;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
}
.kc-scope-tab.active .kc-scope-pill {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.kc-scope-pill.kc-scope-pill-custom {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

/* ── APPEARANCE B · round 1 (2026-10) ─────────────────────────────
   Theme grid with mini previews, plain scope note, no duplicate
   summary / current-theme pills. Markup: familyCardHTML in shared.js. */
.kc-theme-menu .kc-theme-meta { display: none; }
.kc-theme-menu [data-theme-col] .kc-theme-current-pill { display: none; }
.kc-theme-menu .kc-scope-pill { display: none; }
.kc-theme-menu .kc-scope-toggle { margin-bottom: 6px; }
.kc-scope-note {
  font-size: 11px; line-height: 1.45; color: var(--muted);
  margin: 0 2px 16px;
}
.kc-scope-note > span { display: none; }
.kc-theme-menu[data-scope="global"] .kc-scope-note-global { display: inline; }
.kc-theme-menu[data-scope="page"] .kc-scope-note:not([data-custom]) [data-follow] { display: inline; }
.kc-theme-menu[data-scope="page"] .kc-scope-note[data-custom] [data-custom] { display: inline; color: var(--accent); }

/* 2-column theme grid (only the visible scope column) */
.kc-theme-menu[data-scope="global"] [data-theme-col="global"],
.kc-theme-menu[data-scope="page"] [data-theme-col="page"] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  align-items: start;
}
.kc-theme-menu [data-theme-col] .kc-font-col-head { grid-column: 1 / -1; }
.kc-theme-menu [data-theme-col] .kc-font-col-head:not(:has(button)) { display: none; }
.kc-theme-menu[data-scope] [data-theme-col] .kc-fam-card { margin: 0; padding: 6px; position: relative; }
.kc-theme-menu [data-theme-col] .kc-fam-preview { display: none; }
.kc-theme-menu [data-theme-col] .kc-int-row { display: none; }
.kc-theme-menu [data-theme-col] .kc-fam-row { gap: 6px; margin-top: 7px; align-items: flex-start; }
.kc-theme-menu [data-theme-col] .kc-fam-name { display: flex; align-items: center; gap: 6px; font-size: 12.5px; }
.kc-theme-menu [data-theme-col] .kc-fam-desc { margin-top: 2px; }
.kc-theme-menu [data-theme-col] .kc-fam-check { margin-top: 1px; }
.kc-fam-new {
  font-family: 'Space Mono', monospace; font-size: 8.5px; letter-spacing: .06em;
  padding: 0 4px; border-radius: 3px; line-height: 14px;
  color: var(--fam-color); border: 1px solid color-mix(in srgb, var(--fam-color) 55%, transparent);
}
/* mini preview: nav bar, candles in the theme's own up/down, accent bar */
.kc-fam-mini {
  background: var(--fam-bg);
  border: 1px solid var(--fam-border);
  border-radius: 6px;
  padding: 6px 7px;
}
.kc-fam-mini-top { display: flex; align-items: center; gap: 5px; }
.kc-fam-mini-top i { width: 7px; height: 7px; border-radius: 2px; background: var(--fam-color); flex: none; }
.kc-fam-mini-top b { height: 3px; flex: 1; border-radius: 2px; background: var(--fam-border); }
.kc-fam-mini-candles { display: flex; align-items: flex-end; gap: 4px; height: 26px; margin: 6px 0; }
.kc-fam-mini-candles i { flex: 1; border-radius: 1px; }
.kc-fam-mini-candles .u { background: var(--fam-up); }
.kc-fam-mini-candles .d { background: var(--fam-dn); }
.kc-fam-mini-bar { height: 3px; border-radius: 2px; background: var(--fam-border); }
.kc-fam-mini-bar i { display: block; width: 62%; height: 3px; border-radius: 2px; background: var(--fam-color); }
.kc-fam-card[data-locked="1"] .kc-fam-mini { filter: grayscale(.45); }

/* ── APPEARANCE B · round 2 — font controls ─────────────────────── */
.kc-theme-menu .kc-font-fam-tag { display: none; }
.kc-theme-menu .kc-size-value { margin-left: auto; }
.kc-size-reset {
  margin-left: 8px; padding: 0; background: none; border: 0;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: var(--accent); cursor: pointer;
}
.kc-size-reset:hover { text-decoration: underline; }
.kc-size-reset[hidden] { display: none; }
.kc-theme-menu .kc-lh-pip { font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif; font-size: 11.5px; }
.kc-theme-menu .kc-maxw-pip { font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif; }

/* ── APPEARANCE B · round 3 — Display (market colours + motion) ─── */
.kc-display-box {
  border: 1px solid var(--border); border-radius: 8px; padding: 4px 10px 10px;
  background: color-mix(in srgb, var(--card2, var(--bg)) 50%, transparent);
}
.kc-theme-menu .kc-market-opt b { font-size: 10px; margin-right: 2px; }
.kc-mk-up { color: var(--up); }
.kc-mk-dn { color: var(--red); }
html[data-market="bo"] .kc-mk-up { color: #6dd99c; }
html[data-market="bo"] .kc-mk-dn { color: #e08896; }
.kc-display-hint { font-size: 10.5px; color: var(--muted); margin: 5px 4px 0; line-height: 1.4; }

/* Keep the existing theme-opt list nicely contained in its tab */
.kc-appear-panel .kc-theme-opt {
  padding: 6px 10px;
}

/* ══════════════════════════════════════════════════════════════════
   SETTINGS MODAL (gear) — ported from dashboard so every page has
   the same API/GitHub-sync modal without local CSS duplication.
   Pages that already ship their own copy will just use these anyway
   (class names are the same).
   ══════════════════════════════════════════════════════════════════ */

/* .settings-gear is already overridden by .kc-nav .settings-gear /
   .kc-nav-right .settings-gear earlier in this file — those rules
   make the gear sit inside the nav. The base styles below only kick
   in if the gear is used outside the nav (legacy fallback). */
.settings-gear {
  position: fixed;
  top: 14px;
  right: 20px;
  width: 48px;
  height: 48px;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 500;
  transition: all 0.2s;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--accent);
  font-size: 22px;
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 18%, transparent),
              inset 0 0 0 1px rgba(255,255,255,0.04);
}
.settings-gear:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  transform: rotate(45deg);
  box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 35%, transparent);
}
/* .settings-gear.needs-setup + @keyframes kcGearPulse removed
   alongside BYO API-key UI (Tier 5, May 2026). The pulse animation
   only flagged "no Anthropic key configured" — irrelevant now that
   paid features run through the Razor Alpha Worker. */


.settings-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.75);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  z-index: 1500;
  display: none;
  align-items: center;
  justify-content: center;
  animation: kcFadeIn 0.2s ease;
}
.settings-overlay.show { display: flex; }
@keyframes kcFadeIn { from { opacity: 0; } to { opacity: 1; } }

.settings-modal {
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 10px;
  width: 90%;
  max-width: 520px;
  /* Compensate for body `zoom` (--kc-font-scale). Without dividing,
     90vh renders at e.g. 108vh visual at scale 1.2 and the modal
     spills past the viewport. */
  max-height: calc(90vh / var(--kc-font-scale, 1));
  overflow-y: auto;
  animation: kcModalSlide 0.25s ease;
}
@keyframes kcModalSlide {
  from { opacity: 0; transform: translateY(20px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

.settings-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
}
.settings-head h3 {
  font-size: 18px;
  font-weight: var(--w-bold);
  color: var(--text);
  letter-spacing: -0.3px;
}
.settings-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.15s;
  line-height: 1;
}
.settings-close:hover { color: var(--red); background: color-mix(in srgb, var(--red) 10%, transparent); }

.settings-body { padding: 20px 24px; }
.settings-section { margin-bottom: 20px; }
.settings-section:last-child { margin-bottom: 0; }

.settings-label {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 8px;
  display: block;
}

.settings-input {
  width: 100%;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 14px;
  color: var(--text);
  font-family: 'Space Mono', monospace;
  font-size: 13px;
  letter-spacing: 0.3px;
  outline: none;
  transition: border-color 0.15s;
}
.settings-input:focus { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.settings-input::placeholder { color: var(--muted); }

.settings-helper {
  font-size: 13px;
  color: var(--muted);
  margin-top: 6px;
  line-height: 1.5;
}
.settings-helper a { color: var(--accent2); text-decoration: none; }
.settings-helper a:hover { text-decoration: underline; }

.settings-row { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

.settings-btn {
  padding: 9px 14px;
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--card2);
  color: var(--text-mid);
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.settings-btn:hover { border-color: var(--border2); color: var(--text); }
.settings-btn.primary { background: var(--accent); border-color: var(--accent); color: var(--bg); font-weight: var(--w-bold); }
.settings-btn.primary:hover { background: var(--accent); }
.settings-btn.danger { color: var(--red); }
.settings-btn.danger:hover { border-color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent); }

.settings-status {
  margin-top: 10px;
  padding: 9px 12px;
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.5px;
  display: none;
}
.settings-status.show { display: block; }
.settings-status.ok   { background: color-mix(in srgb, var(--accent2) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent2) 30%, transparent); color: var(--accent2); }
.settings-status.err  { background: color-mix(in srgb, var(--red) 10%, transparent);     border: 1px solid color-mix(in srgb, var(--red) 30%, transparent);     color: var(--red); }
.settings-status.info { background: color-mix(in srgb, var(--accent3) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent3) 30%, transparent); color: var(--accent3); }

/* .settings-key-status rules removed alongside BYO API-key UI
   (Tier 5, May 2026). Used to flag "key saved" / "no key — paste
   one below" in the Settings panel keyStatusBadge container. */

.settings-warning {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.6;
  padding: 12px;
  background: var(--card2);
  border-radius: 6px;
  border-left: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
}
.settings-warning strong { color: var(--yellow); }

/* .api-error-cta removed — was the "Open Settings" button in
   formatApiError, retired alongside BYO API-key UI (Tier 5, May 2026). */

/* Narrow viewport: stack the two-column layout vertically inside the
   drawer body, and let the drawer go full-width. The drawer is fixed to
   the right edge regardless of viewport, but at narrow widths a 480px
   panel + side-by-side columns gets cramped — fold to single col + 100vw. */
@media (max-width: 720px) {
  .kc-font-cols { grid-template-columns: 1fr; }
  .kc-theme-menu { width: 100vw; max-width: 100vw; }
  .kc-theme-body { padding: 14px 16px; }
  .kc-theme-panel-head { padding: 14px 16px 12px; }
  .kc-theme-meta { padding: 9px 16px; }
}

/* Reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .kc-theme-menu { transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════════
   SETUP WIZARD — first-run overlay injected by shared.js
   ════════════════════════════════════════════════════════════════ */
.kc-setup-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.78);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  z-index: 9999;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* `vh` is divided by font-scale so the wizard sits at the same visual
     position regardless of zoom (otherwise 5vh becomes 6vh visual at 1.2x). */
  padding: calc(5vh / var(--kc-font-scale, 1)) 20px 20px;
  overflow-y: auto;
  animation: kc-setup-fade 180ms ease-out;
}
@keyframes kc-setup-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.kc-setup-card {
  width: 100%;
  max-width: 580px;
  background: var(--bg-card, #151515);
  border: 1px solid var(--border, rgba(255,255,255,0.08));
  border-radius: 16px;
  padding: 28px 32px 32px;
  color: var(--text-hi, #e8e8e8);
  font-family: var(--font-body, 'Space Mono', monospace);
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
}
.kc-setup-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}
.kc-setup-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent, #f7931a);
  box-shadow: 0 0 12px var(--accent, #f7931a);
}
.kc-setup-kicker {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mid, #888);
}
.kc-setup-progress {
  display: flex;
  gap: 6px;
  margin-bottom: 28px;
}
.kc-setup-progress-seg {
  flex: 1;
  height: 3px;
  background: rgba(255,255,255,0.08);
  border-radius: 2px;
  transition: background 200ms ease;
}
.kc-setup-progress-seg.active {
  background: var(--accent, #f7931a);
}
.kc-setup-h1 {
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 26px;
  font-weight: var(--w-semibold);
  margin: 0 0 10px;
  color: var(--text-hi, #fff);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.kc-setup-req, .kc-setup-opt {
  display: inline-block;
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 10px;
  font-weight: var(--w-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 3px;
  vertical-align: middle;
  margin-left: 8px;
}
.kc-setup-req {
  background: rgba(239, 68, 68, 0.12);
  color: #f87171;
}
.kc-setup-opt {
  background: rgba(255,255,255,0.06);
  color: var(--text-mid, #888);
}
.kc-setup-lead {
  font-size: 14px;
  color: var(--text-mid, #999);
  margin: 0 0 22px;
  line-height: 1.6;
}
.kc-setup-why {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-left: 2px solid var(--accent, #f7931a);
  padding: 12px 14px;
  margin: 0 0 20px;
  border-radius: 0 6px 6px 0;
}
.kc-setup-why--info {
  background: rgba(90, 183, 255, 0.06);
  border-left-color: #5ab7ff;
}
.kc-setup-why--warn {
  background: rgba(239, 159, 39, 0.08);
  border-left-color: #EF9F27;
}
.kc-setup-why-label {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 10px;
  font-weight: var(--w-semibold);
  letter-spacing: 0.1em;
  color: var(--accent, #f7931a);
  margin-bottom: 6px;
}
.kc-setup-why--info .kc-setup-why-label { color: #5ab7ff; }
.kc-setup-why--warn .kc-setup-why-label { color: #EF9F27; }
.kc-setup-why-body {
  font-size: 13px;
  color: var(--text-hi, #ccc);
  line-height: 1.6;
}
.kc-setup-label {
  display: block;
  font-size: 12px;
  font-weight: var(--w-medium);
  color: var(--text-hi, #ccc);
  margin: 0 0 6px;
  letter-spacing: 0.02em;
}
.kc-setup-label--mt { margin-top: 18px; }
.kc-setup-label-aux {
  display: block;
  font-size: 11px;
  text-align: right;
  margin-top: -22px;
  margin-bottom: 6px;
  height: 16px;
}
.kc-setup-link {
  color: var(--accent, #f7931a);
  text-decoration: none;
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 11px;
}
.kc-setup-link:hover { text-decoration: underline; }
.kc-setup-input {
  width: 100%;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.1);
  color: var(--text-hi, #ddd);
  padding: 10px 12px;
  border-radius: 6px;
  font-family: var(--font-body, inherit);
  font-size: 14px;
  box-sizing: border-box;
  outline: none;
  transition: border-color 150ms ease, background 150ms ease;
}
.kc-setup-input:focus {
  border-color: var(--accent, #f7931a);
  background: rgba(0,0,0,0.6);
}
.kc-setup-input--mono {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 13px;
}
.kc-setup-input-row {
  display: flex;
  align-items: stretch;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 6px;
  overflow: hidden;
  background: rgba(0,0,0,0.4);
  transition: border-color 150ms ease;
}
.kc-setup-input-row:focus-within { border-color: var(--accent, #f7931a); }
.kc-setup-prefix {
  display: flex;
  align-items: center;
  padding: 0 10px;
  background: rgba(255,255,255,0.04);
  color: var(--text-mid, #888);
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 14px;
  border-right: 1px solid rgba(255,255,255,0.08);
}
.kc-setup-input--prefixed {
  border: none;
  border-radius: 0;
  background: transparent;
}
.kc-setup-input--prefixed:focus { background: transparent; }
.kc-setup-hint {
  font-size: 11px;
  color: var(--text-low, #666);
  margin-top: 6px;
  font-family: var(--font-mono, 'Space Mono', monospace);
  line-height: 1.5;
}
.kc-setup-hint code {
  background: rgba(255,255,255,0.06);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 11px;
}
.kc-setup-err {
  background: rgba(239, 68, 68, 0.08);
  border-left: 2px solid #f87171;
  padding: 10px 12px;
  margin: 14px 0 0;
  font-size: 12px;
  color: #fca5a5;
  border-radius: 0 6px 6px 0;
}
.kc-setup-help {
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 6px;
  padding: 14px 16px;
  margin: 14px 0 0;
}
.kc-setup-help-title {
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent, #f7931a);
  margin-bottom: 10px;
}
.kc-setup-help-list {
  margin: 0;
  padding-left: 20px;
  font-size: 12px;
  color: var(--text-hi, #ccc);
  line-height: 1.7;
}
.kc-setup-help-list li { margin-bottom: 4px; }
.kc-setup-help-list code {
  background: rgba(255,255,255,0.06);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 11px;
  font-family: var(--font-mono, 'Space Mono', monospace);
}
.kc-setup-help-list a {
  color: var(--accent, #f7931a);
  text-decoration: none;
}
.kc-setup-help-list a:hover { text-decoration: underline; }

.kc-setup-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 26px;
  flex-wrap: wrap;
}
.kc-setup-spacer { flex: 1; }
.kc-setup-btn {
  background: transparent;
  border: 1px solid rgba(255,255,255,0.15);
  color: var(--text-hi, #ccc);
  padding: 10px 16px;
  border-radius: 6px;
  font-family: var(--font-body, inherit);
  font-size: 13px;
  cursor: pointer;
  transition: all 120ms ease;
}
.kc-setup-btn:hover {
  border-color: rgba(255,255,255,0.3);
  background: rgba(255,255,255,0.04);
}
.kc-setup-btn--ghost {
  color: var(--text-mid, #888);
  border-color: rgba(255,255,255,0.08);
}
.kc-setup-btn--primary {
  background: var(--accent, #f7931a);
  border-color: var(--accent, #f7931a);
  color: #000;
  font-weight: var(--w-semibold);
  padding: 10px 22px;
}
.kc-setup-btn--primary:hover {
  filter: brightness(1.12);
  background: var(--accent, #f7931a);
}
.kc-setup-btn--danger {
  color: #f87171;
  border-color: rgba(239, 68, 68, 0.4);
}
.kc-setup-btn--danger:hover {
  background: rgba(239, 68, 68, 0.08);
  border-color: #f87171;
}

/* Mobile tuning */
@media (max-width: 520px) {
  .kc-setup-overlay { padding: calc(2vh / var(--kc-font-scale, 1)) 12px 12px; }
  .kc-setup-card { padding: 22px 20px 24px; border-radius: 12px; }
  .kc-setup-h1 { font-size: 22px; }
  .kc-setup-actions { flex-direction: column-reverse; align-items: stretch; }
  .kc-setup-actions .kc-setup-spacer { display: none; }
  .kc-setup-btn { width: 100%; text-align: center; }
}

/* "Sync disabled" / "AI key missing" banner shown on pages that need them */
.kc-feature-warn {
  background: rgba(239, 159, 39, 0.08);
  border: 1px solid rgba(239, 159, 39, 0.2);
  border-left: 3px solid #EF9F27;
  padding: 12px 16px;
  border-radius: 6px;
  margin: 12px 0;
  color: var(--text-hi, #ccc);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.kc-feature-warn-icon { color: #EF9F27; font-size: 15px; flex: 0 0 auto; }
.kc-feature-warn-text { flex: 1 1 200px; line-height: 1.5; }
.kc-feature-warn-btn {
  background: transparent;
  border: 1px solid rgba(239, 159, 39, 0.4);
  color: #EF9F27;
  padding: 5px 12px;
  border-radius: 4px;
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 11px;
  cursor: pointer;
  letter-spacing: 0.04em;
}
.kc-feature-warn-btn:hover {
  background: rgba(239, 159, 39, 0.1);
  border-color: #EF9F27;
}


/* ── GLOBAL PLACEHOLDER SOFTENING ───────────────────────────
   Trimmed placeholders ship shorter; this rule makes them
   sit back visually so they stop competing with real input. */
input::placeholder,
textarea::placeholder {
  color: var(--muted) !important;
  opacity: 0.55;
  font-weight: var(--w-regular);
  font-style: italic;
}
input:focus::placeholder,
textarea:focus::placeholder {
  opacity: 0.35;
}


/* ══════════════════════════════════════════════════════════════════
   COMMAND PALETTE — Cmd/Ctrl+K
   Dark glass overlay with centered command panel. Matches the
   settings-overlay treatment (same blur + fade). Sits at z-index
   2000 so it stacks above settings (1500) and theme menu.
   ══════════════════════════════════════════════════════════════════ */

.kc-palette-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 10, 0.72);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* Divide vh by font-scale so the palette sits at the right visual
     offset under body `zoom` (otherwise 12vh becomes ~14vh visual at 1.2x
     and the palette drops below the fold). */
  padding-top: calc(12vh / var(--kc-font-scale, 1));
  animation: kcFadeIn 0.15s ease;
}

.kc-palette {
  width: 92%;
  max-width: 560px;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5),
              0 0 0 1px rgba(255, 255, 255, 0.03) inset;
  overflow: hidden;
  animation: kcPaletteSlide 0.18s ease;
}
@keyframes kcPaletteSlide {
  from { opacity: 0; transform: translateY(-8px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

.kc-palette-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.kc-palette-prompt {
  font-family: 'Space Mono', monospace;
  font-size: 16px;
  color: var(--accent, #f7931a);
  font-weight: var(--w-bold);
  flex-shrink: 0;
  line-height: 1;
}
.kc-palette-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 15px;
  letter-spacing: 0.2px;
  padding: 2px 0;
}
.kc-palette-input::placeholder {
  color: var(--muted);
  opacity: 0.7;
  font-style: normal;  /* override the global italic placeholder softening */
}
.kc-palette-esc {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 6px;
  line-height: 1;
  flex-shrink: 0;
}

.kc-palette-list {
  max-height: calc(52vh / var(--kc-font-scale, 1));
  overflow-y: auto;
  padding: 6px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border2) transparent;
}
.kc-palette-list::-webkit-scrollbar { width: 6px; }
.kc-palette-list::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}

.kc-palette-group {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: var(--muted);
  padding: 10px 16px 4px;
}
.kc-palette-group:first-child { padding-top: 4px; }

.kc-palette-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 16px;
  cursor: pointer;
  font-size: 13.5px;
  color: var(--text);
  line-height: 1.3;
  border-left: 2px solid transparent;
  transition: background 0.08s ease, border-color 0.08s ease;
}
.kc-palette-item.active {
  background: rgba(255, 255, 255, 0.04);
  border-left-color: var(--accent, #f7931a);
}
.kc-palette-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kc-palette-hint {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
  opacity: 0.75;
}

.kc-palette-empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  font-style: italic;
}

.kc-palette-foot {
  display: flex;
  gap: 16px;
  justify-content: flex-end;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  font-size: 10.5px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.3px;
}
.kc-palette-foot kbd {
  display: inline-block;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  font-size: 10px;
  font-family: inherit;
  margin-right: 4px;
  color: var(--text);
  line-height: 1.2;
}

/* Mobile: take more of the screen */
@media (max-width: 560px) {
  .kc-palette-overlay { padding-top: calc(6vh / var(--kc-font-scale, 1)); padding-left: 10px; padding-right: 10px; }
  .kc-palette { width: 100%; }
  .kc-palette-list { max-height: calc(60vh / var(--kc-font-scale, 1)); }
  .kc-palette-foot { flex-wrap: wrap; gap: 10px; justify-content: flex-start; }
}

/* ── Palette toast — small success/fail message after running a command */
.kc-palette-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 10px 16px;
  font-size: 13px;
  color: var(--text);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transition: opacity 0.18s ease, transform 0.18s ease;
  pointer-events: none;
  z-index: 2100;
}
.kc-palette-toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── CHANGELOG / "WHAT'S NEW" MODAL (global, every page) ───────────── */
.kc-changelog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  z-index: 2200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s;
}
.kc-changelog-overlay.show { opacity: 1; pointer-events: auto; }
.kc-changelog-modal {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  width: 100%;
  max-width: 480px;
  max-height: calc(85vh / var(--kc-font-scale, 1));
  overflow-y: auto;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  transform: translateY(12px);
  transition: transform 0.2s;
}
.kc-changelog-overlay.show .kc-changelog-modal { transform: translateY(0); }
.kc-changelog-head {
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.kc-changelog-badge {
  display: flex;
  align-items: center;
  gap: 10px;
}
.kc-changelog-badge-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--accent);
}
.kc-changelog-badge-label {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--accent);
  text-transform: uppercase;
}
.kc-changelog-version {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 1px;
}
.kc-changelog-body { padding: 20px 22px; }
.kc-changelog-title {
  font-size: 20px;
  font-weight: var(--w-bold);
  color: var(--text-bright);
  letter-spacing: -0.5px;
  margin-bottom: 6px;
}
.kc-changelog-sub {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 18px;
  line-height: 1.5;
}
.kc-changelog-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 20px;
}
.kc-changelog-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.kc-changelog-item-dot {
  margin-top: 6px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent2);
  flex-shrink: 0;
}
.kc-changelog-item-title {
  font-size: 13px;
  font-weight: var(--w-bold);
  color: var(--text-bright);
  margin-bottom: 2px;
}
.kc-changelog-item-desc {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}
.kc-changelog-item-body {
  flex: 1;
  min-width: 0;
}
.kc-changelog-item-toggle {
  margin-top: 6px;
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--accent);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: opacity 0.15s;
}
.kc-changelog-item-toggle:hover { opacity: 0.85; }
.kc-changelog-item-toggle .kc-changelog-toggle-label-less { display: none; }
.kc-changelog-item.open .kc-changelog-item-toggle .kc-changelog-toggle-label-more { display: none; }
.kc-changelog-item.open .kc-changelog-item-toggle .kc-changelog-toggle-label-less { display: inline; }
.kc-changelog-toggle-arrow {
  display: inline-block;
  transition: transform 0.18s;
  font-size: 10px;
  line-height: 1;
}
.kc-changelog-item.open .kc-changelog-toggle-arrow { transform: rotate(180deg); }
.kc-changelog-item-details {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
  font-size: 12px;
  color: var(--muted);
  line-height: 1.55;
}
.kc-changelog-item-details p { margin: 0 0 6px; }
.kc-changelog-item-details p:last-child { margin-bottom: 0; }
.kc-changelog-item-details ul {
  margin: 0;
  padding-left: 16px;
  list-style: disc;
}
.kc-changelog-item-details li { margin-bottom: 4px; }
.kc-changelog-item-details li:last-child { margin-bottom: 0; }
.kc-changelog-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 0 22px 20px;
}
.kc-changelog-btn {
  padding: 9px 18px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: var(--w-bold);
  letter-spacing: 1px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.15s;
}
.kc-changelog-btn.secondary {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
}
.kc-changelog-btn.secondary:hover { color: var(--text-bright); border-color: var(--border2); }
.kc-changelog-btn.primary {
  background: var(--accent);
  color: var(--bg);
  border: none;
}
.kc-changelog-btn.primary:hover { opacity: 0.9; }

/* ══════════════════════════════════════════════════════════════════
   KC DIALOG — platform-wide replacement for native confirm/alert/prompt
   Razor Alpha never shows native browser dialogs. Pages call:
     await window.KCDialog.confirm({title, body, sub, kind, okLabel})
     await window.KCDialog.alert({title, body, sub, kind})
     await window.KCDialog.prompt({title, body, value, multiline, readonly})
   Single overlay, swappable head/body/foot. ESC + backdrop = cancel.
   Auto-focus primary action so Enter confirms instantly.
   ══════════════════════════════════════════════════════════════════ */
.kc-dlg-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 10, 0.6);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 9400;            /* above settings drawer (9200) + editors (9300); below toasts (9999) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s;
}
.kc-dlg-overlay.show {
  opacity: 1;
  pointer-events: auto;
}
.kc-dlg-modal {
  width: 380px;
  max-width: calc(100vw - 32px);
  max-height: calc(85vh / var(--kc-font-scale, 1));
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 10px;
  padding: 18px 20px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  transform: translateY(8px);
  transition: transform 0.20s;
}
.kc-dlg-overlay.show .kc-dlg-modal { transform: translateY(0); }

/* ── Mobile: KCDialog + profile modal become bottom sheets ──────────
   On phones a centered 380px box floats with dead margins and low
   action buttons. Instead, dock to the bottom edge, full-width, rounded
   top, with a grab handle and safe-area padding so the buttons sit in
   thumb reach above the gesture bar. Desktop is untouched. The
   .kc-sheet-handle is injected by JS only on mobile (see _wireOnce /
   profile mount); the swipe-to-dismiss handler reuses the existing
   backdrop-click close path. Overlays align to the bottom so the sheet
   transform reads as "slide up from the floor". */
@media (max-width: 640px) {
  .kc-dlg-overlay {
    align-items: flex-end;
    padding: 0;
  }
  .kc-dlg-modal,
  .kc-profile-modal {
    width: 100%;
    max-width: 100%;
    max-height: calc(90dvh / var(--kc-font-scale, 1));
    border-radius: 18px 18px 0 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    /* Start lower for the slide-up feel; the .show rule lands it. */
    transform: translateY(100%);
    padding-bottom: calc(20px + var(--kc-safe-b));
    will-change: transform;
  }
  .kc-dlg-overlay.show .kc-dlg-modal,
  .kc-dlg-overlay.show .kc-profile-modal { transform: translateY(0); }

  /* While a drag is in progress, follow the finger 1:1 with no
     transition; JS sets --kc-sheet-drag and toggles .is-dragging. */
  .kc-dlg-modal.is-dragging,
  .kc-profile-modal.is-dragging {
    transition: none;
    transform: translateY(var(--kc-sheet-drag, 0px));
  }

  /* Grab handle (JS-injected on mobile). */
  .kc-sheet-handle {
    width: 38px;
    height: 4px;
    border-radius: 4px;
    background: var(--border2, #3a342d);
    margin: 2px auto 14px;
    flex-shrink: 0;
  }

  /* Stack dialog actions full-width, primary on top (thumb reach). */
  .kc-dlg-foot {
    flex-direction: column-reverse;
    gap: 9px;
  }
  .kc-dlg-foot .kc-dlg-btn { width: 100%; }
}
.kc-dlg-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-mid);
}
.kc-dlg-head .kc-dlg-icon { font-size: 13px; }
.kc-dlg-head.danger  { color: var(--red, #e24b4a); }
.kc-dlg-head.neutral { color: var(--accent); }
.kc-dlg-head.warn    { color: var(--amber, #f59e0b); }
.kc-dlg-head.info    { color: var(--text-mid); }
.kc-dlg-body {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  color: var(--text-mid);
  line-height: 1.55;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.kc-dlg-body b,
.kc-dlg-body strong { color: var(--text-bright); font-weight: 700; }
.kc-dlg-body .kc-dlg-sub {
  color: var(--muted);
  font-size: 11px;
  margin-top: 8px;
  line-height: 1.5;
}
/* Pre-formatted body — used for multi-line confirm strings that contain
   '\n' separators so the layout matches what native confirm() would do. */
.kc-dlg-body.pre {
  white-space: pre-wrap;
}
.kc-dlg-input-wrap { margin-top: 12px; }
.kc-dlg-input,
.kc-dlg-textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--card2, var(--bg, #0f0e17));
  border: 1px solid var(--border);
  color: var(--text-bright);
  padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  border-radius: 5px;
  outline: none;
  transition: border-color 0.13s;
}
.kc-dlg-input:focus,
.kc-dlg-textarea:focus { border-color: var(--accent); }
.kc-dlg-textarea {
  min-height: 96px;
  resize: vertical;
  line-height: 1.5;
}
.kc-dlg-input[readonly],
.kc-dlg-textarea[readonly] {
  color: var(--text-mid);
  cursor: text;
}
.kc-dlg-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.kc-dlg-btn {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-mid);
  padding: 6px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.13s;
}
.kc-dlg-btn:hover { color: var(--text-bright); border-color: var(--text-mid); }
.kc-dlg-btn:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.kc-dlg-btn.primary.neutral {
  background: rgba(77, 217, 154, 0.14);
  border-color: rgba(77, 217, 154, 0.4);
  color: var(--accent);
}
.kc-dlg-btn.primary.neutral:hover {
  background: rgba(77, 217, 154, 0.22);
  border-color: var(--accent);
  color: var(--accent);
}
.kc-dlg-btn.primary.danger {
  background: rgba(226, 75, 74, 0.14);
  border-color: rgba(226, 75, 74, 0.4);
  color: var(--red, #e24b4a);
}
.kc-dlg-btn.primary.danger:hover {
  background: rgba(226, 75, 74, 0.22);
  border-color: var(--red, #e24b4a);
  color: var(--red, #e24b4a);
}
.kc-dlg-btn.primary.warn {
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.4);
  color: var(--amber, #f59e0b);
}
.kc-dlg-btn.primary.warn:hover {
  background: rgba(245, 158, 11, 0.22);
  border-color: var(--amber, #f59e0b);
  color: var(--amber, #f59e0b);
}
@media (max-width: 700px) {
  .kc-dlg-modal { width: calc(100vw - 24px); padding: 14px; }
}

/* ═══════════════════════════════════════════════════════════
   KC PROFILE CARD — modal opened by clicking @handles / avatars

   Hosted inside .kc-dlg-overlay so the backdrop + z-index +
   open transition come for free. The modal body is a sibling
   primitive to .kc-dlg-modal — same outer surface, different
   internal sections (id row + stats grid + foot).

   data-kcc-hue on the modal sets the avatar + handle accent
   color via the same per-hue rules used by chat rows. The
   handle is highlighted in that color; the avatar SVG inherits
   it via currentColor (same mechanism as the inline badges).
   ═══════════════════════════════════════════════════════════ */
.kc-profile-modal {
  width: 440px;
  max-width: calc(100vw - 32px);
  max-height: calc(85vh / var(--kc-font-scale, 1));
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 10px;
  padding: 0;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  transform: translateY(8px);
  transition: transform 0.20s;
  /* Default color (overridden by per-hue rules below). */
  color: var(--accent, #d4a335);
}
.kc-dlg-overlay.show .kc-profile-modal { transform: translateY(0); }

.kc-profile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.kc-profile-eyebrow {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.kc-profile-x {
  background: transparent;
  border: 0;
  font-family: 'Space Mono', monospace;
  font-size: 18px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  transition: color 120ms ease, background 120ms ease;
}
.kc-profile-x:hover {
  color: var(--text-bright);
  background: color-mix(in srgb, var(--text) 8%, transparent);
}

.kc-profile-id {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 18px 16px;
  border-bottom: 1px solid var(--border);
}
.kc-profile-avatar {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  display: inline-block;
  color: inherit;       /* badge picks up modal's hue color */
}
.kc-profile-meta { min-width: 0; flex: 1; }
.kc-profile-handle-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  row-gap: 6px;
  margin-bottom: 4px;
}
.kc-profile-handle {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 18px;
  font-weight: 600;
  color: inherit;        /* hue applied below */
  word-break: break-word;
}
.kc-profile-admin {
  display: inline-flex;
  align-items: center;
  color: var(--brass, #d4a335);
}

/* ─── Tier chip — small uppercase pill next to handle ─────────────
   The chip uses the tier's color via --kc-tier-color (set inline
   per-tier). 14% color-mix gives the same restrained brass-on-dark
   feel as the LVL chip but tinted per rank. Border + text use the
   tier color directly so a Peaky Boss chip reads as oxblood +
   brass-tinged glow rather than a flat color pill. */
.kc-profile-tier {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  padding: 3px 7px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--kc-tier-color, #888780) 14%, transparent);
  color: var(--kc-tier-color, #888780);
  border: 1px solid color-mix(in srgb, var(--kc-tier-color, #888780) 32%, transparent);
  white-space: nowrap;
  /* Subtle inner glow for the top rank — adds the "boss" feel
     without changing the chip's footprint. */
}
.kc-profile-tier[data-kc-tier="peaky_boss"] {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--brass, #d4a335) 28%, transparent) inset,
              0 0 6px color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
}

/* ─── Tier-colored avatar ring — overrides hue-based ring when a
   tier is known (set as data-kc-tier on .kc-profile-modal). The
   badge SVG itself stays the hue color so the tier ring + hue glyph
   feel like two layers, not a clash. Scout (default) tier draws no
   special ring — falls back to the hue rules below. */
.kc-profile-modal[data-kc-tier="runner"]     .kc-profile-avatar { color: #7aa4c9; }
.kc-profile-modal[data-kc-tier="lookout"]    .kc-profile-avatar { color: #a89dd9; }
.kc-profile-modal[data-kc-tier="hunter"]     .kc-profile-avatar { color: #5dcaa5; }
.kc-profile-modal[data-kc-tier="sniper"]     .kc-profile-avatar { color: #d4a335; }
.kc-profile-modal[data-kc-tier="marksman"]   .kc-profile-avatar { color: #e08a8a; }
.kc-profile-modal[data-kc-tier="made_man"]   .kc-profile-avatar { color: #a83232; }
.kc-profile-modal[data-kc-tier="peaky_boss"] .kc-profile-avatar {
  color: #a83232;
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brass, #d4a335) 30%, transparent));
}
.kc-profile-sub {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  text-transform: uppercase;
}

.kc-profile-stats {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}

/* ─── XP block — slots between identity row and stats grid ─────────
   Own-profile only (Phase 3 has no public XP endpoint yet). Level
   chip on the left, "1,240 / 3,981 XP" on the right, narrow brass
   progress bar underneath. The bar's fill uses currentColor so it
   inherits the modal's hue accent — own-profile is brass via the
   modal's default color, and tier rules can later tint the bar by
   overriding the chip + bar's color. */
.kc-profile-xp {
  padding: 12px 18px 14px;
  border-bottom: 1px solid var(--border);
}
.kc-profile-xp-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}
.kc-profile-xp-chip {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  padding: 3px 8px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  color: var(--brass, #d4a335);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 30%, transparent);
}
.kc-profile-xp-chip--ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted);
}
/* Capped (max-level) state — razor-gold accents. The chip and bar shift
   from brass to the brighter razor highlight so "maxed" reads as an
   achievement rather than a stalled bar. */
.kc-profile-xp-chip.is-capped {
  background: color-mix(in srgb, var(--razor, #e8c560) 18%, transparent);
  color: var(--razor, #e8c560);
  border-color: color-mix(in srgb, var(--razor, #e8c560) 45%, transparent);
}
.kc-profile-xp-bar.is-capped > span {
  background: linear-gradient(90deg, var(--brass, #d4a335), var(--razor, #e8c560));
}
.kc-profile-xp-text {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* Inline Unlock Road entry on the level row — always present (even when
   maxed), so the road is reachable from the card regardless of the
   conditional next-unlock teaser below. Opens via the shared
   data-kc-open-road delegate; the chip stays left, this group sits right. */
.kc-profile-xp-right {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.kc-profile-xp-road-sep {
  color: var(--border2, #3a3b42);
  font-size: 11px;
  line-height: 1;
}
.kc-profile-road-link {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: none;
  margin: 0;
  padding: 0;
  cursor: pointer;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--brass, #d4a335);
  display: inline-flex;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
  transition: color 140ms ease;
}
.kc-profile-road-link:hover { color: var(--razor, #e8c560); }
.kc-profile-road-link:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brass, #d4a335) 55%, transparent);
  outline-offset: 2px;
  border-radius: 3px;
}
.kc-profile-road-link-arrow {
  font-size: 14px;
  line-height: 1;
}
.kc-profile-xp-bar {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}
.kc-profile-xp-bar > span {
  display: block;
  height: 100%;
  background: var(--brass, #d4a335);
  border-radius: 2px;
  transition: width 280ms ease;
}
/* Next-unlock teaser — the row under the XP bar that names what unlocks at
   the next gated level and opens the Unlock Road drawer. */
.kc-unlock-teaser {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 10px;
  padding: 8px 11px;
  background: color-mix(in srgb, var(--brass, #d4a335) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
  border-radius: 9px;
  cursor: pointer;
  text-align: left;
  transition: background 140ms ease, border-color 140ms ease;
}
.kc-unlock-teaser:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 12%, transparent);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 32%, transparent);
}
.kc-unlock-teaser:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--brass, #d4a335) 55%, transparent);
  outline-offset: 2px;
}
.kc-unlock-teaser-lbl {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted, #8a857a);
  white-space: nowrap;
  flex: 0 0 auto;
}
.kc-unlock-teaser-items {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
.kc-unlock-teaser-chip {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, #fff 9%, transparent);
  background: color-mix(in srgb, #000 18%, transparent);
  color: var(--text, #e8e2d6);
  white-space: nowrap;
}
.kc-unlock-teaser-more { color: var(--text-muted, #8a857a); }
.kc-unlock-teaser-arrow {
  margin-left: auto;
  flex: 0 0 auto;
  color: var(--brass, #d4a335);
  font-size: 16px;
  line-height: 1;
}
.kc-profile-stats-lbl {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.kc-profile-stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
/* 4-col variant used when the GHOSTED cell is present. Mobile-narrow
   viewports could tighten the gap further but the 4-col grid renders
   fine at 320px+ since each cell only holds a single 1-2 digit number
   plus a short label. */
.kc-profile-stats-grid--four {
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.kc-profile-stat-val {
  font-family: 'Space Mono', monospace;
  font-size: 18px;
  color: var(--text-bright);
  font-variant-numeric: tabular-nums;
}
.kc-profile-stat-lbl {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-top: 2px;
}

/* GHOSTED stat — oxblood when > 0 (visible warning), muted gray
   when 0 (still present but doesn't draw attention). The .is-active
   class is set by the renderer when ghost_count > 0. The dash
   placeholder ('—') falls back to the default text color while
   the value is loading. */
.kc-profile-stat--ghosted .kc-profile-stat-val {
  color: var(--text-muted);
}
.kc-profile-stat--ghosted.is-active .kc-profile-stat-val {
  color: var(--oxblood-text, #c47373);
}
.kc-profile-stat--ghosted.is-active .kc-profile-stat-lbl {
  color: var(--oxblood-text, #c47373);
}

/* ── Badge case (profile modal) ──────────────────────────────────────
   Earned-badge grid. Reuses the chat-row flair chip (.kcc-msg__flair) so
   the visual language is identical to the inline flair, bumped up a notch
   for the modal. Collapses entirely when the host is empty (not loaded /
   no module). */
.kc-profile-case {
  padding: 14px 16px 4px;
}
.kc-profile-case:empty { display: none; }
.kc-profile-case-lbl {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-mono, 'Space Mono'), monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted, #8a857a);
  margin-bottom: 10px;
}
.kc-profile-case-count {
  font-weight: 700;
  color: var(--accent, #d4a335);
  letter-spacing: 0.08em;
}
.kc-profile-case-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* The full catalogue (earned + locked) can run to ~40 tiles. Cap the grid
   height so the case never dominates the modal; it scrolls past a few rows. */
.kc-profile-case-icons {
  max-height: 188px;
  overflow-y: auto;
  scrollbar-width: thin;
  padding-right: 2px;
}
/* Locked silhouette — dimmed + desaturated, with a brass corner lock pip.
   Still a full tap/focus target so its criteria show in the detail strip. */
.kc-profile-case-ico.is-locked {
  opacity: 0.42;
  filter: grayscale(0.7);
}
.kc-profile-case-ico.is-locked:hover {
  opacity: 0.62;
  filter: grayscale(0.4);
}
.kc-profile-case-ico.is-locked.is-focused {
  opacity: 0.85;
  filter: grayscale(0.15);
}
.kc-profile-case-lock {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 12px;
  height: 12px;
  color: var(--accent, #d4a335);
  background: var(--card, #1a1610);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 1.5px var(--card, #1a1610);
}
.kc-profile-case-lock svg { width: 8px; height: 8px; }
/* Locked detail strip — muted icon, LOCKED tag in place of a flair action. */
.kc-profile-case-detail.is-locked .kc-profile-case-detail-ico { opacity: 0.55; filter: grayscale(0.6); }
.kc-profile-case-lockedtag {
  color: var(--muted, #8a857a) !important;
  border-color: color-mix(in srgb, #fff 10%, transparent) !important;
}
/* Coming-soon shelf — badges with no way to earn them yet. Sits under the
   case on a dashed rule, outside the earned/total counter. Tiles are
   dashed, colourless and still tappable (the detail strip says what's
   coming). */
.kc-profile-case-shelf {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed color-mix(in srgb, #fff 9%, transparent);
}
.kc-profile-case-shelf .kc-profile-case-lbl { margin-bottom: 8px; }
.kc-profile-case-count.is-muted {
  color: var(--muted, #8a857a);
  font-weight: 400;
}
.kc-profile-case-ico.is-soon .kcc-msg__flair {
  background: transparent !important;
  border-style: dashed;
  border-color: color-mix(in srgb, #fff 16%, transparent) !important;
  box-shadow: none !important;
  color: var(--muted, #8a857a) !important;
  opacity: 0.6;
}
.kc-profile-case-ico.is-soon .kcc-msg__flair svg { color: var(--muted, #8a857a) !important; }
.kc-profile-case-ico.is-soon:hover .kcc-msg__flair,
.kc-profile-case-ico.is-soon.is-focused .kcc-msg__flair { opacity: 0.95; }
.kc-profile-case-detail.is-soon .kc-profile-case-detail-ico { opacity: 0.55; filter: grayscale(1); }
.kc-profile-case-soontag {
  color: var(--yellow, #e8c560) !important;
  border-style: dashed !important;
  border-color: color-mix(in srgb, var(--yellow, #e8c560) 38%, transparent) !important;
}
.kc-profile-case-empty {
  font-size: 12px;
  color: var(--muted, #8a857a);
}

/* Compact icon grid (option D). Each earned badge is an icon-only tile —
   the label is hidden and surfaces in the detail strip instead, so the
   whole 38-badge collection stays a few rows tall. Every tile is a tap
   target: focusing one drives the detail strip; the focused tile gets a
   brass ring, and the current flair carries a persistent corner dot so it
   stays locatable while browsing. */
.kc-profile-case-ico {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  border-radius: 7px;
  line-height: 0;
  position: relative;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.kc-profile-case-ico:hover { transform: translateY(-1px); }
.kc-profile-case-ico:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent, #d4a335) 55%, transparent);
  outline-offset: 2px;
}
.kc-profile-case-ico.is-focused {
  box-shadow: 0 0 0 1.5px var(--accent, #d4a335),
              0 0 9px color-mix(in srgb, var(--accent, #d4a335) 28%, transparent);
}
.kc-profile-case-ico.is-primary::after {
  content: '';
  position: absolute;
  top: -2px;
  right: -2px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent, #d4a335);
  box-shadow: 0 0 0 1.5px var(--card, #1a1610);
}
/* Icon-only square: drop the label + tighten the reused flair chip. */
.kc-profile-case-icons .kcc-msg__flair {
  gap: 0;
  padding: 6px;
  top: 0;
  border-radius: 7px;
}
.kc-profile-case-icons .kcc-msg__flair-lbl { display: none; }
.kc-profile-case-icons .kcc-msg__flair svg {
  width: 16px;
  height: 16px;
}

/* Detail strip — the focused badge's name, rarity, and flair status. */
.kc-profile-case-detail {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: 11px;
  padding: 9px 11px;
  background: color-mix(in srgb, #000 22%, transparent);
  border: 1px solid color-mix(in srgb, #fff 5%, transparent);
  border-radius: 8px;
}
.kc-profile-case-detail:empty { display: none; }
.kc-profile-case-detail-ico { line-height: 0; flex: 0 0 auto; }
.kc-profile-case-detail-ico .kcc-msg__flair {
  gap: 0;
  padding: 8px;
  top: 0;
  border-radius: 8px;
}
.kc-profile-case-detail-ico .kcc-msg__flair-lbl { display: none; }
.kc-profile-case-detail-ico .kcc-msg__flair svg {
  width: 18px;
  height: 18px;
}
.kc-profile-case-detail-txt {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.kc-profile-case-detail-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-bright, #faf6ec);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Earn-description — a short sentence, so sentence-case UI type that wraps
   to a second line rather than the single-word uppercase rarity tag this
   replaced. */
.kc-profile-case-detail-meta {
  font-size: 11.5px;
  line-height: 1.35;
  letter-spacing: 0.005em;
  color: var(--muted, #8a857a);
}
.kc-profile-case-flairtag {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--font-mono, 'Space Mono'), monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted, #8a857a);
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  border-radius: 4px;
  padding: 3px 7px;
}
.kc-profile-case-flairtag.is-yours {
  color: var(--accent, #d4a335);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
}
.kc-profile-case-setbtn {
  margin-left: auto;
  flex: 0 0 auto;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  font-family: var(--font-mono, 'Space Mono'), monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
  border-radius: 4px;
  padding: 4px 9px;
  transition: background 0.12s ease;
}
.kc-profile-case-setbtn:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 18%, transparent);
}
.kc-profile-case-setbtn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent, #d4a335) 55%, transparent);
  outline-offset: 2px;
}

.kc-profile-foot {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 14px;
}
.kc-profile-btn {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  padding: 7px 14px;
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.kc-profile-btn:hover {
  color: var(--text-bright);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 35%, var(--border2));
}
.kc-profile-btn.primary {
  background: color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
  border-color: var(--accent, #d4a335);
  color: var(--accent, #d4a335);
}
.kc-profile-btn.primary:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 22%, transparent);
}

/* Actions container — when viewing someone else's profile, the foot
   row holds @MENTION + TIP side by side. */
.kc-profile-actions {
  display: flex;
  gap: 8px;
}
/* Tip button — brass-tinted to match the in-card Tip chip. */
.kc-profile-btn.tip {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 35%, var(--border2));
  color: color-mix(in srgb, var(--accent, #d4a335) 80%, var(--text));
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.kc-profile-btn.tip:hover {
  border-color: var(--accent, #d4a335);
  color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 6%, transparent);
}
.kc-profile-btn.tip .kcp-tip-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 11px;
  height: 11px;
}

/* Per-hue accent — same 7-bucket palette used by chat rows + presence.
   Drives both the handle text color AND the avatar badge stroke (via
   currentColor cascading from the modal's color property). */
.kc-profile-modal[data-kcc-hue="1"] { color: #e08a8a; }
.kc-profile-modal[data-kcc-hue="1"] .kc-profile-handle { color: #e08a8a; }
.kc-profile-modal[data-kcc-hue="2"] { color: #7fc9a8; }
.kc-profile-modal[data-kcc-hue="2"] .kc-profile-handle { color: #7fc9a8; }
.kc-profile-modal[data-kcc-hue="3"] { color: #a89dd9; }
.kc-profile-modal[data-kcc-hue="3"] .kc-profile-handle { color: #a89dd9; }
.kc-profile-modal[data-kcc-hue="4"] { color: #d9b766; }
.kc-profile-modal[data-kcc-hue="4"] .kc-profile-handle { color: #d9b766; }
.kc-profile-modal[data-kcc-hue="5"] { color: #7aa4c9; }
.kc-profile-modal[data-kcc-hue="5"] .kc-profile-handle { color: #7aa4c9; }
.kc-profile-modal[data-kcc-hue="6"] { color: #d98ab0; }
.kc-profile-modal[data-kcc-hue="6"] .kc-profile-handle { color: #d98ab0; }
.kc-profile-modal[data-kcc-hue="7"] { color: #a4adb8; }
.kc-profile-modal[data-kcc-hue="7"] .kc-profile-handle { color: #a4adb8; }

@media (max-width: 700px) {
  .kc-profile-modal { width: calc(100vw - 24px); }
  .kc-profile-id { padding: 16px 14px 14px; }
  .kc-profile-stats { padding: 12px 14px; }
}

/* Handles + avatars in chat are now interactive (open profile card). */
.kcc-msg__handle:not(.kcc-msg__handle--app),
.kcc-msg__avatar:not(.kcc-msg__avatar--app),
.kcc-presence-handle,
.kcc-presence-avatar,
.kcc-topcallers__handle,
.kcc-topcallers__avatar {
  cursor: pointer;
}
.kcc-msg__handle:not(.kcc-msg__handle--app):hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════
   KC EXPLAINER — platform-wide "?" info popup system.
   Lifted from radar.html so every page can use it.

   Markup contract (per page, once):
     <div class="kc-explainer-overlay hidden" id="kcExplainerOverlay" ...>...
   Markup contract (per card):
     <div class="kc-explainer-title-wrap">
       <span class="panel-title">Card Name</span>
       <button class="kc-explainer-btn" data-explainer="cardKey" ...>?</button>
     </div>
   ═══════════════════════════════════════════════════════════ */

/* Inline icon next to a title (Option B — small, subtle, not in the action row) */
.kc-explainer-btn {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--muted);
  border-radius: 50%;
  cursor: pointer;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  transition: all 0.15s;
  padding: 0;
  line-height: 1;
  flex-shrink: 0;
  opacity: 0.55;
  vertical-align: middle;
  margin-left: 4px;
}
.kc-explainer-btn:hover {
  color: var(--accent3, #7b61ff);
  background: color-mix(in srgb, var(--accent3) 12%, transparent);
  opacity: 1;
  transform: scale(1.15);
}
.kc-explainer-btn:focus-visible {
  outline: 2px solid var(--accent3, #7b61ff);
  outline-offset: 2px;
  opacity: 1;
}

/* Wrapper that lets the button sit next to a title without breaking layout
   (use when the parent has flex with flex:1 on the title) */
.kc-explainer-title-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0;
  min-width: 0;
}

/* ═══════════════════════════════════════════════════════════
   KC PRO TIP — small inline practitioner tip, sits below an input.
   Differs from the explainer card (which is on-demand modal):
   tips are always-visible by default until dismissed.

   Markup contract:
     <div class="kc-tip" data-tip="uniqueId">
       <button class="kc-tip-close" aria-label="Dismiss tip">×</button>
       <strong><i class="kc-ic ic-warn" data-icon="bulb"></i> Pro tip</strong>
       Tip body text. Use <em>highlight</em> to soft-emphasize a key term,
       and <code>{{var}}</code> for code-style snippets.
     </div>

   When the close button is clicked, KC.tips.dismiss(id) hides this tip
   and remembers it in localStorage so it stays dismissed across sessions.
   ═══════════════════════════════════════════════════════════ */
.kc-tip {
  position: relative;
  margin-top: 10px;
  padding: 12px 32px 12px 14px;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.65;
}
.kc-tip strong {
  color: var(--accent3);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
  text-transform: uppercase;
  font-weight: 700;
}
.kc-tip strong .kc-ic {
  flex-shrink: 0;
}
.kc-tip em {
  color: var(--text-mid);
  font-style: normal;
}
.kc-tip code {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-mid);
  background: color-mix(in srgb, var(--accent3) 8%, transparent);
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid color-mix(in srgb, var(--accent3) 18%, transparent);
}
.kc-tip-close {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0.5;
  transition: all 0.15s;
  padding: 0;
}
.kc-tip-close:hover {
  opacity: 1;
  color: var(--text-bright);
  background: color-mix(in srgb, var(--muted) 14%, transparent);
}
.kc-tip-close:focus-visible {
  opacity: 1;
  outline: 2px solid var(--accent3);
  outline-offset: 1px;
}
.kc-tip.is-dismissed {
  display: none !important;
}

/* ─── Modal overlay ───────────────────────────────────────── */
.kc-explainer-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.72);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 9998;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: kcExpFade 0.2s ease-out;
}
@keyframes kcExpFade { from { opacity: 0; } to { opacity: 1; } }
.kc-explainer-overlay.hidden { display: none; }

.kc-explainer-panel {
  background: var(--bg-elev, var(--surface, #111118));
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 100%;
  max-width: 640px;
  max-height: calc(85vh / var(--kc-font-scale, 1));
  display: flex; flex-direction: column;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
  overflow: hidden;
  animation: kcExpRise 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes kcExpRise {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

.kc-explainer-head {
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
}
.kc-explainer-head .dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
.kc-explainer-eyebrow {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.kc-explainer-title-block { flex: 1; min-width: 0; }
.kc-explainer-title {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 18px;
  font-weight: 700;
  color: var(--text-bright);
  letter-spacing: -0.2px;
}
.kc-explainer-close {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  color: var(--muted);
  width: 28px; height: 28px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  flex-shrink: 0;
}
.kc-explainer-close:hover {
  color: var(--red);
  border-color: var(--red);
}

.kc-explainer-body {
  padding: 18px 22px 6px;
  overflow-y: auto;
  flex: 1;
}

.kc-explainer-section { margin-bottom: 18px; }
.kc-explainer-section-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--accent3);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.kc-explainer-section-label::before {
  content: '';
  width: 14px; height: 1px;
  background: var(--accent3);
  opacity: 0.6;
}
.kc-explainer-section-label.label-orange { color: var(--accent); }
.kc-explainer-section-label.label-orange::before { background: var(--accent); }
.kc-explainer-section-label.label-teal { color: var(--accent2); }
.kc-explainer-section-label.label-teal::before { background: var(--accent2); }
.kc-explainer-section-label.label-yellow { color: var(--yellow); }
.kc-explainer-section-label.label-yellow::before { background: var(--yellow); }
.kc-explainer-section-label.label-red { color: var(--red); }
.kc-explainer-section-label.label-red::before { background: var(--red); }

.kc-explainer-section p {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-mid);
}
.kc-explainer-section p strong { color: var(--text-bright); font-weight: 600; }
.kc-explainer-section p em {
  color: var(--accent);
  font-style: normal;
  font-family: 'Space Mono', monospace;
  font-size: 12.5px;
}

.kc-explainer-source {
  margin-top: 6px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--accent2) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent2) 18%, transparent);
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.5px;
  color: var(--muted);
}
.kc-explainer-source span {
  color: var(--accent2);
  text-transform: uppercase;
  font-weight: 700;
  margin-right: 8px;
}

.kc-explainer-foot {
  padding: 12px 22px 16px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.kc-explainer-foot-hint {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
  text-transform: uppercase;
}
.kc-explainer-foot-hint kbd {
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--border2);
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text-mid);
  margin: 0 2px;
}
.kc-explainer-foot-cta {
  background: var(--accent3);
  color: var(--bg);
  border: none;
  padding: 8px 16px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  font-weight: 700;
  text-transform: uppercase;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.15s;
}
.kc-explainer-foot-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent3) 35%, transparent);
}

/* Navigation arrows in modal footer (only shown when card has siblings registered in same group) */
.kc-explainer-nav {
  display: flex;
  align-items: center;
  gap: 8px;
}
.kc-explainer-nav-btn {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border2);
  color: var(--text-mid);
  width: 32px;
  height: 32px;
  border-radius: 6px;
  cursor: pointer;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  padding: 0;
}
.kc-explainer-nav-btn:hover {
  color: var(--accent3);
  border-color: var(--accent3);
  background: color-mix(in srgb, var(--accent3) 10%, transparent);
  transform: scale(1.05);
}
.kc-explainer-nav-btn:active { transform: scale(0.96); }
.kc-explainer-nav-btn:focus-visible {
  outline: 2px solid var(--accent3);
  outline-offset: 2px;
}
.kc-explainer-nav-counter {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.5px;
  color: var(--muted);
  min-width: 44px;
  text-align: center;
  user-select: none;
}

@media (max-width: 560px) {
  .kc-explainer-panel { max-height: calc(92vh / var(--kc-font-scale, 1)); }
  .kc-explainer-head { padding: 14px 16px 12px; }
  .kc-explainer-title { font-size: 16px; }
  .kc-explainer-body { padding: 14px 16px 4px; }
  .kc-explainer-foot {
    padding: 10px 16px 14px;
    flex-wrap: wrap;
    gap: 10px;
  }
  .kc-explainer-foot-hint {
    order: 3;
    width: 100%;
    text-align: center;
    margin-top: 2px;
  }
  .kc-explainer-nav { order: 1; }
  .kc-explainer-foot-cta { order: 2; flex: 1; }
}

/* ═══════════════════════════════════════════════════════════
   QUICK CAPTURE BAR — sticky idea capture across all pages.

   Two states:
   • Collapsed (default): small floating "💡 Capture idea" pill in
     the bottom-right corner. Minimal footprint, does not block
     any page content.
   • Expanded: full-width bar docked to bottom of viewport with
     input + tag selector + add button.

   Activated by:
     • Click on the pill
     • Cmd/Ctrl+I keyboard shortcut
     • Esc collapses it
   ═══════════════════════════════════════════════════════════ */

/* COLLAPSED DOCK — three icon buttons in one shell.
   Writer (✎) · Assistant (✦) · Capture idea (💡 + count badge).
   Each .kc-qc-act renders a custom tooltip on hover from data-tip. */
.kc-qc-pill {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 1500;
  display: flex;
  align-items: center;
  gap: 4px;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 999px;
  padding: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45), 0 0 0 1px color-mix(in srgb, var(--accent) 6%, transparent);
  transition: box-shadow 0.18s ease, border-color 0.18s ease;
  user-select: none;
}
.kc-qc-pill:hover {
  border-color: color-mix(in srgb, var(--accent) 22%, transparent);
  box-shadow: 0 10px 28px rgba(0,0,0,0.55), 0 0 0 1px color-mix(in srgb, var(--accent) 12%, transparent);
}

/* Individual action buttons inside the dock.
   May 2026 redesign: chip-style backgrounds (always visible, not just
   on hover) so the four actions read as distinct affordances at rest.
   Each .kc-qc-act-* variant below sets its own tint + ring; this base
   class supplies the chassis (size, hit-target, transitions). */
.kc-qc-act {
  position: relative;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--text-bright);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  line-height: 1;
  padding: 0;
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.18s ease;
}
.kc-qc-act:hover { transform: translateY(-1px); }
.kc-qc-act:active { transform: translateY(0); }
.kc-qc-act-glyph { font-size: 15px; line-height: 1; }
.kc-qc-act .kc-ic { font-size: 16px; }

/* ── Per-action chips ─────────────────────────────────────────────
   Each button is its own coloured affordance with a permanent tinted
   disc + hairline ring. Hover intensifies the same hue. The Razor AI
   chip (#kcQcAssist) is the "hero" — a filled brass disc with dark-
   on-brass icon — to anchor the dock and signal the primary action.
   Palette mirrors variant 3 of the redesign mockup:
     · Writer    → violet  (--accent2 family)
     · Razor AI  → brass   (--accent fill, hero)
     · Support   → teal    (override to mint, see KCSupport block)
     · Capture   → yellow  (--yellow / bulb family) */
.kc-qc-act-writer {
  color: color-mix(in srgb, var(--accent2, #b693f5) 80%, white);
  background: color-mix(in srgb, var(--accent2, #b693f5) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent2, #b693f5) 24%, transparent);
}
.kc-qc-act-writer:hover {
  background: color-mix(in srgb, var(--accent2, #b693f5) 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent2, #b693f5) 38%, transparent);
}

/* Razor AI — primary / hero. Solid brass fill with dark icon, soft
   outer glow that intensifies on hover. */
.kc-qc-act-assist {
  color: #1a1610;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 92%, white 8%), var(--accent));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent),
    0 0 12px color-mix(in srgb, var(--accent) 28%, transparent);
}
.kc-qc-act-assist:hover {
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 96%, white 14%), color-mix(in srgb, var(--accent) 90%, white));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.24),
    0 0 0 1px color-mix(in srgb, var(--accent) 75%, transparent),
    0 0 18px color-mix(in srgb, var(--accent) 40%, transparent);
}

.kc-qc-act-capture {
  color: color-mix(in srgb, var(--yellow, #ffd166) 85%, white);
  background: color-mix(in srgb, var(--yellow, #ffd166) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--yellow, #ffd166) 24%, transparent);
}
.kc-qc-act-capture:hover {
  background: color-mix(in srgb, var(--yellow, #ffd166) 20%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--yellow, #ffd166) 38%, transparent);
}

/* Custom hover tooltip — appears above the button, fades in.
   Pure CSS via data-tip; no JS needed. */
.kc-qc-act::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 5px;
  padding: 5px 9px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text-bright);
  letter-spacing: 0.4px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.45);
  z-index: 1;
}
.kc-qc-act:hover::after,
.kc-qc-act:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Sticky-bottom pagers across the platform (predict, kol, future
   pages tagged [data-pager]) sit at bottom:12px and the corner dock
   sits at bottom:16px right:16px. On wide viewports they don't
   collide because the pager is centered in a max-1100/1200px column,
   leaving plenty of room on the right for the dock. On narrower
   viewports the centered pager extends past the dock's left edge
   and its rightmost button (Next ›) ends up underneath the dock.

   Fix: when the viewport is narrow enough that overlap is possible,
   shift sticky pagers leftward via margin-right equal to the dock
   footprint plus a safe gap (108px dock + 32px gap = 140px).
   1380px breakpoint = 1100px column + 140px dock zone + 140px
   minimum left margin for symmetry. */
@media (max-width: 1380px) {
  .pd-pager,
  .kc-pager,
  [data-pager] {
    margin-right: 140px;
  }
}
/* On phones the dock shrinks (32px buttons, padding 4px → ~108px)
   and the pager often becomes a non-sticky single-row block via the
   page's own media query. Keep some right buffer regardless so the
   dock doesn't cover even a left-aligned pager edge. */
@media (max-width: 700px) {
  .pd-pager,
  .kc-pager,
  [data-pager] {
    margin-right: 120px;
  }
}

/* Hide the dock when the expanded bar is open or user dismissed it */
.kc-qc-pill.is-hidden { display: none; }

/* EXPANDED BAR */
.kc-qc-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1500;
  background: rgba(13,13,25,0.92);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--border2);
  padding: 10px 20px;
  transform: translateY(100%);
  transition: transform 0.22s cubic-bezier(.2,.8,.2,1);
  box-shadow: 0 -8px 30px rgba(0,0,0,0.45);
}
.kc-qc-bar.is-open { transform: translateY(0); }

/* Quick-capture bar retired. It was parked off-screen with
   translateY(100%), but a fixed bottom:0 element can still be revealed
   by over-scrolling the page (it surfaced as a stray bar at the very
   bottom on every page). Its only entry point was the ⌘I shortcut — the
   dock opener was already removed — so it has no surfaced affordance to
   keep. display:none takes it out of the layout entirely so it can never
   be scrolled into view; the JS still builds it (keeping ⌘I and
   KCQuickCapture.open() null-safe), it just never paints. The dock pill
   (#kcQcPill — Assistant/chat/Support) is a separate element and is
   unaffected. */
.kc-qc-bar { display: none !important; }

.kc-qc-bar-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.kc-qc-icon {
  font-size: 14px;
  flex-shrink: 0;
  width: 22px;
  text-align: center;
}

.kc-qc-input {
  flex: 1;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 9px 12px;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  color: var(--text-bright);
  letter-spacing: 0.3px;
  outline: none;
  transition: border-color 0.15s;
  min-width: 0; /* allow flex shrink */
}
.kc-qc-input:focus { border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.kc-qc-input::placeholder { color: var(--muted); }

.kc-qc-tag {
  background: var(--card2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-bright);
  letter-spacing: 0.3px;
  outline: none;
  cursor: pointer;
  flex-shrink: 0;
}
/* Stripe accent matches selected tag (mirrors the index .idea-tag-select pattern) */
.kc-qc-tag.tag-btc      { border-left-color: var(--accent); }
.kc-qc-tag.tag-macro    { border-left-color: var(--red); }
.kc-qc-tag.tag-alt      { border-left-color: var(--accent3); }
.kc-qc-tag.tag-thread   { border-left-color: var(--accent2); }
.kc-qc-tag.tag-poll     { border-left-color: var(--yellow); }
.kc-qc-tag.tag-hottake  { border-left-color: var(--red); }
.kc-qc-tag.tag-personal { border-left-color: var(--text-bright); }
.kc-qc-tag.tag-data     { border-left-color: var(--accent2); }
.kc-qc-tag.tag-reply    { border-left-color: var(--accent3); }
.kc-qc-tag.tag-other    { border-left-color: var(--muted); }

.kc-qc-add {
  background: var(--accent);
  color: #0a0a0f;
  border: none;
  border-radius: 6px;
  padding: 9px 16px;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s, transform 0.1s;
}
.kc-qc-add:hover { background: #ffa840; }
.kc-qc-add:active { transform: scale(0.97); }
.kc-qc-add:disabled {
  background: var(--border2);
  color: var(--muted);
  cursor: not-allowed;
}

.kc-qc-close {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}
.kc-qc-close:hover {
  color: var(--text-bright);
  border-color: var(--border2);
}

/* Count badge — small corner pill on the 💡 capture button so the
   user sees ideas accumulating without taking up dock width. */
.kc-qc-pill-count {
  position: absolute;
  top: -2px;
  right: -3px;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 999px;
  padding: 0 5px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  line-height: 1.45;
  letter-spacing: 0.2px;
  pointer-events: none;
}
.kc-qc-pill-count:empty { display: none; }

/* Toast (added-confirmation) — same vibe as showIdeaToast on index */
.kc-qc-toast {
  position: fixed;
  bottom: 80px;
  right: 20px;
  z-index: 2100;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 10px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-bright);
  letter-spacing: 0.4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.2s, transform 0.2s;
  pointer-events: none;
}
.kc-qc-toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* MOBILE — bar adapts to narrow viewports */
@media (max-width: 700px) {
  .kc-qc-bar { padding: 8px 10px; }
  .kc-qc-icon { display: none; }
  .kc-qc-tag { padding: 8px 6px; font-size: 10px; max-width: 90px; }
  .kc-qc-add { padding: 9px 12px; }
  .kc-qc-pill { bottom: 12px; right: 12px; padding: 5px; gap: 3px; }
  .kc-qc-act { width: 34px; height: 34px; }
  .kc-qc-act .kc-ic { font-size: 15px; }
  /* Tooltip on the right-most button can clip the viewport edge on
     narrow phones — anchor it to the right of the button instead. */
  .kc-qc-act:last-child::after {
    left: auto;
    right: 0;
    transform: translateY(2px);
  }
  .kc-qc-act:last-child:hover::after,
  .kc-qc-act:last-child:focus-visible::after {
    transform: translateY(0);
  }
}

/* (No page exclusion — the pill appears everywhere including the
   dashboard. On the dashboard, captures from the pill write to the
   same kc_ideas store, so the existing Scratchpad panel re-renders
   automatically via its 'storage' event listener.) */

/* ─────────────────────────────────────────────────────────────
   ADVANCED ANIMATIONS PACK (kca-*)
   Platform-wide motion primitives for signal communication.
   ───────────────────────────────────────────────────────────── */

/* 1 · Signal pulse — score change / important update on a card or row */
@keyframes kcaSignalPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent),
                    inset 0 0 0 0 transparent; }
  50%  { box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 0%, transparent),
                    inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent, inset 0 0 0 0 transparent; }
}
.kca-signal-pulse { animation: kcaSignalPulse 1.4s ease-out; }
@keyframes kcaSignalPulseAccent2 {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent2) 55%, transparent),
                    inset 0 0 0 0 transparent; }
  50%  { box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent2) 0%, transparent),
                    inset 0 0 0 1px color-mix(in srgb, var(--accent2) 45%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent, inset 0 0 0 0 transparent; }
}
.kca-signal-pulse-good { animation: kcaSignalPulseAccent2 1.4s ease-out; }

/* 2 · Number rolling — used by JS via data-kca-roll on a numeric element */
.kca-num {
  font-variant-numeric: tabular-nums;
  display: inline-block;
}

/* 3 · Score delta spark — floats up from a score, then disappears */
@keyframes kcaSparkUp {
  0%   { transform: translateY(6px); opacity: 0; }
  18%  { transform: translateY(0); opacity: 1; }
  78%  { transform: translateY(-2px); opacity: 1; }
  100% { transform: translateY(-14px); opacity: 0; }
}
.kca-spark {
  position: absolute;
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  white-space: nowrap;
  z-index: 5;
  animation: kcaSparkUp 1.2s ease-out forwards;
}
.kca-spark.up   { color: var(--up, #00d4aa); }
.kca-spark.down { color: #ff5e7a; }

/* 4 · Radar sweep — for radar.html ambient idle motion */
@keyframes kcaRadarSweep {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.kca-radar-sweep { transform-origin: center; animation: kcaRadarSweep 4s linear infinite; }
@keyframes kcaBlipPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
.kca-blip { animation: kcaBlipPulse 2.6s ease-in-out infinite; }

/* 5 · Row enter — new item slides in with a brief amber wash */
@keyframes kcaRowEnter {
  0%  { transform: translateX(-12px); opacity: 0;
        background: color-mix(in srgb, var(--accent) 18%, transparent);
        border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
  60% { background: color-mix(in srgb, var(--accent) 18%, transparent);
        border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
  100%{ transform: translateX(0); opacity: 1; }
}
.kca-row-enter { animation: kcaRowEnter 1s cubic-bezier(0.2,0.8,0.2,1) both; }

/* 6 · Generation progress bar with shimmer */
.kca-bar {
  height: 6px;
  background: rgba(127,127,127,0.12);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.kca-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
  width: 0%;
  transition: width 1.4s cubic-bezier(0.2,0.8,0.2,1);
  position: relative;
}
.kca-bar-fill::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 28px;
  right: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.45));
  animation: kcaBarShimmer 1.4s linear infinite;
}
@keyframes kcaBarShimmer {
  0%   { transform: translateX(-32px); }
  100% { transform: translateX(8px); }
}
.kca-bar-fill.is-done::after { display: none; }

/* 7 · Live indicator dot — for "Live" / "Active" status pills */
@keyframes kcaLiveDot {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent2) 60%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent2) 0%, transparent); }
}
.kca-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent2, #00d4aa);
  display: inline-block;
  vertical-align: middle;
  animation: kcaLiveDot 1.6s ease-in-out infinite;
}
.kca-dot.warm { background: var(--accent, #f7931a); }
.kca-dot.warm { animation-name: kcaLiveDotWarm; }
@keyframes kcaLiveDotWarm {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 0%, transparent); }
}

/* 8 · Tab indicator slide — animated underline that travels */
.kca-tabs {
  position: relative;
  display: flex;
  border-bottom: 0.5px solid var(--border, rgba(127,127,127,0.2));
}
.kca-tab-indicator {
  position: absolute;
  bottom: -0.5px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
  transition: left 0.4s cubic-bezier(0.2,0.8,0.2,1),
              width 0.4s cubic-bezier(0.2,0.8,0.2,1);
  pointer-events: none;
}

/* 10 · Card lift on hover — accent border + 3px translate */
.kca-card-lift {
  transition: transform 0.25s cubic-bezier(0.2,0.8,0.2,1),
              border-color 0.25s ease,
              background 0.25s ease,
              box-shadow 0.25s ease;
}
.kca-card-lift:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  box-shadow: 0 6px 22px -10px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* 11 · Burst — JS-driven particle confetti from a button */
.kca-burst-anchor { position: relative; display: inline-block; }
.kca-burst-piece {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 1px;
  pointer-events: none;
  z-index: 100;
  animation: kcaBurst 0.7s cubic-bezier(0.2,0.8,0.2,1) forwards;
}
@keyframes kcaBurst {
  0%   { transform: translate(0,0) scale(0); opacity: 1; }
  100% { transform: translate(var(--kca-dx, 0), var(--kca-dy, 0)) scale(1); opacity: 0; }
}

/* 12 · Rank-up ring — concentric pulse around an avatar */
.kca-rank-ring { position: relative; }
.kca-rank-ring::before,
.kca-rank-ring::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 1.5px solid var(--accent2, #00d4aa);
  pointer-events: none;
  animation: kcaRankRing 1.4s ease-out infinite;
}
.kca-rank-ring::after { animation-delay: 0.7s; }
@keyframes kcaRankRing {
  0%   { transform: scale(1);   opacity: 0.85; }
  100% { transform: scale(1.6); opacity: 0; }
}

/* Reduced motion — kill all of the above for accessibility */
@media (prefers-reduced-motion: reduce) {
  .kca-signal-pulse,
  .kca-signal-pulse-good,
  .kca-spark,
  .kca-radar-sweep,
  .kca-blip,
  .kca-row-enter,
  .kca-bar-fill::after,
  .kca-dot,
  .kca-rank-ring::before,
  .kca-rank-ring::after { animation: none !important; }
  .kca-card-lift:hover { transform: none !important; }
}

/* ══════════════════════════════════════════════════════════════════
   ICON SYSTEM · v1
   ──────────────────────────────────────────────────────────────────
   Base styles for icons rendered by KC.icon() and <i.kc-ic>.
   Icons inherit currentColor so they tint to whatever text color
   their container uses — works in all 7 themes.
   ══════════════════════════════════════════════════════════════════ */
.kc-ic {
  display: inline-block;
  vertical-align: -2px;        /* sit on text baseline cleanly */
  flex-shrink: 0;
  pointer-events: none;        /* clicks pass through to parent button */
}

/* When inside flex containers (most buttons), reset vertical-align */
button .kc-ic,
.btn .kc-ic,
[class*="-btn"] .kc-ic,
.flex .kc-ic,
.row .kc-ic {
  vertical-align: middle;
}

/* Spacing helper: ".kc-ic + text" gets a small gap */
.kc-ic + span,
.kc-ic + * {
  margin-left: 4px;
}

/* Status colors — opt-in via class on the icon element itself */
.kc-ic.ic-ok       { color: var(--accent2, #00d4aa); }
.kc-ic.ic-warn     { color: var(--yellow, #ffd166); }
.kc-ic.ic-danger   { color: var(--red, #ff4d6d); }
.kc-ic.ic-accent   { color: var(--accent, #f7931a); }
.kc-ic.ic-muted    { color: var(--muted, #a0a0c0); }

/* Subtle hover for icon-only buttons */
button:hover > .kc-ic,
.btn:hover > .kc-ic { opacity: 0.85; }

/* Inline signal dots — replace 🟢🔴🟡 in radar headers */
.signal-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  vertical-align: 1px;
  margin-right: 6px;
  flex-shrink: 0;
}
.signal-dot.signal-green { background: var(--accent2, #00d4aa); }
.signal-dot.signal-red   { background: var(--red, #ff4d6d); }
.signal-dot.signal-yellow{ background: var(--yellow, #ffd166); }
.signal-dot.signal-orange{ background: var(--accent, #f7931a); }

/* ══════════════════════════════════════════════════════════════════
   KEYBOARD SHORTCUTS OVERLAY (?)
   ────────────────────────────────────────────────────────────────── */
.kc-sc-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 10, 0.72);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: kcFadeIn 0.15s ease;
  padding: 24px;
}
.kc-sc-modal {
  width: 100%;
  max-width: 580px;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5),
              0 0 0 1px rgba(255, 255, 255, 0.03) inset;
  overflow: hidden;
  animation: kcPaletteSlide 0.18s ease;
}
.kc-sc-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.kc-sc-title {
  flex: 1;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 14px;
  font-weight: var(--w-bold);
  color: var(--text-bright, #fff);
  letter-spacing: 0.2px;
}
.kc-sc-esc {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.04);
  padding: 3px 8px;
  border-radius: 3px;
}
.kc-sc-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  padding: 16px 0;
}
.kc-sc-col {
  padding: 0 18px;
}
.kc-sc-col + .kc-sc-col {
  border-left: 1px solid var(--border);
}
@media (max-width: 540px) {
  .kc-sc-body { grid-template-columns: 1fr; }
  .kc-sc-col + .kc-sc-col { border-left: none; border-top: 1px solid var(--border); padding-top: 14px; margin-top: 8px; }
}
.kc-sc-group {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}
.kc-sc-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  font-size: 13px;
  color: var(--text);
}
.kc-sc-row > span {
  flex: 1;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
}
.kc-sc-row kbd {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-bright, #fff);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  padding: 2px 7px;
  border-radius: 4px;
  min-width: 22px;
  text-align: center;
  line-height: 1.4;
}
.kc-sc-foot {
  border-top: 1px solid var(--border);
  padding: 10px 18px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  text-align: center;
  letter-spacing: 0.5px;
}

/* ══════════════════════════════════════════════════════════════════
   UNDO TOASTS — kcToastUndo
   ────────────────────────────────────────────────────────────────── */
.kc-toast-undo-host {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 2100;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  max-width: calc(100vw - 48px);
}
.kc-toast-undo {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 8px;
  padding: 10px 14px;
  min-width: 320px;
  max-width: 420px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.kc-toast-undo.show {
  opacity: 1;
  transform: translateY(0);
}
.kc-toast-undo-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  flex-shrink: 0;
  font-family: 'Space Mono', monospace;
}
.kc-toast-undo--danger .kc-toast-undo-icon {
  background: color-mix(in srgb, var(--red, #ff4d6d) 15%, transparent);
  color: var(--red, #ff4d6d);
}
.kc-toast-undo--danger .kc-toast-undo-icon::before { content: '×'; font-size: 14px; }
.kc-toast-undo--success .kc-toast-undo-icon {
  background: color-mix(in srgb, var(--accent2, #00d4aa) 15%, transparent);
  color: var(--accent2, #00d4aa);
}
.kc-toast-undo--success .kc-toast-undo-icon::before { content: '✓'; }
.kc-toast-undo--info .kc-toast-undo-icon {
  background: color-mix(in srgb, var(--accent, #f7931a) 15%, transparent);
  color: var(--accent, #f7931a);
}
.kc-toast-undo--info .kc-toast-undo-icon::before { content: 'i'; font-style: italic; }
.kc-toast-undo--danger .kc-toast-undo-ring  { color: var(--red, #ff4d6d); }
.kc-toast-undo--success .kc-toast-undo-ring { color: var(--accent2, #00d4aa); }
.kc-toast-undo--info .kc-toast-undo-ring    { color: var(--accent, #f7931a); }
.kc-toast-undo-text {
  flex: 1;
  min-width: 0;
}
.kc-toast-undo-title {
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 13px;
  color: var(--text-bright, #fff);
  line-height: 1.3;
}
.kc-toast-undo-sub {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kc-toast-undo-btn {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--border);
  color: var(--text-bright, #fff);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.5px;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
  flex-shrink: 0;
}
.kc-toast-undo-btn:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: var(--border2);
}
.kc-toast-undo-ring {
  flex-shrink: 0;
}
.kc-toast-undo-ring-text {
  font-family: 'Space Mono', monospace;
}

@media (max-width: 480px) {
  .kc-toast-undo-host { left: 12px; right: 12px; bottom: 12px; }
  .kc-toast-undo { min-width: 0; width: 100%; max-width: none; }
}

/* ══════════════════════════════════════════════════════════════════
   INLINE EDITABLE — data-kc-editable
   ────────────────────────────────────────────────────────────────── */
.kc-editable {
  cursor: text;
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
  position: relative;
  transition: background 0.15s ease, box-shadow 0.15s ease;
  outline: none;
}
.kc-editable:hover:not(.kc-editable--editing) {
  background: rgba(255, 255, 255, 0.04);
  box-shadow: inset 0 0 0 1px var(--border);
}
.kc-editable--editing {
  background: rgba(255, 255, 255, 0.05);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, #f7931a) 50%, var(--border));
  cursor: text;
}
.kc-editable-saved {
  position: absolute;
  top: -22px;
  right: 0;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--accent2, #00d4aa);
  background: color-mix(in srgb, var(--accent2, #00d4aa) 12%, var(--card));
  border: 1px solid color-mix(in srgb, var(--accent2, #00d4aa) 30%, var(--border));
  padding: 2px 6px;
  border-radius: 3px;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.18s ease, transform 0.18s ease;
  pointer-events: none;
  white-space: nowrap;
}
.kc-editable-saved.show {
  opacity: 1;
  transform: translateY(0);
}

/* ══════════════════════════════════════════════════════════════════
   PLATFORM-WIDE CONTEXT MENU (right-click registry)
   ────────────────────────────────────────────────────────────────── */
.kc-ctx-menu {
  position: fixed;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 8px;
  padding: 4px;
  min-width: 220px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  z-index: 2200;
  animation: kcFadeIn 0.12s ease;
}
.kc-ctx-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 12px;
  color: var(--text);
  transition: background 0.12s ease;
  white-space: nowrap;
}
.kc-ctx-item:hover,
.kc-ctx-item:focus,
.kc-ctx-item.active {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-bright, #fff);
}
.kc-ctx-item:focus { outline: none; }
.kc-ctx-item .kc-ctx-icon {
  width: 14px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  flex-shrink: 0;
}
.kc-ctx-item:hover .kc-ctx-icon,
.kc-ctx-item:focus .kc-ctx-icon,
.kc-ctx-item.active .kc-ctx-icon {
  color: var(--accent, #f7931a);
}
.kc-ctx-item .kc-ctx-shortcut {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
}
.kc-ctx-item--danger { color: var(--red, #ff4d6d); }
.kc-ctx-item--danger:hover,
.kc-ctx-item--danger:focus { background: color-mix(in srgb, var(--red, #ff4d6d) 12%, transparent); }
.kc-ctx-item--disabled { opacity: 0.4; cursor: default; pointer-events: none; }
.kc-ctx-divider {
  height: 1px;
  background: var(--border);
  margin: 4px 8px;
}

/* Long-press (touch) context-menu targets — on coarse pointers, stop
   iOS Safari's native callout / text-selection from competing with the
   ~500ms long-press that opens the platform context menu. Scoped to the
   block-level card rows only (not inline .kc-ticker), so selecting text
   in prose is unaffected; the menu's own Copy action covers card text. */
@media (pointer: coarse) {
  .hm-card,
  .kcc-msg__signal,
  .kcc-msg__bet,
  .kcc-msg__chal,
  .kcc-mypinned__card,
  .today-post,
  .feed-row,
  .tcard,
  .tcard-row,
  .tracker-row,
  .scraper-kol-row,
  .pd-card-strip,
  .wl-row,
  .cp-table tbody tr[data-handle] {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}

/* ══════════════════════════════════════════════════════════════════
   PLATFORM-WIDE TICKER AUTO-DETECTION
   $TICKER tokens are wrapped in <span class="kc-ticker"> on every
   page. Subtle hover affordance signals "right-click for actions".
   ────────────────────────────────────────────────────────────────── */
.kc-ticker {
  color: var(--type-cashtag, #7dc4d4);
  cursor: context-menu;
  border-radius: 3px;
  padding: 0 1px;
  transition: background 0.12s ease, outline-color 0.12s ease;
  outline: 1px dashed transparent;
  outline-offset: 1px;
}
.kc-ticker:hover {
  background: color-mix(in srgb, var(--type-cashtag, #7dc4d4) 14%, transparent);
  outline-color: color-mix(in srgb, var(--type-cashtag, #7dc4d4) 45%, transparent);
}
/* Opt out of the cashtag colour, keep every other behaviour.
   In prose a cyan $TICKER is the affordance. In a dense table whose column
   is already headed SYMBOL, recolouring every row would be noise — and the
   whole row is clickable anyway, so cyan would be claiming an interactivity
   the rest of the row also has. These wrap for the preview card and the
   right-click menu, and say so on hover through the tint and dashed outline
   rather than through colour. */
.kc-ticker.is-plain { color: inherit; }

/* ══════════════════════════════════════════════════════════════════
   WRITER FOCUS MODE
   ────────────────────────────────────────────────────────────────── */
body.kc-focus-on > *:not(.kc-focus-overlay):not(script):not(style) {
  filter: blur(2px);
  opacity: 0.18;
  pointer-events: none;
  transition: filter 0.25s ease, opacity 0.25s ease;
}
.kc-focus-overlay {
  position: fixed;
  inset: 0;
  background: rgba(8, 8, 12, 0.85);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  z-index: 2500;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48px 24px 24px;
  overflow-y: auto;
  animation: kcFadeIn 0.22s ease;
}
.kc-focus-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 560px;
  margin-bottom: 16px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--muted);
}
.kc-focus-counter {
  letter-spacing: 1px;
  text-transform: uppercase;
}
.kc-focus-nav {
  display: flex;
  gap: 8px;
}
.kc-focus-nav-btn {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.12s ease;
}
.kc-focus-nav-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text-bright, #fff);
}
.kc-focus-nav-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.kc-focus-card {
  width: 100%;
  max-width: 560px;
  /* Heavy glass — the only true blur surface in the platform besides the
     sidebar. Layered fill (gradient) over a backdrop blur, so whatever
     sits behind shows through softly. Inner highlight + faint drop give
     the floating-pane feeling. */
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.012));
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px;
  padding: 28px 28px 18px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 6px 22px -10px rgba(0,0,0,0.45);
  animation: kcPaletteSlide 0.22s ease;
}
.kc-focus-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--muted);
}
.kc-focus-meta-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent3, #c896ff) 18%, transparent);
  color: var(--accent3, #c896ff);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: var(--w-bold);
}
.kc-focus-text {
  color: var(--text-bright, #fff);
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 16px;
  line-height: 1.65;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.kc-focus-tweet + .kc-focus-tweet {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  color: var(--text);
  opacity: 0.92;
}
.kc-focus-actions {
  display: flex;
  gap: 8px;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.kc-focus-btn {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.5px;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.kc-focus-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--border2);
  color: var(--text-bright, #fff);
}
.kc-focus-btn--post {
  margin-left: auto;
  background: color-mix(in srgb, var(--accent2, #00d4aa) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent2, #00d4aa) 40%, var(--border));
  color: var(--accent2, #00d4aa);
}
.kc-focus-btn--post:hover {
  background: color-mix(in srgb, var(--accent2, #00d4aa) 24%, transparent);
}
.kc-focus-hints {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-top: 16px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  flex-wrap: wrap;
}
.kc-focus-hints kbd {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 3px;
  margin-right: 4px;
}

/* ══════════════════════════════════════════════════════════════════
   DASHBOARD WIDGETS — drag handles + filter chips
   ────────────────────────────────────────────────────────────────── */
.kc-widget-handle {
  cursor: grab;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  user-select: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.kc-widget-card:hover .kc-widget-handle,
.kc-stat-card:hover .kc-widget-handle,
.stat-card:hover .kc-widget-handle,
.macro-card:hover .kc-widget-handle {
  opacity: 0.7;
}
.kc-widget-handle:hover { opacity: 1 !important; }
.kc-widget-handle:active { cursor: grabbing; }
.kc-widget-dragging {
  opacity: 0.55;
  transform: rotate(-0.5deg) scale(0.99);
  transition: none !important;
}
.kc-widget-drop-target {
  outline: 1.5px dashed color-mix(in srgb, var(--accent, #f7931a) 60%, transparent);
  outline-offset: 2px;
}

.kc-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  background: color-mix(in srgb, var(--accent, #f7931a) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent, #f7931a) 36%, var(--border));
  border-radius: 4px;
  color: var(--accent, #f7931a);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.4px;
}
.kc-filter-chip-clear {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 0;
  opacity: 0.7;
}
.kc-filter-chip-clear:hover { opacity: 1; }

.kc-bar--active {
  filter: brightness(1.25);
  outline: 1.5px solid var(--accent, #f7931a);
  outline-offset: 1px;
}

.kc-tooltip {
  position: fixed;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 6px 9px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text);
  z-index: 2050;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
  white-space: nowrap;
  line-height: 1.5;
}
.kc-tooltip-strong { color: var(--text-bright, #fff); }

/* ══════════════════════════════════════════════════════════════════
   V3 · GLOW UTILITIES (platform-wide audit, 2026-04)
   ──────────────────────────────────────────────────────────────────
   Drop-in classes that any page can apply to opt into the upgraded
   glow vocabulary identified in the platform audit. All values
   reference theme accents via color-mix so they auto-adapt to every
   theme (kolhub / dusk / horizon × easy/calm/standard) and are
   automatically dimmer in calm-tier themes because their accents
   are desaturated.

   Audit categories — glow YES:
     1. Live state             → .kc-glow-live, .kc-live-dot
     2. Active selection       → .kc-glow-selected
     3. Primary CTA            → .kc-btn-primary-glow
     4. Hero metric / KPI      → .kc-glow-num
     5. Urgency / alert        → .kc-sev-high, .kc-glow-urgent
     6. Streak / momentum      → .kc-glow-streak
     7. Progress / charge      → .kc-glow-progress (apply to fill)
     8. New / unread           → .kc-new-dot
     9. "Just landed" item     → .kc-glow-fresh

   Glow NO (deliberate omission): body text, form inputs, inactive
   nav, tables, dense data, calendar heatmaps. These intentionally
   stay flat so the items above can do their job.

   All animations are wrapped in @media (prefers-reduced-motion: …)
   in the existing reduced-motion block at the end of the file.
   ══════════════════════════════════════════════════════════════════ */

/* ── 1. Live dots (red live ticker, audio-on, ws-connected) ─── */
.kc-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
  display: inline-block;
  flex-shrink: 0;
  box-shadow:
    0 0 10px var(--red),
    0 0 20px color-mix(in srgb, var(--red) 50%, transparent);
  animation: kcLivePulse 1.4s ease-in-out infinite;
}
.kc-live-dot.accent {
  background: var(--accent);
  box-shadow:
    0 0 10px var(--accent),
    0 0 20px color-mix(in srgb, var(--accent) 50%, transparent);
}
.kc-live-dot.accent2 {
  background: var(--accent2);
  box-shadow:
    0 0 10px var(--accent2),
    0 0 20px color-mix(in srgb, var(--accent2) 50%, transparent);
}
.kc-live-dot.accent3 {
  background: var(--accent3);
  box-shadow:
    0 0 10px var(--accent3),
    0 0 20px color-mix(in srgb, var(--accent3) 50%, transparent);
}
@keyframes kcLivePulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* Generic wrapper utility — adds a soft halo around a status element. */
.kc-glow-live {
  box-shadow: 0 0 18px -2px color-mix(in srgb, var(--red) 35%, transparent);
}

/* ── 2. Active selection (filter chip, niche tag, mod-tab) ──── */
.kc-glow-selected {
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--accent2) 50%, transparent);
}
.kc-glow-selected.accent {
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--accent) 50%, transparent);
}
.kc-glow-selected.accent3 {
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--accent3) 50%, transparent);
}

/* ── 3. Primary CTA (Generate, Launch, Run) ─────────────────── */
.kc-btn-primary-glow {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent),
    0 0 18px color-mix(in srgb, var(--accent) 35%, transparent),
    0 6px 20px -6px color-mix(in srgb, var(--accent) 50%, transparent);
  transition: box-shadow 0.2s ease, transform 0.18s ease;
}
.kc-btn-primary-glow:hover:not(:disabled) {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent),
    0 0 26px color-mix(in srgb, var(--accent) 50%, transparent),
    0 8px 28px -6px color-mix(in srgb, var(--accent) 65%, transparent);
}
.kc-btn-primary-glow:disabled {
  box-shadow: none;
  opacity: 0.5;
}

/* ── 4. Hero metric / KPI (signal score, pulse number, big stats) */
.kc-glow-num {
  text-shadow:
    0 0 14px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 32px color-mix(in srgb, var(--accent) 25%, transparent);
}
.kc-glow-num.warn {
  text-shadow:
    0 0 14px color-mix(in srgb, var(--yellow) 55%, transparent),
    0 0 32px color-mix(in srgb, var(--yellow) 25%, transparent);
}
.kc-glow-num.danger {
  text-shadow:
    0 0 14px color-mix(in srgb, var(--red) 55%, transparent),
    0 0 32px color-mix(in srgb, var(--red) 25%, transparent);
}
.kc-glow-num.accent2 {
  text-shadow:
    0 0 14px color-mix(in srgb, var(--accent2) 55%, transparent),
    0 0 32px color-mix(in srgb, var(--accent2) 25%, transparent);
}
.kc-glow-num.accent3 {
  text-shadow:
    0 0 14px color-mix(in srgb, var(--accent3) 55%, transparent),
    0 0 32px color-mix(in srgb, var(--accent3) 25%, transparent);
}

/* ── 5. Urgency / alert (severity HIGH only — hierarchy matters) */
.kc-sev-high {
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--red) 45%, transparent);
}
.kc-glow-urgent {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--red) 30%, transparent),
    0 0 18px -2px color-mix(in srgb, var(--red) 40%, transparent);
}

/* ── 6. Streak / momentum (warm amber halo, no animation) ───── */
.kc-glow-streak {
  box-shadow: 0 0 18px -2px color-mix(in srgb, var(--yellow) 35%, transparent);
}
.kc-glow-streak .flame,
.kc-glow-streak [data-flame] {
  text-shadow:
    0 0 8px color-mix(in srgb, var(--yellow) 60%, transparent),
    0 0 16px color-mix(in srgb, var(--yellow) 30%, transparent);
}

/* ── 7. Progress / charge (apply to .fill, not the track) ───── */
.kc-glow-progress {
  background: linear-gradient(
    90deg,
    var(--accent),
    color-mix(in srgb, var(--accent3) 70%, var(--accent))
  );
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 50%, transparent);
}

/* ── 8. New / unread dot ─────────────────────────────────────── */
.kc-new-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent3);
  display: inline-block;
  flex-shrink: 0;
  box-shadow:
    0 0 8px var(--accent3),
    0 0 14px color-mix(in srgb, var(--accent3) 40%, transparent);
  animation: kcNewPulse 1.6s ease-in-out infinite;
}
@keyframes kcNewPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* ── 9. Fresh-arrival highlight (just-saved, just-added card) ── */
.kc-glow-fresh {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent3) 30%, transparent),
    0 0 24px -4px color-mix(in srgb, var(--accent3) 40%, transparent);
  animation: kcFreshFade 4s ease-out forwards;
}
@keyframes kcFreshFade {
  0%   {
    box-shadow:
      0 0 0 1px color-mix(in srgb, var(--accent3) 50%, transparent),
      0 0 32px -4px color-mix(in srgb, var(--accent3) 55%, transparent);
  }
  100% {
    box-shadow:
      0 0 0 1px transparent,
      0 0 0 transparent;
  }
}

/* ── Reduced-motion: kill animations, keep static glows ──────── */
@media (prefers-reduced-motion: reduce) {
  .kc-live-dot,
  .kc-new-dot,
  .kc-glow-fresh {
    animation: none !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   ASSISTANT (KC.assistant · Stage 1)
   ───────────────────────────────────────────────────────────────────
   The sidebar-foot ✦ button was removed (2026-05); the AI launcher
   now lives only in the floating dock (.kc-qc-pill #kcQcAssist) and
   per-surface ✦ hooks (radar cockpit, tracked rows, etc.).
   The .kc-assist-btn class below is kept for the per-surface ✦ hooks
   that still re-use it. The panel itself (.ka-panel-overlay /
   .ka-panel) is unchanged: z 1500, 480px, right-anchored, ESC- and
   click-outside dismissable.
   ═════════════════════════════════════════════════════════════════ */

/* ── Per-surface ✦ button (kept after sidebar mount removal) ───── */
.kc-assist-btn {
  width: 30px;
  height: 30px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  color: var(--text-mid);
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s;
  font-family: inherit;
  flex-shrink: 0;
  padding: 0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
}
.kc-assist-btn:hover {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 35%, transparent);
  color: var(--accent2, #b693f5);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent2, #b693f5) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent2, #b693f5) 18%, transparent);
}
.kc-assist-btn .kc-assist-glyph {
  font-size: 14px;
  line-height: 1;
  font-weight: 500;
}

/* ── Panel overlay + slide-in ─────────────────────────────────── */
.ka-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.ka-panel-overlay:not([hidden]) { display: block; }
.ka-panel {
  position: fixed;
  top: 0;
  right: 0;
  /* Compensate for body `zoom: var(--kc-font-scale)` (Appearance text-size
     slider). Without dividing, viewport-relative units stay at the unzoomed
     viewport size while the body scales up — so a 110% font-size pushes
     the bottom 10% of the panel off-screen, clipping the composer. The
     same pattern is used throughout the codebase for modals (kc-modal,
     kc-palette, kc-theme-menu, etc.). */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  /* Clip the outer panel so flex children share the height budget.
     Inner overflow is handled by .ka-body / .ka-chat-thread which
     each carry their own overflow-y: auto. Without this, when the
     chat-root's content (thread + context chip + attachments +
     composer) exceeds the budget, the panel itself scrolls and the
     composer ends up clipped below the viewport edge. */
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.ka-panel-overlay.show .ka-panel { transform: translateX(0); }

/* ── Head ─────────────────────────────────────────────────────── */
.ka-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.ka-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
}
.ka-panel-title .ka-glyph {
  color: var(--accent2, #b693f5);
  font-size: 14px;
  line-height: 1;
}
.ka-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.ka-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.ka-head-btn {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--muted);
  padding: 5px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  font-weight: 700;
  text-transform: uppercase;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.15s;
}
.ka-head-btn:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.ka-head-btn.is-open {
  color: var(--accent2, #b693f5);
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ka-head-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.ka-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.15s;
  line-height: 1;
}
.ka-panel-close:hover {
  color: var(--red, #f0726a);
  background: color-mix(in srgb, var(--red, #f0726a) 10%, transparent);
}

/* ── Meta line (between head and body) ─────────────────────────── */
.ka-meta {
  padding: 10px 20px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.5px;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

/* ── Settings strip ───────────────────────────────────────────── */
.ka-settings {
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 50%, var(--card));
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 12px;
}
.ka-settings[hidden] { display: none; }
.ka-set-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.ka-set-label {
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  flex-shrink: 0;
}
.ka-set-val {
  color: var(--text-bright);
  text-align: right;
  word-break: break-all;
  font-size: 12px;
}
.ka-set-val a {
  color: var(--accent2, #b693f5);
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ka-set-val a:hover { color: var(--text-bright); border-bottom-color: var(--text-bright); }
.ka-set-warn { color: var(--amber, #efb968); }
.ka-set-divider {
  height: 1px;
  background: var(--border);
  margin: 4px -20px;
}
.ka-set-input-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 4px;
}
.ka-set-aux {
  text-transform: none;
  letter-spacing: 0.3px;
  font-size: 10px;
  color: var(--muted);
  font-family: inherit;
  font-weight: 400;
}
.ka-set-input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 5px;
  padding: 8px 10px;
  color: var(--text-bright);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.3px;
  transition: border-color 0.15s;
}
.ka-set-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ka-set-input::placeholder { color: var(--muted); opacity: 0.6; }
.ka-set-actions {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}

/* ── Body (Stage 2-4 will fill this) ──────────────────────────── */
.ka-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ka-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 20px;
  margin: auto;
  max-width: 320px;
  gap: 10px;
}
.ka-empty-glyph {
  font-size: 28px;
  color: var(--accent2, #b693f5);
  line-height: 1;
  margin-bottom: 4px;
  opacity: 0.7;
}
.ka-empty-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-bright);
  letter-spacing: 0.3px;
}
.ka-empty-body {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.55;
}

/* ── Body components (defined now so Stages 2-4 don't need CSS edits) */
.ka-msg {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  line-height: 1.55;
}
.ka-msg.user {
  align-self: flex-end;
  max-width: 85%;
}
.ka-msg.assistant {
  align-self: stretch;
  max-width: 100%;
}
.ka-msg-bubble {
  padding: 10px 12px;
  border-radius: 10px;
  word-wrap: break-word;
}
.ka-msg.user .ka-msg-bubble {
  background: color-mix(in srgb, var(--accent2, #b693f5) 18%, transparent);
  color: var(--text-bright);
  border: 1px solid color-mix(in srgb, var(--accent2, #b693f5) 25%, transparent);
}
.ka-msg.assistant .ka-msg-bubble {
  background: transparent;
  color: var(--text-bright);
  padding: 4px 0;
}
.ka-tool-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.3px;
  padding: 4px 8px;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--muted);
  align-self: flex-start;
}
.ka-tool-chip.running {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 40%, transparent);
  color: var(--accent2, #b693f5);
}
.ka-tool-chip.done {
  border-color: color-mix(in srgb, var(--accent, #4dd99a) 40%, transparent);
  color: var(--accent, #4dd99a);
}
.ka-tool-chip.error {
  border-color: color-mix(in srgb, var(--red, #f0726a) 40%, transparent);
  color: var(--red, #f0726a);
}

/* Verdict pills (Stage 2 signal insight uses these) */
.ka-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 4px;
  font-weight: 500;
}
.ka-pill.info    { background: color-mix(in srgb, var(--accent3, #5dd5e8) 18%, transparent); color: var(--accent3, #5dd5e8); }
.ka-pill.success { background: color-mix(in srgb, var(--accent, #4dd99a) 18%, transparent);  color: var(--accent, #4dd99a); }
.ka-pill.warn    { background: color-mix(in srgb, var(--amber, #efb968) 18%, transparent);   color: var(--amber, #efb968); }
.ka-pill.danger  { background: color-mix(in srgb, var(--red, #f0726a) 18%, transparent);     color: var(--red, #f0726a); }
.ka-pill.neutral { background: var(--bg); border: 1px solid var(--border2); color: var(--muted); }

/* Composer (Stage 4 chat uses this) */
.ka-composer {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--card);
}
.ka-composer-input {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text-bright);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.45;
  resize: none;
  min-height: 36px;
  max-height: 140px;
  transition: border-color 0.15s;
}
.ka-composer-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ka-composer-send {
  background: var(--accent2, #b693f5);
  color: #1a1426;
  border: none;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: filter 0.15s, opacity 0.15s;
}
.ka-composer-send:hover { filter: brightness(1.1); }
.ka-composer-send:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Streaming caret — pulses while a message is mid-stream */
.ka-stream-caret {
  display: inline-block;
  width: 6px;
  height: 12px;
  background: var(--accent2, #b693f5);
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: kaCaretPulse 1s steps(2) infinite;
}
@keyframes kaCaretPulse {
  50% { opacity: 0.25; }
}

/* ── Mobile ───────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .ka-panel { width: 100vw; max-width: 100vw; }
  .ka-set-row { flex-direction: column; align-items: stretch; gap: 4px; }
  .ka-set-val { text-align: left; }
}

/* ── Reduced-motion ───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ka-panel { transition: none !important; }
  .ka-stream-caret { animation: none !important; opacity: 0.6 !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   BUG REPORT (KCBugReport · added 2026-05)
   ───────────────────────────────────────────────────────────────────
   Sidebar-foot 🐞 button + slide-in panel from the right. Mirrors
   the .ka-panel chassis (480px, right-anchored, ESC + click-outside
   dismiss) so font-scale / overflow behaviour matches Razor AI
   exactly. Brass --accent throughout (Razor Alpha primary); oxblood
   stays reserved for paid-API badges.
   ═════════════════════════════════════════════════════════════════ */

/* ── Sidebar 🐞 button — same glass-tile chassis as the bell ──── */
.kc-bugrep-btn {
  width: 30px;
  height: 30px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 8px;
  color: var(--text-mid);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s;
  font-family: inherit;
  flex-shrink: 0;
  padding: 0;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
}
.kc-bugrep-btn:hover,
.kc-bugrep-btn:focus-visible {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 45%, transparent);
  color: var(--accent, #d4a335);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent, #d4a335) 12%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent, #d4a335) 22%, transparent);
  outline: none;
}
.kc-bugrep-btn svg { display: block; }

/* ── Panel overlay + slide-in (mirrors .ka-panel sizing) ──────── */
.kbr-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.kbr-panel-overlay:not([hidden]) { display: block; }
.kbr-panel {
  position: fixed;
  top: 0;
  right: 0;
  /* Compensate for body `zoom: var(--kc-font-scale)` (Appearance text-size
     slider). Without dividing, viewport-relative units stay at the unzoomed
     viewport size while the body scales up — so a 110% font-size pushes
     the bottom 10% of the panel off-screen, clipping the footer. Same
     pattern .ka-panel uses. */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  /* Clip the outer panel so flex children share the height budget;
     scrolling lives on .kbr-body which has its own overflow-y: auto.
     Without this, when the form grows past the panel height, the
     footer ends up clipped below the viewport edge — same bug the
     .ka-panel comment calls out. */
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.kbr-panel-overlay.show .kbr-panel { transform: translateX(0); }
.kbr-panel.kbr-drag-over {
  outline: 2px dashed color-mix(in srgb, var(--accent, #d4a335) 60%, transparent);
  outline-offset: -8px;
}

/* ── Head ─────────────────────────────────────────────────────── */
.kbr-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.kbr-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
}
.kbr-panel-title .kbr-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.kbr-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.kbr-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.kbr-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
}
.kbr-panel-close:hover { color: var(--text-bright); background: rgba(255,255,255,0.04); }

/* ── Meta line ────────────────────────────────────────────────── */
.kbr-meta {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.kbr-meta-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent, #d4a335);
  opacity: 0.8;
}

/* ── Body (scrollable) ────────────────────────────────────────── */
.kbr-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  /* Smooth wheel scrolling on the panel without bleeding to body */
  overscroll-behavior: contain;
}

/* ── Field row ────────────────────────────────────────────────── */
.kbr-field { margin-bottom: 16px; }
.kbr-field:last-child { margin-bottom: 4px; }
.kbr-label {
  display: block;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 600;
}
.kbr-label .kbr-req {
  color: var(--accent, #d4a335);
  margin-left: 2px;
}
.kbr-label .kbr-opt {
  color: var(--muted);
  letter-spacing: 0.6px;
  text-transform: none;
  font-size: 9px;
  font-weight: 400;
  margin-left: 4px;
  opacity: 0.7;
}

/* ── Type pills ───────────────────────────────────────────────── */
.kbr-pills {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.kbr-pill {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 11px;
  color: var(--text-mid);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.kbr-pill:hover { color: var(--text-bright); border-color: var(--text-mid); }
.kbr-pill.active {
  border-color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
  color: var(--accent, #d4a335);
}

/* ── Inputs / textareas / selects ─────────────────────────────── */
.kbr-input,
.kbr-select,
.kbr-textarea {
  width: 100%;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 9px 11px;
  color: var(--text-bright);
  font-family: inherit;
  font-size: 12px;
  line-height: 1.5;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.kbr-input:focus,
.kbr-select:focus,
.kbr-textarea:focus {
  outline: none;
  border-color: var(--accent, #d4a335);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
}
.kbr-textarea {
  resize: vertical;
  min-height: 70px;
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kbr-counter {
  font-size: 9px;
  letter-spacing: 0.6px;
  color: var(--muted);
  text-align: right;
  margin-top: 4px;
  opacity: 0.7;
}
.kbr-hint {
  font-size: 10px;
  color: var(--muted);
  margin-top: 6px;
  line-height: 1.4;
}

/* ── Screenshot row ───────────────────────────────────────────── */
.kbr-shot-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: stretch;
}
.kbr-shot-thumb {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border2);
  background: var(--page-bg, #0a0a13);
  flex-shrink: 0;
}
.kbr-shot-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.kbr-shot-x {
  position: absolute;
  top: 3px; right: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: rgba(0,0,0,0.7);
  color: #fff;
  border: none;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.kbr-shot-x:hover { background: var(--red, #ef4444); }
.kbr-shot-add {
  width: 72px;
  height: 72px;
  background: var(--page-bg, #0a0a13);
  border: 1px dashed var(--border2);
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 0;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  flex-shrink: 0;
}
.kbr-shot-add > span:first-child { font-size: 18px; line-height: 1; }
.kbr-shot-add-text {
  font-size: 9px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
.kbr-shot-add:hover:not(:disabled) {
  border-color: var(--accent, #d4a335);
  color: var(--accent, #d4a335);
}
.kbr-shot-add:disabled { cursor: not-allowed; }

/* ── Diagnostics card ─────────────────────────────────────────── */
.kbr-diag {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 10px 12px;
}
.kbr-diag-row {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 12px;
  color: var(--text-bright);
  user-select: none;
}
.kbr-diag-check {
  width: 14px; height: 14px;
  margin: 0;
  accent-color: var(--accent, #d4a335);
  cursor: pointer;
  flex-shrink: 0;
}
.kbr-diag-text { line-height: 1; }
.kbr-diag-list {
  margin-top: 8px;
  padding-left: 22px;
  font-size: 10px;
  color: var(--muted);
  line-height: 1.6;
}
.kbr-diag-list ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.kbr-diag-list li {
  padding: 1px 0;
  word-break: break-all;
}
.kbr-diag-redacted {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border2);
  font-size: 10px;
  color: var(--muted);
  font-style: italic;
  opacity: 0.85;
}

/* ── Footer ──────────────────────────────────────────────────── */
.kbr-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding: 12px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--card);
}
.kbr-note {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.5;
}
.kbr-note strong { color: var(--text-mid); font-weight: 600; }
.kbr-actions {
  display: flex;
  gap: 8px;
}
.kbr-btn {
  flex: 1;
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-mid);
  padding: 8px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 4px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.kbr-btn:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.kbr-btn.primary {
  background: var(--accent, #d4a335);
  border-color: var(--accent, #d4a335);
  color: #0a0a0f;
}
.kbr-btn.primary:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
}

/* ── Mobile ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .kbr-panel { width: 100vw; max-width: 100vw; }
  .kbr-body { padding: 14px 16px; }
  .kbr-panel-head { padding: 14px 16px 12px; }
  .kbr-meta { padding: 9px 16px; }
  .kbr-footer { padding: 10px 16px 14px; }
}

/* ── Reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .kbr-panel { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   RAZORS · sidebar-foot balance pill + slide-in drawer (Razor Alpha)
   ───────────────────────────────────────────────────────────────────
   Pill lives at the top of .kc-sb-foot (rendered statically inside
   renderNav()). Drawer mirrors the .kbr-panel chassis so font-scale
   / overflow behaviour is identical to Razor AI and bug-report. The
   brass --accent runs the show; oxblood stays reserved for paid-API
   badges and ledger-spend rows specifically.
   ═════════════════════════════════════════════════════════════════ */

/* ─── Sidebar pill (expanded sidebar) ──────────────────────────── */
.kc-sb-razors {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px 9px 9px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent, #d4a335) 8%, transparent),
    color-mix(in srgb, var(--accent, #d4a335) 2%, transparent));
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 18%, transparent);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.06s, box-shadow 0.15s;
  text-align: left;
  font-family: inherit;
  color: inherit;
  width: 100%;
  position: relative;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
}
.kc-sb-razors:hover,
.kc-sb-razors:focus-visible {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 38%, transparent);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent, #d4a335) 12%, transparent),
    color-mix(in srgb, var(--accent, #d4a335) 4%, transparent));
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 0 12px color-mix(in srgb, var(--accent, #d4a335) 16%, transparent);
}
.kc-sb-razors:active { transform: translateY(1px); }
.kc-sb-razors.is-zero {
  /* Slightly muted look at zero balance — still tappable, less brass-loud */
  border-color: var(--border2);
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
}
.kc-sb-razors.is-low:not(.is-zero) {
  border-color: color-mix(in srgb, var(--yellow, #ffd166) 35%, transparent);
}

.kc-sb-razors-glyph {
  width: 26px; height: 26px;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent, #d4a335) 16%, transparent),
    color-mix(in srgb, var(--accent, #d4a335) 5%, transparent));
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 32%, transparent);
  border-radius: 6px;
  color: var(--accent, #d4a335);
}
.kc-sb-razors.is-zero .kc-sb-razors-glyph {
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border-color: var(--border2);
  color: var(--muted);
}

.kc-sb-razors-info {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.kc-sb-razors-amount {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 13px; font-weight: 700;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kc-sb-razors-amount .unit {
  font-size: 9px; letter-spacing: 1.4px;
  color: var(--muted); font-weight: 400;
  margin-left: 4px;
  text-transform: uppercase;
}
.kc-sb-razors-sub {
  font-size: 10px;
  color: var(--muted);
  font-feature-settings: 'tnum';
  letter-spacing: 0.2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kc-sb-razors-chev {
  color: var(--muted);
  font-size: 14px;
  flex-shrink: 0;
  line-height: 1;
  transition: color 0.15s, transform 0.15s;
}
.kc-sb-razors:hover .kc-sb-razors-chev {
  color: var(--accent, #d4a335);
  transform: translateX(1px);
}

/* Compact-number pip — visible only when sidebar is collapsed (56px),
   sits as a tiny badge at the bottom-right of the glyph tile. Hidden
   in expanded mode where the full amount is already visible. */
.kc-sb-razors-pip {
  position: absolute;
  bottom: -2px; right: -2px;
  background: var(--page-bg, #0a0a13);
  color: var(--accent, #d4a335);
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 35%, transparent);
  border-radius: 999px;
  font-family: 'Space Mono', monospace;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.2px;
  padding: 1px 4px;
  line-height: 1;
  font-feature-settings: 'tnum';
  display: none;
  pointer-events: none;
}

/* Collapsed sidebar — pill compresses to a 30×30 glyph tile that
   matches the sibling icon buttons (.kc-bugrep-btn, .kc-inbox-btn,
   .kc-theme-btn). The amount + sub + chev are hidden; the pip
   shows the abbreviated count instead. */
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors {
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent, #d4a335) 12%, rgba(255,255,255,0.05)),
    rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent, #d4a335) 22%, transparent);
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors-glyph {
  width: 22px; height: 22px;
  background: transparent;
  border: none;
  color: var(--text-mid);
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors:hover .kc-sb-razors-glyph {
  color: var(--accent, #d4a335);
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors-info,
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors-chev {
  display: none;
}
.kc-sidebar:not(.kc-sb-peek):not(.kc-sb-locked) .kc-sb-razors-pip {
  display: inline-block;
}

/* ─── Drawer overlay + slide-in ────────────────────────────────── */
.krz-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.krz-panel-overlay:not([hidden]) { display: block; }
.krz-panel {
  position: fixed;
  top: 0; right: 0;
  /* Compensate for body `zoom: var(--kc-font-scale)` — same trick as
     .kbr-panel and .ka-panel. */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.krz-panel-overlay.show .krz-panel { transform: translateX(0); }

/* ── Head / meta ──────────────────────────────────────────────── */
.krz-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.krz-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
}
.krz-panel-title .krz-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.krz-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.krz-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.krz-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
}
.krz-panel-close:hover { color: var(--text-bright); background: rgba(255,255,255,0.04); }

.krz-meta {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
  display: flex; align-items: center; gap: 6px;
}
.krz-meta-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent, #d4a335);
  opacity: 0.8;
}
.krz-meta b { color: var(--text-mid); font-weight: 600; }

/* ── Body (scrollable) ────────────────────────────────────────── */
.krz-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px 24px;
  overscroll-behavior: contain;
}

/* ── Hero balance card ────────────────────────────────────────── */
.krz-hero {
  background:
    radial-gradient(circle at top right, color-mix(in srgb, var(--accent, #d4a335) 14%, transparent) 0%, transparent 60%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent, #d4a335) 6%, transparent),
      color-mix(in srgb, var(--accent, #d4a335) 1%, transparent));
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 25%, transparent);
  border-radius: 8px;
  padding: 18px 18px 16px;
  margin-bottom: 16px;
  position: relative;
  overflow: hidden;
}
.krz-hero-label {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--accent, #d4a335);
  font-weight: 600;
  margin-bottom: 4px;
}
.krz-hero-amount {
  font-family: 'Space Mono', monospace;
  font-size: 30px;
  font-weight: 700;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  line-height: 1.1;
  margin-bottom: 2px;
}
.krz-hero-amount .unit {
  font-size: 13px; letter-spacing: 1.6px;
  color: var(--muted); font-weight: 400;
  text-transform: uppercase;
  margin-left: 6px;
}
.krz-hero-usd {
  font-size: 11px;
  color: var(--text-mid);
  font-feature-settings: 'tnum';
  margin-bottom: 14px;
}
.krz-hero-usd b { color: var(--text-bright); font-weight: 600; }
.krz-hero-actions {
  display: flex; gap: 8px;
  flex-wrap: wrap;
}

/* ── Buttons (mirror .kbr-btn) ────────────────────────────────── */
.krz-btn {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-mid);
  padding: 8px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 4px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.krz-btn:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.krz-btn.primary {
  background: var(--accent, #d4a335);
  border-color: var(--accent, #d4a335);
  color: #0a0a0f;
}
.krz-btn.primary:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
}

/* ── Section heads + window seg ──────────────────────────────── */
.krz-section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 18px 0 10px;
  gap: 10px;
}
.krz-section-head:first-child { margin-top: 0; }
.krz-section-title {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.krz-section-title b {
  color: var(--text-bright);
  font-weight: 700;
}

.krz-seg {
  display: inline-flex;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  overflow: hidden;
  flex-shrink: 0;
}
.krz-seg button {
  background: transparent;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.4px;
  padding: 4px 10px;
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.krz-seg button.active {
  color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
}
.krz-seg button:not(.active):hover { color: var(--text-bright); }

/* ── 3-up stat cards ──────────────────────────────────────────── */
.krz-stats {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
}
.krz-stat {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 10px 12px;
}
.krz-stat-label {
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.krz-stat-val {
  font-family: 'Space Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  line-height: 1.1;
}
.krz-stat-sub {
  font-size: 9px;
  color: var(--muted);
  margin-top: 2px;
  font-feature-settings: 'tnum';
}

/* ── Spending breakdown ──────────────────────────────────────── */
.krz-breakdown {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 12px 14px;
}
.krz-breakdown-empty {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.5;
  text-align: center;
  padding: 4px 0;
}
.krz-bar {
  height: 8px;
  width: 100%;
  background: rgba(255,255,255,0.04);
  border-radius: 4px;
  display: flex;
  overflow: hidden;
  margin-bottom: 12px;
}
.krz-bar-seg.ai      { background: var(--accent, #d4a335); }
.krz-bar-seg.tw      { background: var(--accent2, #00d4aa); }
.krz-bar-seg.scanner { background: #8b5cf6; }
.krz-bar-seg.other   { background: var(--muted); }
.krz-bar-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.krz-legend-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px;
  color: var(--text-mid);
}
.krz-legend-dot {
  width: 8px; height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
}
.krz-legend-dot.ai      { background: var(--accent, #d4a335); }
.krz-legend-dot.tw      { background: var(--accent2, #00d4aa); }
.krz-legend-dot.scanner { background: #8b5cf6; }
.krz-legend-dot.other   { background: var(--muted); }
.krz-legend-name { flex: 1; }
.krz-legend-name .ic {
  display: inline-block;
  width: 12px; text-align: center;
  color: var(--oxblood, #a83232);
  font-size: 9px;
  margin-left: 2px;
}
.krz-legend-amt {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  font-weight: 600;
}
.krz-legend-pct {
  font-size: 10px;
  color: var(--muted);
  font-feature-settings: 'tnum';
  min-width: 36px;
  text-align: right;
}

/* ── Activity ledger list ────────────────────────────────────── */
.krz-activity {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 6px;
  overflow: hidden;
}
.krz-act-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
}
.krz-act-row:last-child { border-bottom: none; }
.krz-act-icon {
  width: 22px; height: 22px;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  font-family: 'Space Mono', monospace;
}
.krz-act-icon.deposit { background: color-mix(in srgb, var(--green, #1fd687) 14%, transparent); color: var(--green, #1fd687); }
.krz-act-icon.spend   { background: color-mix(in srgb, var(--oxblood, #a83232) 18%, transparent); color: var(--oxblood, #a83232); }
.krz-act-icon.bonus   { background: color-mix(in srgb, var(--accent, #d4a335) 18%, transparent); color: var(--accent, #d4a335); }
.krz-act-info {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
}
.krz-act-label {
  color: var(--text-bright);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.krz-act-meta {
  font-size: 10px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
}
.krz-act-amt {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  font-feature-settings: 'tnum';
  flex-shrink: 0;
}
.krz-act-amt.pos { color: var(--green, #1fd687); }
.krz-act-amt.neg { color: var(--oxblood, #a83232); }
.krz-act-empty {
  padding: 18px;
  text-align: center;
  font-size: 11px;
  color: var(--muted);
}
.krz-act-foot {
  padding: 8px 12px;
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.4px;
  border-top: 1px solid var(--border);
}
.krz-act-foot a { color: var(--accent, #d4a335); text-decoration: none; cursor: pointer; }
.krz-act-foot a:hover { text-decoration: underline; }

/* Pager variant of .krz-act-foot — used when the ledger has more than
   ACTIVITY_PAGE_SIZE entries. Lays out Prev · "Page N of M" · Next in
   one row. Buttons take the muted bordered look that matches the rest
   of the wallet drawer; the page-number readout is a quiet inline label. */
.krz-act-foot.krz-act-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
}
.krz-act-pgbtn {
  background: transparent;
  border: 1px solid var(--border, rgba(212,163,53,0.18));
  color: var(--text-2, #c9c5b8);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 3px;
  cursor: pointer;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.krz-act-pgbtn:hover:not([disabled]) {
  border-color: var(--accent, #d4a335);
  color: var(--accent, #d4a335);
}
.krz-act-pgbtn[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}
.krz-act-pgnum {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.4px;
  color: var(--muted, #8a8578);
}
.krz-act-pgnum b {
  color: var(--text, #e8e6df);
  font-weight: 600;
}

/* ── Top-up section ──────────────────────────────────────────── */
.krz-deposit {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 14px;
}
.krz-deposit-rate {
  font-size: 10px;
  letter-spacing: 0.4px;
  color: var(--muted);
  text-align: right;
}
.krz-deposit-rate b { color: var(--accent, #d4a335); font-weight: 600; }

.krz-packs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin-bottom: 12px;
}
.krz-pack {
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 9px 6px 8px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  font-family: inherit;
  color: inherit;
  position: relative;
}
.krz-pack:hover { border-color: var(--text-mid); }
.krz-pack.active {
  border-color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 8%, transparent);
}
.krz-pack-usd {
  font-family: 'Space Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  line-height: 1.1;
  margin-bottom: 2px;
}
.krz-pack-razors {
  font-size: 9px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-feature-settings: 'tnum';
  letter-spacing: 0.2px;
}
.krz-pack.active .krz-pack-razors { color: var(--accent, #d4a335); }
.krz-pack-tag {
  position: absolute;
  top: -8px; right: 5px;
  background: var(--accent, #d4a335);
  color: var(--bg, #0b0a09);
  font-size: 8px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 3px;
  font-family: 'Space Mono', monospace;
}

.krz-custom {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 12px;
}
.krz-custom-label {
  font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  flex-shrink: 0;
}
.krz-custom-input-wrap {
  position: relative; flex: 1;
}
.krz-custom-input {
  width: 100%;
  background: var(--bg, #0a0a0f);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 7px 10px 7px 22px;
  color: var(--text-bright);
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-feature-settings: 'tnum';
  box-sizing: border-box;
}
.krz-custom-input:focus {
  outline: none;
  border-color: var(--accent, #d4a335);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
}
/* Hide the spinner — looks cleaner with our custom prefix */
.krz-custom-input::-webkit-outer-spin-button,
.krz-custom-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.krz-custom-input { -moz-appearance: textfield; }
.krz-custom-prefix {
  position: absolute;
  left: 9px; top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  pointer-events: none;
}
.krz-custom-out {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-mid);
  font-feature-settings: 'tnum';
  flex-shrink: 0;
  min-width: 86px;
  text-align: right;
}
.krz-custom-out b { color: var(--accent, #d4a335); font-weight: 700; }

.krz-checkout {
  display: flex; flex-direction: column; gap: 8px;
}
.krz-checkout-btn {
  background: var(--accent, #d4a335);
  border: 1px solid var(--accent, #d4a335);
  color: #0a0a0f;
  padding: 11px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 4px;
  cursor: pointer;
  width: 100%;
  transition: filter 0.15s ease, transform 0.15s ease;
}
.krz-checkout-btn:hover  { filter: brightness(1.1); }
.krz-checkout-btn:active { transform: translateY(1px); }
.krz-checkout-btn:disabled,
.krz-checkout-btn[disabled] {
  cursor: not-allowed;
  opacity: 0.6;
  filter: none;
}
.krz-checkout-note {
  font-size: 10px;
  color: var(--muted);
  text-align: center;
  line-height: 1.5;
}
.krz-checkout-note b { color: var(--yellow, #ffd166); font-weight: 600; }

/* ── Pending purchase state ──────────────────────────────────── */
.krz-pending-wrap {
  display: flex; flex-direction: column; gap: 10px;
}
.krz-pending-box {
  background: rgba(212, 163, 53, 0.05);
  border: 1px solid rgba(212, 163, 53, 0.3);
  border-radius: 6px;
  padding: 12px 14px;
}
.krz-pending-head {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  margin-bottom: 6px;
}
.krz-pending-title {
  font-size: 11px;
  color: var(--text, #e8e3d6);
}
.krz-pending-title .krz-mono { color: var(--accent, #d4a335); font-weight: 600; }
.krz-pending-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 99px;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  background: rgba(212, 163, 53, 0.12);
  color: var(--accent, #d4a335);
  border: 1px solid rgba(212, 163, 53, 0.35);
  font-family: 'Space Mono', monospace;
}
.krz-pending-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent, #d4a335);
  animation: krzPulse 1.2s ease-in-out infinite;
}
@keyframes krzPulse {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}
.krz-pending-meta {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: 8px;
}
.krz-pending-meta b { color: var(--text, #e8e3d6); font-weight: 600; }
.krz-pending-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.krz-pending-steps li {
  font-size: 10px;
  padding: 4px 0 4px 12px;
  margin-left: 2px;
  border-left: 2px solid var(--border);
  color: var(--muted);
  position: relative;
}
.krz-pending-steps li.done {
  color: var(--green, #7dc188);
  border-left-color: var(--green, #7dc188);
}
.krz-pending-steps li.done::before  { content: '✓ '; }
.krz-pending-steps li.active {
  color: var(--accent, #d4a335);
  border-left-color: var(--accent, #d4a335);
}
.krz-pending-steps li.active::before     { content: '→ '; }
.krz-pending-steps li.pending-step       { color: var(--muted-2, #5a5446); }
.krz-pending-steps li.pending-step::before { content: '○ '; }
.krz-pending-actions {
  display: flex; gap: 6px;
}
.krz-pending-actions > * { flex: 1; }
.krz-pending-ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.krz-pending-ghost:hover {
  color: var(--text, #e8e3d6);
  border-color: var(--text-mid, #888);
}
.krz-mono {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--accent, #d4a335);
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* ── Success purchase state ──────────────────────────────────── */
.krz-success-box {
  background: rgba(80, 160, 90, 0.06);
  border: 1px solid rgba(125, 193, 136, 0.3);
  border-radius: 6px;
  padding: 14px 16px;
  text-align: center;
}
.krz-success-pill {
  display: inline-flex;
  padding: 4px 10px;
  border-radius: 99px;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  background: rgba(80, 160, 90, 0.12);
  color: var(--green, #7dc188);
  border: 1px solid rgba(125, 193, 136, 0.35);
  font-family: 'Space Mono', monospace;
  margin-bottom: 6px;
}
.krz-success-num {
  font-size: 22px;
  color: var(--green, #7dc188);
  font-weight: 700;
  margin: 4px 0;
  font-family: 'Space Mono', monospace;
}
.krz-success-sub {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.6;
}
.krz-success-sub b { color: var(--text, #e8e3d6); font-weight: 600; }

/* ── Failed/expired/cancelled purchase state ─────────────────── */
.krz-fail-box {
  background: rgba(168, 50, 50, 0.06);
  border: 1px solid rgba(212, 120, 122, 0.3);
  border-radius: 6px;
  padding: 12px 14px;
}
.krz-fail-head {
  font-size: 11px;
  color: var(--oxblood-text, #d4787a);
  font-weight: 600;
  margin-bottom: 6px;
  font-family: 'Space Mono', monospace;
}
.krz-fail-meta {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.6;
}
.krz-fail-meta b { color: var(--text, #e8e3d6); font-weight: 600; }

/* ── Activity row: order-status icon variants ────────────────── */
.krz-act-icon.pending {
  background: rgba(212, 163, 53, 0.12);
  color: var(--accent, #d4a335);
  border: 1px solid rgba(212, 163, 53, 0.35);
}
.krz-act-icon.fail {
  background: rgba(168, 50, 50, 0.10);
  color: var(--oxblood-text, #d4787a);
  border: 1px solid rgba(212, 120, 122, 0.35);
}
.krz-act-amt.muted { color: var(--muted); }

/* ── Reduced motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .krz-pending-dot { animation: none; opacity: 0.7; }
  .krz-checkout-btn { transition: none; }
}

/* ── Footer note ─────────────────────────────────────────────── */
.krz-footnote {
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 10px;
  color: var(--muted);
  line-height: 1.55;
}
.krz-footnote b { color: var(--text-mid); font-weight: 600; }

/* ── Mobile ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .krz-panel { width: 100vw; max-width: 100vw; }
  .krz-body { padding: 14px 16px 22px; }
  .krz-panel-head { padding: 14px 16px 12px; }
  .krz-meta { padding: 9px 16px; }
}

/* ── Reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .krz-panel { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   API SETTINGS DRAWER (Razor Alpha) — slide-in from right
   ───────────────────────────────────────────────────────────────────
   Mirrors the .kbr-panel chassis (480px desktop, full-width mobile,
   ESC + outside-click close). Used by the platform-wide #settingsGear
   button. The dashboard's domain modals (Score Targets / X-Sync /
   Macro Goals) intentionally keep the centered .settings-overlay /
   .settings-modal chassis — those are wider data-entry dialogs, not
   account/API config.
   ═══════════════════════════════════════════════════════════════════ */
.kc-settings-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.kc-settings-panel-overlay.show,
.kc-settings-panel-overlay:not([hidden]).show { display: block; }

.kc-settings-panel {
  position: fixed;
  top: 0;
  right: 0;
  /* Compensate for body `zoom: var(--kc-font-scale)` — same trick the
     .kbr-panel and .ka-panel chassis use. Without this, viewport-relative
     units stay at the unzoomed viewport size while the body scales up,
     and the bottom of the panel slides off-screen at scale > 1. */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  /* Clip the outer panel so flex children share the height budget;
     scrolling lives on .kc-settings-body which has its own overflow-y. */
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.kc-settings-panel-overlay.show .kc-settings-panel { transform: translateX(0); }

/* Mobile: the settings panel goes edge-to-edge and uses the dynamic
   viewport minus the safe area, so its scrolling body + admin section
   clear Safari's collapsing toolbar instead of sliding off-screen. */
@media (max-width: 640px) {
  .kc-settings-panel {
    width: 100vw;
    max-width: 100vw;
    border-left: 0;
    height: calc(100vh / var(--kc-font-scale, 1));
    height: calc((100dvh - var(--kc-safe-b)) / var(--kc-font-scale, 1));
  }
  .kc-settings-body { padding-bottom: calc(18px + var(--kc-safe-b)); }
}

.kc-settings-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.kc-settings-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: var(--w-bold, 600);
  color: var(--text-bright, var(--text));
  min-width: 0;
}
.kc-settings-panel-title .kc-settings-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.kc-settings-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.kc-settings-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
}
.kc-settings-panel-close:hover {
  color: var(--text-bright, var(--text));
  background: rgba(255,255,255,0.04);
}

.kc-settings-meta {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
}

.kc-settings-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
}
.kc-settings-body .settings-section { margin-bottom: 18px; }
.kc-settings-body .settings-section:last-child { margin-bottom: 0; }
.kc-settings-body .settings-section + .settings-section {
  padding-top: 18px;
  border-top: 1px solid var(--border);
}

/* ══════════════════════════════════════════════════════════════════
   ACCOUNT SECTION — top of the Settings drawer
   Razor Alpha auth: email, handle, razors balance, log out.
   Brass --accent runs the show; oxblood reserved for sign-out danger.
   ══════════════════════════════════════════════════════════════════ */

.kc-acc-section-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: var(--w-medium);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-bright);
  margin-bottom: 12px;
}
.kc-acc-section-label::before {
  content: '';
  width: 3px;
  height: 12px;
  background: var(--accent, #d4a335);
  border-radius: 1px;
}

.kc-acc-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 5px;
  margin-bottom: 8px;
  min-height: 40px;
}
.kc-acc-row-l {
  color: var(--muted);
  font-size: 11px;
  font-family: var(--font-mono, 'Space Mono', monospace);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.kc-acc-row-r {
  color: var(--text-bright);
  font-size: 13px;
  font-family: var(--font-mono, 'Space Mono', monospace);
  word-break: break-all;
  text-align: right;
}

.kc-acc-handle-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  justify-content: flex-end;
}

.kc-acc-edit-btn {
  color: var(--accent, #d4a335);
  font-size: 11px;
  font-family: inherit;
  padding: 3px 9px;
  background: color-mix(in srgb, var(--accent, #d4a335) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s;
}
.kc-acc-edit-btn:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 45%, transparent);
}

.kc-acc-handle-input {
  background: var(--bg);
  border: 1px solid var(--accent, #d4a335);
  color: var(--text-bright);
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 13px;
  padding: 4px 8px;
  border-radius: 3px;
  outline: none;
  width: 180px;
  text-align: right;
  letter-spacing: 0.3px;
}
.kc-acc-handle-input:focus {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #d4a335) 18%, transparent);
}
.kc-acc-handle-actions {
  display: flex;
  gap: 4px;
  margin-left: 6px;
}
.kc-acc-handle-actions button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-mid);
  font-family: var(--font-mono, 'Space Mono', monospace);
  font-size: 10px;
  padding: 3px 7px;
  border-radius: 3px;
  cursor: pointer;
}
.kc-acc-handle-actions button.primary {
  color: var(--accent, #d4a335);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
}
.kc-acc-handle-actions button:hover { color: var(--text-bright); }

.kc-acc-balance {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 14px;
  background: color-mix(in srgb, var(--accent, #d4a335) 5%, var(--card2));
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 22%, transparent);
  border-radius: 5px;
  margin: 8px 0 0;
}
.kc-acc-balance-l {
  color: var(--accent, #d4a335);
  font-size: 11px;
  font-family: var(--font-mono, 'Space Mono', monospace);
  letter-spacing: 1px;
  text-transform: uppercase;
}
.kc-acc-balance-num {
  color: var(--accent, #d4a335);
  font-size: 22px;
  font-weight: var(--w-bold);
  font-family: var(--font-mono, 'Space Mono', monospace);
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.kc-acc-balance-num small {
  font-size: 10px;
  font-weight: var(--w-regular);
  color: var(--muted);
  letter-spacing: 1px;
  text-transform: uppercase;
}
.kc-acc-balance.loading .kc-acc-balance-num { opacity: 0.55; }

.kc-acc-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}
.kc-acc-btn {
  flex: 1;
  font-size: 11px;
  padding: 9px 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.kc-acc-btn .kc-ic { font-size: 12px; }

.kc-acc-hint {
  font-size: 10px;
  color: var(--text-faint, var(--muted));
  line-height: 1.55;
  margin-top: 12px;
}

.kc-acc-status {
  margin-top: 8px;
  font-size: 11px;
}
.kc-acc-status.ok    { color: var(--accent, #d4a335); }
.kc-acc-status.error { color: #e88c8c; }

@media (max-width: 480px) {
  .kc-acc-balance-num { font-size: 18px; }
  .kc-acc-row-r { font-size: 12px; }
  .kc-acc-handle-input { width: 130px; }
}

/* Belt-and-suspenders: hard-hide the legacy welcome wizard if anything
   still injects it into the DOM. The JS killer in shared.js removes
   the node entirely; this rule covers the brief instant before removal
   and also any cached copy that bypasses the JS pathway. */
#kcSetupOverlay,
.kc-setup-overlay {
  display: none !important;
}

/* ── Right-size .settings-* content inside the drawer ─────────────
   The legacy .settings-* classes (label/input/helper/btn/warning) were
   authored for the wider centered .settings-modal chassis (520px max,
   chunkier scale). Inside this 480px slide-in drawer they read 1-2px
   bigger than the equivalent .ka-* content in Razor AI — visibly so
   once Appearance font-scale is cranked up. These overrides only fire
   when the classes are nested inside .kc-settings-panel, so the three
   dashboard modals (Score Targets / X-Sync / Macro Goals) and any
   page that still uses .settings-modal stay untouched. */
.kc-settings-panel .settings-label {
  font-size: 10px;
  letter-spacing: 1px;
  margin-bottom: 6px;
}
.kc-settings-panel .settings-input {
  font-size: 12px;
  padding: 8px 12px;
}
.kc-settings-panel .settings-helper {
  font-size: 12px;
  line-height: 1.5;
  margin-top: 6px;
}
.kc-settings-panel .settings-row {
  gap: 6px;
  margin-top: 10px;
}
.kc-settings-panel .settings-btn {
  font-size: 10px;
  padding: 7px 11px;
  letter-spacing: 0.8px;
}
.kc-settings-panel .settings-status {
  font-size: 10px;
  padding: 7px 10px;
  margin-top: 8px;
}
.kc-settings-panel .settings-warning {
  font-size: 12px;
  line-height: 1.55;
  padding: 10px 12px;
}

/* ── Mobile ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .kc-settings-panel { width: 100vw; max-width: 100vw; }
  .kc-settings-body { padding: 14px 16px; }
  .kc-settings-panel-head { padding: 14px 16px 12px; }
  .kc-settings-meta { padding: 9px 16px; }
}

/* ── Reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .kc-settings-panel { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   MOTION PREFERENCE — user-facing animation gating
   ───────────────────────────────────────────────────────────────────
   One attribute on <html> scopes two override blocks that throttle
   animation. Future-proof by construction — no per-animation maintenance:
     • data-motion="off"     → EVERY animation (current + future) snaps to
                               its end state once and stops.
     • data-motion="reduced" → same, EXCEPT elements tagged .kc-fx-keep,
                               whose animation is preserved. Tag only the
                               semantic cues you want to survive Reduced
                               (e.g. a "new" blink, scan-progress shimmer,
                               trade-trigger pulse). Everything else, incl.
                               anything added later, is throttled by default.
   We use near-zero duration + iteration 1 (NOT animation:none) so that
   `forwards` entrance animations still land on their final/visible state
   rather than vanishing. CSS transitions are intentionally left intact.
   data-motion absent / "full" == no override; ships exactly as designed.
   ═══════════════════════════════════════════════════════════════════ */
html[data-motion="off"] *,
html[data-motion="off"] *::before,
html[data-motion="off"] *::after {
  animation-duration: 1ms !important;
  animation-delay: -1ms !important;
  animation-iteration-count: 1 !important;
}
/* Reduced — throttle everything EXCEPT (a) anything tagged .kc-fx-keep
   [the convention for any future animation], and (b) the legacy semantic
   cues below, which pre-date the convention and are exempted by selector
   so they keep running: live "new" blink (.sr-lc-pill::before), scan
   progress shimmer (.hm-progress-bar::after), the Harmonics D-pivot
   trade-trigger pulse (.hv6-pulse-core/ring/ring--late), and spinners
   (a frozen spinner reads as broken; they are transient). OFF still stops
   all of these — Reduced is the only mode that keeps them. */
html[data-motion="reduced"] *:not(.kc-fx-keep):not(.hv6-pulse-core):not(.hv6-pulse-ring):not(.hv6-pulse-ring--late):not(.sc-scan-all-icon):not(.spinner):not(.ra-pp-spinner) {
  animation-duration: 1ms !important;
  animation-delay: -1ms !important;
  animation-iteration-count: 1 !important;
}
html[data-motion="reduced"] *:not(.kc-fx-keep):not(.sr-lc-pill)::before {
  animation-duration: 1ms !important;
  animation-delay: -1ms !important;
  animation-iteration-count: 1 !important;
}
html[data-motion="reduced"] *:not(.kc-fx-keep):not(.hm-progress-bar):not(.kcch-btn--loading)::after {
  animation-duration: 1ms !important;
  animation-delay: -1ms !important;
  animation-iteration-count: 1 !important;
}

/* ── Motion control — settings drawer (variant B: segmented pill + caption) ── */
.kc-motion-seg {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: color-mix(in srgb, var(--text) 4%, transparent);
  margin-top: 8px;
}
.kc-motion-seg button {
  flex: 1;
  appearance: none;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--border);
  color: var(--muted);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 9px 4px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.kc-motion-seg button:last-child { border-right: 0; }
.kc-motion-seg button:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
}
.kc-motion-seg button.is-active {
  background: color-mix(in srgb, var(--brass, #d4a335) 16%, transparent);
  color: var(--brass, #d4a335);
}
.kc-motion-desc {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
  margin-top: 9px;
  min-height: 30px;
}
.kc-motion-desc b { color: var(--text); font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  .kc-motion-seg button { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   ASSISTANT · STAGE 4a — Chat surface
   ───────────────────────────────────────────────────────────────────
   Mounted into .ka-body when the panel opens on the 'chat' surface
   (floating dock ✦). The chat surface has three vertical zones:
   thread (scrollable), context chips strip (hidden when empty),
   composer (fixed bottom). Followups live between thread and
   context — Phase 4c will populate them.

   Tool boxes use option-C collapse: the latest box stays expanded
   to keep the just-generated context visible; the next assistant
   turn auto-collapses earlier boxes (handled in JS by toggling
   .collapsed on all tool boxes before streaming the new turn).
   Click any collapsed box's head to re-expand.
   ═════════════════════════════════════════════════════════════════ */
.ka-body.ka-chat-mode {
  padding: 0;
  gap: 0;
}
.ka-chat-root {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* ── Thread ──────────────────────────────────────────────────── */
.ka-chat-thread {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}

/* Empty state with quick-start chips */
.ka-chat-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: auto 0;
  padding: 24px 12px;
  gap: 12px;
}
.ka-chat-empty-glyph {
  font-size: 28px;
  color: var(--accent2, #b693f5);
  opacity: 0.7;
  line-height: 1;
}
.ka-chat-empty-title {
  font-size: 13px;
  color: var(--muted);
}
.ka-chat-quickstart {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  max-width: 320px;
}
.ka-chat-qs {
  text-align: left;
  font-size: 12px;
  padding: 9px 12px;
  background: var(--card, var(--bg));
  border: 1px solid var(--border2);
  border-radius: 8px;
  color: var(--text-bright, var(--muted));
  cursor: pointer;
  font-family: inherit;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.ka-chat-qs:hover {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
  color: var(--accent2, #b693f5);
}
.ka-chat-empty-hint {
  font-size: 11px;
  color: var(--muted);
  opacity: 0.7;
  margin-top: 6px;
}
.ka-chat-empty-hint code {
  font-family: 'Space Mono', monospace;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 3px;
  padding: 0 4px;
  color: var(--accent2, #b693f5);
}

/* Assistant message can carry text bubble + tool boxes */
.ka-msg.assistant > .ka-msg-bubble + .ka-tool-box,
.ka-msg.assistant > .ka-tool-box + .ka-tool-box,
.ka-msg.assistant > .ka-tool-box + .ka-msg-bubble {
  margin-top: 8px;
}
.ka-msg-bubble.streaming {
  /* While streaming, keep the bubble height stable */
  min-height: 18px;
}
.ka-msg-bubble code {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 3px;
  padding: 0 4px;
  color: var(--accent2, #b693f5);
}
.ka-msg-error {
  color: var(--red, #f0726a);
  font-style: italic;
}

/* ── Tool box ────────────────────────────────────────────────── */
.ka-tool-box {
  border: 1px solid var(--border2);
  border-radius: 8px;
  background: var(--card, var(--bg));
  overflow: hidden;
  transition: border-color 0.15s;
}
.ka-tool-box[data-status="running"] {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 35%, var(--border2));
}
.ka-tool-box[data-status="done"] {
  border-color: color-mix(in srgb, var(--accent, #4dd99a) 25%, var(--border2));
}
.ka-tool-box[data-status="error"] {
  border-color: color-mix(in srgb, var(--red, #f0726a) 35%, var(--border2));
}
.ka-tool-box-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg);
  cursor: pointer;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  user-select: none;
}
.ka-tool-box-head:hover { background: color-mix(in srgb, var(--accent2, #b693f5) 6%, var(--bg)); }
.ka-tool-box-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}
.ka-tool-box[data-status="running"] .ka-tool-box-dot {
  background: var(--accent2, #b693f5);
  animation: kaToolPulse 1.2s ease-in-out infinite;
}
.ka-tool-box[data-status="done"] .ka-tool-box-dot { background: var(--accent, #4dd99a); }
.ka-tool-box[data-status="error"] .ka-tool-box-dot { background: var(--red, #f0726a); }
@keyframes kaToolPulse {
  50% { opacity: 0.4; transform: scale(0.85); }
}
.ka-tool-box-name {
  color: var(--text-bright, var(--muted));
  letter-spacing: 0.2px;
}
.ka-tool-box-args {
  color: var(--accent3, #5dd5e8);
  opacity: 0.85;
  font-size: 10px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ka-tool-box-status {
  font-size: 10px;
  padding: 2px 7px;
  border-radius: 3px;
  background: var(--bg-elev, var(--bg));
  border: 1px solid var(--border2);
  color: var(--muted);
  font-family: inherit;
  flex-shrink: 0;
}
.ka-tool-box[data-status="done"] .ka-tool-box-status {
  border-color: color-mix(in srgb, var(--accent, #4dd99a) 35%, transparent);
  color: var(--accent, #4dd99a);
}
.ka-tool-box[data-status="running"] .ka-tool-box-status {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 40%, transparent);
  color: var(--accent2, #b693f5);
}
.ka-tool-box[data-status="error"] .ka-tool-box-status {
  border-color: color-mix(in srgb, var(--red, #f0726a) 40%, transparent);
  color: var(--red, #f0726a);
}
.ka-tool-box-caret {
  font-size: 10px;
  color: var(--muted);
  flex-shrink: 0;
  transition: transform 0.15s;
}
.ka-tool-box.collapsed .ka-tool-box-caret { transform: rotate(-90deg); }
.ka-tool-box-body {
  padding: 12px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-bright, var(--muted));
  max-height: 600px;
  overflow-y: auto;
  transition: max-height 0.18s ease-out;
}
.ka-tool-box.collapsed .ka-tool-box-body {
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  overflow: hidden;
}
.ka-tool-running {
  display: flex;
  gap: 4px;
  padding: 4px 0;
}
.ka-tool-running-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent2, #b693f5);
  animation: kaToolDot 1.2s ease-in-out infinite;
  opacity: 0.4;
}
.ka-tool-running-dot:nth-child(2) { animation-delay: 0.2s; }
.ka-tool-running-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes kaToolDot {
  50% { opacity: 1; transform: translateY(-2px); }
}
.ka-tool-error {
  color: var(--red, #f0726a);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  white-space: pre-wrap;
  word-break: break-word;
}
.ka-tool-json {
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  overflow-x: auto;
  margin: 0;
  max-height: 240px;
  overflow-y: auto;
}
.ka-tool-empty {
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}

/* ── Snapshot tool cards (option B · 2026-10-08) ────────────────
   Built by KC.assistant.tools.snapCard(spec) for every read-only data
   tool (radar, screeners, confluence, dashboard, floor). Rows reuse the
   .ka-tool-result-* rules below. Up/down use the theme-independent
   price tokens so a gain never renders brass on the Razor theme. */
.ka-snap { display: flex; flex-direction: column; gap: 8px; }
.ka-snap-verdict {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 9%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border2));
}
.ka-snap-verdict b {
  font-family: 'Space Mono', monospace; font-size: 12px; font-weight: 700;
  letter-spacing: 0.6px; color: var(--accent);
}
.ka-snap-verdict span { font-size: 11.5px; color: var(--text-mid, var(--muted)); }
.ka-snap-verdict.up b { color: var(--type-price-up); }
.ka-snap-verdict.dn b { color: var(--type-price-dn); }
.ka-snap-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.ka-snap-strip.n1 { grid-template-columns: minmax(0, 1fr); }
.ka-snap-strip.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ka-snap-strip.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ka-snap-tile {
  min-width: 0; padding: 6px 8px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border2);
}
.ka-snap-tile small {
  display: block; font-family: 'Space Mono', monospace; font-size: 9.5px;
  letter-spacing: 0.6px; text-transform: uppercase; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ka-snap-tile b {
  display: block; font-family: 'Space Mono', monospace; font-size: 13px; font-weight: 700;
  color: var(--text-bright, var(--text));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ka-snap-tile b.up, .ka-snap-bar i.up { color: var(--type-price-up); }
.ka-snap-tile b.dn, .ka-snap-bar i.dn { color: var(--type-price-dn); }
.ka-snap-tile b.warn { color: var(--amber, #efb968); }
.ka-snap-tile b.brass { color: var(--accent); }
.ka-snap-sec {
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--muted); margin-top: 2px;
}
.ka-snap-bars {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 4px 10px; align-items: center;
}
.ka-snap-bk, .ka-snap-bv { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--muted); }
.ka-snap-bv { color: var(--text-bright, var(--text)); }
.ka-snap-bar { height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.ka-snap-bar i { display: block; height: 100%; border-radius: 3px; background: var(--accent); }
.ka-snap-bar i.up { background: var(--type-price-up); }
.ka-snap-bar i.dn { background: var(--type-price-dn); }
.ka-snap-bar i.warn { background: var(--amber, #efb968); }
.ka-snap-why { font-size: 11px; color: var(--text-mid, var(--muted)); }
.ka-snap-fresh { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--muted); }
.ka-snap-fresh.stale { color: var(--amber, #efb968); }
.ka-snap .ka-pill.up    { background: color-mix(in srgb, var(--type-price-up) 16%, transparent); color: var(--type-price-up); }
.ka-snap .ka-pill.down  { background: color-mix(in srgb, var(--type-price-dn) 16%, transparent); color: var(--type-price-dn); }
.ka-snap .ka-pill.brass { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
/* Phone width: four tiles leave ~48px each, which cuts "−$12.40M" short. */
@media (max-width: 420px) {
  .ka-snap-strip.n3, .ka-snap-strip.n4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── tracked.list result card ────────────────────────────────── */
.ka-tool-result-tracked {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ka-tool-result-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
  padding-bottom: 4px;
  border-bottom: 1px dashed var(--border2);
}
.ka-tool-result-count {
  color: var(--text-bright, var(--accent2, #b693f5));
  font-weight: 500;
}
.ka-tool-result-filter {
  color: var(--muted);
  opacity: 0.8;
}
.ka-tool-result-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ka-tool-result-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 6px;
}
.ka-tr-top {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.ka-tr-sym {
  font-weight: 500;
  font-size: 12px;
  color: var(--type-cashtag);
}
.ka-tr-meta {
  font-size: 10px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
}
.ka-tr-prices {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  font-size: 11px;
  color: var(--muted);
}
.ka-tr-prices strong {
  color: var(--text-bright, var(--accent2, #b693f5));
  font-weight: 500;
}

/* ── Followups (Phase 4c will populate) ──────────────────────── */
.ka-chat-followups {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  background: var(--card, var(--bg));
  flex-shrink: 0;
}
.ka-chat-followups[hidden] { display: none; }
.ka-chat-followups-label {
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--muted);
  opacity: 0.7;
  text-transform: uppercase;
  margin-bottom: 2px;
}
.ka-chat-fchip {
  text-align: left;
  font-size: 12px;
  padding: 7px 10px;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
}
.ka-chat-fchip:hover {
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
  color: var(--text-bright, var(--accent2, #b693f5));
}

/* ── Context chips strip ─────────────────────────────────────── */
.ka-chat-context {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  background: var(--card, var(--bg));
  flex-shrink: 0;
}
.ka-chat-context[hidden] { display: none; }
.ka-chat-context-label {
  font-size: 10px;
  letter-spacing: 0.5px;
  color: var(--muted);
  opacity: 0.7;
  text-transform: uppercase;
  margin-right: 4px;
}
.ka-chat-ctx-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  padding: 3px 8px 3px 10px;
  background: color-mix(in srgb, var(--accent, #4dd99a) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent, #4dd99a) 30%, transparent);
  border-radius: 999px;
  color: var(--accent, #4dd99a);
  font-family: inherit;
}
.ka-chat-ctx-x {
  cursor: pointer;
  opacity: 0.6;
  font-size: 12px;
  line-height: 1;
}
.ka-chat-ctx-x:hover { opacity: 1; }

/* ── Composer ────────────────────────────────────────────────── */
.ka-chat-composer {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--card, var(--bg));
}
.ka-chat-input {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 8px;
  padding: 11px 14px;
  color: var(--text-bright, var(--muted));
  font-family: inherit;
  font-size: 13px;
  line-height: 1.45;
  resize: none;
  min-height: 42px;
  max-height: 140px;
  transition: border-color 0.15s;
  overflow-y: auto;
}
.ka-chat-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ka-chat-input::placeholder { color: var(--muted); opacity: 0.55; }
.ka-chat-send {
  background: var(--accent2, #b693f5);
  color: #1a1426;
  border: none;
  width: 42px;
  height: 42px;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: filter 0.15s, opacity 0.15s;
  font-family: inherit;
}
.ka-chat-send:hover:not(:disabled) { filter: brightness(1.1); }
.ka-chat-send:disabled { opacity: 0.4; cursor: not-allowed; }
/* Stop mode (1a) — the send button becomes a Stop control while a turn is
   in flight. Oxblood fill + square glyph signals "cancel". */
.ka-chat-send.ka-chat-send-stop {
  background: var(--ox, #a83232);
  color: #f4ece8;
}
.ka-chat-send.ka-chat-send-stop:hover { filter: brightness(1.12); }

/* ── Attach button + attachments preview (Stage 5d) ───────────── */
.ka-chat-attach {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border2);
  width: 42px;
  height: 42px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  font-family: inherit;
}
.ka-chat-attach:hover {
  background: var(--bg);
  color: var(--text-bright, var(--muted));
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 40%, var(--border2));
}
.ka-chat-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 16px 0;
  background: var(--card, var(--bg));
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.ka-chat-attachment {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 8px;
  border: 1px solid var(--border2);
  overflow: hidden;
  background: var(--bg);
  flex-shrink: 0;
}
.ka-chat-attachment img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ka-chat-attachment-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  border: none;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-family: inherit;
  transition: background 0.15s;
}
.ka-chat-attachment-remove:hover { background: rgba(220, 60, 60, 0.85); }
/* Drag-over state on the composer */
.ka-chat-composer.ka-drag-over {
  background: color-mix(in srgb, var(--accent2, #b693f5) 8%, var(--card, var(--bg)));
  outline: 2px dashed color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
  outline-offset: -4px;
}
/* Image thumbs in user message bubbles */
.ka-msg-images {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
  justify-content: flex-end;
}
.ka-msg-image {
  max-width: 220px;
  max-height: 220px;
  width: auto;
  height: auto;
  border-radius: 8px;
  border: 1px solid var(--border2);
  display: block;
  object-fit: contain;
  background: var(--bg);
}
/* Tombstone for an image whose bytes were stripped from history after the
   turn was sent (keeps history small). Shown on reload in place of the
   thumbnail. */
.ka-msg-image-tomb {
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: var(--muted, #8b8e96);
  border-style: dashed;
  object-fit: unset;
}

/* ── Slash / @ menu (floats above the composer) ───────────────── */
.ka-chat-menu {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 16px;
  right: 16px;
  background: var(--card, var(--bg));
  border: 1px solid var(--border2);
  border-radius: 8px;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  z-index: 5;
  max-height: 240px;
  overflow-y: auto;
}
.ka-chat-menu[hidden] { display: none; }
.ka-chat-menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  cursor: pointer;
  font-size: 12px;
  border-bottom: 1px solid var(--border2);
}
.ka-chat-menu-item:last-child { border-bottom: none; }
.ka-chat-menu-item.active {
  background: color-mix(in srgb, var(--accent2, #b693f5) 10%, transparent);
}
.ka-chat-menu-item:hover { background: color-mix(in srgb, var(--accent2, #b693f5) 8%, transparent); }
.ka-chat-menu-cmd {
  font-family: 'Space Mono', monospace;
  color: var(--accent2, #b693f5);
  font-size: 11px;
  min-width: 76px;
  letter-spacing: 0.3px;
}
.ka-chat-menu-desc {
  font-size: 11px;
  color: var(--muted);
}

/* ── Reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ka-tool-box[data-status="running"] .ka-tool-box-dot { animation: none !important; }
  .ka-tool-running-dot { animation: none !important; opacity: 0.6 !important; }
  .ka-tool-box-body { transition: none !important; }
}

/* ── Mobile ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .ka-chat-thread { padding: 12px 14px; }
  .ka-chat-composer { padding: 10px 14px; }
  .ka-chat-menu { left: 14px; right: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════
   ASSISTANT · STAGE 2 — Per-signal insight (✦ on tracked rows)
   ───────────────────────────────────────────────────────────────────
   ✦ button mirrors .ks-row-act.fire / .tv — same min-height, same
   border + hover idiom — but accents to var(--accent2) so it reads
   as the AI surface, not a trade action. The inline panel below the
   row is structured: pills row → read paragraph → confirms/invalidates
   two-column grid → footer (timestamp + regenerate + caveat).
   ═════════════════════════════════════════════════════════════════ */

/* ── ✦ button on the row ──────────────────────────────────────── */
.ks-row-act.ai {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-left: 6px;
  padding-right: 8px;
}
.ks-row-act.ai .ks-row-act-glyph {
  font-size: 11px;
  line-height: 1;
  color: var(--accent2, #b693f5);
}
.ks-row-act.ai:hover {
  color: var(--accent2, #b693f5);
  border-color: var(--accent2, #b693f5);
}
.ks-row-act.ai.is-open {
  color: var(--accent2, #b693f5);
  border-color: color-mix(in srgb, var(--accent2, #b693f5) 60%, transparent);
  background: color-mix(in srgb, var(--accent2, #b693f5) 10%, transparent);
}
.ks-row-act.ai.is-open .ks-row-act-glyph { color: var(--accent2, #b693f5); }
.ks-row-act.ai.has-cache::after {
  content: '';
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent2, #b693f5);
  margin-left: 2px;
}

/* ── Inline panel below the row ───────────────────────────────── */
.ks-row-ai-panel {
  border: 1px solid var(--border);
  border-top: 1px solid color-mix(in srgb, var(--accent2, #b693f5) 30%, var(--border));
  border-radius: 0 0 6px 6px;
  margin: -7px 0 8px 0;
  background: color-mix(in srgb, var(--accent2, #b693f5) 4%, var(--card));
  padding: 12px 14px 10px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-bright);
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* When the parent .ks-row has a side-color border-left, mirror it
     here so the panel reads as visually attached. */
}
.ks-row.bull + .ks-row-ai-panel,
.ks-row.bull .ks-row-ai-panel,
.wl-row.bull + .ks-row-ai-panel,
.wl-row.bull .ks-row-ai-panel {
  border-left: 3px solid color-mix(in srgb, var(--up, #4dd99a) 60%, transparent);
}
.ks-row.bear + .ks-row-ai-panel,
.ks-row.bear .ks-row-ai-panel,
.wl-row.bear + .ks-row-ai-panel,
.wl-row.bear .ks-row-ai-panel {
  border-left: 3px solid color-mix(in srgb, var(--red) 60%, transparent);
}
/* When the panel is *inside* the row (which it is in our renderer),
   reset the negative margin since there's no row separator above it.
   Both .ks-row (scanners.html) and .wl-row (wallet.html) embed the
   panel as a direct child via KCSignalInsight.htmlForRow / wireRow. */
.ks-row > .ks-row-ai-panel,
.wl-row > .ks-row-ai-panel {
  margin: 8px 0 0;
  border-top: 1px solid var(--border);
}

/* Header line — small uppercase eyebrow + cached-at timestamp */
.ks-row-ai-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
}
.ks-row-ai-head-left {
  display: flex;
  align-items: center;
  gap: 6px;
}
.ks-row-ai-head .ks-row-ai-glyph {
  color: var(--accent2, #b693f5);
  font-size: 11px;
  letter-spacing: 0;
}

/* Verdict pills row */
.ks-row-ai-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.ks-row-ai-pill {
  display: inline-flex;
  align-items: center;
  font-size: 10px;
  font-weight: 600;
  padding: 3px 7px;
  border-radius: 3px;
  letter-spacing: 0.2px;
  white-space: nowrap;
}
.ks-row-ai-pill.info    { background: color-mix(in srgb, var(--accent3, #5dd5e8) 18%, transparent); color: var(--accent3, #5dd5e8); }
.ks-row-ai-pill.success { background: color-mix(in srgb, var(--accent, #4dd99a) 18%, transparent);  color: var(--accent, #4dd99a); }
.ks-row-ai-pill.warn    { background: color-mix(in srgb, var(--amber, #efb968) 18%, transparent);   color: var(--amber, #efb968); }
.ks-row-ai-pill.danger  { background: color-mix(in srgb, var(--red) 18%, transparent);              color: var(--red); }
.ks-row-ai-pill.neutral { background: var(--bg); border: 1px solid var(--border2); color: var(--muted); }
.ks-row-ai-pill.purple  { background: color-mix(in srgb, var(--accent2, #b693f5) 18%, transparent); color: var(--accent2, #b693f5); }

/* The read — main paragraph */
.ks-row-ai-read {
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-bright);
}

/* Confirms / Invalidates two-column grid */
.ks-row-ai-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
.ks-row-ai-cell {
  background: var(--bg);
  border-radius: 4px;
  padding: 7px 9px;
  border: 1px solid var(--border);
}
.ks-row-ai-cell-label {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 3px;
  display: flex;
  align-items: center;
  gap: 4px;
}
.ks-row-ai-cell-label.success::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent, #4dd99a);
  display: inline-block;
}
.ks-row-ai-cell-label.danger::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--red);
  display: inline-block;
}
.ks-row-ai-cell-body {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-bright);
}

/* Foot: actions + caveat */
.ks-row-ai-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
}
.ks-row-ai-caveat {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.4;
  flex: 1;
  min-width: 0;
}
.ks-row-ai-actions {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}
.ks-row-ai-act {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--muted);
  padding: 3px 8px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  font-weight: 700;
  text-transform: uppercase;
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.ks-row-ai-act:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.ks-row-ai-act:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Loading state */
.ks-row-ai-loading {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px 0;
}
.ks-row-ai-loading-line {
  height: 10px;
  border-radius: 3px;
  background: linear-gradient(
    90deg,
    var(--bg) 0%,
    color-mix(in srgb, var(--accent2, #b693f5) 12%, var(--bg)) 50%,
    var(--bg) 100%
  );
  background-size: 200% 100%;
  animation: ksAiShimmer 1.4s linear infinite;
}
.ks-row-ai-loading-line:nth-child(1) { width: 65%; }
.ks-row-ai-loading-line:nth-child(2) { width: 90%; }
.ks-row-ai-loading-line:nth-child(3) { width: 80%; }
@keyframes ksAiShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.ks-row-ai-loading-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--accent2, #b693f5);
  margin-top: 4px;
}

/* Error state */
.ks-row-ai-error {
  background: color-mix(in srgb, var(--red) 6%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--red) 30%, var(--border));
  border-radius: 4px;
  padding: 10px 12px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-bright);
}
.ks-row-ai-error-head {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 4px;
}
.ks-row-ai-error a {
  color: var(--accent2, #b693f5);
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent2, #b693f5) 50%, transparent);
}
.ks-row-ai-error a:hover { color: var(--text-bright); border-bottom-color: var(--text-bright); }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .ks-row-ai-loading-line { animation: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   Razor AI insight popout — KCSignalInsight (shared.js)
   ─────────────────────────────────────────────────────────────────
   The ✦ read opens here instead of inline: centered card on desktop,
   bottom sheet on mobile. Mirrors KCDialog overlay conventions. z 9350
   is the generic-page slot: above editor overlays (9300), below the
   dialog layer (9400) and toasts (9999) so razors / confirm dialogs and
   toasts stack above it. Pages with their own stacking range override it
   — scanners.html pins it to its row-modal tier via body .ks-ai-modal.
   The card renders its own header + levels block from
   the local signal, then reuses the .ks-row-ai-* content classes for
   the AI body (pills / read / confirms-invalidates / foot).
   ═════════════════════════════════════════════════════════════════ */
.ks-ai-modal {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 10, 0.6);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 9350;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s;
}
.ks-ai-modal.show { opacity: 1; pointer-events: auto; }
.ks-ai-modal-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 560px;
  max-width: calc(100vw - 32px);
  max-height: calc(88vh / var(--kc-font-scale, 1));
  background: var(--card);
  border: 1px solid var(--border2);
  border-top: 2px solid var(--accent, #d4a335);
  border-radius: 12px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  transform: translateY(8px);
  transition: transform 0.2s;
}
.ks-ai-modal.show .ks-ai-modal-card { transform: translateY(0); }
.ks-ai-modal-inner {
  overflow-y: auto;
  overflow-x: hidden;
  padding: 16px 18px 14px;
}
.ks-ai-modal-x {
  position: absolute;
  top: 11px;
  right: 11px;
  z-index: 3;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border: 1px solid var(--border2);
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  transition: color 0.15s, border-color 0.15s;
}
.ks-ai-modal-x:hover { color: var(--text-bright); border-color: var(--text-mid); }

/* Header — symbol / side / grade + meta line */
.ks-ai-head2 { padding-right: 28px; }
.ks-ai-eyebrow {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--accent2, #b88b1f);
}
.ks-ai-spark { color: var(--accent, #d4a335); font-size: 11px; letter-spacing: 0; }
.ks-ai-titlerow {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 9px;
}
.ks-ai-sym { font-size: 18px; font-weight: 700; letter-spacing: 0.3px; }
.ks-ai-sym.bull { color: var(--up, #6dd99c); }
.ks-ai-sym.bear { color: var(--red); }
.ks-ai-side {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.8px;
  padding: 3px 8px;
  border-radius: 4px;
}
.ks-ai-side.bull { background: color-mix(in srgb, var(--up, #6dd99c) 16%, transparent); color: var(--up, #6dd99c); }
.ks-ai-side.bear { background: color-mix(in srgb, var(--red) 18%, transparent); color: var(--red); }
.ks-ai-grade {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  padding: 3px 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--accent, #d4a335) 16%, transparent);
  color: var(--accent, #d4a335);
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 35%, transparent);
}
.ks-ai-meta {
  font-family: 'Space Mono', monospace;
  font-size: 11.5px;
  color: var(--text-mid);
  margin-top: 6px;
}

/* Levels strip + R/R bar — local signal data */
.ks-ai-levels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(62px, 1fr));
  gap: 7px;
  margin-top: 12px;
}
.ks-ai-lv-cell {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 7px 9px;
}
.ks-ai-lv-lab {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
}
.ks-ai-lv-val {
  font-family: 'Space Mono', monospace;
  font-size: 13px;
  margin-top: 2px;
  color: var(--text-bright);
}
.ks-ai-lv-val.entry { color: var(--accent, #d4a335); }
.ks-ai-lv-val.stop  { color: var(--red); }
.ks-ai-lv-val.tp    { color: var(--up, #6dd99c); }
.ks-ai-rr { margin-top: 10px; }
.ks-ai-rr-top { display: flex; align-items: center; justify-content: space-between; }
.ks-ai-rr-lab {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
}
.ks-ai-rr-val {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: var(--up, #6dd99c);
}
.ks-ai-rr-track {
  height: 6px;
  border-radius: 3px;
  background: var(--bg);
  margin-top: 5px;
  overflow: hidden;
}
.ks-ai-rr-fill { height: 100%; background: var(--up, #6dd99c); }

/* AI body — reuses .ks-row-ai-pills / -read / -grid / -foot inside */
.ks-ai-body { margin-top: 13px; }
.ks-ai-body > * + * { margin-top: 11px; }
.ks-ai-body > .ks-row-ai-grid {
  border-top: 1px solid var(--border);
  padding-top: 11px;
}
.ks-ai-verdict-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.ks-ai-verdict {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.2px;
  color: var(--text-bright);
}
.ks-ai-ts {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--muted);
  flex-shrink: 0;
}
.ks-ai-sec {
  border-top: 1px solid var(--border);
  padding-top: 11px;
}
.ks-ai-sec-lab {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--accent2, #b88b1f);
  margin-bottom: 5px;
}
.ks-ai-sec-body {
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-bright);
}

/* Mobile — dock to bottom as a sheet (mirrors KCDialog) */
@media (max-width: 640px) {
  .ks-ai-modal { align-items: flex-end; padding: 0; }
  .ks-ai-modal-card {
    width: 100%;
    max-width: 100%;
    max-height: calc(90dvh / var(--kc-font-scale, 1));
    border-radius: 18px 18px 0 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    transform: translateY(100%);
  }
  .ks-ai-modal.show .ks-ai-modal-card { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .ks-ai-modal,
  .ks-ai-modal-card { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   KCPaidBadge — small label next to buttons that trigger paid APIs
   ─────────────────────────────────────────────────────────────────
   Two shapes:
     .kc-paid-badge--inline  — trailing pill on labeled buttons
     .kc-paid-badge--corner  — top-right corner indicator on bare-icon buttons

   Three providers, color-coded:
     [data-paid-provider="claude"]      uses --accent2 (theme purple)
     [data-paid-provider="twitterapi"]  uses a brand-stable twitter-blue
     [data-paid-provider="razor"]       uses --accent (theme brass) for
                                        razor-only Worker routes (e.g.
                                        on-demand scanner Scan buttons)
   ═════════════════════════════════════════════════════════════════ */
:root {
  --kc-paid-twitter:   #1d9bf0;
  --kc-paid-twitter-d: rgba(29, 155, 240, 0.45);
}

/* Host hooks — when an element gets tagged, give it room for the badge */
.kc-paid-tagged {
  /* Nothing structural — the badge inserts itself. */
}

/* The badge node itself */
.kc-paid-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
  user-select: none;
  pointer-events: none;          /* never blocks clicks on host button */
  flex-shrink: 0;
  white-space: nowrap;
  -webkit-font-smoothing: antialiased;
}

/* ── INLINE shape (trailing pill on labeled buttons) ─────────────── */
.kc-paid-badge--inline {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
  min-width: 16px;
  height: 15px;
  vertical-align: middle;
}

/* ── CORNER shape (top-right of bare icon buttons) ───────────────── */
.kc-paid-badge--corner {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 14px;
  height: 14px;
  font-size: 9px;
  border-radius: 50%;
  border: 1.5px solid var(--bg, #0f0e1a);
  z-index: 1;
}
/* When mode flips to 'credits', corner badges may carry "2c", "5c"
   etc. — widen them to a pill so the digits fit. */
html[data-paid-mode="credits"] .kc-paid-badge--corner {
  width: auto;
  min-width: 14px;
  padding: 0 5px;
  border-radius: 8px;
}

/* ── Provider colors ─────────────────────────────────────────────── */
.kc-paid-badge[data-paid-provider="claude"] {
  background: color-mix(in srgb, var(--accent2, #b693f5) 18%, transparent);
  color: var(--accent2, #b693f5);
}
.kc-paid-badge[data-paid-provider="claude"].kc-paid-badge--corner {
  background: var(--accent2, #b693f5);
  color: var(--bg, #0f0e1a);
}

.kc-paid-badge[data-paid-provider="twitterapi"] {
  background: color-mix(in srgb, var(--kc-paid-twitter) 18%, transparent);
  color: var(--kc-paid-twitter);
}
.kc-paid-badge[data-paid-provider="twitterapi"].kc-paid-badge--corner {
  background: var(--kc-paid-twitter);
  color: var(--bg, #0f0e1a);
}

/* Razor-only Worker routes (no third-party upstream) — brass token to
   match the platform's "razor" identity. Used by on-demand scanner Scan
   buttons that call /v1/scan/run for a flat-rate razor charge.

   Inline variant uses a solid dark bg + brass text rather than the
   translucent-on-host treatment used for claude/twitterapi. Reason: the
   razor SCAN button is itself colored (--accent3 pewter on the default
   theme), so a translucent badge picks up the host's color and the
   brass text blends in. A solid dark surface guarantees contrast
   against every host button color across every theme. */
.kc-paid-badge[data-paid-provider="razor"] {
  background: var(--card2, #100f0d);
  color: var(--accent, #d4a335);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 45%, transparent);
}
.kc-paid-badge[data-paid-provider="razor"].kc-paid-badge--corner {
  background: var(--accent, #d4a335);
  color: var(--bg, #0f0e1a);
  box-shadow: none;
}

/* Hover/focus on host button — slight lift on the badge so it stays legible */
.kc-paid-tagged:hover  > .kc-paid-badge--inline,
.kc-paid-tagged:focus-visible > .kc-paid-badge--inline {
  filter: brightness(1.1);
}

/* Disabled host — fade the badge alongside */
.kc-paid-tagged:disabled > .kc-paid-badge,
.kc-paid-tagged[aria-disabled="true"] > .kc-paid-badge {
  opacity: 0.45;
}


/* ════════════════════════════════════════════════════════════════
   ║                                                              ║
   ║   WALLET PAGE  (.wl-*)  —  AlphaDesk Wallet consolidation v2 ║
   ║                                                              ║
   ║   Ported verbatim from the wallet.html mockup approved in    ║
   ║   the same conversation that shipped Step 1 (KCCompete       ║
   ║   two-book API). Page absorbs the legacy scanners drawer     ║
   ║   (#ksDrawer body) plus the Compete page Portfolio/Bets      ║
   ║   tabs, and exposes one unified equity surface across both   ║
   ║   trading and betting.                                       ║
   ║                                                              ║
   ║   All values driven from theme tokens (--bg, --surface,      ║
   ║   --border, --up, --red/--down, --blue, --muted, --accent)   ║
   ║   so every theme — Midnight, Slate, Carbon, Aurora etc. —    ║
   ║   gets correct colours without per-theme overrides.          ║
   ║                                                              ║
   ╚══════════════════════════════════════════════════════════════*/

/* ── TOOLBAR ───────────────────────────────────── */
  .wl-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 10px; padding: 18px 0 14px;
  }
  .wl-toolbar-left  { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .wl-toolbar-right { display: flex; align-items: center; gap: 8px; }
  .wl-toolbar-right .kc-explainer-btn { margin-left: 2px; }
  .wl-status {
    display: inline-flex; align-items: center; gap: 6px;
    font: var(--w-medium) 11px/1 var(--font-mono);
    color: var(--muted); letter-spacing: 0.4px; text-transform: uppercase;
  }
  .wl-status .dot {
    width: 6px; height: 6px; border-radius: 50%; background: var(--up);
    box-shadow: 0 0 8px rgba(109,217,156,0.6);
  }
  .wl-iconbtn {
    background: var(--surface); border: 1px solid var(--border);
    color: var(--text); border-radius: 8px;
    padding: 7px 12px;
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: var(--w-medium);
    line-height: 1;
    cursor: pointer; transition: all 0.15s ease;
    display: inline-flex; align-items: center; gap: 6px;
  }
  .wl-iconbtn:hover { border-color: var(--accent); color: var(--accent); }
  .wl-iconbtn.danger:hover { border-color: var(--red); color: var(--red); }

  /* ── SEASON HERO ──────────────────────────────── */
  .wl-season-hero {
    background: linear-gradient(135deg, rgba(140,170,255,0.08) 0%, rgba(109,217,156,0.06) 100%);
    border: 1px solid var(--border); border-radius: 14px;
    padding: 16px 18px; margin: 0 0 16px;
    display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 18px;
  }
  .wl-season-id {
    font: var(--w-bold) 13px/1 var(--font-mono);
    color: var(--text-bright); letter-spacing: 1px; text-transform: uppercase;
  }
  .wl-season-sub {
    font-size: 11px; color: var(--muted); margin-top: 4px; line-height: 1.4;
  }
  .wl-countdown-num {
    font: var(--w-bold) 22px/1 var(--font-mono);
    color: var(--text-bright); letter-spacing: 0.5px;
    font-variant-numeric: tabular-nums; text-align: right;
  }
  .wl-countdown-label {
    font-size: 10px; color: var(--muted); text-transform: uppercase;
    letter-spacing: 0.6px; margin-top: 4px; text-align: right;
  }
  .wl-season-progress {
    height: 4px; background: rgba(255,255,255,0.06);
    border-radius: 2px; overflow: hidden;
    grid-column: 1 / -1; margin-top: 4px;
  }
  .wl-season-progress-fill {
    height: 100%; width: 67%;
    background: linear-gradient(90deg, var(--up), var(--accent));
    border-radius: 2px;
  }

  /* ── EQUITY GRID ──────────────────────────────── */
  .wl-equity-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 0 0 18px;
  }
  @media (max-width: 1100px) { .wl-equity-grid { grid-template-columns: 1fr; } }

  .wl-book {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 12px; padding: 18px;
    position: relative; overflow: hidden;
  }
  .wl-book::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  }
  .wl-book.trade::before { background: var(--up); }
  .wl-book.bet::before   { background: #8caaff; }

  .wl-book-head {
    display: flex; align-items: center; justify-content: space-between;
    margin: 0 0 14px;
  }
  .wl-book-title {
    font: var(--w-bold) 13px/1 var(--font-display);
    color: var(--text-bright); letter-spacing: 0.4px;
    display: flex; align-items: center; gap: 8px;
  }
  .wl-book-title-icon {
    width: 22px; height: 22px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    font: var(--w-bold) 12px/1 var(--font-mono);
  }
  .wl-book.trade .wl-book-title-icon { background: rgba(109,217,156,0.15); color: var(--up); }
  .wl-book.bet   .wl-book-title-icon { background: rgba(140,170,255,0.15); color: #8caaff; }

  .wl-book-rank {
    font: var(--w-medium) 11px/1 var(--font-mono);
    color: var(--muted); background: var(--bg);
    border: 1px solid var(--border);
    padding: 5px 8px; border-radius: 6px;
    display: inline-flex; align-items: center; gap: 5px;
  }
  .wl-book-rank b { color: var(--text-bright); }

  .wl-book-equity {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 0 0 6px;
  }
  .wl-book-equity-num {
    font: var(--w-bold) 28px/1 var(--font-mono);
    color: var(--text-bright); letter-spacing: 0.3px;
    font-variant-numeric: tabular-nums;
  }
  .wl-book-equity-delta {
    font: var(--w-bold) 12px/1 var(--font-mono);
    padding: 4px 8px; border-radius: 6px;
    font-variant-numeric: tabular-nums;
  }
  .wl-book-equity-delta.up   { background: rgba(109,217,156,0.15); color: var(--up); }
  .wl-book-equity-delta.down { background: rgba(255,107,107,0.15); color: var(--down); }
  .wl-book-equity-delta.flat { background: rgba(255,255,255,0.04); color: var(--muted); }

  .wl-book-baseline { font-size: 11px; color: var(--muted); margin: 0 0 14px; }

  .wl-split-bar {
    height: 8px; border-radius: 4px; overflow: hidden;
    background: rgba(255,255,255,0.04); display: flex; margin: 0 0 8px;
  }
  .wl-split-free   { background: linear-gradient(90deg, var(--up), rgba(109,217,156,0.6)); }
  .wl-split-locked { background: linear-gradient(90deg, rgba(140,170,255,0.6), #8caaff); }
  .wl-split-upnl-up { background: linear-gradient(90deg, rgba(109,217,156,0.5), var(--up)); }

  .wl-split-legend {
    display: flex; gap: 14px; flex-wrap: wrap;
    font: var(--w-medium) 11px/1 var(--font-mono);
    color: var(--muted); margin: 0 0 14px;
  }
  .wl-split-legend > span {
    display: inline-flex; align-items: center; gap: 6px;
    font-variant-numeric: tabular-nums;
  }
  .wl-split-legend .sw { width: 8px; height: 8px; border-radius: 2px; }
  .wl-split-legend b { color: var(--text-bright); font-weight: var(--w-bold); }

  .wl-book-spark {
    width: 100%; height: 50px; display: block; margin: 6px 0 12px;
  }

  .wl-book-foot {
    display: flex; gap: 8px; flex-wrap: wrap;
    padding-top: 12px; border-top: 1px dashed var(--border);
  }
  .wl-book-foot a, .wl-book-foot button {
    flex: 1; min-width: 110px; background: transparent;
    border: 1px solid var(--border); color: var(--text);
    padding: 8px 10px;
    font: var(--w-medium) 11px/1 var(--font-display);
    border-radius: 7px; cursor: pointer; text-decoration: none;
    text-align: center; transition: all 0.15s ease;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  }
  .wl-book-foot a:hover, .wl-book-foot button:hover {
    border-color: var(--accent); color: var(--accent);
  }

  /* ── EXPOSURE SECTION ─────────────────────────── */
  .wl-section-head {
    display: flex; align-items: center; justify-content: space-between;
    margin: 22px 0 10px; flex-wrap: wrap; gap: 8px;
  }
  .wl-section-title {
    font: var(--w-bold) 14px/1 var(--font-display);
    color: var(--text-bright); letter-spacing: 0.3px;
    display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  }
  .wl-section-title .ct {
    font: var(--w-medium) 11px/1 var(--font-mono);
    color: var(--muted); background: var(--bg);
    border: 1px solid var(--border); padding: 4px 7px; border-radius: 5px;
  }

  .wl-cols-2 {
    display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  }
  @media (max-width: 1100px) { .wl-cols-2 { grid-template-columns: 1fr; } }

  .wl-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 10px; padding: 14px;
  }
  .wl-card-head {
    display: flex; align-items: center; justify-content: space-between;
    margin: 0 0 10px; padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
    gap: 8px; flex-wrap: wrap;
  }
  .wl-card-title {
    font: var(--w-bold) 12px/1 var(--font-display);
    color: var(--text-bright); letter-spacing: 0.3px; text-transform: uppercase;
    display: inline-flex; align-items: center; gap: 6px;
  }
  .wl-card-sub {
    font: var(--w-medium) 11px/1 var(--font-mono); color: var(--muted);
  }
  .wl-card-actions {
    display: flex; gap: 4px; align-items: center;
  }
  .wl-card-mini-btn {
    background: transparent; border: 1px solid var(--border);
    color: var(--muted); padding: 4px 8px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: var(--w-medium);
    line-height: 1;
    border-radius: 5px; cursor: pointer;
    letter-spacing: 0.3px; text-transform: uppercase;
    transition: all 0.15s ease;
  }
  .wl-card-mini-btn:hover {
    border-color: var(--accent); color: var(--accent);
  }

  /* Stat chip strip — replaces ks-stats from drawer */
  .wl-stat-chips {
    display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 12px;
  }
  .wl-stat-chip {
    background: var(--bg); border: 1px solid var(--border);
    color: var(--muted); padding: 6px 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: var(--w-medium);
    line-height: 1;
    border-radius: 6px; cursor: pointer;
    letter-spacing: 0.3px; text-transform: uppercase;
    display: inline-flex; align-items: center; gap: 5px;
    transition: all 0.15s ease;
  }
  .wl-stat-chip:hover { border-color: var(--accent); color: var(--text); }
  .wl-stat-chip.active {
    background: var(--accent); color: var(--bg); border-color: var(--accent);
  }
  .wl-stat-chip b {
    background: rgba(255,255,255,0.06); color: var(--text-bright);
    padding: 2px 5px; border-radius: 3px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: var(--w-bold);
    line-height: 1;
    margin-left: 2px;
  }
  .wl-stat-chip.active b { background: rgba(0,0,0,0.2); color: var(--bg); }

  /* ── ROW LIST — replaces .ks-row drawer rows ──── */
  .wl-rows { display: flex; flex-direction: column; gap: 6px; }

  .wl-row {
    background: var(--bg); border: 1px solid var(--border);
    border-left: 3px solid transparent;
    border-radius: 8px; padding: 8px 12px;
    cursor: pointer; transition: all 0.15s ease;
  }
  .wl-row:hover { border-color: var(--border2, var(--border)); }
  /* The .bull / .bear modifier classes are still applied by renderPositionRow
     and renderBetRow (LONG/SHORT or YES/NO maps to bull/bear). The previous
     border-left-color overrides for these classes painted a green/red side
     stripe on every row — visual noise that duplicates information already
     shown by the LONG/SHORT and YES/NO pills in the row header. Removing
     just the color overrides keeps the 3px transparent reservation so row
     widths don't shift, and leaves the classes available for future styling
     hooks. */
  .wl-row.live   { background: color-mix(in srgb, #f2a83a 4%, var(--bg)); }
  .wl-row.won    { background: color-mix(in srgb, var(--up) 5%, var(--bg)); }
  .wl-row.lost   { background: color-mix(in srgb, var(--red) 4%, var(--bg)); }

  .wl-row-head {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 10px; align-items: center;
  }
  .wl-row-sym-block { min-width: 0; }
  .wl-row-sym {
    font: var(--w-bold) 13px/1.3 var(--font-display);
    color: var(--text-bright);
    min-width: 0;
    overflow-wrap: anywhere;
  }
  /* Pills are inline-flex so they don't split between two lines mid-cluster.
     With display: inline-flex, the whole pill cluster flows as a single
     inline atom — when the question text wraps, the pills land next to
     the last word that fits, then the cluster jumps to the next line as
     a unit if needed. Whitespace-nowrap inside keeps "● OPEN" together. */
  .wl-row-sym .wl-row-pills {
    display: inline-flex; align-items: center; gap: 6px;
    white-space: nowrap;
    vertical-align: 1px;
  }
  .wl-row-sym .wl-row-q {
    /* Plain inline so the trailing pills span participates in line layout */
  }
  .wl-row-sym .sym-tf {
    font: var(--w-medium) 9px/1 var(--font-mono);
    background: rgba(255,255,255,0.05);
    color: var(--muted); padding: 2px 5px; border-radius: 3px;
    vertical-align: 1px;
  }
  .wl-row-meta {
    font: var(--w-medium) 11px/1.4 var(--font-mono);
    color: var(--muted); margin-top: 3px;
    display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  }

  .wl-pill {
    display: inline-block; padding: 2px 7px; border-radius: 4px;
    font: var(--w-bold) 10px/1.4 var(--font-mono);
    letter-spacing: 0.4px; text-transform: uppercase;
  }
  .wl-pill-bull    { background: rgba(109,217,156,0.15); color: var(--up); }
  .wl-pill-bear    { background: rgba(255,107,107,0.15); color: var(--down); }
  .wl-pill-yes     { background: rgba(109,217,156,0.15); color: var(--up); }
  .wl-pill-no      { background: rgba(255,107,107,0.15); color: var(--down); }
  .wl-pill-live    { background: rgba(242,168,58,0.13); color: #f2a83a; }
  .wl-pill-waiting { background: rgba(140,170,255,0.13); color: #8caaff; }
  .wl-pill-won     { background: rgba(109,217,156,0.15); color: var(--up); }
  .wl-pill-lost    { background: rgba(255,107,107,0.15); color: var(--down); }
  .wl-pill-void    { background: rgba(255,255,255,0.06); color: var(--muted); }
  .wl-pill-manual  { background: rgba(180,140,255,0.12); color: #b48cff; border: 1px dashed rgba(180,140,255,0.3); }
  .wl-pill-venue   { background: rgba(255,255,255,0.04); border: 1px solid var(--border); color: var(--muted); }
  .wl-pill-scanner { background: rgba(255,255,255,0.04); border: 1px solid var(--border); color: var(--muted); }

  .wl-row-progress {
    margin-top: 10px;
    background: rgba(255,255,255,0.03);
    border-radius: 5px; padding: 8px 10px;
    font: var(--w-medium) 11px/1 var(--font-mono);
    color: var(--muted);
    display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center;
  }
  .wl-row-prog-track {
    height: 4px; background: rgba(255,255,255,0.05);
    border-radius: 2px; position: relative; overflow: hidden;
  }
  .wl-row-prog-fill {
    position: absolute; left: 0; top: 0; bottom: 0;
    background: linear-gradient(90deg, var(--up), var(--accent));
    border-radius: 2px;
  }
  .wl-row-prog-marker {
    position: absolute; top: -3px; bottom: -3px;
    width: 2px; background: var(--text-bright);
  }

  .wl-row-numeric {
    font-family: var(--font-mono); font-variant-numeric: tabular-nums;
    text-align: right; white-space: nowrap;
  }
  .wl-row-numeric .top {
    font: var(--w-bold) 13px/1 var(--font-mono);
    color: var(--text-bright);
  }
  .wl-row-numeric .top.up   { color: var(--up); }
  .wl-row-numeric .top.down { color: var(--down); }
  .wl-row-numeric .sub {
    font-size: 10px; color: var(--muted); margin-top: 3px;
  }
  .wl-row-numeric .sub.up   { color: var(--up); }
  .wl-row-numeric .sub.down { color: var(--down); }

  .wl-row-actions {
    display: flex; gap: 4px; align-items: center;
  }
  .wl-row-actbtn {
    background: transparent; border: 1px solid var(--border);
    color: var(--muted); width: 28px; height: 28px; border-radius: 5px;
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: var(--w-bold);
    line-height: 1;
    cursor: pointer;
    transition: all 0.15s ease;
  }
  .wl-row-actbtn:hover { border-color: var(--accent); color: var(--accent); }
  .wl-row-actbtn.danger:hover { border-color: var(--red); color: var(--red); }
  .wl-row-actbtn.fire:hover { border-color: #f2a83a; color: #f2a83a; }
  /* ✦ insight — brass styling matches the platform's Razor/paid-AI
     convention. The dot indicator on .has-cache mirrors scanners.html's
     .ks-row-act.ai treatment so users can see at a glance which signals
     have a cached reading. .is-open pins the brass border when the
     panel is expanded. */
  .wl-row-actbtn.ai {
    color: var(--brass, #d4a335);
    border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
  }
  .wl-row-actbtn.ai:hover {
    border-color: var(--brass, #d4a335);
    color: var(--brass, #d4a335);
    background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
  }
  .wl-row-actbtn.ai.is-open {
    border-color: var(--brass, #d4a335);
    background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  }
  .wl-row-actbtn.ai.has-cache::after {
    content: '';
    position: absolute;
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--brass, #d4a335);
    margin: -14px 0 0 14px;
  }
  .wl-row-actbtn.ai { position: relative; }

  .wl-rows-foot {
    margin-top: 10px; padding-top: 10px;
    border-top: 1px dashed var(--border);
    text-align: center;
  }
  .wl-rows-foot a {
    color: var(--accent); text-decoration: none;
    font: var(--w-medium) 11px/1 var(--font-display);
  }

  /* ── ACTIVITY ─────────────────────────────────── */
  .wl-activity-filter { display: flex; gap: 6px; flex-wrap: wrap; }
  .wl-chip {
    background: transparent; border: 1px solid var(--border);
    color: var(--muted); padding: 5px 10px;
    font-family: var(--font-mono);
    font-size: 10px;
    font-weight: var(--w-medium);
    line-height: 1;
    border-radius: 6px; cursor: pointer;
    letter-spacing: 0.3px; text-transform: uppercase;
    transition: all 0.15s ease;
  }
  .wl-chip:hover { border-color: var(--accent); color: var(--accent); }
  .wl-chip.active {
    background: var(--accent); color: var(--bg); border-color: var(--accent);
  }

  .wl-activity-row {
    display: grid; grid-template-columns: 24px minmax(0, 1fr) auto auto;
    align-items: center; gap: 10px;
    padding: 7px 14px; border-bottom: 1px solid var(--border);
  }
  .wl-activity-row:last-child { border-bottom: 0; }
  .wl-activity-row:hover { background: rgba(255,255,255,0.02); }

  .wl-act-icon {
    width: 22px; height: 22px; border-radius: 5px;
    display: inline-flex; align-items: center; justify-content: center;
    font: var(--w-bold) 11px/1 var(--font-mono);
  }
  .wl-act-icon.trade-win  { background: rgba(109,217,156,0.13); color: var(--up); }
  .wl-act-icon.trade-loss { background: rgba(255,107,107,0.13); color: var(--down); }
  .wl-act-icon.trade-open { background: rgba(140,170,255,0.13); color: #8caaff; }
  .wl-act-icon.bet-win    { background: rgba(109,217,156,0.13); color: var(--up); }
  .wl-act-icon.bet-loss   { background: rgba(255,107,107,0.13); color: var(--down); }
  .wl-act-icon.bet-open   { background: rgba(140,170,255,0.13); color: #8caaff; }
  .wl-act-icon.bet-close  { background: rgba(255,180,80,0.13); color: var(--yellow); }
  .wl-act-icon.manual     { background: rgba(180,140,255,0.13); color: #b48cff; }
  .wl-act-icon.reset      { background: rgba(255,255,255,0.04); color: var(--muted); }

  /* Body is a single inline-flow line — title in bright text, sub
     follows muted with a leading "·" separator. Long titles ellipsize
     via the row's minmax(0, 1fr) clamp; whole line never wraps. */
  .wl-act-body {
    min-width: 0;
    font: var(--w-medium) 11px/1.4 var(--font-mono);
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .wl-act-title {
    font-family: var(--font-display);
    font-weight: var(--w-medium);
    font-size: 12px;
    color: var(--text-bright);
  }
  .wl-act-sub {
    color: var(--muted);
  }

  .wl-act-amount {
    font: var(--w-bold) 12px/1 var(--font-mono);
    color: var(--text-bright);
    font-variant-numeric: tabular-nums;
    text-align: right; white-space: nowrap;
  }
  .wl-act-amount.up   { color: var(--up); }
  .wl-act-amount.down { color: var(--down); }
  .wl-act-amount.flat { color: var(--muted); }

  .wl-act-time {
    font: var(--w-medium) 10px/1 var(--font-mono);
    color: var(--muted); text-align: right; white-space: nowrap;
    min-width: 48px;
  }

  /* Slimmer day divider — keeps the "TODAY · MAY 9" anchor for date
     orientation but drops the tinted background band so it reads as a
     muted label inside the ledger, not a chunky section header. */
  .wl-act-divider {
    padding: 8px 14px 4px;
    font: var(--w-medium) 9px/1 var(--font-mono);
    color: var(--muted);
    letter-spacing: 0.5px; text-transform: uppercase;
    border-bottom: 1px solid var(--border);
  }
  /* First divider in the list has no top spacer — the pagination/header
     already provides the separation. */
  .wl-act-divider:first-child { padding-top: 6px; }

  .wl-foot-note {
    text-align: center; color: var(--muted); font-size: 11px;
    padding: 24px 0 0; border-top: 1px solid var(--border); margin-top: 24px;
  }
  .wl-foot-note a { color: var(--muted); text-decoration: underline; }
  .wl-foot-note a:hover { color: var(--accent); }


/* ════════════════════════════════════════════════════════════════
   ║                                                              ║
   ║   COMPETE PAGE  (.cp-*)  —  Leaderboard + Stats + Recap +    ║
   ║                              Achievements (4-tab strip)      ║
   ║                                                              ║
   ║   Ported verbatim from compete.html's inline <style> block.  ║
   ║   Compete has been narrowed to the competitive-lens layer    ║
   ║   (rankings, season recap, badges) — Wallet now owns the     ║
   ║   balance / positions / bets / activity surfaces.            ║
   ║                                                              ║
   ╚══════════════════════════════════════════════════════════════*/

/* Top toolbar (page title + season + ?) */
.cp-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 8px 0 12px;
}
.cp-toolbar-left  { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cp-toolbar-right { display: flex; align-items: center; gap: 8px; }

.cp-status {
  font-family: 'Space Mono', monospace;
  font-size: 11px; color: var(--muted);
}
.cp-status .dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--up); margin-right: 4px;
  box-shadow: 0 0 6px rgba(109,217,156,0.6);
}
.cp-status.warn .dot { background: var(--yellow); }

.cp-iconbtn {
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); padding: 5px 10px; border-radius: 6px;
  font-size: 12px; cursor: pointer;
  font-family: inherit; font-weight: var(--w-medium);
  display: inline-flex; align-items: center; gap: 5px;
  transition: all 0.15s ease;
}
.cp-iconbtn:hover    { border-color: var(--accent); color: var(--accent); }
.cp-iconbtn:disabled { opacity: 0.5; cursor: not-allowed; }

/* 4-stat strip */
.cp-stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 10px; margin: 0 0 14px;
}
@media (max-width: 880px) { .cp-stats { grid-template-columns: repeat(2, 1fr); } }

.cp-stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px;
  position: relative;
}
.cp-stat-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); display: flex; align-items: center; gap: 6px;
}
.cp-stat-value {
  font-size: 22px; font-weight: var(--w-bold); color: var(--text-bright);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.cp-stat-sub {
  font-size: 11px; color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
}
.cp-stat-sub.up   { color: var(--up); }
.cp-stat-sub.down { color: var(--down); }
.cp-stat .kc-explainer-btn {
  position: absolute; top: 8px; right: 8px;
  width: 18px; height: 18px; min-width: 0; padding: 0;
  font-size: 11px;
}

/* Tab strip (Leaderboard / Stats / Recap / Achievements) */
.cp-tabs {
  display: flex; gap: 4px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 4px;
  margin: 0 0 14px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.cp-tab {
  flex: 1 1 auto;
  padding: 8px 14px;
  background: transparent; border: 0; border-radius: 7px;
  color: var(--muted); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: var(--w-medium);
  white-space: nowrap;
  transition: all 0.15s ease;
}
.cp-tab:hover { color: var(--text); background: rgba(255,255,255,0.03); }
.cp-tab.active {
  background: var(--bg); color: var(--text-bright);
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}

/* Tab panel */
.cp-panel { display: none; }
.cp-panel.active { display: block; }

/* Two-column layout (main + side rail) */
.cp-cols {
  display: grid; grid-template-columns: 1fr 320px;
  gap: 14px;
}
@media (max-width: 1100px) { .cp-cols { grid-template-columns: 1fr; } }

/* Generic card (inside any tab panel) */
.cp-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px;
  margin: 0 0 12px;
}
.cp-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin: 0 0 10px;
}
.cp-card-title {
  font-size: 13px; font-weight: var(--w-bold); color: var(--text-bright);
  letter-spacing: 0.3px;
  display: flex; align-items: center; gap: 6px;
}
.cp-card-sub {
  font-size: 11px; color: var(--muted);
  font-family: 'Space Mono', monospace;
}

/* Equity sparkline (recap tab) */
.cp-equity-row {
  display: flex; align-items: center; gap: 14px;
  margin: 0 0 8px;
}
.cp-equity-num {
  font-size: 26px; font-weight: var(--w-bold); color: var(--text-bright);
  font-variant-numeric: tabular-nums;
}
.cp-equity-delta {
  font-family: 'Space Mono', monospace;
  font-size: 12px; font-weight: var(--w-medium);
  padding: 2px 8px; border-radius: 5px;
}
.cp-equity-delta.up   { background: rgba(109,217,156,0.15); color: var(--up); }
.cp-equity-delta.down { background: rgba(255,107,107,0.15); color: var(--down); }
.cp-equity-delta.flat { background: rgba(255,255,255,0.04); color: var(--muted); }
.cp-spark {
  width: 100%; height: 70px;
  margin: 6px 0 0;
}

/* Position / row table (leaderboard / history) */
.cp-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cp-table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: 12px;
}
.cp-table thead th {
  text-align: left; font-weight: var(--w-medium);
  color: var(--muted); padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  position: sticky; top: 0;
}
.cp-table tbody td {
  padding: 10px; border-bottom: 1px solid var(--border);
  color: var(--text); vertical-align: middle;
}
.cp-table tbody tr:last-child td { border-bottom: 0; }
.cp-table tbody tr:hover         { background: rgba(255,255,255,0.02); }

/* Leaderboard "you" highlighting */
.cp-table tbody tr.cp-row-you        { background: rgba(109,217,156,0.08); }
.cp-table tbody tr.cp-row-you:hover  { background: rgba(109,217,156,0.13); }
.cp-table tbody tr.cp-row-you td:first-child {
  border-left: 2px solid var(--up);
}

.cp-table .cp-num {
  font-family: 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.cp-table .cp-pill {
  display: inline-block; padding: 2px 7px; border-radius: 5px;
  font-family: 'Space Mono', monospace;
  font-size: 10px; font-weight: var(--w-medium);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* Compete pills (parallel to .wl-pill but distinct namespace) */
.cp-pill-bull    { background: rgba(109,217,156,0.15); color: var(--up); }
.cp-pill-bear    { background: rgba(255,107,107,0.15); color: var(--down); }
.cp-pill-yes     { background: rgba(109,217,156,0.15); color: var(--up); }
.cp-pill-no      { background: rgba(255,107,107,0.15); color: var(--down); }
.cp-pill-win     { background: rgba(109,217,156,0.15); color: var(--up); }
.cp-pill-loss    { background: rgba(255,107,107,0.15); color: var(--down); }
.cp-pill-void    { background: rgba(255,255,255,0.06); color: var(--muted); }
.cp-pill-skip    { background: rgba(255,255,255,0.06); color: var(--muted); }
.cp-pill-expired { background: rgba(255,180,80,0.13);  color: var(--yellow); }
.cp-pill-early   { background: rgba(140,170,255,0.13); color: var(--blue); }
.cp-pill-venue   {
  background: rgba(255,255,255,0.05); color: var(--text);
  border: 1px solid var(--border);
}

.cp-row-action {
  background: transparent; border: 1px solid var(--border);
  color: var(--muted); padding: 3px 8px; border-radius: 5px;
  font-family: inherit; font-size: 11px; cursor: pointer;
  transition: all 0.15s ease;
}
.cp-row-action:hover         { border-color: var(--accent); color: var(--accent); }
.cp-row-action.danger:hover  { border-color: var(--red); color: var(--red); }

/* Empty state inside any cp-card */
.cp-empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.cp-empty .cp-empty-icon { font-size: 28px; margin: 0 0 6px; opacity: 0.6; }
.cp-empty a, .cp-empty .cp-empty-link {
  color: var(--accent); text-decoration: none; cursor: pointer;
}
.cp-empty a:hover, .cp-empty .cp-empty-link:hover {
  text-decoration: underline;
}

/* Side panel cards (right rail, e.g. season recap, milestones) */
.cp-side-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px; margin: 0 0 10px;
}
.cp-side-title {
  font-family: 'Space Mono', monospace;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); margin: 0 0 8px;
  display: flex; align-items: center; gap: 6px;
}
.cp-kv {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 0; font-size: 12px;
}
.cp-kv + .cp-kv { border-top: 1px dashed var(--border); }
.cp-kv .k { color: var(--muted); }
.cp-kv .v {
  font-family: 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  color: var(--text-bright); font-weight: var(--w-medium);
}

/* Inline help dot (small ? next to titles) */
.cp-help {
  width: 16px; height: 16px;
  background: transparent; border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 50%;
  font-size: 10px; line-height: 1;
  cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s ease;
  font-family: inherit;
}
.cp-help:hover { border-color: var(--accent); color: var(--accent); }

/* Filter chip row (for History / Stats filters) */
.cp-chip-row {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 6px 0 10px;
}
.cp-chip {
  padding: 4px 10px; border-radius: 999px;
  background: transparent; border: 1px solid var(--border);
  color: var(--muted); cursor: pointer;
  font-family: inherit; font-size: 11px;
  transition: all 0.15s ease;
}
.cp-chip:hover  { border-color: var(--accent); color: var(--accent); }
.cp-chip.active {
  background: var(--accent); color: var(--bg);
  border-color: var(--accent);
}

/* Per-scanner stats list (Stats tab) */
.cp-bar-row {
  display: grid; grid-template-columns: 130px 1fr 100px;
  align-items: center; gap: 10px;
  padding: 6px 0;
}
.cp-bar-row + .cp-bar-row { border-top: 1px dashed var(--border); }
.cp-bar-name {
  font-size: 12px; color: var(--text);
  text-transform: capitalize;
}
.cp-bar-track {
  height: 8px; background: rgba(255,255,255,0.05);
  border-radius: 4px; overflow: hidden;
  position: relative;
}
.cp-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--up), var(--accent));
  border-radius: 4px;
  transition: width 0.4s ease;
}
.cp-bar-fill.cool {
  background: linear-gradient(90deg, var(--blue), var(--accent));
}
.cp-bar-num {
  text-align: right;
  font-family: 'Space Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 11px; color: var(--muted);
}

/* Modal (close-bet confirm / wallet-reset confirm / etc) */
.cp-modal {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6); -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  display: none; align-items: center; justify-content: center;
  z-index: 200;
  padding: 20px;
}
.cp-modal.open { display: flex; }
.cp-modal-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px;
  width: 100%; max-width: 440px;
  padding: 20px;
}
.cp-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 0 14px;
}
.cp-modal-title {
  font-size: 14px; font-weight: var(--w-bold); color: var(--text-bright);
}
.cp-modal-close {
  background: transparent; border: 0; color: var(--muted);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.cp-modal-close:hover { color: var(--text-bright); }
.cp-modal-body { font-size: 13px; color: var(--text); line-height: 1.5; }
.cp-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  margin: 16px 0 0;
}
.cp-modal-btn {
  padding: 7px 14px; border-radius: 6px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text); cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: var(--w-medium);
  transition: all 0.15s ease;
}
.cp-modal-btn:hover         { border-color: var(--accent); color: var(--accent); }
.cp-modal-btn.primary       {
  background: var(--accent); color: var(--bg); border-color: var(--accent);
}
.cp-modal-btn.primary:hover { opacity: 0.9; }
.cp-modal-btn.danger:hover  { border-color: var(--red); color: var(--red); }

/* Manual trade entry form (lives inside a cp-modal-body) */
.cp-form-grid {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 8px;
  align-items: end;
}
@media (max-width: 880px) { .cp-form-grid { grid-template-columns: repeat(2, 1fr); } }

.cp-field { display: flex; flex-direction: column; gap: 4px; }
.cp-field-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted);
}
.cp-input, .cp-select {
  background: var(--bg); border: 1px solid var(--border);
  color: var(--text); padding: 7px 10px; border-radius: 6px;
  font-family: inherit; font-size: 12px;
}
.cp-input:focus, .cp-select:focus {
  outline: 0; border-color: var(--accent);
}

.cp-form-side-toggle {
  display: flex; gap: 0;
  border: 1px solid var(--border); border-radius: 6px;
  overflow: hidden;
}
.cp-form-side-toggle button {
  flex: 1; padding: 7px 10px;
  background: transparent; border: 0;
  color: var(--muted); cursor: pointer;
  font-family: inherit; font-size: 11px; font-weight: var(--w-medium);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.cp-form-side-toggle button.active.bull { background: rgba(109,217,156,0.15); color: var(--up); }
.cp-form-side-toggle button.active.bear { background: rgba(255,107,107,0.15); color: var(--down); }

.cp-form-submit {
  background: var(--accent); color: var(--bg);
  border: 0; padding: 8px 14px; border-radius: 6px;
  font-family: inherit; font-size: 12px; font-weight: var(--w-bold);
  cursor: pointer;
  transition: opacity 0.15s ease;
}
.cp-form-submit:hover    { opacity: 0.9; }
.cp-form-submit:disabled { opacity: 0.5; cursor: not-allowed; }

.cp-form-hint {
  font-size: 11px; color: var(--muted);
  margin: 6px 0 0;
  font-family: 'Space Mono', monospace;
}
.cp-form-hint.warn  { color: var(--yellow); }
.cp-form-hint.error { color: var(--red); }

/* Leaderboard scanner picker */
.cp-lead-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px;
}
.cp-lead-mode-toggle {
  display: flex; gap: 0;
  border: 1px solid var(--border); border-radius: 6px;
  overflow: hidden;
}
.cp-lead-mode-toggle button {
  padding: 6px 12px;
  background: transparent; border: 0;
  color: var(--muted); cursor: pointer;
  font-family: inherit; font-size: 11px; font-weight: var(--w-medium);
}
.cp-lead-mode-toggle button.active {
  background: var(--accent); color: var(--bg);
}

/* Toast */
.cp-toast {
  position: fixed; bottom: 20px; left: 50%;
  transform: translateX(-50%) translateY(100px);
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  padding: 10px 16px; border-radius: 6px;
  font-size: 12px; color: var(--text);
  z-index: 300;
  box-shadow: 0 6px 20px rgba(0,0,0,0.4);
  transition: transform 0.25s ease, opacity 0.25s ease;
  opacity: 0; pointer-events: none;
}
.cp-toast.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}
.cp-toast.error { border-left-color: var(--red); }
.cp-toast.warn  { border-left-color: var(--yellow); }

/* Misc utility classes used inside .cp-* surfaces */
.cp-section-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: var(--w-bold); color: var(--text-bright);
  margin: 6px 0 10px;
  letter-spacing: 0.3px;
}
.cp-mono  { font-family: 'Space Mono', monospace; font-variant-numeric: tabular-nums; }
.cp-muted { color: var(--muted); }
.cp-up    { color: var(--up); }
.cp-down  { color: var(--down); }

/* ════════════════════════════════════════════════════════════════════
   alpha desk · RAZOR ALPHA INBOX · v1
   ────────────────────────────────────────────────────────────────────
   Unified bell + drawer that replaces:
     • KCNotify bell on scanners.html / kol.html (legacy .kn-bell-btn)
     • Radar alerts bell on radar.html (legacy .alert-bell)
     • Earn "What's new" status bar pings (Activity tab)
     • kcSharedToast + kcToastUndo confirmation log (Activity tab)
   Mounted by KCInbox (shared.js) into .kc-sb-foot, between the
   ✦ assistant button and the 🎨 palette button. Glass-tile look
   matches .kc-theme-btn and .settings-gear (30px, dark gradient,
   1px hairline border, hover-to-accent).
   ════════════════════════════════════════════════════════════════════ */

/* Hide the legacy bell hosts — KCNotify.refreshBell still updates
   their counts in the DOM (we don't want to break that wiring),
   but the buttons themselves are invisible because the new sidebar
   bell takes over. The legacy slide-in panel is also hidden in
   case anything in shared.js still mounts it before KCInbox steps
   in to redirect KCNotify.openPanel. */
.kn-bell-btn,
.kn-panel-overlay,
.alert-bell-wrap {
  display: none !important;
}

/* ── BELL BUTTON · sidebar foot ─────────────────────────────── */
.kc-inbox-btn {
  position: relative;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  color: var(--text-mid);
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s;
  padding: 0;
}
.kc-inbox-btn:hover {
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent) 18%, transparent);
}
.kc-inbox-btn.has-unread {
  color: var(--text-bright);
  border-color: color-mix(in srgb, var(--amber, #f59e0b) 40%, rgba(255,255,255,0.06));
}
.kc-inbox-btn.has-unread:hover {
  color: var(--accent);
}
/* has-update = a fresh platform-update row in Activity. Quieter than
   has-unread: brass border tint, smaller dot, no pulse. The class
   is independent of has-unread — refreshBell() picks one or the other
   based on which queue has unread items (events take precedence). */
.kc-inbox-btn.has-update {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 40%, rgba(255,255,255,0.06));
}
.kc-inbox-btn.has-update:hover {
  color: var(--accent);
}
.kc-inbox-btn .kc-ic { display: inline-block; }

/* Pip badge — top-right corner, count when ≥1, dot when small */
.kc-inbox-pip {
  position: absolute;
  top: -3px; right: -3px;
  min-width: 14px; height: 14px;
  padding: 0 3px;
  border-radius: 7px;
  background: var(--amber, #f59e0b);
  color: #1a1a22;
  font-family: 'Space Mono', monospace;
  font-size: 9px; font-weight: 700;
  line-height: 1;
  display: none;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--bg, #0a0a14);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.kc-inbox-btn.has-unread .kc-inbox-pip { display: flex; }
.kc-inbox-btn.has-unread .kc-inbox-pip {
  animation: kciPipPulse 1.6s ease-in-out infinite;
}
/* has-update pip: brass dot, no number, no pulse. Smaller too —
   it's an ambient "something new shipped" cue, not an alert. */
.kc-inbox-btn.has-update .kc-inbox-pip {
  display: flex;
  background: var(--accent, #d4a335);
  min-width: 8px; height: 8px;
  border-radius: 50%;
  padding: 0;
  top: -2px; right: -2px;
  border-width: 1.5px;
}
@keyframes kciPipPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--amber, #f59e0b) 60%, transparent); }
  50%      { box-shadow: 0 0 0 4px color-mix(in srgb, var(--amber, #f59e0b) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .kc-inbox-btn.has-unread .kc-inbox-pip { animation: none; }
}

/* ── DRAWER OVERLAY ─────────────────────────────────────────── */
.kci-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.36);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 1900;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}
.kci-overlay.show { opacity: 1; pointer-events: auto; }

.kci-drawer {
  position: fixed;
  top: 0; right: 0;
  width: 460px;
  max-width: 100vw;
  height: 100vh;
  height: 100dvh;
  background: var(--card, #13131f);
  border-left: 1px solid var(--border, #1e1e2e);
  z-index: 1901;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 220ms ease;
  box-shadow: -8px 0 32px rgba(0,0,0,0.4);
}
.kci-overlay.show .kci-drawer { transform: translateX(0); }

/* ── DRAWER HEAD ─────────────────────────────────────────────── */
.kci-head {
  padding: 14px 14px 0;
  border-bottom: 1px solid var(--border, #1e1e2e);
  flex-shrink: 0;
}
.kci-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.kci-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: var(--w-bold, 600);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-bright);
}
.kci-title .kc-ic { color: var(--amber, #f59e0b); }
.kci-head-actions { display: flex; gap: 4px; align-items: center; }
.kci-ico-btn {
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-mid);
  cursor: pointer;
  padding: 5px 9px;
  border-radius: 6px;
  font-size: 11px;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.kci-ico-btn:hover {
  color: var(--text-bright);
  border-color: rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.03);
}
.kci-ico-btn.is-close { font-size: 16px; padding: 3px 9px; }
.kci-ico-btn .kc-ic { width: 12px; height: 12px; }

/* Icon-only header buttons (gear + close) share one square so they read as a
   matched pair and their hover frames line up exactly. Scoped to these two —
   the text buttons (Mark all / Clear) keep their pill padding. */
.kci-ico-btn.is-close,
.kci-ico-btn#kciSettingsBtn {
  width: 28px;
  height: 28px;
  padding: 0;
  justify-content: center;
  line-height: 1;
}
.kci-ico-btn.is-close { font-size: 18px; }
.kci-ico-btn#kciSettingsBtn .kc-ic { width: 14px; height: 14px; }

/* Mark all read button — brass when there's something to clear,
   muted + non-clickable when there isn't. The state flips via the
   `.hot` class and the `disabled` attribute, both set by JS in
   _refreshMarkAllBtn(). Brass weight (500 in JS but visually 600
   here) draws the eye to the right action when unread > 0. */
.kci-ico-btn#kciMarkAllBtn.hot {
  color: var(--accent, #d4a335);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 35%, transparent);
  background: color-mix(in srgb, var(--accent, #d4a335) 8%, transparent);
  font-weight: 600;
}
.kci-ico-btn#kciMarkAllBtn.hot:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 55%, transparent);
  background: color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
}
.kci-ico-btn#kciMarkAllBtn[disabled] {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

/* Clear button — oxblood, destructive accent. Subtle at rest, stronger
   on hover; greyed + non-clickable when the tab has nothing to clear.
   Hidden entirely on the Challenges tab (set via JS display:none). */
.kci-ico-btn.kci-clear-btn {
  color: color-mix(in srgb, var(--oxblood, #a83232) 78%, var(--text-mid));
  border-color: color-mix(in srgb, var(--oxblood, #a83232) 28%, transparent);
}
.kci-ico-btn.kci-clear-btn:hover {
  color: #e0a0a0;
  border-color: color-mix(in srgb, var(--oxblood, #a83232) 55%, transparent);
  background: color-mix(in srgb, var(--oxblood, #a83232) 12%, transparent);
}
.kci-ico-btn.kci-clear-btn[disabled] {
  opacity: 0.4;
  cursor: default;
  pointer-events: none;
}

/* ── TABS ────────────────────────────────────────────────────── */
.kci-tabs {
  display: flex;
  gap: 0;
  margin-bottom: -1px;
}
.kci-tab {
  position: relative;
  flex: 1;
  border: none;
  background: transparent;
  padding: 10px 0 11px;
  font-size: 11px;
  font-weight: var(--w-bold, 600);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: color 0.15s;
}
.kci-tab:hover { color: var(--text-mid); }
.kci-tab.is-active { color: var(--text-bright); }
.kci-tab.is-active::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--amber, #f59e0b);
}
.kci-tab-pip {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 9px;
  min-width: 16px;
  text-align: center;
  background: var(--amber, #f59e0b);
  color: #1a1a22;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}
.kci-tab-pip.muted {
  background: rgba(255,255,255,0.06);
  color: var(--muted);
}
.kci-tab-pip[hidden] { display: none; }

/* ── FILTER CHIPS ────────────────────────────────────────────── */
.kci-filt {
  display: flex;
  gap: 6px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border, #1e1e2e);
  overflow-x: auto;
  flex-wrap: nowrap;
  flex-shrink: 0;
}
.kci-filt::-webkit-scrollbar { display: none; }
.kci-filt { scrollbar-width: none; }
.kci-chip {
  font-family: inherit;
  font-size: 10.5px;
  letter-spacing: 0.4px;
  padding: 4px 10px;
  border: 1px solid var(--border, #1e1e2e);
  border-radius: 99px;
  background: transparent;
  color: var(--text-mid);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.kci-chip:hover {
  border-color: rgba(255,255,255,0.18);
  color: var(--text-bright);
}
.kci-chip.is-active {
  background: var(--text-bright);
  color: var(--bg, #0a0a14);
  border-color: var(--text-bright);
}

/* ── LIST ────────────────────────────────────────────────────── */
.kci-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0 12px;
}
.kci-list::-webkit-scrollbar { width: 6px; }
.kci-list::-webkit-scrollbar-thumb {
  background: var(--border, #1e1e2e);
  border-radius: 3px;
}
.kci-day {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  padding: 12px 14px 4px;
}
.kci-row {
  display: flex;
  gap: 10px;
  padding: 10px 14px;
  border-left: 2px solid transparent;
  border-bottom: 1px solid color-mix(in srgb, var(--border, #1e1e2e) 60%, transparent);
  cursor: pointer;
  transition: background 0.12s;
}
.kci-row:hover { background: rgba(255,255,255,0.02); }
.kci-row.unread {
  background: color-mix(in srgb, var(--accent, #d4a335) 5%, transparent);
}

/* Type-specific left bar + tinted background on unread */
.kci-row.t-triggered    { border-left-color: var(--accent, #7c4dff); }
.kci-row.t-won-partial  { border-left-color: color-mix(in srgb, var(--up, #00d4aa) 65%, white); }
.kci-row.t-won          { border-left-color: var(--up, #00d4aa); }
.kci-row.t-won-trail    { border-left-color: var(--up, #00d4aa); }
.kci-row.t-lost         { border-left-color: var(--down, #ef4444); }
.kci-row.t-expiring-soon{ border-left-color: var(--amber, #f59e0b); }
.kci-row.t-progress75   { border-left-color: color-mix(in srgb, var(--accent, #7c4dff) 65%, white); }
.kci-row.t-auto-expired { border-left-color: var(--muted, #a0a0c0); }
.kci-row.t-kol-call     { border-left-color: var(--yellow, #facc15); }
.kci-row.t-receipt      { border-left-color: transparent; }
/* Bet outcome variants — betSettled rows render with one of these
   based on extra.outcome (win → won/green, loss → red, void → muted).
   Borrows the existing won/lost/auto-expired colors so the visual
   language stays consistent: a "Bet · won" looks the same green as
   a "T2 · won" because they're the same kind of news. */
.kci-row.t-bet-won      { border-left-color: var(--up, #00d4aa); }
.kci-row.t-bet-lost     { border-left-color: var(--down, #ef4444); }
.kci-row.t-bet-void     { border-left-color: var(--muted, #a0a0c0); }
.kci-row.t-price-alert  { border-left-color: var(--accent, #d4a335); }
/* 'update' kind = silent platform-update notification (changelog → inbox).
   Brass left bar to match the Razor Alpha accent — visually distinct from
   the other activity receipts which are intentionally muted. */
.kci-row.t-update       { border-left-color: var(--accent, #d4a335); background: color-mix(in srgb, var(--accent, #d4a335) 4%, transparent); }
.kci-row.t-update:hover { background: color-mix(in srgb, var(--accent, #d4a335) 7%, transparent); }

.kci-row.unread.t-triggered    { background: color-mix(in srgb, var(--accent, #7c4dff) 9%, transparent); }
.kci-row.unread.t-won-partial,
.kci-row.unread.t-won,
.kci-row.unread.t-won-trail    { background: color-mix(in srgb, var(--up, #00d4aa) 9%, transparent); }
.kci-row.unread.t-lost         { background: color-mix(in srgb, var(--down, #ef4444) 9%, transparent); }
.kci-row.unread.t-expiring-soon{ background: color-mix(in srgb, var(--amber, #f59e0b) 10%, transparent); }
.kci-row.unread.t-kol-call     { background: color-mix(in srgb, var(--yellow, #facc15) 9%, transparent); }
.kci-row.unread.t-bet-won      { background: color-mix(in srgb, var(--up, #00d4aa) 9%, transparent); }
.kci-row.unread.t-bet-lost     { background: color-mix(in srgb, var(--down, #ef4444) 9%, transparent); }
.kci-row.unread.t-bet-void     { background: color-mix(in srgb, var(--accent, #d4a335) 5%, transparent); }
.kci-row.unread.t-price-alert  { background: color-mix(in srgb, var(--accent, #d4a335) 9%, transparent); }

.kci-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 6px;
  background: var(--muted);
}
.kci-dot.t-triggered    { background: var(--accent, #7c4dff); }
.kci-dot.t-won-partial  { background: color-mix(in srgb, var(--up, #00d4aa) 65%, white); }
.kci-dot.t-won,
.kci-dot.t-won-trail    { background: var(--up, #00d4aa); }
.kci-dot.t-lost         { background: var(--down, #ef4444); }
.kci-dot.t-expiring-soon{ background: var(--amber, #f59e0b); }
.kci-dot.t-progress75   { background: color-mix(in srgb, var(--accent, #7c4dff) 65%, white); }
.kci-dot.t-auto-expired { background: var(--muted, #a0a0c0); }
.kci-dot.t-kol-call     { background: var(--yellow, #facc15); }
.kci-dot.t-bet-won      { background: var(--up, #00d4aa); }
.kci-dot.t-bet-lost     { background: var(--down, #ef4444); }
.kci-dot.t-bet-void     { background: var(--muted, #a0a0c0); }
.kci-dot.t-price-alert  { background: var(--accent, #d4a335); }
.kci-dot.t-receipt      { background: var(--muted, #a0a0c0); opacity: 0.6; }
.kci-dot.t-update       { background: var(--accent, #d4a335); }

/* Read-state dot variants — used by every row in Events + Activity.
   `.kci-dot--new` is the brass-filled unread marker with a soft halo
   so it pops against the dark surface; `.kci-dot--read` is a hollow
   ring so the column stays visually consistent across rows (the
   layout doesn't reflow when a row is marked read). */
.kci-dot.kci-dot--new {
  background: var(--accent, #d4a335);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #d4a335) 22%, transparent);
}
.kci-dot.kci-dot--read {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--muted, #a0a0c0) 40%, transparent);
  width: 7px;
  height: 7px;
  margin-top: 6px;
}

.kci-body { flex: 1; min-width: 0; }
.kci-r-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 3px;
}
.kci-r-tt {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: var(--w-bold, 600);
  color: var(--text-bright);
  min-width: 0;
}
.kci-r-tt .kci-sym {
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kci-r-tt .kci-side {
  font-size: 10px;
  color: var(--muted);
  text-transform: lowercase;
  letter-spacing: 0.3px;
}
.kci-typ {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 3px;
  background: rgba(255,255,255,0.06);
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
}
.kci-typ.t-triggered    { background: color-mix(in srgb, var(--accent, #7c4dff) 18%, transparent); color: var(--accent, #7c4dff); }
.kci-typ.t-won-partial  { background: color-mix(in srgb, var(--up, #00d4aa) 16%, transparent); color: color-mix(in srgb, var(--up, #00d4aa) 80%, white); }
.kci-typ.t-won,
.kci-typ.t-won-trail    { background: color-mix(in srgb, var(--up, #00d4aa) 22%, transparent); color: var(--up, #00d4aa); }
.kci-typ.t-lost         { background: color-mix(in srgb, var(--down, #ef4444) 20%, transparent); color: var(--down, #ef4444); }
.kci-typ.t-expiring-soon{ background: color-mix(in srgb, var(--amber, #f59e0b) 22%, transparent); color: var(--amber, #f59e0b); }
.kci-typ.t-progress75   { background: color-mix(in srgb, var(--accent, #7c4dff) 14%, transparent); color: color-mix(in srgb, var(--accent, #7c4dff) 80%, white); }
.kci-typ.t-auto-expired { background: rgba(255,255,255,0.06); color: var(--muted); }
.kci-typ.t-kol-call     { background: color-mix(in srgb, var(--yellow, #facc15) 22%, transparent); color: var(--yellow, #facc15); }
.kci-typ.t-bet-won      { background: color-mix(in srgb, var(--up, #00d4aa) 22%, transparent); color: var(--up, #00d4aa); }
.kci-typ.t-bet-lost     { background: color-mix(in srgb, var(--down, #ef4444) 20%, transparent); color: var(--down, #ef4444); }
.kci-typ.t-bet-void     { background: rgba(255,255,255,0.06); color: var(--muted); }
.kci-typ.t-receipt      { background: rgba(255,255,255,0.04); color: var(--muted); }
.kci-typ.t-update       { background: color-mix(in srgb, var(--accent, #d4a335) 22%, transparent); color: var(--accent, #d4a335); }
.kci-typ.t-price-alert  { background: color-mix(in srgb, var(--accent, #d4a335) 20%, transparent); color: var(--accent, #d4a335); }

.kci-r-time {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  flex-shrink: 0;
  white-space: nowrap;
}
.kci-r-msg {
  font-size: 11.5px;
  color: var(--text-mid);
  line-height: 1.45;
  margin-bottom: 3px;
}
.kci-r-msg b, .kci-r-msg strong {
  color: var(--text-bright);
  font-weight: var(--w-bold, 600);
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.3px;
}
.kci-r-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.kci-act {
  font-size: 10.5px;
  letter-spacing: 0.3px;
  padding: 3px 9px;
  border-radius: 5px;
  border: 1px solid var(--border, #1e1e2e);
  background: transparent;
  color: var(--text-mid);
  cursor: pointer;
  font-family: inherit;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.kci-act:hover {
  color: var(--text-bright);
  border-color: rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.03);
}
.kci-act.primary {
  border-color: var(--accent, #7c4dff);
  color: var(--accent, #7c4dff);
}
.kci-act.primary:hover {
  background: color-mix(in srgb, var(--accent, #7c4dff) 14%, transparent);
}
.kci-act.danger {
  border-color: color-mix(in srgb, var(--down, #ef4444) 50%, transparent);
  color: var(--down, #ef4444);
}
.kci-r-dismiss {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
  margin-left: auto;
  font-family: inherit;
}
.kci-r-dismiss:hover { color: var(--down, #ef4444); }

/* Empty / muted-tab states */
.kci-empty {
  padding: 60px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}
.kci-empty .kc-ic { color: var(--muted); margin-bottom: 8px; }
.kci-empty-title {
  color: var(--text-bright);
  font-size: 13px;
  font-weight: var(--w-bold, 600);
  margin-bottom: 6px;
}

/* ── FOOTER META ─────────────────────────────────────────────── */
.kci-foot {
  padding: 9px 14px;
  border-top: 1px solid var(--border, #1e1e2e);
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.4px;
  color: var(--muted);
  text-transform: lowercase;
  flex-shrink: 0;
}
.kci-foot a {
  color: var(--text-mid);
  cursor: pointer;
  text-decoration: none;
}
.kci-foot a:hover { color: var(--text-bright); }

/* ── SETTINGS SUB-PANEL ─────────────────────────────────────── */
.kci-settings {
  display: none;
  flex: 1;
  overflow-y: auto;
  padding: 14px;
}
.kci-settings.show { display: block; }
.kci-settings::-webkit-scrollbar { width: 6px; }
.kci-settings::-webkit-scrollbar-thumb {
  background: var(--border, #1e1e2e);
  border-radius: 3px;
}
.kci-set-h {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 18px 0 8px;
}
.kci-set-h:first-child { margin-top: 0; }
.kci-set-tbl {
  border: 1px solid var(--border, #1e1e2e);
  border-radius: 8px;
  overflow: hidden;
  background: rgba(255,255,255,0.015);
}
.kci-set-thead, .kci-set-row {
  display: grid;
  grid-template-columns: 1fr 50px 50px 50px;
  align-items: center;
  font-size: 11px;
}
.kci-set-thead {
  padding: 8px 12px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--muted);
  background: rgba(255,255,255,0.02);
  border-bottom: 1px solid var(--border, #1e1e2e);
}
.kci-set-thead > span:not(:first-child) { text-align: center; }
.kci-set-row {
  padding: 9px 12px;
  border-top: 1px solid color-mix(in srgb, var(--border, #1e1e2e) 70%, transparent);
}
.kci-set-row:first-of-type { border-top: none; }
.kci-set-row .lbl {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-bright);
  min-width: 0;
}
.kci-set-row .lbl .swatch {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.kci-set-row.locked .lbl { color: var(--muted); }
.kci-set-row.locked { opacity: 0.55; }
.kci-set-row.is-channel {
  grid-template-columns: 1fr 50px;
}

.kci-tier-pill {
  font-family: 'Space Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.6px;
  padding: 1px 5px;
  border-radius: 3px;
  background: rgba(255,255,255,0.06);
  color: var(--muted);
  text-transform: uppercase;
  margin-left: 6px;
  font-weight: 700;
}
.kci-tier-pill.paid {
  background: color-mix(in srgb, var(--accent, #7c4dff) 18%, transparent);
  color: var(--accent, #7c4dff);
}

/* Toggle switch */
.kci-tog {
  position: relative;
  width: 28px;
  height: 16px;
  background: rgba(255,255,255,0.10);
  border-radius: 99px;
  cursor: pointer;
  justify-self: center;
  border: none;
  padding: 0;
  transition: background 0.15s;
}
.kci-tog::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--text-mid);
  transition: left 150ms ease, background 0.15s;
}
.kci-tog.on { background: color-mix(in srgb, var(--up, #00d4aa) 50%, transparent); }
.kci-tog.on::after { left: 14px; background: var(--up, #00d4aa); }
.kci-tog.locked { opacity: 0.35; cursor: not-allowed; }
.kci-set-note {
  font-size: 10.5px;
  color: var(--muted);
  line-height: 1.55;
  padding: 10px 2px 0;
}

/* v2 settings — master channel rows carry a muted helper line, and the
   per-event tags gain soon/opt-in variants (full-taxonomy redesign). */
.kci-set-row.is-channel .lbl { flex-direction: column; align-items: flex-start; gap: 2px; }
.kci-set-row.is-channel .lbl .lbl-main { display: flex; align-items: center; gap: 6px; }
.kci-set-sub { font-size: 10px; color: var(--muted); line-height: 1.3; }
.kci-tier-pill.soon { background: color-mix(in srgb, var(--accent3, #378ADD) 18%, transparent); color: var(--accent3, #378ADD); }
.kci-tier-pill.optin { background: rgba(255,255,255,0.06); color: var(--text-mid, #9aa0a8); }

/* v2 settings — sub-tab strip (Option A split) + locked-column hint. */
.kci-set-subtabs {
  display: flex;
  gap: 2px;
  margin: 0 0 12px;
  overflow-x: auto;
  border-bottom: 0.5px solid var(--border, #1e1e2e);
  scrollbar-width: none;
}
.kci-set-subtabs::-webkit-scrollbar { display: none; }
.kci-set-subtab {
  flex: 0 0 auto;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-mid, #9aa0a8);
  font-family: inherit;
  font-size: 11.5px;
  padding: 7px 9px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.12s, border-color 0.12s;
}
.kci-set-subtab:hover { color: var(--text-bright); }
.kci-set-subtab.on { color: var(--accent, #d4a335); border-bottom-color: var(--accent, #d4a335); }
.kci-set-hint {
  font-size: 11px;
  color: var(--text-mid, #9aa0a8);
  line-height: 1.45;
  background: rgba(255,255,255,0.025);
  border-radius: var(--radius-sm, 6px);
  padding: 8px 10px;
  margin-bottom: 12px;
}
.kci-set-hint strong { color: var(--accent, #d4a335); font-weight: 600; }

/* ── Telegram channel row + Connect-Telegram sub-view (Option B) ──── */
.kci-tg-chrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-top: 1px solid color-mix(in srgb, var(--border, #1e1e2e) 70%, transparent);
}
.kci-tg-chrow .lbl { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; flex: 1; }
.kci-tg-chrow .lbl-main { color: var(--text-bright); font-size: 12.5px; font-weight: 500; }
.kci-tg-rsub { font-size: 10px; color: var(--muted); line-height: 1.3; }
.kci-tg-rsub a { color: var(--accent, #d4a335); cursor: pointer; text-decoration: none; }
.kci-tg-rsub a:hover { text-decoration: underline; }
.kci-tg-connect {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--accent, #d4a335);
  color: #211807;
  border: none;
  border-radius: 7px;
  padding: 6px 11px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.12s;
}
.kci-tg-connect:hover { filter: brightness(1.08); }

.kci-tg-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 4px 8px 10px;
}
.kci-tg-back {
  align-self: flex-start;
  background: none;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  padding: 2px 0 6px;
  transition: color 0.12s;
}
.kci-tg-back:hover { color: var(--text-mid); }
.kci-tg-hero {
  width: 56px;
  height: 56px;
  margin-top: 6px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--border2, #3a3b42);
  color: #229ED9;
  font-size: 24px;
}
.kci-tg-hero.ok { border-color: color-mix(in srgb, var(--up, #6dd99c) 55%, transparent); color: var(--up, #6dd99c); }
.kci-tg-title { font-size: 15px; font-weight: 600; color: var(--text-bright); }
.kci-tg-copy { font-size: 12px; color: var(--text-mid, #c8c2b4); line-height: 1.5; max-width: 264px; }
.kci-tg-copy strong { color: var(--text-bright); font-weight: 600; }
.kci-tg-prim {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  background: var(--accent, #d4a335);
  color: #211807;
  border: none;
  border-radius: 8px;
  padding: 10px 18px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.12s;
}
.kci-tg-prim:hover { filter: brightness(1.08); }
.kci-tg-line {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid var(--border2, #3a3b42);
  color: var(--text-bright);
  border-radius: 8px;
  padding: 8px 14px;
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 0.12s;
}
.kci-tg-line:hover { border-color: var(--muted); }
.kci-tg-ghost {
  background: none;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.12s;
}
.kci-tg-ghost:hover { color: var(--text-mid); }
.kci-tg-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: color-mix(in srgb, var(--up, #6dd99c) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--up, #6dd99c) 30%, transparent);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--text-bright);
  font-size: 13px;
  font-weight: 500;
}
.kci-tg-note { font-size: 10px; color: var(--muted); line-height: 1.5; max-width: 264px; }
.kci-tg-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; justify-content: center; }
.kci-tg-ring {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--accent, #d4a335) 25%, transparent);
  border-top-color: var(--accent, #d4a335);
  animation: kciTgSpin 0.8s linear infinite;
}
@keyframes kciTgSpin { to { transform: rotate(360deg); } }

/* ── RESPONSIVE ─────────────────────────────────────────────── */
@media (max-width: 600px) {
  .kci-drawer { width: 100vw; border-left: none; }
  .kci-filt { padding: 8px 12px; }
  .kci-row { padding: 10px 12px; }
}
/* ═══════════════════════════════════════════════════════════════════
   RAZOR ALPHA · INTERACTIVITY LAYER (animations · empty states · previews)
   ───────────────────────────────────────────────────────────────────
   Appended 2026-05-06 alongside the matching JS at the end of
   shared.js. Provides:

     .kc-fx-payoff[--win|--loss|--fresh]   Brass blade swipe + glow
     .kc-stale-shake / .kc-stale-shake-once Gentle 4° wiggle
     .kc-paid-badge.kc-flip                One-shot 3D coin flip
     .kc-sym-pop                           Symbol hover popover
     .kc-empty                             Razor-Alpha empty state
     .dot.busy (extension)                 Faster pulse for active state

   Brand constants used:
     --accent      = green (wins)
     --kc-brass    = brass / oxblood = locally defined so the fx layer
                     reads the Razor Alpha aesthetic regardless of theme
   ═══════════════════════════════════════════════════════════════════ */

/* Razor Alpha brand tokens — used only by this fx layer. Pages are
   free to override these inline if they want theme-specific tweaks. */
:root {
  --kc-brass:  #d4a335;
  --kc-oxblood: #a83232;
}

/* ─── 1 · PAYOFF — brass blade swipe + glow ─────────────────────── */
.kc-fx-payoff {
  position: relative;
  isolation: isolate;            /* contain the swipe pseudo */
}
.kc-fx-payoff::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  z-index: 1;
}
.kc-fx-payoff--win::before {
  background: linear-gradient(120deg,
    transparent 25%,
    color-mix(in srgb, var(--kc-brass) 30%, transparent) 50%,
    transparent 75%);
  animation: kcBladeSwipe 0.9s cubic-bezier(.2, .7, .3, 1) forwards;
}
.kc-fx-payoff--win {
  animation: kcWinPulse 0.55s ease 0.25s 1;
}
.kc-fx-payoff--loss {
  animation: kcLossPulse 0.5s ease 1;
}
.kc-fx-payoff--fresh {
  animation: kcFreshArrive 1.2s ease 1;
}
@keyframes kcBladeSwipe {
  0%   { transform: translateX(-110%); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translateX(110%); opacity: 0; }
}
@keyframes kcWinPulse {
  0%, 100% { box-shadow: 0 0 0 1px transparent, 0 0 0 0 transparent; }
  45%      {
    box-shadow:
      0 0 0 1px var(--kc-brass),
      0 0 30px color-mix(in srgb, var(--kc-brass) 45%, transparent);
  }
}
@keyframes kcLossPulse {
  0%, 100% { box-shadow: 0 0 0 1px transparent; }
  50%      { box-shadow: 0 0 0 1px var(--kc-oxblood), 0 0 18px color-mix(in srgb, var(--kc-oxblood) 35%, transparent); }
}
@keyframes kcFreshArrive {
  0%   { box-shadow: 0 0 0 1px transparent, 0 0 0 0 transparent; }
  30%  { box-shadow: 0 0 0 1px var(--kc-brass), 0 0 24px color-mix(in srgb, var(--kc-brass) 40%, transparent); }
  100% { box-shadow: 0 0 0 1px transparent, 0 0 0 0 transparent; }
}

/* ─── 2 · STALE SHAKE — gentle wiggle ───────────────────────────── */
.kc-stale-shake {
  /* Slow infinite wiggle: tiny rotation every 12s so it sits at the
     edge of vision rather than in your face. */
  animation: kcStaleNudge 12s ease-in-out infinite;
  transform-origin: 50% 50%;
}
.kc-stale-shake-once {
  animation: kcShakeOnce 0.6s cubic-bezier(.25, .8, .35, 1) 1;
  transform-origin: 50% 50%;
}
@keyframes kcStaleNudge {
  0%, 92%, 100% { transform: rotate(0); }
  93%           { transform: rotate(-1.2deg); }
  95%           { transform: rotate(1.2deg); }
  97%           { transform: rotate(-0.6deg); }
}
@keyframes kcShakeOnce {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-3px); }
  40%      { transform: translateX(3px); }
  60%      { transform: translateX(-2px); }
  80%      { transform: translateX(2px); }
}

/* ─── 3 · PAID BADGE COIN-FLIP ──────────────────────────────────── */
/* The kc-paid-badge module sets pointer-events:none, but we still need
   the badge to be a 3D-flip-capable element. Adding a .kc-flip class
   gives it a one-shot 360° flip + brass shimmer. The trick to keeping
   text legible during the flip: front and back face of the badge use
   the same content so it never reads as "blank" mid-flip. */
.kc-paid-badge {
  transform-style: preserve-3d;
  perspective: 240px;
  transition: transform 0.18s cubic-bezier(.2, .7, .3, 1);
}
.kc-paid-badge.kc-flip {
  animation: kcPaidFlip 0.55s cubic-bezier(.2, .7, .3, 1);
}
@keyframes kcPaidFlip {
  0%   { transform: rotateY(0); filter: brightness(1); }
  50%  { filter: brightness(1.4); }
  100% { transform: rotateY(360deg); filter: brightness(1); }
}
/* Hover-on-host: a subtle shimmer that hints the cost. Restrained —
   no full pulse loop, just a one-cycle highlight. */
[data-paid-provider]:hover > .kc-paid-badge,
[data-paid-provider]:hover + .kc-paid-badge {
  filter: brightness(1.15);
}

/* ─── 4 · BUSY DOT — extension to existing .dot pattern ─────────── */
/* Existing pages mark "work in progress" by adding .busy on a hero-
   badge dot (e.g. #plsBusyDot). The base .dot animation is
   kcPulse (1.4s). When .busy, swap to a tighter, brighter pulse so
   "platform is alive" reads distinctly from "platform is working
   right now". This is purely additive — pages that already use
   .dot.busy automatically benefit without any JS change. */
.kc-hero-badge .dot.busy,
.ra-badge .dot.busy {
  animation: kcBusyPulse 0.7s ease-in-out infinite;
  /* Slight enlargement so it's perceptibly more energetic than calm. */
  box-shadow:
    0 0 14px var(--accent, #1fd687),
    0 0 30px color-mix(in srgb, var(--accent, #1fd687) 55%, transparent);
}
@keyframes kcBusyPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(0.78); }
}

/* ─── 5 · SYMBOL PREVIEW POPOVER ────────────────────────────────── */
.kc-sym-pop {
  position: absolute;
  top: 0; left: 0;
  width: 280px;
  background: var(--bg2, #1a1a20);
  border: 1px solid var(--border, #2a2a30);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: 'Space Mono', monospace;
  color: var(--text, #e4e4e7);
  font-size: 12px;
  z-index: 10000;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s linear 0.14s;
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.5),
    0 0 0 1px color-mix(in srgb, var(--kc-brass) 22%, transparent);
  pointer-events: auto;
}
.kc-sym-pop.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s linear 0s;
}
html.kc-sym-pop-disabled .kc-sym-pop { display: none !important; }

.kc-sym-pop-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 4px;
}
.kc-sym-pop-tick {
  color: var(--kc-brass);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.5px;
}
.kc-sym-pop-ex {
  font-size: 9.5px;
  color: var(--muted, #9aa0a6);
  text-transform: uppercase;
  letter-spacing: 1.2px;
}
.kc-sym-pop-price-row {
  display: flex; align-items: baseline; gap: 8px;
}
.kc-sym-pop-price {
  font-size: 20px;
  font-weight: 700;
  color: var(--text, #e4e4e7);
  font-variant-numeric: tabular-nums;
}
.kc-sym-pop-chg {
  font-size: 12px;
  color: var(--muted, #9aa0a6);
  font-variant-numeric: tabular-nums;
}
.kc-sym-pop-chg.pos { color: var(--accent, #1fd687); }
.kc-sym-pop-chg.neg { color: var(--red, #ff7b7b); }

.kc-sym-pop-spark {
  margin: 8px 0 6px;
  min-height: 38px;
}
.kc-sym-pop-spark-empty {
  height: 38px;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--text, #e4e4e7) 4%, transparent) 0%,
    color-mix(in srgb, var(--text, #e4e4e7) 8%, transparent) 50%,
    color-mix(in srgb, var(--text, #e4e4e7) 4%, transparent) 100%
  );
  background-size: 200% 100%;
  animation: kcSparkSkel 1.2s ease-in-out infinite;
}
@keyframes kcSparkSkel {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.kc-sym-pop-foot {
  display: flex; justify-content: space-between;
  font-size: 10px;
  color: var(--muted, #9aa0a6);
  padding-top: 8px;
  border-top: 1px solid color-mix(in srgb, var(--border, #2a2a30) 80%, transparent);
  margin-top: 6px;
}
.kc-sym-pop-cta {
  color: var(--kc-brass);
  letter-spacing: 0.5px;
}

.kc-sym-pop-acts {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.kc-sym-pop-act {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 10.5px;
  line-height: 1;
  padding: 6px 0;
  border-radius: 6px;
  border: 1px solid var(--border, #2a2a30);
  color: var(--text, #c9cace);
  background: transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.kc-sym-pop-act:hover {
  border-color: color-mix(in srgb, var(--kc-brass) 50%, transparent);
}
.kc-sym-pop-act:disabled { opacity: 0.55; cursor: default; }
/* The class above sets display:flex, which outranks the UA sheet's
   [hidden]{display:none} — without this rule a hidden button still paints.
   Used by ⚡ Read, which stays out of the row until Binance confirms. */
.kc-sym-pop-act[hidden] { display: none; }

/* ── touch: the symbol card opens as a bottom sheet ──────────────────
   Set by KCSymbolPreview when a TAP opens the card (hover never sets it, so
   desktop is untouched). The base rule is an absolutely-positioned 280px
   card with inline top/left written by _position; sheet mode clears those
   inline values and takes over with fixed docking, so !important is only
   needed where the inline style would otherwise win.
   The huge spread shadow paints the scrim without adding a backdrop element —
   and because a shadow never captures pointer events, a tap on the dimmed
   area still reaches the document handler that closes the card. */
@media (max-width: 640px) {
  .kc-sym-pop--sheet {
    position: fixed !important;
    top: auto !important;
    left: 0 !important;
    right: 0;
    bottom: 0;
    width: 100%;
    padding: 10px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    transform: translateY(100%);
    box-shadow:
      0 -8px 40px rgba(0, 0, 0, 0.55),
      0 0 0 100vmax rgba(0, 0, 0, 0.5);
  }
  .kc-sym-pop--sheet.show { transform: translateY(0); }
  /* Grab handle — a sheet affordance without touching the popover's DOM. */
  .kc-sym-pop--sheet::before {
    content: '';
    display: block;
    width: 38px;
    height: 4px;
    border-radius: 3px;
    background: var(--border2, #33333c);
    margin: 0 auto 12px;
  }
  /* Desktop hit-sizes are too small for a thumb once the row is full-width. */
  .kc-sym-pop--sheet .kc-sym-pop-acts { gap: 8px; }
  .kc-sym-pop--sheet .kc-sym-pop-act {
    padding: 12px 0;
    font-size: 12px;
    border-radius: 8px;
  }
  .kc-sym-pop--sheet .kc-sym-pop-spark { height: 56px; }
}
.kc-sym-pop-act.on {
  color: var(--kc-brass);
  border-color: color-mix(in srgb, var(--kc-brass) 50%, transparent);
  background: color-mix(in srgb, var(--kc-brass) 10%, transparent);
}

/* ── ≡ list button + watchlist view ── */
.kc-sym-pop-headright { display: flex; align-items: center; gap: 8px; }
.kc-sym-pop-list {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--border, #2a2a30) 90%, transparent);
  color: var(--muted, #9aa0a6);
  cursor: pointer;
  font-size: 12px; line-height: 1;
  padding: 3px 6px; border-radius: 5px;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.kc-sym-pop-list:hover {
  color: var(--kc-brass);
  border-color: color-mix(in srgb, var(--kc-brass) 45%, transparent);
  background: color-mix(in srgb, var(--kc-brass) 8%, transparent);
}

.kc-sym-pop-whead { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.kc-sym-pop-wnav {
  width: 22px; height: 22px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--border, #2a2a30);
  border-radius: 5px;
  color: var(--muted, #9aa0a6);
  font-size: 14px; line-height: 1; cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}
.kc-sym-pop-wnav:hover { color: var(--kc-brass); border-color: color-mix(in srgb, var(--kc-brass) 45%, transparent); }
.kc-sym-pop-wtitle {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700; font-size: 12px; letter-spacing: 0.5px;
  color: var(--text, #e4e4e7);
}
.kc-sym-pop-wcount { font-size: 10px; color: var(--muted, #9aa0a6); font-variant-numeric: tabular-nums; }
.kc-sym-pop-wx { margin-left: auto; }

.kc-sym-pop-wbody { max-height: 240px; overflow-y: auto; margin: 0 -4px; }
.kc-sym-pop-wrow {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 4px;
  border-bottom: 1px solid color-mix(in srgb, var(--border, #2a2a30) 55%, transparent);
  cursor: pointer;
}
.kc-sym-pop-wrow:last-child { border-bottom: none; }
.kc-sym-pop-wrow:hover { background: color-mix(in srgb, var(--text, #e4e4e7) 4%, transparent); }
.kc-sym-pop-wdot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.kc-sym-pop-wsym { font-weight: 700; font-size: 11.5px; color: var(--text, #e4e4e7); min-width: 56px; line-height: 1.15; }
.kc-sym-pop-wsym small {
  display: block; font-weight: 400; font-size: 9px;
  color: var(--muted, #9aa0a6); letter-spacing: 0.4px;
  text-transform: uppercase; margin-top: 1px;
}
.kc-sym-pop-wpx {
  font-size: 11px; color: var(--text, #e4e4e7);
  font-variant-numeric: tabular-nums;
  margin-left: auto; text-align: right; min-width: 52px;
}
.kc-sym-pop-wcg { font-size: 10.5px; color: var(--muted, #9aa0a6); font-variant-numeric: tabular-nums; text-align: right; min-width: 46px; }
.kc-sym-pop-wcg.pos { color: var(--accent, #1fd687); }
.kc-sym-pop-wcg.neg { color: var(--red, #ff7b7b); }
.kc-sym-pop-wrm {
  background: transparent; border: none;
  color: color-mix(in srgb, var(--muted, #9aa0a6) 70%, transparent);
  font-size: 13px; line-height: 1; cursor: pointer; padding: 0 2px; flex: none;
}
.kc-sym-pop-wrm:hover { color: var(--red, #ff7b7b); }

.kc-sym-pop-wempty { text-align: center; color: var(--muted, #9aa0a6); font-size: 11.5px; padding: 18px 8px; line-height: 1.5; }
.kc-sym-pop-wempty .sub { display: block; font-size: 10px; margin-top: 4px; opacity: 0.8; }

.kc-sym-pop-wunlock {
  width: 100%; margin-top: 8px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.5px;
  color: var(--kc-brass);
  background: color-mix(in srgb, var(--kc-brass) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--kc-brass) 32%, transparent);
  border-radius: 7px; padding: 8px 0; cursor: pointer;
  transition: background 0.12s ease;
}
.kc-sym-pop-wunlock:hover { background: color-mix(in srgb, var(--kc-brass) 16%, transparent); }
.kc-sym-pop-wfootnote { text-align: center; font-size: 10px; color: var(--muted, #9aa0a6); padding-top: 8px; margin-top: 4px; }

/* ─── DEX card (Option A — stat grid) ──────────────────────────────
   On-chain fallback for tokens not on Binance. Reuses the CEX card's
   head / price-row / action-row; only the symbol, venue, price, % and
   the 2×2 stat grid are dex-specific. */
.kc-sym-pop-dtick {
  color: var(--kc-brass);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.5px;
}
.kc-sym-pop-dvenue {
  font-size: 9.5px;
  color: var(--muted, #9aa0a6);
  text-transform: uppercase;
  letter-spacing: 1.2px;
}
.kc-sym-pop-dprice {
  font-size: 20px;
  font-weight: 700;
  color: var(--text, #e4e4e7);
  font-variant-numeric: tabular-nums;
}
.kc-sym-pop-dchg {
  font-size: 12px;
  color: var(--muted, #9aa0a6);
  font-variant-numeric: tabular-nums;
}
.kc-sym-pop-dchg.pos { color: var(--accent, #1fd687); }
.kc-sym-pop-dchg.neg { color: var(--red, #ff7b7b); }
.kc-sym-pop-dgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin: 9px 0 4px;
}
.kc-sym-pop-dtile {
  background: color-mix(in srgb, var(--text, #e4e4e7) 5%, transparent);
  border-radius: 6px;
  padding: 7px 8px;
}
.kc-sym-pop-dtk {
  display: block;
  font-size: 9px;
  color: var(--muted, #9aa0a6);
  text-transform: uppercase;
  letter-spacing: 0.8px;
}
.kc-sym-pop-dtv {
  display: block;
  margin-top: 3px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text, #e4e4e7);
  font-variant-numeric: tabular-nums;
}

/* ─── 6 · EMPTY STATES ──────────────────────────────────────────── */
.kc-empty {
  text-align: center;
  padding: 36px 24px;
  font-family: 'Space Mono', monospace;
  color: var(--muted, #9aa0a6);
}
.kc-empty--compact {
  padding: 22px 16px;
}
.kc-empty-art {
  margin: 0 auto 14px;
  width: 48px;
  height: 48px;
  color: var(--kc-brass);
  opacity: 0.85;
  display: flex;
  align-items: center;
  justify-content: center;
}
.kc-empty--compact .kc-empty-art {
  width: 36px;
  height: 36px;
  margin-bottom: 10px;
}
.kc-empty--compact .kc-empty-art svg {
  width: 36px;
  height: 36px;
}
/* Subtle idle motion on the blade illustration only — restrained. */
.kc-empty-art .kce-blade {
  transform-origin: center;
  animation: kceTilt 4s ease-in-out infinite;
}
@keyframes kceTilt {
  0%, 100% { transform: rotate(-50deg); }
  50%      { transform: rotate(-40deg); }
}
.kc-empty-art .kce-rings,
.kc-empty-art .kce-pip {
  transform-origin: center;
  animation: kceBreathe 3.6s ease-in-out infinite;
}
@keyframes kceBreathe {
  0%, 100% { opacity: 0.85; }
  50%      { opacity: 1; }
}
.kc-empty-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text, #e4e4e7);
  margin-bottom: 6px;
}
.kc-empty--compact .kc-empty-title { font-size: 11px; margin-bottom: 4px; }
.kc-empty-msg {
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--muted, #9aa0a6);
  margin: 0 auto 12px;
  max-width: 36ch;
}
.kc-empty--compact .kc-empty-msg { font-size: 11px; max-width: 32ch; margin-bottom: 10px; }
.kc-empty-cta {
  background: transparent;
  color: var(--kc-brass);
  border: 1px solid color-mix(in srgb, var(--kc-brass) 50%, transparent);
  padding: 6px 14px;
  border-radius: 4px;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.kc-empty-cta:hover {
  background: color-mix(in srgb, var(--kc-brass) 10%, transparent);
  border-color: color-mix(in srgb, var(--kc-brass) 70%, transparent);
}

/* ─── 7 · REDUCED MOTION ────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .kc-fx-payoff::before { animation: none; opacity: 0; }
  .kc-fx-payoff--win,
  .kc-fx-payoff--loss,
  .kc-fx-payoff--fresh { animation: none; }
  /* Use a static brass border for 1.5s instead of animation. */
  .kc-fx-payoff--win,
  .kc-fx-payoff--fresh {
    box-shadow: 0 0 0 1px var(--kc-brass);
  }
  .kc-fx-payoff--loss {
    box-shadow: 0 0 0 1px var(--kc-oxblood);
  }
  .kc-stale-shake,
  .kc-stale-shake-once { animation: none; }
  .kc-paid-badge.kc-flip { animation: none; }
  .kc-empty-art .kce-blade,
  .kc-empty-art .kce-rings,
  .kc-empty-art .kce-pip { animation: none; }
  .kc-hero-badge .dot.busy,
  .ra-badge .dot.busy { animation: none; }
  .kc-sym-pop { transition: opacity 0s, transform 0s, visibility 0s; }
  .kc-sym-pop-spark-empty { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   REFERRALS DRAWER (Razor Alpha) — slide-in from right
   ───────────────────────────────────────────────────────────────────
   Mirrors the .krz-panel chassis (480px desktop, full-width mobile,
   right-edge slide-in) so the Referrals drawer is visually a sibling
   of the Razors drawer one row up in the sidebar foot. Selectors use
   the .krf- prefix to stay scoped — no overlap with .krz- or .kci-.

   Companion JS: KCReferrals IIFE in shared.js. v1 = shell only;
   numbers come from KCReferrals.store (placeholder until backend).
   ═══════════════════════════════════════════════════════════════════ */

/* ── Sidebar-foot button ───────────────────────────────────── */
.kc-referrals-btn {
  position: relative;
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.01));
  border: 1px solid rgba(255,255,255,0.06);
  color: var(--text-mid);
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 1px 2px rgba(0,0,0,0.2);
  transition: color 0.15s, border-color 0.15s, background 0.15s, box-shadow 0.15s;
  padding: 0;
}
.kc-referrals-btn:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 35%, transparent);
  color: var(--accent, #d4a335);
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent, #d4a335) 10%, rgba(255,255,255,0.05)), rgba(255,255,255,0.01));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px color-mix(in srgb, var(--accent, #d4a335) 18%, transparent);
}
.kc-referrals-btn .kc-ic { display: inline-block; }

/* ── Drawer overlay + slide-in ─────────────────────────────── */
.krf-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.krf-overlay:not([hidden]) { display: block; }
.krf-panel {
  position: fixed;
  top: 0; right: 0;
  /* Match .krz-panel — compensate for body `zoom: var(--kc-font-scale)` */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.krf-overlay.show .krf-panel { transform: translateX(0); }

/* ── Head ──────────────────────────────────────────────────── */
.krf-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.krf-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
}
.krf-panel-title .krf-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.krf-panel-title .kc-explainer-btn {
  margin-left: 4px;
  position: relative;
  top: 0; right: 0;
}
.krf-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.krf-panel-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
}
.krf-panel-close:hover { color: var(--text-bright); background: rgba(255,255,255,0.04); }

/* ── Meta strip (subtitle below head) ─────────────────────── */
.krf-meta {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.3px;
  flex-shrink: 0;
}

/* ── Body (scrollable) ────────────────────────────────────── */
.krf-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px 24px;
  overscroll-behavior: contain;
}

/* ── Section + section-head + window seg ─────────────────── */
.krf-section {
  margin-bottom: 14px;
}
.krf-section-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 8px;
}
.krf-section-label .kc-ic {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

.krf-section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 18px 0 10px;
  gap: 10px;
}
.krf-section-title {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.krf-section-title b {
  color: var(--text-bright);
  font-weight: 700;
}

.krf-seg {
  display: inline-flex;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  overflow: hidden;
  flex-shrink: 0;
}
.krf-seg button {
  background: transparent;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.4px;
  padding: 4px 10px;
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.krf-seg button.active {
  color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
}
.krf-seg button:not(.active):hover { color: var(--text-bright); }

/* ── Link row ──────────────────────────────────────────────── */
.krf-link-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
}
.krf-link-input {
  flex: 1;
  min-width: 0;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 8px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-bright);
  line-height: 1.3;
  letter-spacing: 0.2px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  /* Prevent zoom on iOS focus */
  -webkit-text-size-adjust: 100%;
}
.krf-link-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent, #d4a335) 45%, var(--border2));
}
.krf-link-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-mid);
  padding: 6px 10px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 600;
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.krf-link-btn:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.krf-link-btn .kc-ic {
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.krf-link-btn.is-ok {
  color: var(--green, #4ade80);
  border-color: color-mix(in srgb, var(--green, #4ade80) 45%, var(--border2));
}

/* ── Mechanics chips ───────────────────────────────────────── */
.krf-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}
.krf-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 999px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.4px;
  color: var(--text-mid);
  white-space: nowrap;
}
.krf-chip .kc-ic {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

/* ── 4-up stat cards ─────────────────────────────────────── */
.krf-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.krf-stat {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 6px;
  padding: 10px 12px;
  min-width: 0;
}
.krf-stat-label {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.krf-stat-val {
  font-family: 'Space Mono', monospace;
  font-size: 18px;
  font-weight: 700;
  color: var(--text-bright);
  font-feature-settings: 'tnum';
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.krf-stat-val.is-accent {
  color: var(--accent, #d4a335);
}
.krf-stat-sub {
  font-size: 9px;
  color: var(--muted);
  margin-top: 3px;
  font-feature-settings: 'tnum';
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.krf-stat-locked {
  color: var(--accent, #d4a335);
}

/* ── Earnings history table ──────────────────────────────── */
.krf-history {
  margin-top: 0;
}
.krf-tbl-wrap {
  border: 1px solid var(--border2);
  border-radius: 6px;
  overflow: hidden;
  background: var(--page-bg, #0a0a13);
}
.krf-tbl {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
  table-layout: fixed;
}
.krf-tbl thead tr {
  background: rgba(255,255,255,0.025);
}
.krf-tbl th {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border2);
}
.krf-tbl td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text-mid);
  font-feature-settings: 'tnum';
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.krf-tbl tbody tr:last-child td {
  border-bottom: none;
}
/* Column widths — tuned for the 480px drawer width minus padding.
   Status column widened (and date/who/pack trimmed) so the
   "Locked · 23h" / "Confirming · n/m" pills render in full. */
.krf-tbl .col-date   { width: 18%; }
.krf-tbl .col-who    { width: 20%; color: var(--text-bright); }
.krf-tbl .col-pack   { width: 12%; }
.krf-tbl .col-amt    { width: 16%; text-align: right; }
.krf-tbl .col-status { width: 34%; text-align: right; }
.krf-tbl .krf-amt {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  color: var(--accent, #d4a335);
}
.krf-tbl .krf-amt.is-reversed {
  color: var(--muted);
  text-decoration: line-through;
  font-weight: 400;
}

/* ── Status pills ────────────────────────────────────────── */
.krf-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.3px;
  border: 1px solid transparent;
  white-space: nowrap;
  /* No self-clipping: the pill sizes to its content and the (now wider)
     status column gives it room. Previously max-width/overflow/ellipsis
     here truncated "Locked · unlocks in 23h" down to "Locked · u…". */
}
.krf-pill .kc-ic {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  flex-shrink: 0;
}
.krf-pill.is-credited {
  background: color-mix(in srgb, var(--green, #4ade80) 14%, transparent);
  border-color: color-mix(in srgb, var(--green, #4ade80) 30%, transparent);
  color: var(--green, #4ade80);
}
.krf-pill.is-locked {
  background: color-mix(in srgb, var(--yellow, #ffd166) 14%, transparent);
  border-color: color-mix(in srgb, var(--yellow, #ffd166) 30%, transparent);
  color: var(--yellow, #ffd166);
}
.krf-pill.is-confirming {
  background: color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
  color: var(--accent, #d4a335);
}
.krf-pill.is-reversed {
  background: color-mix(in srgb, var(--red, #ff4d6d) 12%, transparent);
  border-color: color-mix(in srgb, var(--red, #ff4d6d) 28%, transparent);
  color: var(--red, #ff4d6d);
}

/* ── Empty state (history) ──────────────────────────────── */
.krf-empty {
  text-align: center;
  padding: 28px 16px;
  background: var(--page-bg, #0a0a13);
  border: 1px dashed var(--border2);
  border-radius: 6px;
}
.krf-empty-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent, #d4a335) 10%, transparent);
  color: color-mix(in srgb, var(--accent, #d4a335) 70%, transparent);
  margin-bottom: 10px;
}
.krf-empty-msg {
  font-size: 12px;
  color: var(--text-mid);
  margin-bottom: 4px;
  font-weight: 600;
}
.krf-empty-hint {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.5;
  max-width: 320px;
  margin: 0 auto;
}

/* ── Footer note ────────────────────────────────────────── */
.krf-footnote {
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 10px;
  color: var(--muted);
  line-height: 1.55;
}
.krf-footnote b { color: var(--text-mid); font-weight: 600; }

/* ── Mobile ─────────────────────────────────────────────── */
@media (max-width: 720px) {
  .krf-panel { width: 100vw; max-width: 100vw; }
  .krf-body { padding: 14px 16px 22px; }
  .krf-panel-head { padding: 14px 16px 12px; }
  .krf-meta { padding: 9px 16px; }

  /* On narrow screens, drop to a 2x2 grid for the stat cards so the
     numbers stay readable. The 4-up packing gets too tight under the
     480→100vw drawer width. */
  .krf-stats {
    grid-template-columns: 1fr 1fr;
  }

  /* Tighten the table — Pack column hides on phones since the dollar
     amount is also implied by the earned-razors column, and the
     status pill is the most important read on mobile. */
  .krf-tbl .col-pack { display: none; }
  .krf-tbl th.col-pack, .krf-tbl td.col-pack { display: none; }
  .krf-tbl .col-date   { width: 26%; }
  .krf-tbl .col-who    { width: 24%; }
  .krf-tbl .col-amt    { width: 18%; }
  .krf-tbl .col-status { width: 32%; }
}

/* ── Reduced-motion ─────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .krf-panel { transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════════
   ADMIN MODE — gates internal-only UI
   ──────────────────────────────────────────────────────────────────
   Activated by KC.adminOn(token) or ?admin=<token>. See KCAdmin in
   shared.js. Anything tagged data-admin-only is hidden by default;
   the html[data-admin] / body.is-admin classes lift the gate.

   Important: the lift selector uses a high-specificity :is() so that
   the hide rule below is fully overridden, but does NOT set `display`
   to a fixed value — the gated element keeps whatever display the
   rest of the cascade gave it (inline-flex on the admin chip, none
   on a closed .settings-overlay, etc.). Setting `display: revert` or
   a fixed value here breaks any element with its own display lifecycle
   (modals that toggle open/closed via a class or inline style).
   ══════════════════════════════════════════════════════════════════ */
:where([data-admin-only]):not(:where(html[data-admin] *, body.is-admin *)) {
  display: none !important;
}

/* Admin mode indicator — when admin is on, the settings gear in the
   sidebar footer tints brass. Subtle status signal that uses an icon
   already present (no new chrome). Hover state still goes to accent.
   Tooltip swap happens via JS in shared.js renderNav binding. */
html[data-admin] .kc-sidebar .settings-gear,
html[data-admin] .kc-sb-foot .settings-gear,
body.is-admin     .kc-sidebar .settings-gear,
body.is-admin     .kc-sb-foot .settings-gear {
  color: var(--brass, #d4a335) !important;
  border-color: rgba(212, 163, 53, 0.32) !important;
  background:
    linear-gradient(180deg, rgba(212, 163, 53, 0.10), rgba(212, 163, 53, 0.02)) !important;
}
html[data-admin] .kc-sidebar .settings-gear:hover,
html[data-admin] .kc-sb-foot .settings-gear:hover,
body.is-admin     .kc-sidebar .settings-gear:hover,
body.is-admin     .kc-sb-foot .settings-gear:hover {
  color: var(--brass, #d4a335) !important;
  border-color: rgba(212, 163, 53, 0.55) !important;
  background:
    linear-gradient(180deg, rgba(212, 163, 53, 0.18), rgba(212, 163, 53, 0.04)) !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.07),
    0 0 12px rgba(212, 163, 53, 0.22) !important;
}

/* ═══════════════════════════════════════════════════════════════════
   RAZOR ALPHA · DASHBOARD INTERACTIVITY LAYER (v1)
   ───────────────────────────────────────────────────────────────────
   Appended 2026-05-08. Adds dashboard-specific micro-interactions on
   top of the existing kc-fx layer (kcBladeSwipe / kcWinPulse / kcPaidFlip).
   All effects respect prefers-reduced-motion via the global guard at
   the bottom of this block.

   New utilities:
     .kc-fx-mt-flash               One-shot brass flash on a market tile
                                   when its number ticks. 0.6s.
     .kc-fx-spark-draw             Sparkline stroke-dash reveal. 1.1s.
     .kc-fx-ring-tween             Ring arc transitions stroke-dasharray
                                   smoothly when set programmatically.
     .kc-fx-ring-breathe           Idle 4s scale 1.000 ↔ 1.018 on F&G ring.
     .kc-fx-prio-arrival           Priority row slide-down + brass swipe.
     .kc-fx-trace                  One-shot brass border trace on a card.
     .kc-fx-row-flash              Brass left-edge flash on a new row.
     .kc-fx-idle-halo              6s ambient brass halo (use sparingly).
     .kc-edge-flip                 Edge-strip chip 360° flip.
     .kc-edge-text-exit/-enter     Edge-strip text crossfade transitions.
     .kc-hub-card-fx               Hover micro-parallax on hub cards.
     .kc-razor-cursor              −45° brass blade cursor inside the el.

   The auto-fired version (.is-auto) uses CSS animations only; the JS
   helpers in KC.fx (shared.js) toggle classes on/off so the same
   keyframes can be re-triggered.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Market tile · flash on tick ───────────────────────────────────
   2026-10: follows the theme's up / down tokens (and Blue/orange market
   colours) instead of fixed brass / oxblood. */
.kc-fx-mt-flash {
  animation: kcFxMtFlash 0.65s cubic-bezier(0.2, 0.7, 0.2, 1);
}
@keyframes kcFxMtFlash {
  0%   { box-shadow: inset 0 0 0 1px transparent, 0 0 0 0 transparent; }
  18%  { box-shadow:
          inset 0 0 0 1px color-mix(in srgb, var(--up, var(--kc-brass)) 38%, transparent),
          0 0 12px -2px color-mix(in srgb, var(--up, var(--kc-brass)) 26%, transparent); }
  100% { box-shadow: inset 0 0 0 1px transparent, 0 0 0 0 transparent; }
}
/* Down-tick variant — the theme's down colour. */
.kc-fx-mt-flash.kc-fx-down {
  animation-name: kcFxMtFlashDown;
}
@keyframes kcFxMtFlashDown {
  0%   { box-shadow: inset 0 0 0 1px transparent; }
  18%  { box-shadow:
          inset 0 0 0 1px color-mix(in srgb, var(--red, var(--kc-oxblood)) 38%, transparent),
          0 0 12px -2px color-mix(in srgb, var(--red, var(--kc-oxblood)) 24%, transparent); }
  100% { box-shadow: inset 0 0 0 1px transparent; }
}

/* ─── Sparkline · stroke-dash draw-on ────────────────────────────── */
/* Applied to the <path> inside an .mt-spark SVG. JS measures path
   length and sets --kc-spark-len so the dasharray stays accurate even
   for paths of varying length. */
.kc-fx-spark-draw {
  stroke-dasharray: var(--kc-spark-len, 240);
  stroke-dashoffset: var(--kc-spark-len, 240);
  animation: kcFxSparkDraw 1.1s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
@keyframes kcFxSparkDraw {
  to { stroke-dashoffset: 0; }
}

/* ─── F&G / BTC.D ring · smooth dasharray tween + idle breathe ─── */
.kc-fx-ring-tween {
  transition: stroke-dasharray 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.kc-fx-ring-breathe {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  animation: kcFxRingBreathe 4.2s ease-in-out infinite;
}
@keyframes kcFxRingBreathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.018); }
}

/* ─── Priority row · arrival slide + brass swipe ────────────────── */
/* Applied by JS to a .rz-hub-prio-row that wasn't in the previous
   render. One-shot. The pseudo-element runs the swipe; the row itself
   slides down. */
.rz-hub-prio-row.kc-fx-prio-arrival {
  position: relative;
  overflow: hidden;
  animation: kcFxPrioArrive 0.85s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.rz-hub-prio-row.kc-fx-prio-arrival::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(110deg,
    transparent 25%,
    color-mix(in srgb, var(--kc-brass) 32%, transparent) 50%,
    transparent 75%);
  /* `forwards` is critical — without it the ::after snaps back to its
     base state at animation end (gradient centered, opacity 1), which
     causes a brief brass band to flash in the middle of the row for
     the ~50ms gap between animation end (900ms) and JS class cleanup
     (950ms). With `forwards` it stays parked at translateX(110%) /
     opacity 0 until the class is removed. The original payoff usage
     of kcBladeSwipe has `forwards` for the same reason. */
  animation: kcBladeSwipe 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  /* kcBladeSwipe is defined earlier in this stylesheet (line ~11624). */
}
@keyframes kcFxPrioArrive {
  0%   { transform: translateY(-6px); opacity: 0; }
  60%  { opacity: 1; }
  100% { transform: translateY(0);    opacity: 1; }
}

/* ─── Card · one-shot brass border trace ────────────────────────── */
/* Wraps a card via a child <svg class="kc-fx-trace-svg"><rect/></svg>.
   When the parent gains .kc-fx-trace, the rect strokes once around
   the perimeter and fades out. Used on hub cards when fresh data
   arrives. JS injects/removes the SVG on demand. */
.kc-fx-trace-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
  border-radius: inherit;
  overflow: visible;
}
.kc-fx-trace-svg rect {
  fill: none;
  stroke: var(--kc-brass);
  stroke-width: 1.5;
  rx: 8;
  ry: 8;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
  opacity: 0;
}
.kc-fx-trace .kc-fx-trace-svg rect {
  animation: kcFxTrace 1.4s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
@keyframes kcFxTrace {
  0%   { stroke-dashoffset: 600; opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { stroke-dashoffset: 0;   opacity: 0; }
}

/* ─── Row · brass left-edge flash ───────────────────────────────── */
/* For new rows arriving inside a card list (e.g. scanner card top-N).
   A 2px brass bar appears on the left edge and fades out. Subtle —
   the row itself doesn't need to slide because the parent card is
   already drawing attention via .kc-fx-trace. */
.kc-fx-row-flash {
  position: relative;
  animation: kcFxRowSlide 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.kc-fx-row-flash::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--kc-brass);
  animation: kcFxLeftFade 1.4s ease forwards;
  pointer-events: none;
}
@keyframes kcFxRowSlide {
  0%   { transform: translateY(-4px); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}
@keyframes kcFxLeftFade {
  0%   { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ─── Idle brass halo · ambient ──────────────────────────────────── */
/* 6s ease-in-out very faint brass glow. Use ONE element max per page
   (currently: priority strip when it has urgent items). */
.kc-fx-idle-halo {
  position: relative;
}
.kc-fx-idle-halo::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 0 0 transparent;
  animation: kcFxIdleHalo 6s ease-in-out infinite;
}
@keyframes kcFxIdleHalo {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50%      { box-shadow: 0 0 14px -4px color-mix(in srgb, var(--kc-brass) 32%, transparent); }
}

/* ─── Edge strip · chip flip + text crossfade ───────────────────── */
.rz-edge-chip {
  transform-style: preserve-3d;
  transition:
    transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1),
    background-color 0.45s ease,
    color 0.45s ease;
}
.rz-edge-chip.kc-edge-flip {
  animation: kcFxEdgeFlip 0.55s cubic-bezier(0.2, 0.7, 0.2, 1);
}
@keyframes kcFxEdgeFlip {
  0%   { transform: rotateY(0)    scale(1); }
  50%  { transform: rotateY(180deg) scale(1.04); filter: brightness(1.25); }
  100% { transform: rotateY(360deg) scale(1); }
}
.rz-edge-text {
  transition: opacity 0.32s ease, transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1);
  display: inline-block;
}
.rz-edge-text.kc-edge-text-exit  { opacity: 0; transform: translateY(-10px); }
.rz-edge-text.kc-edge-text-enter { opacity: 0; transform: translateY(10px);  }

/* The chip becomes clickable when the strip is wired to rotate. The
   rest of the strip stays static. JS adds .is-clickable when the
   handler is attached. */
.rz-edge-chip.is-clickable {
  cursor: pointer;
  user-select: none;
}
.rz-edge-chip.is-clickable:hover {
  filter: brightness(1.15);
}

/* ─── Hub card · hover micro-parallax ───────────────────────────── */
/* Tiny 1-2px shifts on the inner text, plus a brass corner glow that
   fades in on hover. Only the wrapped class gets it so we don't
   accidentally apply this to every hub card if the existing CSS
   already styles them — pages opt in by adding .kc-hub-card-fx to
   the hub container, which delegates to all children. */
.kc-hub-card-fx .rz-hub-card {
  transition:
    border-color 0.18s,
    background 0.18s,
    transform 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
  position: relative;
  overflow: hidden;
}
.kc-hub-card-fx .rz-hub-card::after {
  content: '';
  position: absolute;
  right: -50px;
  top: -50px;
  width: 110px;
  height: 110px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--rz-tint, var(--accent, var(--kc-brass))) 18%, transparent) 0%,
    transparent 70%);
  opacity: 0;
  transition: opacity 0.25s ease;
  pointer-events: none;
  z-index: 0;
}
.kc-hub-card-fx .rz-hub-card:hover { transform: translateY(-1px); }
.kc-hub-card-fx .rz-hub-card:hover::after { opacity: 1; }
.kc-hub-card-fx .rz-hub-card-title,
.kc-hub-card-fx .rz-hub-card-headline,
.kc-hub-card-fx .rz-hub-card-num,
.kc-hub-card-fx .rz-hub-card-sub {
  transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1);
  position: relative;
  z-index: 1;
}
.kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-title { transform: translateX(2px); }
.kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-num   { transform: translateY(-1px); }
.kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-sub   { transform: translateX(1px); }

/* ─── Razor cursor zone ─────────────────────────────────────────── */
/* Inline SVG razor at -45° as the pointer. The SVG is keyframe-stable
   and small enough to inline as a data URI. Hot-spot is centered on
   the blade pivot so the cursor lands where the user expects. */
.kc-razor-cursor,
.kc-razor-cursor * {
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'><g transform='rotate(-45 14 14)'><rect x='6' y='12' width='16' height='4' fill='%23d4a335' stroke='%23a83232' stroke-width='0.5'/><rect x='9' y='10' width='10' height='2' fill='%23a83232'/></g></svg>") 14 14, pointer;
}

/* ─── Reduced motion · global guard for this fx layer ──────────── */
@media (prefers-reduced-motion: reduce) {
  .kc-fx-mt-flash,
  .kc-fx-spark-draw,
  .kc-fx-ring-tween,
  .kc-fx-ring-breathe,
  .rz-hub-prio-row.kc-fx-prio-arrival,
  .rz-hub-prio-row.kc-fx-prio-arrival::after,
  .kc-fx-trace .kc-fx-trace-svg rect,
  .kc-fx-row-flash,
  .kc-fx-row-flash::before,
  .kc-fx-idle-halo::after,
  .rz-edge-chip,
  .rz-edge-chip.kc-edge-flip,
  .rz-edge-text {
    animation: none !important;
    transition: none !important;
  }
  .kc-fx-spark-draw {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  /* Hover parallax — keep the colour change, drop the transform. */
  .kc-hub-card-fx .rz-hub-card,
  .kc-hub-card-fx .rz-hub-card-title,
  .kc-hub-card-fx .rz-hub-card-num,
  .kc-hub-card-fx .rz-hub-card-sub {
    transition: border-color 0.18s, background 0.18s !important;
    transform: none !important;
  }
  .kc-hub-card-fx .rz-hub-card:hover { transform: none; }
  .kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-title,
  .kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-num,
  .kc-hub-card-fx .rz-hub-card:hover .rz-hub-card-sub { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════
   MAINTENANCE MODE OVERLAY (KCMaintenance)
   Full-screen lockout shown when admin sets maintenance_banner.
   Sits above everything (z-index very high). Pulls the brass+oxblood
   palette so it feels native to Razor Alpha rather than a generic error.
   ════════════════════════════════════════════════════════════════════ */
#kc-maintenance-overlay{
  position:fixed; inset:0; z-index: 99999;
  background:
    radial-gradient(ellipse 800px 400px at 80% -10%, rgba(212,163,53,.06), transparent 60%),
    radial-gradient(ellipse 600px 300px at 20% 110%, rgba(168,50,50,.05), transparent 60%),
    rgba(11,10,9,.985);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  display:flex; align-items:center; justify-content:center;
  padding:40px 22px;
  animation: kc-mm-fade 220ms ease both;
  color: var(--kc-ink, #e8e1cf);
  font-family: var(--font-ui, "Space Grotesk"), system-ui, sans-serif;
}
@keyframes kc-mm-fade { from{opacity:0} to{opacity:1} }
#kc-maintenance-overlay .kc-mm-card{
  max-width: 460px; width: 100%; text-align: center;
  background: #141210;
  border: 1px solid rgba(212,163,53,.14);
  border-radius: 14px;
  padding: 44px 32px 36px;
  box-shadow: 0 24px 80px -20px rgba(0,0,0,.6), 0 8px 24px -6px rgba(0,0,0,.4);
}
#kc-maintenance-overlay .kc-mm-mark{
  width: 64px; height: 64px; border-radius: 50%;
  background: linear-gradient(135deg, rgba(212,163,53,.18), transparent);
  border: 1px solid #d4a335;
  display: inline-flex; align-items: center; justify-content: center;
  margin: 0 auto 22px;
  color: #d4a335;
}
#kc-maintenance-overlay .kc-mm-title{
  font-size: 22px; font-weight: 600; margin: 0 0 12px;
  letter-spacing: -.01em; color: #e8e1cf;
}
#kc-maintenance-overlay .kc-mm-body{
  font-size: 14.5px; color: #9a8f78;
  margin: 0 0 22px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
}
#kc-maintenance-overlay .kc-mm-hint{
  font-family: "Space Mono", ui-monospace, monospace;
  font-size: 11px; letter-spacing: .08em;
  color: #5a5345; text-transform: uppercase;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid rgba(255,255,255,.06);
}

/* Prevent body scroll/interaction while overlay is up */
body:has(#kc-maintenance-overlay){
  overflow: hidden !important;
}
/* ═══════════════════════════════════════════════════════════════════
   KCSupport · threaded support ticket drawer
   ───────────────────────────────────────────────────────────────────
   Mounted in the floating quick-control dock as the 4th button
   (.kc-qc-act-support, between Razor AI ✦ and Capture-idea).
   Drawer chassis mirrors .kbr-panel and .ka-panel so font-scale +
   overflow behaviour are consistent across all right-anchored
   panels on the platform. Brass --accent drives state colors;
   oxblood stays reserved for paid-API badges per platform rules.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Dock-pill button color ──────────────────────────────────────
   Support chip is teal/mint — distinct from the brass Razor AI hero,
   the violet Writer, and the yellow Capture. Matches variant 3 of
   the May 2026 dock redesign. */
.kc-qc-act-support {
  color: color-mix(in srgb, #5fc4a8 80%, white);
  background: color-mix(in srgb, #5fc4a8 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #5fc4a8 24%, transparent);
}
.kc-qc-act-support:hover {
  background: color-mix(in srgb, #5fc4a8 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #5fc4a8 38%, transparent);
}
/* When unread badge is showing, give the button a gentle pulse to
   draw the eye without being obnoxious. Pulse colour matches the
   teal chip so it reads as the same affordance, not a state change. */
.kc-qc-act-support.has-unread .kc-qc-pill-count {
  animation: kcsSupportPulse 1.8s ease-out infinite;
}
@keyframes kcsSupportPulse {
  0%, 60%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #5fc4a8 50%, transparent); }
  30% { box-shadow: 0 0 0 4px color-mix(in srgb, #5fc4a8 0%, transparent); }
}

/* ── Overlay + panel chassis ─────────────────────────────────── */
.kcs-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.kcs-panel-overlay:not([hidden]) { display: block; }
.kcs-panel {
  position: fixed;
  top: 0;
  right: 0;
  /* Match .kbr-panel — divide viewport height by font-scale so the
     panel fits when Appearance text-size slider is above 100%. */
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.kcs-panel-overlay.show .kcs-panel { transform: translateX(0); }
.kcs-panel.kcs-drag-over {
  outline: 2px dashed color-mix(in srgb, var(--accent, #d4a335) 60%, transparent);
  outline-offset: -8px;
}

/* ── Head ────────────────────────────────────────────────────── */
.kcs-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.kcs-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
  flex: 1;
}
.kcs-panel-title .kcs-glyph {
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.kcs-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.kcs-panel-close,
.kcs-back-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 22px;
  cursor: pointer;
  padding: 0;
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
  font-family: inherit;
}
.kcs-back-btn { font-size: 22px; }
.kcs-back-btn[hidden] { display: none; }
.kcs-panel-close:hover,
.kcs-back-btn:hover { color: var(--text-bright); background: rgba(255,255,255,0.04); }

/* ── View host (flex-1 region between head and footer) ──────── */
.kcs-view-host {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

/* ── Eyebrow line (compose) ─────────────────────────────────── */
.kcs-eyebrow {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--accent, #d4a335);
  flex-shrink: 0;
}

/* ── Body (scroll region) ───────────────────────────────────── */
.kcs-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 20px;
  overscroll-behavior: contain;
  min-height: 0;
}

/* ── Tab bar (list view) ────────────────────────────────────── */
.kcs-tabbar {
  display: flex;
  gap: 6px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.kcs-tab {
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 5px 11px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-mid);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.kcs-tab:hover { color: var(--text-bright); border-color: var(--text-mid); }
.kcs-tab.active {
  background: color-mix(in srgb, var(--accent, #d4a335) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
  color: var(--accent, #d4a335);
}
.kcs-tab-ct {
  font-size: 9px;
  opacity: 0.6;
}
.kcs-tab.active .kcs-tab-ct { opacity: 1; }

/* ── Ticket rows ────────────────────────────────────────────── */
.kcs-ticket {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 12px 0;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  transition: background 0.12s;
}
.kcs-ticket:hover { background: rgba(255,255,255,0.02); }
.kcs-ticket:last-child { border-bottom: none; }
.kcs-tk-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 5px;
}
.kcs-tk-id {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.5px;
}
.kcs-tk-status {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 3px;
  font-weight: 600;
}
.kcs-st-open {
  background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
  color: var(--accent, #d4a335);
}
.kcs-st-waiting {
  background: color-mix(in srgb, var(--red, #a83232) 15%, transparent);
  color: color-mix(in srgb, var(--red, #a83232) 65%, #ffb0b0);
}
.kcs-st-pending {
  background: color-mix(in srgb, var(--accent2, #b693f5) 14%, transparent);
  color: var(--accent2, #b693f5);
}
.kcs-st-resolved {
  background: rgba(120,120,120,0.15);
  color: var(--muted);
}
.kcs-tk-unread {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent, #d4a335);
  margin-left: auto;
  flex-shrink: 0;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #d4a335) 25%, transparent);
}
.kcs-tk-subject {
  font-size: 13px;
  color: var(--text-bright);
  line-height: 1.4;
  margin-bottom: 4px;
  font-weight: 500;
  /* Single-line clamp with ellipsis */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kcs-tk-meta {
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.3px;
}

/* ── Empty state ────────────────────────────────────────────── */
.kcs-empty {
  text-align: center;
  padding: 40px 20px;
  color: var(--muted);
}
.kcs-empty-title {
  font-size: 13px;
  color: var(--text-mid);
  margin-bottom: 6px;
  font-weight: 500;
}
.kcs-empty-sub {
  font-size: 11px;
  line-height: 1.5;
}

/* ── Form fields (compose view) ─────────────────────────────── */
.kcs-field { margin-bottom: 16px; }
.kcs-field:last-child { margin-bottom: 4px; }
.kcs-label {
  display: block;
  font-size: 10px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 600;
}
.kcs-label .kcs-req {
  color: var(--accent, #d4a335);
  margin-left: 2px;
}
.kcs-label .kcs-opt {
  color: var(--muted);
  letter-spacing: 0.6px;
  text-transform: none;
  font-size: 9px;
  font-weight: 400;
  margin-left: 4px;
  opacity: 0.7;
}

/* ── Topic pills ────────────────────────────────────────────── */
.kcs-pills {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.kcs-pill {
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 11px;
  color: var(--text-mid);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.kcs-pill:hover { color: var(--text-bright); border-color: var(--text-mid); }
.kcs-pill.active {
  border-color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
  color: var(--accent, #d4a335);
}

/* ── Inputs / textareas / selects ───────────────────────────── */
.kcs-input,
.kcs-select,
.kcs-textarea {
  width: 100%;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 9px 11px;
  color: var(--text-bright);
  font-family: inherit;
  font-size: 12px;
  line-height: 1.5;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.kcs-input:focus,
.kcs-select:focus,
.kcs-textarea:focus {
  outline: none;
  border-color: var(--accent, #d4a335);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
}
.kcs-textarea {
  resize: vertical;
  min-height: 100px;
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcs-counter {
  font-size: 9px;
  letter-spacing: 0.6px;
  color: var(--muted);
  text-align: right;
  margin-top: 4px;
  opacity: 0.7;
}
.kcs-hint {
  font-size: 10px;
  color: var(--muted);
  margin-top: 6px;
  line-height: 1.4;
}

/* ── Screenshot thumb row ───────────────────────────────────── */
.kcs-shot-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.kcs-shot-thumb {
  position: relative;
  width: 64px;
  height: 64px;
  border: 1px solid var(--border2);
  border-radius: 4px;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--page-bg, #0a0a13);
}
.kcs-shot-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.kcs-shot-x {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(0,0,0,0.7);
  color: #fff;
  border: none;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-family: inherit;
  transition: background 0.12s;
}
.kcs-shot-x:hover { background: var(--red, #ef4444); }
.kcs-shot-add {
  width: 64px;
  height: 64px;
  background: transparent;
  border: 1px dashed var(--border2);
  border-radius: 4px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-family: inherit;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}
.kcs-shot-add > span:first-child { font-size: 18px; line-height: 1; }
.kcs-shot-add-text {
  font-size: 9px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
.kcs-shot-add:hover:not(:disabled) {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.kcs-shot-add:disabled { cursor: not-allowed; opacity: 0.4; }

/* ── Footer (list + compose) ────────────────────────────────── */
.kcs-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding: 12px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--card);
}
.kcs-actions {
  display: flex;
  gap: 8px;
}
.kcs-btn {
  flex: 1;
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-mid);
  padding: 8px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 4px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.kcs-btn:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.kcs-btn.primary {
  background: var(--accent, #d4a335);
  border-color: var(--accent, #d4a335);
  color: #0a0a0f;
}
.kcs-btn.primary:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
}
.kcs-btn.primary:disabled,
.kcs-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.kcs-btn-full { flex: 1 1 100%; }

/* ── Thread view: conversation meta + messages ──────────────── */
.kcs-conv-meta {
  padding: 14px 20px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.kcs-conv-subject {
  font-size: 14px;
  color: var(--text-bright);
  margin-bottom: 8px;
  line-height: 1.4;
  font-weight: 500;
}
.kcs-conv-meta-row {
  display: flex;
  gap: 10px;
  align-items: center;
  font-size: 10px;
}
.kcs-conv-meta-sep {
  color: var(--muted);
  letter-spacing: 0.3px;
}
.kcs-conv-body {
  /* Inherit .kcs-body's scroll; override padding for tighter rows */
  padding: 10px 20px;
}

.kcs-msg {
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.kcs-msg:last-child { border-bottom: none; }
.kcs-msg-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 5px;
}
.kcs-msg-who {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 600;
}
.kcs-msg-who.user  { color: var(--text-mid); }
.kcs-msg-who.staff { color: var(--accent, #d4a335); }
.kcs-msg-time {
  font-size: 10px;
  color: var(--muted);
  margin-left: auto;
}
.kcs-msg-body {
  font-size: 12px;
  color: var(--text-bright);
  line-height: 1.55;
  word-wrap: break-word;
  /* Whitespace from data — let \n become <br> via JS, but preserve
     single-line wrapping behaviour. */
}
.kcs-msg-body a {
  color: var(--accent, #d4a335);
  text-decoration: underline;
  text-underline-offset: 2px;
  word-break: break-all;
}
.kcs-msg-shots {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.kcs-msg-shot {
  display: block;
  width: 72px;
  height: 72px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--border2);
}
.kcs-msg-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Reply box (thread view) ────────────────────────────────── */
.kcs-reply-box {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding: 10px 20px 14px;
  background: var(--card);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.kcs-reply-box .kcs-shot-row { gap: 6px; }
.kcs-reply-box .kcs-shot-row:empty { display: none; }
.kcs-reply-box .kcs-shot-thumb { width: 48px; height: 48px; }
.kcs-reply-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.kcs-reply-input {
  flex: 1;
  background: var(--page-bg, #0a0a13);
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 9px 11px;
  color: var(--text-bright);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.5;
  resize: none;
  min-height: 38px;
  max-height: 120px;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.kcs-reply-input:focus {
  outline: none;
  border-color: var(--accent, #d4a335);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 30%, transparent);
}
.kcs-reply-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.kcs-reply-attach {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--muted);
  width: 32px;
  height: 32px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  font-family: inherit;
  padding: 0;
  line-height: 1;
  transition: color 0.15s, border-color 0.15s;
}
.kcs-reply-attach:hover {
  color: var(--text-bright);
  border-color: var(--text-mid);
}
.kcs-send {
  background: var(--accent, #d4a335);
  border: 1px solid var(--accent, #d4a335);
  color: #0a0a0f;
  padding: 0 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s;
  min-height: 32px;
  white-space: nowrap;
}
.kcs-send:hover {
  background: color-mix(in srgb, var(--accent, #d4a335) 90%, #fff);
}
.kcs-send:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Mobile ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .kcs-panel { width: 100vw; max-width: 100vw; }
  .kcs-body, .kcs-conv-body { padding: 12px 16px; }
  .kcs-panel-head { padding: 14px 16px 12px; }
  .kcs-tabbar { padding: 10px 16px; }
  .kcs-eyebrow { padding: 9px 16px; }
  .kcs-conv-meta { padding: 12px 16px 10px; }
  .kcs-reply-box { padding: 9px 16px 12px; }
  .kcs-footer { padding: 10px 16px 14px; }
}

/* ── Reduced-motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .kcs-panel { transition: none !important; }
  .kc-qc-act-support.has-unread .kc-qc-pill-count { animation: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   KCChat — Floor drawer (Step 3 MVP)
   ═══════════════════════════════════════════════════════════════════
   Mirrors .kcs-panel / .ka-panel / .kbr-panel chassis:
     • Right-anchored slide-in, 480px wide, full viewport height
     • Backdrop overlay with blur, z-index 1500
     • Slide animation 0.22s cubic-bezier
   Drives the chat dock button (.kc-qc-act-chat) — inserted between
   Razor AI (✦) and Support (✉) by KCChat at runtime.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Dock-pill button color — calm conversational blue ─────────── */
.kc-qc-act-chat {
  color: color-mix(in srgb, #5fa8d3 80%, white);
  background: color-mix(in srgb, #5fa8d3 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #5fa8d3 24%, transparent);
}
.kc-qc-act-chat:hover {
  background: color-mix(in srgb, #5fa8d3 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #5fa8d3 38%, transparent);
}
.kc-qc-act-chat.has-unread .kc-qc-pill-count {
  animation: kccChatPulse 1.8s ease-out infinite;
}
@keyframes kccChatPulse {
  0%, 60%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #5fa8d3 50%, transparent); }
  30% { box-shadow: 0 0 0 4px color-mix(in srgb, #5fa8d3 0%, transparent); }
}

/* ── Overlay + panel chassis (mirrors .kcs-panel) ─────────────── */
.kcc-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5,5,10,0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1500;
  display: none;
  animation: kcFadeIn 0.18s ease;
}
.kcc-panel-overlay:not([hidden]) { display: block; }
.kcc-panel {
  position: fixed;
  top: 0;
  right: 0;
  height: calc(100vh / var(--kc-font-scale, 1));
  height: calc(100dvh / var(--kc-font-scale, 1));
  width: 480px;
  max-width: calc(92vw / var(--kc-font-scale, 1));
  background: var(--card);
  border-left: 1px solid var(--border2);
  box-shadow: -8px 0 24px rgba(0,0,0,0.4);
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
}
.kcc-panel-overlay.show .kcc-panel { transform: translateX(0); }

/* ── Head ────────────────────────────────────────────────────── */
.kcc-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  gap: 10px;
}
.kcc-panel-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 0;
  flex: 1;
}
.kcc-panel-title .kcc-glyph {
  color: #5fa8d3;
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.kcc-panel-title-text { display: inline-flex; align-items: baseline; gap: 8px; }
.kcc-panel-title-text small {
  font-size: 11px;
  font-weight: 400;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
}
.kcc-panel-title-text small .dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-success, #1fd687);
  margin-right: 4px;
  vertical-align: 1px;
}
.kcc-panel-head-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.kcc-panel-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 22px;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
  border-radius: 6px;
  transition: color .12s ease, background .12s ease;
}
.kcc-panel-close:hover {
  color: var(--text-bright);
  background: var(--bg2);
}
.kcc-panel-expand {
  background: transparent;
  border: none;
  color: var(--text-muted);
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 6px;
  transition: color .12s ease, background .12s ease;
}
.kcc-panel-expand:hover {
  color: var(--text-bright);
  background: var(--bg2);
}
.kcc-panel-expand .kc-ic { display: inline-flex; }

/* ── Active calls strip ─────────────────────────────────────────── */
.kcc-panel-calls {
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: var(--bg);
}
.kcc-calls-label {
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.08em;
  font-family: 'Space Mono', monospace;
  display: flex;
  align-items: center;
  gap: 6px;
}
.kcc-calls-label .kcc-calls-icon {
  color: var(--accent, #d4a335);
  font-size: 12px;
}
.kcc-calls-empty {
  font-size: 11px;
  color: var(--text-muted);
  text-align: center;
  padding: 8px 0 4px;
  opacity: 0.6;
}

/* ── Message stream ─────────────────────────────────────────────── */
.kcc-stream {
  flex: 1;
  overflow-y: auto;
  padding: 12px 20px;
  /* Reads the active chat palette's surface (defaults to var(--card)
     for Brass; explicit hex for Slate/Midnight/Sage/Oxblood). */
  background: var(--kcc-surface, var(--card));
  scrollbar-width: thin;
  /* Establish a positioned container so descendant .kcc-msg offsetTop
     is measured relative to the stream's top (not the document). The
     scroll-restore logic in KCChat._renderStream relies on this so
     periodic re-renders (presence polls, tier resolves, active-calls
     refresh, signal-resolution polls) don't drift the viewer's scroll
     position upward each tick. .kcc-stream__pill is a sibling, not a
     descendant, so this does NOT change pill anchoring. */
  position: relative;
}
.kcc-stream::-webkit-scrollbar { width: 6px; }
.kcc-stream::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}

.kcc-msg {
  display: flex;
  gap: 10px;
  padding: 7px 0;
  position: relative; /* anchor for .kcc-msg__delete (admin trash) */
}
.kcc-msg__avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  /* Style C — dark wax-seal aesthetic. Initials in the user's hue
     color sit inside a dark fill with a 1.5px colored ring. Hue
     rules below override the ring + text color per user; the
     default (no hue / app rows / pending) is brass. */
  background: var(--card, #13131f);
  border: 1.5px solid var(--accent, #d4a335);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-family: 'Space Mono', monospace;
  flex-shrink: 0;
  color: var(--accent, #d4a335);
  box-sizing: border-box;
  position: relative;            /* anchor for the X-verified seal */
}

/* ── X-verified seal — corner badge on the avatar (bottom-right). ──
   The seal markup is always present inside .kcc-msg__avatar; it stays
   hidden until KCChat stamps .is-x-verified on the wrapper once
   /v1/profile/by-handle resolves x_verified=true. The notch disc takes
   the stream surface colour so the seal reads as sitting in the corner. */
.kcc-msg__avatar .kc-xseal {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--kcc-surface, var(--card, #171513));
  color: var(--accent, #d4a335);
  display: none;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  box-sizing: border-box;
}
.kcc-msg__avatar.is-x-verified .kc-xseal { display: inline-flex; }
.kc-xseal svg { width: 12px; height: 12px; display: block; }

/* ── X-verified seal on the small list avatars (presence rail + board) ──
   These avatars are 26px (smaller than the chat avatar), so the seal is
   scaled down. Presence sits top-right to clear the green online dot at
   bottom-right; the board seal sits bottom-right like the chat one. */
.kcc-presence-avatar .kc-xseal,
.kcc-board__avatar .kc-xseal {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--kcc-surface, var(--card, #171513));
  color: var(--accent, #d4a335);
  display: none;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  box-sizing: border-box;
}
.kcc-presence-avatar .kc-xseal { top: -3px; right: -3px; }
.kcc-board__avatar   .kc-xseal { bottom: -3px; right: -3px; }
.kcc-presence-avatar.is-x-verified .kc-xseal,
.kcc-board__avatar.is-x-verified .kc-xseal { display: inline-flex; }
.kcc-presence-avatar .kc-xseal svg,
.kcc-board__avatar   .kc-xseal svg { width: 9px; height: 9px; }

/* ── X-verified seal + link on the profile-card avatar ──────────── */
.kc-profile-avatar { position: relative; }
.kc-profile-avatar .kc-xseal {
  position: absolute;
  bottom: -3px;
  right: -3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--card, #171513);
  color: var(--accent, #d4a335);
  display: none;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}
.kc-profile-avatar.is-x-verified .kc-xseal { display: inline-flex; }
.kc-profile-avatar .kc-xseal svg { width: 18px; height: 18px; }
.kc-profile-xchip { display: inline-flex; align-items: center; }
.kc-profile-xchip[hidden] { display: none; }
.kc-profile-xlink {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  gap: 2px;
  font-size: 11px;
  font-family: 'Space Mono', ui-monospace, monospace;
  color: var(--accent, #d4a335);
  text-decoration: none;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 32%, transparent);
  background: color-mix(in srgb, var(--accent, #d4a335) 8%, transparent);
}
.kc-profile-xlink:hover { background: color-mix(in srgb, var(--accent, #d4a335) 16%, transparent); }
.kc-profile-xlink-ext { font-size: 9px; opacity: 0.8; }

.kcc-msg__body { flex: 1; min-width: 0; }
.kcc-msg__meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.kcc-msg__handle {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-bright);
  font-family: 'Space Grotesk', system-ui, sans-serif;
}
.kcc-msg__time {
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
}
.kcc-msg__text {
  font-size: 13px;
  /* Use palette-scoped text var; falls back to --text. The palette
     defaults dim this a touch from --text-bright so chat reads as a
     calmer surface than the rest of the page. */
  color: var(--kcc-text, var(--text));
  line-height: 1.5;
  margin-top: 2px;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.kcc-day {
  text-align: center;
  margin: 10px 0;
  font-size: 10px;
  color: var(--text-muted);
  letter-spacing: 0.05em;
  font-family: 'Space Mono', monospace;
}
.kcc-empty {
  text-align: center;
  padding: 60px 20px;
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.6;
}

/* Render window — "show N earlier messages" row at the top of the stream
   (older history stays loaded; only the newest rows are painted). */
.kcc-older {
  display: flex;
  justify-content: center;
  padding: 10px 0 14px;
}
.kcc-older__btn {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--kcc-self, var(--brass, #d4a335));
  background: transparent;
  border: 1px solid var(--kcc-edge, var(--border));
  border-radius: 999px;
  padding: 6px 14px;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.kcc-older__btn:hover {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 8%, transparent);
}

/* ── Composer ───────────────────────────────────────────────────── */
/* ─── Composer — unified card ─────────────────────────────────────
   Single card wraps the input row + an internal toolbar row, so the
   composer reads as one surface instead of three separate buttons
   floating against the floor. The card has its own border + focus
   ring; the inner attach/emoji/send buttons drop their individual
   borders to keep visual weight low. */
.kcc-composer {
  background: var(--bg);
  padding: 12px 20px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.kcc-composer__card {
  background: var(--kcc-surface, var(--card));
  border: 1px solid var(--kcc-edge, var(--border2));
  border-radius: 8px;
  /* Slightly slower + gentler ease so the focus glow lands as a warm
     brass light coming up rather than a snap. Matches the considered
     pace of the rest of the chat micro-animations (pill rise 220ms,
     msg-in 220ms, presence pulse 2.4s). */
  transition: border-color 180ms cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow   180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-composer__card:focus-within {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 60%, var(--border2));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 8%, transparent);
}

/* ── Lift-on-scroll composer (inline floor) ──────────────────────────
   The composer is always a flush, in-flow bar at the bottom of the
   column — so it's never scrolled out of view. When the viewer scrolls
   UP into history, .kcc-inline__main gains .is-lifted (set by the
   stream scroll handler) and the composer lifts into a floating pill.
   It's transform + margin only — no in-flow → absolute switch — so the
   stream never reflows and the scroll position can't jump. Snaps back
   flush the instant the stream returns to bottom. Scoped to the inline
   mount; the drawer composer is untouched. The existing jump-to-latest
   pill + FAB ride along unchanged. */
.kcc-inline__main .kcc-composer {
  position: relative;
  transition: background 180ms ease, border-color 180ms ease;
}
.kcc-inline__main .kcc-composer__card {
  transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1),
              margin 220ms cubic-bezier(0.16, 1, 0.3, 1),
              border-radius 200ms ease,
              box-shadow 200ms ease,
              border-color 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-inline__main.is-lifted .kcc-composer {
  background: transparent;
  border-top-color: transparent;
}
.kcc-inline__main.is-lifted .kcc-composer__card {
  transform: translateY(-8px);
  margin-left: 6px;
  margin-right: 6px;
  border-radius: 14px;
  border-color: var(--border2);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.18);
}
@media (prefers-reduced-motion: reduce) {
  .kcc-inline__main .kcc-composer__card { transition: none; }
}

/* ─── Room lock — composer + banner ─────────────────────────────────
   When the admin locks the room, non-admin viewers get a brass strip
   banner above a dimmed composer. Input + send are disabled at the
   element level (JS sets .disabled); these styles communicate the
   state visually so it's obvious why the input isn't responding. */
.kcc-composer--locked .kcc-composer__card {
  opacity: 0.55;
  pointer-events: none;
  /* Pointer-events:none kills the focus ring too; that's fine because
     the input is disabled. Keep the border at the dormant color so it
     doesn't read as "active and waiting." */
  border-color: var(--border2);
  box-shadow: none;
}
.kcc-composer--locked .kcc-composer__card:focus-within {
  /* Override the focus-within rule above so a stale focus state can't
     paint brass on a locked composer. */
  border-color: var(--border2);
  box-shadow: none;
}
/* The lock banner sits in the .kcc-composer container, just above the
   .kcc-composer__card. JS injects/removes it via _applyRoomLockToComposer. */
.kcc-room-lock-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin: 0 0 10px;
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 35%, var(--border2));
  border-radius: 6px;
  color: var(--kcc-self, var(--brass, #d4a335));
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.kcc-room-lock-banner[hidden] { display: none; }
.kcc-room-lock-banner svg {
  width: 14px;
  height: 14px;
  display: block;
  flex-shrink: 0;
}

/* Drag-to-attach overlay — JS adds .kcc-composer__card--dragging when
   a file is being dragged over the composer (entered + not yet left).
   The card itself gets a brass dashed border via box-shadow inset, and
   a centered "Drop to attach" caption appears via ::after. Both are
   pointer-events: none so the underlying drop handler keeps receiving
   events from anywhere inside the card. Removed the moment the file
   is dropped, the drag leaves, or staging finishes. */
.kcc-composer__card { position: relative; }
.kcc-composer__card--dragging {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 14%, transparent),
    inset 0 0 0 1px var(--kcc-self, var(--brass, #d4a335));
}
.kcc-composer__card--dragging::before {
  /* Translucent brass wash so the staging hint reads against busy
     content (existing staged thumb, in-flight text). */
  content: '';
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
  animation: kcc-drag-wash-in 140ms ease-out;
}
.kcc-composer__card--dragging::after {
  content: 'Drop to attach';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--kcc-self, var(--brass, #d4a335));
  pointer-events: none;
  z-index: 2;
  animation: kcc-drag-wash-in 160ms ease-out;
}
@keyframes kcc-drag-wash-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-composer__card--dragging::before,
  .kcc-composer__card--dragging::after { animation: none; }
}
.kcc-composer__row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
}
.kcc-composer__input {
  flex: 1;
  background: transparent;
  border: 0;
  color: var(--text-bright);
  padding: 6px 6px;
  font-size: 13px;
  font-family: 'Space Mono', monospace;
  min-width: 0;
  outline: none;
}
.kcc-composer__input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.kcc-composer__send {
  background: var(--accent, #d4a335);
  color: #1a1408;
  border: none;
  padding: 6px 14px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  font-family: 'Space Mono', monospace;
  cursor: pointer;
  flex-shrink: 0;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: filter .12s ease, transform .12s ease;
}
.kcc-composer__send:hover { filter: brightness(1.1); }
.kcc-composer__send:active { transform: scale(0.97); }
.kcc-composer__send:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.kcc-composer__send-arrow {
  font-size: 13px;
  line-height: 1;
  transition: transform 140ms ease;
}
.kcc-composer__send:hover .kcc-composer__send-arrow {
  transform: translateX(2px);
}

/* Internal toolbar — slow mode, share signal, char counter. Sits
   below the input row, separated by a hairline. Compact mono text
   in muted tone; brass when active. */
.kcc-composer__toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border-top: 1px solid var(--border);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}
.kcc-composer__tool {
  background: transparent;
  border: 0;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  padding: 3px 6px;
  border-radius: 3px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  text-transform: lowercase;
  transition: background 100ms ease, color 100ms ease;
}
.kcc-composer__tool:hover {
  color: var(--text-bright);
  background: color-mix(in srgb, var(--text-bright, #fff) 4%, transparent);
}
.kcc-composer__tool[data-state="on"],
.kcc-composer__tool[aria-pressed="true"] {
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
}
.kcc-composer__tool svg {
  width: 10px;
  height: 10px;
  display: block;
}
.kcc-composer__cooldown {
  color: var(--kcc-self, var(--brass, #d4a335));
  font-weight: 500;
  padding: 0 4px;
}
.kcc-composer__counter {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  transition: color 120ms ease;
  white-space: nowrap;
}
.kcc-composer__counter.is-warn {
  color: #c9a046;
}
.kcc-composer__counter.is-over {
  color: var(--down, #d05a4a);
  font-weight: 500;
}

.kcc-composer__hint {
  font-size: 10px;
  color: var(--text-muted);
  margin-top: 6px;
  text-align: right;
}
.kcc-composer__hint--err { color: var(--accent-danger, #ff7a7a); }

/* ─── Typing indicator ─────────────────────────────────────────
   Floating row above the composer showing "@x is typing" + three
   bouncing dots. Hidden when no one's typing; fades in via the
   row's own opacity transition. */
.kcc-typing {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--text-muted);
  font-style: italic;
  min-height: 18px;
  opacity: 1;
  transition: opacity 140ms ease;
}
.kcc-typing[hidden] { display: none; }
.kcc-typing-label {
  letter-spacing: 0.02em;
}
.kcc-typing-dots {
  display: inline-flex;
  gap: 3px;
  align-items: center;
}
.kcc-typing-dots > span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--text-muted);
  animation: kcc-typing-bounce 1.1s ease-in-out infinite;
}
.kcc-typing-dots > span:nth-child(2) { animation-delay: 0.18s; }
.kcc-typing-dots > span:nth-child(3) { animation-delay: 0.36s; }
@keyframes kcc-typing-bounce {
  0%, 60%, 100% { transform: translateY(0);   opacity: 0.4; }
  30%           { transform: translateY(-3px); opacity: 1;   }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-typing-dots > span { animation: none; opacity: 0.7; }
}

/* ── Mobile: full-width panel ──────────────────────────────────── */
@media (max-width: 760px) {
  .kcc-panel { width: 100vw; max-width: 100vw; }
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .kcc-panel { transition: none !important; }
}

/* Pending state for optimistic messages — visible until server echo
   replaces them via realtime. Subtle dim so it doesn't look broken. */
.kcc-msg--pending .kcc-msg__text,
.kcc-msg--pending .kcc-msg__handle,
.kcc-msg--pending .kcc-msg__time {
  opacity: 0.65;
}

/* In-flight indicator: while the row is .kcc-msg--pending, swap the
   "just now" timestamp text for three pulsing brass dots. Reads as
   "still in transit" without shifting layout — the dots replace the
   timestamp glyph-for-glyph and disappear the moment the server echo
   strips the .kcc-msg--pending class and re-renders the row. */
.kcc-msg--pending .kcc-msg__time {
  /* Hide the underlying timestamp text without removing the node —
     using font-size 0 collapses the text-node width to zero while
     keeping the element measurable for the ::after dots. */
  font-size: 0;
  opacity: 1; /* override the 0.65 dim above for the dots themselves */
  color: transparent;
  line-height: 1; /* keep baseline stable when text collapses */
}
.kcc-msg--pending .kcc-msg__time::after {
  content: '• • •';
  font-size: 10px;
  letter-spacing: -1px;
  color: var(--kcc-self, var(--brass, #d4a335));
  font-family: 'Space Mono', monospace;
  animation: kcc-msg-pending-dots 1.2s ease-in-out infinite;
  display: inline-block;
}
@keyframes kcc-msg-pending-dots {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1;    }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-msg--pending .kcc-msg__time::after { animation: none; opacity: 0.7; }
}

/* ─── Chat — chat.html inline mount ─────────────────────────────────
   The full-page route at /chat.html embeds the same stream + composer
   the drawer uses, but inline inside the page body next to a right rail
   of online users. JS still drives renders against existing .kcc-stream,
   .kcc-msg*, .kcc-composer* classes — these rules are layout chrome
   only. Sized so the stream fills the viewport minus hero + chrome.
*/
/* ════════════════════════════════════════════════════════════════
   CHAT PALETTE VARIABLES — orthogonal to layout themes.

   Each chat surface (.kcc-inline for inline mounts, .kcc-panel-overlay
   for the slide-in drawer) carries a [data-kcc-palette="<id>"] attr
   stamped by KCChat._applyPaletteToMounts(). The defaults declared
   below inherit from page-level theme vars (--brass, --up, --down,
   --ox) so the Brass palette = today's appearance with zero risk.
   Each non-brass palette overrides only the chat-scoped vars; the
   wider page (sidebar, nav, etc.) is unaffected.

   Vars (semantics):
     --kcc-self     — your own message accent (handle, edge, signal stripe)
     --kcc-long     — long-side call indicator (border, pip background)
     --kcc-long-fg  — long-side text on the pip
     --kcc-short    — short-side call indicator
     --kcc-short-fg — short-side text on the pip
     --kcc-system   — admin/system message accent
     --kcc-surface  — card / row surface (overrides --surface inside chat)
     --kcc-edge     — card border baseline
     --kcc-text     — body text color
     --kcc-text-dim — meta / time / dim text
   ════════════════════════════════════════════════════════════════ */

/* Defaults — Brass palette. Same colors that the chat has rendered
   with from day one; the page theme's existing vars provide them so
   any non-Razor page theme (KolHub, Dusk, Graphite) automatically
   inherits its own brass-equivalent here unless the user picks a
   non-Brass palette. */
.kcc-inline,
.kcc-panel-overlay {
  --kcc-self:      var(--brass, #d4a335);
  --kcc-long:      var(--up,    #1d9e75);
  --kcc-long-fg:   color-mix(in srgb, var(--up, #1d9e75) 78%, var(--text-bright, #fff));
  --kcc-short:     var(--down,  #d05a4a);
  --kcc-short-fg:  color-mix(in srgb, var(--down, #d05a4a) 78%, var(--text-bright, #fff));
  --kcc-system:    var(--ox,    #a83232);
  /* Default surface + edge inherit the page theme's card + border —
     matches what every chat panel currently paints, so the Brass
     palette is identical to pre-palette-fix appearance. Non-brass
     palettes override --kcc-surface / --kcc-edge with hex values to
     finally take ownership of the structural panel backgrounds. */
  --kcc-surface:   var(--card);
  --kcc-edge:      var(--border);
  /* Dim body text a touch from --text-bright. Mix 78% bright + 22%
     muted = warm off-white that reads as text but doesn't shout. */
  --kcc-text:      color-mix(in srgb, var(--text-bright, #fff) 78%, var(--text-muted, #888));
  --kcc-text-dim:  var(--text-muted);
}

/* Slate — fintech cool. Ice-blue self, mint long, coral short. */
.kcc-inline[data-kcc-palette="slate"],
.kcc-panel-overlay[data-kcc-palette="slate"] {
  --kcc-self:      #6db6e8;
  --kcc-long:      #4dc8a8;
  --kcc-long-fg:   #6dd9bb;
  --kcc-short:     #e87a78;
  --kcc-short-fg:  #ef8a89;
  --kcc-system:    #c46868;
  --kcc-surface:   #181a1c;
  --kcc-edge:      #2a2f35;
  --kcc-text:      #c8cdd2;
  --kcc-text-dim:  #6a737d;
}

/* Midnight — deep navy. Sky-blue self, jade long, ember short. */
.kcc-inline[data-kcc-palette="midnight"],
.kcc-panel-overlay[data-kcc-palette="midnight"] {
  --kcc-self:      #7eb8e8;
  --kcc-long:      #4fc8a0;
  --kcc-long-fg:   #6dd9b6;
  --kcc-short:     #e07a6f;
  --kcc-short-fg:  #ec8a80;
  --kcc-system:    #c46868;
  --kcc-surface:   #131826;
  --kcc-edge:      #1f2840;
  --kcc-text:      #c2cce0;
  --kcc-text-dim:  #6a7488;
}

/* Sage — deep forest. Olive-gold self, mint long, warm-rust short.
   Replaces Eclipse — same niche (a 4th distinct palette) but in
   trader-friendly green territory rather than aubergine. Long stays
   mint so positions still read green; short shifts to rust so it
   pops against the green surface rather than disappearing. */
.kcc-inline[data-kcc-palette="sage"],
.kcc-panel-overlay[data-kcc-palette="sage"] {
  --kcc-self:      #c0b86a;
  --kcc-long:      #6ab896;
  --kcc-long-fg:   #82c8a8;
  --kcc-short:     #d97a5e;
  --kcc-short-fg:  #e58c72;
  --kcc-system:    #b8704a;
  --kcc-surface:   #121a17;
  --kcc-edge:      #1f2c25;
  --kcc-text:      #c4cdc4;
  --kcc-text-dim:  #6d7a72;
}

/* Oxblood — wine-dark. Rose-blush self, forest long, deep-wine short.
   Replaces Carbon — same niche (warm + dark) but bloodier and more
   identity-driven than Carbon's neutral monochrome. Pairs naturally
   with Brass as a sibling "warm dark" option for users who want the
   trading-floor-at-midnight feel. */
.kcc-inline[data-kcc-palette="oxblood"],
.kcc-panel-overlay[data-kcc-palette="oxblood"] {
  --kcc-self:      #e09a8a;
  --kcc-long:      #5fb88c;
  --kcc-long-fg:   #78c99e;
  --kcc-short:     #c44848;
  --kcc-short-fg:  #d36262;
  --kcc-system:    #b04848;
  --kcc-surface:   #1a1012;
  --kcc-edge:      #2c1c1f;
  --kcc-text:      #d6c4c0;
  --kcc-text-dim:  #7a6464;
}

.kcc-inline {
  display: grid;
  /* 3-rail layout: left sidebar (modules) · main (chat) · right rail
     (online/presence). Left rail is narrower than the right since
     its content is dashboard-density mini-cards; right rail holds
     more verbose avatar+handle rows. */
  grid-template-columns: 220px minmax(0, 1fr) 240px;
  gap: 14px;
  align-items: stretch;
  /* Lock the card to the viewport so its bottom aligns with the floating
     dock row instead of leaving a fat tail of empty body underneath.
     ~24px above (.kc-hero + * top padding) + ~80px below (dock cluster
     clearance) = 104px to subtract from 100vh. The nudge bar (when shown)
     sits above the chat container and is not part of the 104 — KCNudge
     publishes its measured footprint into --kcc-nudge-h so the column
     gives that height back and the composer never drops below the fold. */
  height: calc(100vh - 104px - var(--kcc-nudge-h, 0px));
  height: calc(100dvh - 104px - var(--kcc-nudge-h, 0px));
}

/* ── Rails wrapper + responsive scaffolding ──────────────────────────
   The sidebar (modules) and rail (online + settings) are wrapped in
   .kcc-inline__rails. On desktop the wrapper is display:contents, so
   sidebar / main / rail stay three real grid columns; explicit order
   restores left·centre·right after the DOM reorder (main now follows
   the wrapper in source). On mobile the wrapper becomes a single
   off-canvas slide-in panel (see the max-width:760px block below). */
.kcc-inline__rails { display: contents; }
.kcc-inline__sidebar { order: 1; }
.kcc-inline__main    { order: 2; }
.kcc-inline__rail    { order: 3; }

/* Mobile-only chrome — hidden until the phone breakpoint. */
.kcc-mob-head,
.kcc-mob-rail-head,
.kcc-mob-rail-backdrop { display: none; }

.kcc-mob-head {
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--kcc-edge, var(--border));
  background: var(--kcc-surface, var(--card));
  flex-shrink: 0;
}
.kcc-mob-head__id { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.kcc-mob-head__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--kcc-online, #45b37a); flex: 0 0 auto;
}
.kcc-mob-head__title {
  font-weight: 600; font-size: 15px;
  color: var(--text, #f0ece2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kcc-mob-head__rails {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent;
  border: 1px solid var(--kcc-edge, var(--border));
  border-radius: 20px; padding: 5px 11px;
  cursor: pointer; flex: 0 0 auto;
  color: var(--brass, #d4a335);
  font-family: inherit; font-size: 13px;
}
.kcc-mob-head__rails svg { width: 16px; height: 16px; }
.kcc-mob-head__count { font-family: 'Space Mono', monospace; font-size: 12px; }

.kcc-mob-rail-head {
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--kcc-edge, var(--border));
  font-weight: 600; font-size: 15px;
  color: var(--text, #f0ece2);
  position: sticky; top: 0;
  background: var(--kcc-surface, var(--card));
  z-index: 1;
}
.kcc-mob-rail-head button {
  background: transparent; border: 0;
  color: var(--text-muted, #8a857d);
  font-size: 24px; line-height: 1; cursor: pointer; padding: 0 4px;
}

/* Left rail — sidebar of read-only modules (Active Calls + future
   trending / top-callers / pinned blocks). Mirrors the right rail
   structurally (sticky, scrollable) but has its own visual rhythm. */
.kcc-inline__sidebar {
  background: var(--kcc-surface, var(--card));
  border: 1px solid var(--kcc-edge, var(--border));
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-self: stretch;
  /* Explicit height (not just max-height) so the rail actually fills
     the column. With max-height alone, the container collapses to the
     natural height of its content and flex:1 children have no empty
     space to grow into. height + max-height pinned to the same value
     gives us "fill, but don't overflow". The 104px subtracts the
     same nav + page-padding that .kcc-inline uses (see the grid). */
  height:     calc(100vh - 104px);
  height: calc(100dvh - 104px);
  max-height: calc(100vh - 104px);
  max-height: calc(100dvh - 104px);
  overflow-y: auto;       /* rail scrolls when modules overflow (e.g. busy
                             pins list) — children no longer need to clip */
  scrollbar-width: thin;
}
/* The pins module is the last in the rail and grows to fill any
   remaining vertical space — without this, modules pack at the top
   and leave a tall empty gap when content is light (typical on a
   quiet day). The pins list inside scrolls internally when it has
   more entries than the rail can show. The empty hint sits in the
   middle of the available space so it doesn't look like dead room.
   min-height ≈ head (30px) + 2 pin rows (44px each) so the module
   never shrinks below the point where at least 2 pins are visible
   even when the modules above are content-heavy. Anything beyond
   the visible window scrolls inside the list. */
.kcc-inline__sidebar > .kcc-mypinned {
  flex: 1 1 auto;
  min-height: 120px;
  display: flex;
  flex-direction: column;
}
/* Pins list flows naturally. The rail itself scrolls when total
   content exceeds rail height (overflow-y: auto on .kcc-inline__sidebar),
   so a second nested scroll here would just create awkward
   trap-the-wheel UX. */
.kcc-inline__sidebar > .kcc-mypinned .kcc-mypinned__list {
  display: flex;
  flex-direction: column;
}
/* When the pins list is just the empty hint, center it in the
   available space so the bottom of the rail still feels intentional
   rather than abandoned. */
.kcc-inline__sidebar > .kcc-mypinned .kcc-mypinned__list:has(> .kcc-mypinned__empty:only-child) {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
/* Active Calls is the top module and shouldn't push the others off-
   screen when the room is busy. Cap its inner list with an internal
   scroll so the user can still see Trending / Top Callers / Pins
   below it. (Properties on the base rule below get merged with the
   max-height defined here.) */
.kcc-inline__sidebar::-webkit-scrollbar { width: 6px; }
.kcc-inline__sidebar::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}

/* Shared module shell — every left-rail block uses this. Title row +
   optional count chip + body. */
.kcc-sidebar-module {
  display: flex;
  flex-direction: column;
}
.kcc-sidebar-module__head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 8px;
}
.kcc-sidebar-module__title {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-sidebar-module__count {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 18%, transparent);
  padding: 1px 6px;
  border-radius: 8px;
  line-height: 1.4;
}
.kcc-sidebar-module__count[hidden] { display: none; }

/* Active Calls mini-cards. Each is an <a> linking to scanners.html
   with the symbol pre-seeded. Stack vertically, separated by a thin
   divider. The first card has no top divider. */
.kcc-actcalls__list {
  display: flex;
  flex-direction: column;
  /* Cap so Active Calls can't push Trending/Top Callers/Pins
     off-screen when the room is very busy. Above this height the
     list scrolls internally. */
  max-height: 240px;
  overflow-y: auto;
  scrollbar-width: thin;
}
.kcc-actcalls__list::-webkit-scrollbar { width: 4px; }
.kcc-actcalls__list::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 2px;
}
.kcc-actcalls__empty {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
  padding: 4px 0;
}
.kcc-actcall {
  display: block;
  text-decoration: none;
  color: inherit;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  transition: background 100ms ease;
}
.kcc-actcall:first-child {
  border-top: 0;
  padding-top: 0;
}
.kcc-actcall:hover {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 4%, transparent);
}
.kcc-actcall__head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  margin-bottom: 3px;
}
.kcc-actcall__symbol {
  color: var(--text-bright);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.kcc-actcall__side {
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 1px 4px;
  border-radius: 2px;
  line-height: 1.4;
}
.kcc-actcall__side--long {
  color: var(--kcc-long, var(--up, #1d9e75));
  background: color-mix(in srgb, var(--kcc-long, var(--up, #1d9e75)) 18%, transparent);
}
.kcc-actcall__side--short {
  color: var(--kcc-short, var(--down, #d05a4a));
  background: color-mix(in srgb, var(--kcc-short, var(--down, #d05a4a)) 18%, transparent);
}
.kcc-actcall__age {
  margin-left: auto;
  font-size: 9px;
  color: var(--text-muted);
}
.kcc-actcall__row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text-muted);
}
.kcc-actcall__prices {
  color: var(--text);
}
.kcc-actcall__delta {
  margin-left: auto;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.kcc-actcall__delta--pos {
  color: var(--kcc-long, var(--up, #1d9e75));
}
.kcc-actcall__delta--neg {
  color: var(--kcc-short, var(--down, #d05a4a));
}

/* Live target-ladder pips on the active-call card. Reached targets fill
   sage-green with a tick; pending stay outlined; SL caps the row in
   oxblood. Approximate (client-side) — the server resolver owns the
   authoritative reached-before-stop grade. */
.kcc-actcall__pips {
  display: flex;
  align-items: center;
  gap: 0;
  margin-top: 6px;
}
.kcc-actcall__pip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 4px;
  color: var(--text-muted);
  border: 1px solid var(--border, #2a2b30);
}
.kcc-actcall__pip.is-on {
  color: #0b0a09;
  background: var(--up, #6dd99c);
  border-color: var(--up, #6dd99c);
}
.kcc-actcall__pip--sl {
  margin-left: auto;
  color: var(--red, #a83232);
  border-color: color-mix(in srgb, var(--red, #a83232) 55%, transparent);
  background: transparent;
}
.kcc-actcall__pipsep {
  width: 8px;
  height: 2px;
  flex: 0 0 8px;
  background: var(--border2, #3a3b42);
  margin: 0 2px;
}

/* Waiting-for-entry state (entry gate). Pewter is the platform's
   established waiting/locked colour. The pill sits in the head row; the
   delta becomes a distance-to-entry readout; pips dim until the call
   arms. */
.kcc-actcall__wait {
  display: inline-flex;
  align-items: center;
  gap: 0;
  line-height: 1;
  padding: 3px;
  border-radius: 5px;
  color: var(--blue, #8a96a3);
  border: 1px solid color-mix(in srgb, var(--blue, #8a96a3) 45%, transparent);
  background: color-mix(in srgb, var(--blue, #8a96a3) 14%, transparent);
}
.kcc-actcall__delta--wait {
  color: var(--blue, #8a96a3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.kcc-actcall__pips--wait { opacity: 0.45; }

/* ── Locked active-call card (Option C — progress tease) ── */
.kcc-actcall--locked .kcc-actcall__row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.kcc-actcall__hit {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--up, #6dd99c);
}
.kcc-actcall__live {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted, #8a857a);
}
.kcc-actcall__lockmark {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  color: var(--muted, #8a857a);
}
.kcc-actcall__lock { display: block; }
.kcc-actcall__unlock {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--brass, #d4a335);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 45%, transparent);
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, transparent);
  border-radius: 6px;
  padding: 5px 6px;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.kcc-actcall--locked:hover .kcc-actcall__unlock {
  background: color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 65%, transparent);
}

/* The sparkline inside the active-calls card. The same renderer that
   feeds in-stream cards (200×28 viewBox); we shrink the height here
   via the wrapping module class. */
.kcc-actcall__spark {
  margin-top: 4px;
}
.kcc-actcall__spark .kcc-msg__sig-spark {
  margin: 0;
}
.kcc-actcall__spark .kcc-msg__sig-spark svg {
  height: 18px;
}
.kcc-actcall__spark .kcc-msg__sig-spark-caption {
  display: none;
}

/* ══════════════════════════════════════════════════════════════════
   COLLAPSIBLE SIDEBAR MODULES — <details>/<summary> support
   ══════════════════════════════════════════════════════════════════
   The three auto modules (Calls / Bets / Challenges) wrap in a
   <details> element so the user can collapse any module with one
   click. We strip the native disclosure triangle and rotate our own
   chevron based on the [open] attribute. */
details.kcc-sidebar-module summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
}
details.kcc-sidebar-module summary::-webkit-details-marker {
  display: none;
}
.kcc-sidebar-module__chev {
  color: var(--text-muted, #8a8780);
  flex: none;
  transition: transform 140ms ease;
  transform: rotate(-90deg);  /* collapsed default — points right */
}
details.kcc-sidebar-module[open] > summary .kcc-sidebar-module__chev {
  transform: rotate(0deg);    /* expanded — points down */
}
details.kcc-sidebar-module > summary:hover .kcc-sidebar-module__chev {
  color: var(--kcc-self, var(--brass, #d4a335));
}

/* ══════════════════════════════════════════════════════════════════
   ACTIVE BET + CHALLENGE MINI-CARD VARIANTS
   ══════════════════════════════════════════════════════════════════
   The base .kcc-actcall mini-card is a 2-row anchor (head row + price
   row). Bet and challenge variants add a middle question row and
   override the symbol palette to match each card type's identity
   (pewter for bets, oxblood for challenges). */

/* ── Bet variant ─────────────────────────────────────────────────── */
.kcc-actcall--bet .kcc-actcall__symbol--bet {
  color: var(--blue, #8a96a3);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  background: color-mix(in srgb, var(--blue, #8a96a3) 14%, transparent);
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 600;
}
.kcc-actcall--bet:hover {
  background: color-mix(in srgb, var(--blue, #8a96a3) 5%, transparent);
}

/* ── Challenge variant ───────────────────────────────────────────── */
.kcc-actcall--chal .kcc-actcall__symbol--chal {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 600;
}
.kcc-actcall--chal .kcc-actcall__status--open {
  color: var(--red, #d05a4a);
  background: color-mix(in srgb, var(--red, #d05a4a) 14%, transparent);
}
.kcc-actcall--chal .kcc-actcall__status--locked {
  color: var(--up, #5acf7a);
  background: color-mix(in srgb, var(--up, #5acf7a) 14%, transparent);
}
.kcc-actcall--chal:hover {
  background: color-mix(in srgb, var(--red, #a83232) 5%, transparent);
}

/* Question / subject middle row — single-line clamp so long bet
   questions or challenge subjects don't push the card tall. */
.kcc-actcall__q {
  font-size: 11px;
  color: var(--text, #e8e3d4);
  line-height: 1.35;
  margin: 2px 0 3px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

/* Challenge participants cell — replaces the prices cell on chal
   cards. Slightly smaller than prices since handles aren't mono. */
.kcc-actcall__parts {
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  font-size: 10.5px;
  color: var(--text-muted, #8a8780);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kcc-actcall__parts b {
  color: var(--text, #e8e3d4);
  font-weight: 500;
}

/* Pot value on the right of the chal card row. Locked challenges
   tint green (live), open ones stay oxblood (waiting). */
.kcc-actcall__pot {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--red, #d05a4a);
  font-weight: 600;
  margin-left: auto;
  flex-shrink: 0;
}
.kcc-actcall--chal:has(.kcc-actcall__status--locked) .kcc-actcall__pot {
  color: var(--up, #5acf7a);
}
.kcc-actcall__pot-lbl {
  color: var(--text-muted, #6e6b63);
  font-weight: 400;
  margin-right: 3px;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ─── Trending tickers module ────────────────────────────────
   Cashtag mention counts within a rolling window. Bar length = the
   item's share of the top item's count. Top-3 bars use brass; the
   rest use the muted border color. */
.kcc-trending__wins {
  margin-left: auto;
  display: inline-flex;
  gap: 0;
  background: var(--bg2, transparent);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px;
}
.kcc-trending__win {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 2px 5px;
  cursor: pointer;
  border-radius: 2px;
  transition: color 100ms ease, background 100ms ease;
}
.kcc-trending__win:hover {
  color: var(--text-bright);
}
.kcc-trending__win.is-on {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 18%, transparent);
  color: var(--kcc-self, var(--brass, #d4a335));
  font-weight: 700;
}
.kcc-trending__empty {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
  padding: 4px 0;
}
.kcc-trending__row {
  display: grid;
  grid-template-columns: 14px auto 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 100ms ease;
}
.kcc-trending__row:last-child { border-bottom: 0; }
.kcc-trending__row:hover {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 6%, transparent);
}
.kcc-trending__rank {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--text-muted);
  text-align: center;
}
.kcc-trending__ticker {
  color: var(--text-bright);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.kcc-trending__bar {
  display: inline-block;
  height: 3px;
  border-radius: 1px;
  background: var(--border2);
  min-width: 4px;
  max-width: 100%;
  justify-self: end;
}
.kcc-trending__bar--top {
  background: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-trending__count {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 18px;
}

/* ─── Top callers module ─────────────────────────────────────
   Rank + avatar + handle + avg P&L. Click → scroll to that user's
   latest message in the stream. */
.kcc-topcallers__win {
  margin-left: auto;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
}
.kcc-topcallers__empty {
  font-size: 10px;
  color: var(--text-muted);
  font-style: italic;
  padding: 4px 0;
}
.kcc-topcallers__row {
  display: grid;
  grid-template-columns: 14px 22px 1fr auto;
  align-items: center;
  gap: 7px;
  width: 100%;
  padding: 5px 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  transition: background 100ms ease;
}
.kcc-topcallers__row:last-child { border-bottom: 0; }
.kcc-topcallers__row:hover {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 6%, transparent);
}
.kcc-topcallers__rank {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-muted);
  text-align: center;
}
.kcc-topcallers__rank--lead {
  color: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-topcallers__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.kcc-topcallers__initials {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--card, #13131f);
  border: 1.5px solid var(--accent, #d4a335);
  color: var(--accent, #d4a335);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  box-sizing: border-box;
}
/* Match hue palette to per-message avatars. */
.kcc-topcallers__avatar[data-kcc-hue="1"] .kcc-topcallers__initials { border-color: #e08a8a; color: #e08a8a; }
.kcc-topcallers__avatar[data-kcc-hue="2"] .kcc-topcallers__initials { border-color: #7fc9a8; color: #7fc9a8; }
.kcc-topcallers__avatar[data-kcc-hue="3"] .kcc-topcallers__initials { border-color: #a89dd9; color: #a89dd9; }
.kcc-topcallers__avatar[data-kcc-hue="4"] .kcc-topcallers__initials { border-color: #d9b766; color: #d9b766; }
.kcc-topcallers__avatar[data-kcc-hue="5"] .kcc-topcallers__initials { border-color: #7aa4c9; color: #7aa4c9; }
.kcc-topcallers__avatar[data-kcc-hue="6"] .kcc-topcallers__initials { border-color: #d98ab0; color: #d98ab0; }
.kcc-topcallers__avatar[data-kcc-hue="7"] .kcc-topcallers__initials { border-color: #a4adb8; color: #a4adb8; }
.kcc-topcallers__handle[data-kcc-hue="1"] { color: #e08a8a; }
.kcc-topcallers__handle[data-kcc-hue="2"] { color: #7fc9a8; }
.kcc-topcallers__handle[data-kcc-hue="3"] { color: #a89dd9; }
.kcc-topcallers__handle[data-kcc-hue="4"] { color: #d9b766; }
.kcc-topcallers__handle[data-kcc-hue="5"] { color: #7aa4c9; }
.kcc-topcallers__handle[data-kcc-hue="6"] { color: #d98ab0; }
.kcc-topcallers__handle[data-kcc-hue="7"] { color: #a4adb8; }
.kcc-topcallers__who {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.kcc-topcallers__handle {
  font-size: 10.5px;
  font-weight: 600;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kcc-topcallers__calls {
  font-size: 9.5px;
  /* --text-muted reads too dark on the card surface; mix bright text
     down to a readable 55% instead. Keeps the secondary-text hierarchy
     intact (handle stays brighter) but actually visible. */
  color: color-mix(in srgb, var(--text-bright, #faf6ec) 55%, transparent);
  font-family: 'Space Mono', monospace;
  line-height: 1.4;
}
.kcc-topcallers__pnl {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.kcc-topcallers__pnl--pos { color: var(--kcc-long, var(--up, #1d9e75)); }
.kcc-topcallers__pnl--neg { color: var(--kcc-short, var(--down, #d05a4a)); }

/* ─── MY PINNED module — unified Calls / Bets / Challenges ─────
   User-curated sidebar list backed by KCPins (Supabase-synced).
   Three sub-tabs at the top switch between card types; each
   card uses a tier-colored left border (brass=signal, pewter=bet,
   oxblood=challenge) so types are scannable in a mixed mental
   model. The module itself shares the .kcc-sidebar-module shell;
   tab + card styles are scoped here. */

.kcc-mypinned__tabs {
  display: flex;
  gap: 0;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.kcc-mypinned__tab {
  flex: 1;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 4px 0 5px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-muted, #6e6b63);
  cursor: pointer;
  transition: color 100ms ease, border-color 100ms ease;
  /* Pull -1px so the tab's border-bottom paints over the tabs row's
     border-bottom, creating the standard "tab merges with its panel"
     look. Without this the active underline floats above the panel. */
  margin-bottom: -1px;
}
.kcc-mypinned__tab:hover {
  color: var(--text-bright, #e8e3d4);
}
.kcc-mypinned__tab.is-active {
  color: var(--brass, #d4a335);
  border-bottom-color: var(--brass, #d4a335);
}
.kcc-mypinned__tab [data-kc="mypinned-tab-count"] {
  font-variant-numeric: tabular-nums;
}

/* Cards list — flex column, no scrollbar of its own (the whole rail
   scrolls). Cards are anchors so they're keyboard-tabbable. */
.kcc-mypinned__list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.kcc-mypinned__empty {
  font-size: 10px;
  color: var(--text-muted, #8a8780);
  font-style: italic;
  padding: 4px 0;
  line-height: 1.5;
}
.kcc-mypinned__empty-hint {
  display: block;
  font-size: 9px;
  margin-top: 3px;
  font-style: italic;
  color: var(--text-muted, #8a8780);
  opacity: 0.7;
}

/* Pinned mini-card — same 2-row compact shape across all three types.
   Tier color on the left border encodes type at a glance. We reuse
   .kcc-actcall__head / __row / __symbol / __age / __side / __prices
   / __delta children so the inner content matches the Active Calls
   look without duplicating CSS. The wrapper class .kcc-mypinned__card
   adds the colored left border + small padding shift. */
.kcc-mypinned__card {
  display: block;
  text-decoration: none;
  color: inherit;
  padding: 6px 6px 6px 9px;
  background: var(--bg2, transparent);
  border-left: 2px solid var(--border2, #2d2a25);
  border-radius: 0 4px 4px 0;
  transition: background 100ms ease;
}
.kcc-mypinned__card:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 5%, var(--bg2, transparent));
}
.kcc-mypinned__card--signal {
  border-left-color: var(--brass, #d4a335);
}
.kcc-mypinned__card--bet {
  border-left-color: var(--blue, #8a96a3);
}
.kcc-mypinned__card--bet:hover {
  background: color-mix(in srgb, var(--blue, #8a96a3) 5%, var(--bg2, transparent));
}
.kcc-mypinned__card--chal {
  border-left-color: var(--red, #a83232);
}
.kcc-mypinned__card--chal:hover {
  background: color-mix(in srgb, var(--red, #a83232) 5%, var(--bg2, transparent));
}

/* Stale placeholder — for pins whose source message isn't currently
   in chat history. Compact, dimmed, with a manual unpin button. */
.kcc-mypinned__card--stale {
  position: relative;
  padding: 8px 22px 8px 9px;
  font-size: 10px;
  color: var(--text-muted, #8a8780);
  font-style: italic;
}
.kcc-mypinned__stale {
  line-height: 1.4;
}
.kcc-mypinned__unpin {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 16px;
  height: 16px;
  background: transparent;
  border: 0;
  color: var(--text-muted, #6e6b63);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
  opacity: 0.6;
  transition: opacity 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-mypinned__unpin:hover {
  opacity: 1;
  color: var(--red, #d05a4a);
  background: color-mix(in srgb, var(--red, #d05a4a) 12%, transparent);
}

/* Variant-specific symbol pills inside pinned cards. Bet uses pewter
   for the venue chip, challenge has open/locked status colors. These
   mirror the in-stream card palette so types stay consistent across
   the rail and the chat. */
.kcc-mypinned__card .kcc-actcall__symbol--bet {
  color: var(--blue, #8a96a3);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  background: color-mix(in srgb, var(--blue, #8a96a3) 14%, transparent);
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 600;
}
.kcc-mypinned__card .kcc-actcall__symbol--chal {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 600;
}
.kcc-mypinned__card .kcc-actcall__status--open {
  color: var(--red, #d05a4a);
  background: color-mix(in srgb, var(--red, #d05a4a) 14%, transparent);
}
.kcc-mypinned__card .kcc-actcall__status--locked {
  color: var(--up, #5acf7a);
  background: color-mix(in srgb, var(--up, #5acf7a) 14%, transparent);
}
.kcc-mypinned__card .kcc-actcall__pot {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--red, #d05a4a);
  font-weight: 600;
}
.kcc-mypinned__card--chal:has(.kcc-actcall__status--locked) .kcc-actcall__pot {
  color: var(--up, #5acf7a);
}
.kcc-mypinned__card .kcc-actcall__pot-lbl {
  color: var(--text-muted, #6e6b63);
  font-weight: 400;
  margin-right: 3px;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.kcc-inline__main {
  background: var(--kcc-surface, var(--card));
  border: 1px solid var(--kcc-edge, var(--border));
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  min-width: 0;        /* allow shrink under grid */
  overflow: hidden;    /* keep child rounded corners clean */
  position: relative;  /* anchor for .kcc-stream__pill */
}
/* The active-calls strip + composer inside the inline main column reuse
   their drawer styling. Stream needs to flex-grow inside this column. */
.kcc-inline__main .kcc-stream {
  flex: 1 1 auto;
  min-height: 0;
}
.kcc-inline__main .kcc-panel-calls {
  border-top: 0;       /* no panel-head above it in inline mode */
}

/* Right rail — online presence list. */
.kcc-inline__rail {
  background: var(--kcc-surface, var(--card));
  border: 1px solid var(--kcc-edge, var(--border));
  border-radius: 8px;
  padding: 12px 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-self: stretch;
  position: sticky;
  top: 12px;
  /* Rail mirrors the card's viewport-tied height so its bottom edge
     lines up with the composer row. The rail is a flex column that
     does NOT scroll as a whole: the ONLINE list (.kcc-presence) is the
     single scroll region and the settings cluster (THEME / COLOR /
     SOUND) is pinned below it — so a growing online list scrolls
     internally instead of pushing the cluster down off the rail. */
  max-height: calc(100vh - 104px);
  max-height: calc(100dvh - 104px);
  overflow: hidden;
}
.kcc-inline__rail::-webkit-scrollbar { width: 6px; }
.kcc-inline__rail::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}
.kcc-rail-head {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--border);
}
.kcc-rail-label {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  text-transform: uppercase;
  flex: 0 0 auto;
}
.kcc-rail-count {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--accent);
  background: rgba(212, 163, 53, 0.08);
  border: 1px solid rgba(212, 163, 53, 0.32);
  border-radius: 999px;
  padding: 2px 6px;
  min-width: 0;
  text-align: center;
  margin-right: auto; /* sits next to ONLINE; pushes Admin + Board to the right edge */
  flex: 0 0 auto;
}
/* Thin vertical divider between the count chip and the admin icon
   row. Only rendered (in JS) when the viewer is admin. */
.kcc-rail-head__divider {
  width: 1px;
  height: 12px;
  background: var(--border);
}
/* Admin-only icon bar that sits directly below .kcc-rail-head.
   Renders the 5 admin controls (slow-mode, post-system, post-app,
   select-mode, clear-chat) in a single row. The icons are bigger
   here than they would be packed inline with the ONLINE label so
   they read clearly even at the rail's narrow width. */
.kcc-rail-admin-bar {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 8px 0 4px;
  flex-wrap: nowrap;        /* all admin tools stay on a single row */
}
/* Compact icon buttons that replace the labeled MODERATION block.
   24px squares with 13px glyphs — sized so the full set (slow-mode,
   lock, system, announce, House, select, clear) fits one rail row. */
.kcc-rail-head__icon {
  width: 24px;
  height: 24px;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  padding: 0;
  cursor: pointer;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  transition: border-color 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-rail-head__icon:hover {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 35%, var(--border2));
  color: var(--text-bright);
}
.kcc-rail-head__icon[aria-pressed="true"] {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 8%, transparent);
}
.kcc-rail-head__icon--danger:hover {
  border-color: color-mix(in srgb, var(--down, #d05a4a) 50%, var(--border2));
  color: var(--down, #d05a4a);
}
.kcc-rail-head__icon svg {
  width: 13px;
  height: 13px;
  display: block;
}

/* Slow-mode admin icon — shares the 22px square geometry of the
   other admin icons but adds a small "Ns" badge floating in the
   top-right corner when slow mode is enabled. Brass tint when on. */
.kcc-rail-head__icon--slowmode {
  position: relative;
  overflow: visible;
}
.kcc-rail-head__icon--slowmode[data-state="on"] {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 8%, transparent);
}
.kcc-rail-head__icon-badge {
  position: absolute;
  top: -5px;
  right: -6px;
  background: var(--kcc-self, var(--brass, #d4a335));
  color: var(--bg, #0e1217);
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 4px;
  border-radius: 6px;
  line-height: 1.1;
  pointer-events: none;
}
.kcc-rail-head__icon-badge[hidden] { display: none; }

/* ── Admin tools — Option A: single "Admin" pill → grouped menu ──
   Replaces the cramped 7-icon row. The pill sits where the bar did;
   the menu and the existing slow-mode / post popovers all live in the
   rail's natural flow (they push the presence list down when open), so
   no absolute positioning is needed. Reuses the original data-kc hooks,
   so every existing handler + state-render drives these rows too. */
.kcc-rail-adminrow {
  margin: 8px 0 4px;
  display: flex;
}
.kcc-rail-admin-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent, var(--brass, #d4a335));
  background: rgba(212, 163, 53, 0.06);
  border: 1px solid rgba(212, 163, 53, 0.32);
  border-radius: 5px;
  padding: 3px 6px;
  cursor: pointer;
  transition: border-color 100ms ease, background 100ms ease, color 100ms ease;
}
.kcc-rail-admin-btn:hover {
  border-color: var(--brass, #d4a335);
  background: rgba(212, 163, 53, 0.12);
}
.kcc-rail-admin-btn[aria-expanded="true"] {
  border-color: var(--brass, #d4a335);
  background: rgba(212, 163, 53, 0.14);
}
.kcc-rail-admin-btn svg { width: 12px; height: 12px; display: block; }
.kcc-rail-admin-btn__chev { width: 9px; height: 9px; opacity: 0.7; transition: transform 120ms ease; }
.kcc-rail-admin-btn[aria-expanded="true"] .kcc-rail-admin-btn__chev { transform: rotate(180deg); }
.kcc-rail-admin-btn__label { line-height: 1; }

.kcc-admin-menu {
  margin: 0 0 6px;
  background: var(--bg2, var(--card));
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 26%, var(--border2));
  border-radius: 8px;
  padding: 5px;
  animation: kcc-slowmode-pop-in 140ms cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-admin-menu[hidden] { display: none; }
.kcc-admin-menu__grp {
  font-family: 'Space Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint, var(--text-muted));
  padding: 7px 8px 3px;
}
.kcc-admin-menu__grp:first-child { padding-top: 3px; }
.kcc-admin-menu__row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 7px 8px;
  cursor: pointer;
  color: var(--text-bright, var(--text));
  font-family: inherit;
  font-size: 12.5px;
  text-align: left;
  transition: background 100ms ease, color 100ms ease;
}
.kcc-admin-menu__row:hover { background: rgba(212, 163, 53, 0.08); }
.kcc-admin-menu__ic { width: 14px; height: 14px; flex: 0 0 auto; color: var(--text-muted); }
.kcc-admin-menu__row:hover .kcc-admin-menu__ic { color: var(--text-bright); }
.kcc-admin-menu__lbl { flex: 1 1 auto; }
.kcc-admin-menu__sec {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--brass, #d4a335);
  flex: 0 0 auto;
}
.kcc-admin-menu__sec[hidden] { display: none; }
/* Inline toggle switch — reflects aria-pressed on the row (lock,
   select). The existing handlers flip aria-pressed on every matching
   [data-kc], so these update with no extra wiring. */
.kcc-admin-menu__switch {
  flex: 0 0 auto;
  width: 24px;
  height: 13px;
  border-radius: 7px;
  background: rgba(120, 110, 90, 0.3);
  position: relative;
  transition: background 120ms ease;
}
.kcc-admin-menu__switch::after {
  content: '';
  position: absolute;
  top: 1.5px;
  left: 1.5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--text-bright, #e9e3d5);
  transition: left 120ms ease;
}
.kcc-admin-menu__row[aria-pressed="true"] .kcc-admin-menu__switch {
  background: color-mix(in srgb, var(--brass, #d4a335) 50%, transparent);
}
.kcc-admin-menu__row[aria-pressed="true"] .kcc-admin-menu__switch::after { left: 12.5px; }
.kcc-admin-menu__row[aria-pressed="true"] .kcc-admin-menu__lbl,
.kcc-admin-menu__row[data-state="on"] .kcc-admin-menu__lbl { color: var(--brass, #d4a335); }
.kcc-admin-menu__row[data-state="on"] .kcc-admin-menu__ic { color: var(--brass, #d4a335); }
.kcc-admin-menu__row--danger { color: var(--down, #d05a4a); }
.kcc-admin-menu__row--danger .kcc-admin-menu__ic { color: var(--down, #d05a4a); }
.kcc-admin-menu__row--danger:hover { background: color-mix(in srgb, var(--down, #d05a4a) 12%, transparent); }

/* ── Test-room indicator (Option B) ─────────────────────────────
   An oxblood flag at the top of the chat column + a thin accent
   stripe on the column itself, both shown only while you're in the
   Test room. Reuses the brand oxblood (#a83232 — the flask colour)
   rather than --down so it reads as "staging surface", not "error". */
.kcc-roomflag {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  margin-bottom: 10px;
  background: rgba(168, 50, 50, 0.14);
  border: 1px solid rgba(168, 50, 50, 0.4);
  border-radius: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: #e0a0a0;
  animation: kcc-slowmode-pop-in 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-roomflag[hidden] { display: none; }
.kcc-roomflag__ic { width: 14px; height: 14px; flex: 0 0 auto; color: #d98a8a; }
.kcc-roomflag__txt { flex: 1 1 auto; }
.kcc-roomflag__txt b { color: #f0c4c4; letter-spacing: 0.12em; }
.kcc-roomflag__exit {
  flex: 0 0 auto;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #e0a0a0;
  background: transparent;
  border: 1px solid rgba(168, 50, 50, 0.5);
  border-radius: 5px;
  padding: 3px 9px;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.kcc-roomflag__exit:hover { background: rgba(168, 50, 50, 0.22); color: #f6d6d6; }
/* Thin oxblood accent along the top of the chat column while in Test. */
.kcc-inline__main--test { box-shadow: inset 0 2px 0 #a83232; }

/* Slow-mode popover — drops down below the admin icon row. Sits in
   the rail's natural flow so it pushes the presence list down when
   open. (Better than absolute positioning here because the rail is
   the natural anchor; users see it open WITH the rail rather than
   floating over it.) */
/* Slow-mode admin popover. Lives as a sibling of .kcc-rail-head
   (inside the rail body) so it stretches to the rail's actual width
   rather than fighting the head's flex layout. Tucks itself in just
   below the head when open. */
.kcc-slowmode-pop {
  margin: 8px 0 4px;
  background: var(--bg2, var(--card));
  border: 1px solid color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 30%, var(--border2));
  border-radius: 6px;
  padding: 10px 12px;
  font-family: 'Space Mono', monospace;
  /* Subtle slide-in so the rail opening doesn't feel jarring. */
  animation: kcc-slowmode-pop-in 140ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes kcc-slowmode-pop-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.kcc-slowmode-pop[hidden] { display: none; }
.kcc-slowmode-pop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.kcc-slowmode-pop__title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--kcc-self, var(--brass, #d4a335));
  text-transform: uppercase;
}
.kcc-slowmode-pop__close {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
  transition: color 100ms ease;
}
.kcc-slowmode-pop__close:hover { color: var(--text-bright); }
.kcc-slowmode-pop__hint {
  font-size: 10px;
  color: var(--text-muted);
  margin-bottom: 10px;
  line-height: 1.4;
}
.kcc-slowmode-pop__opts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.kcc-slowmode-pop__opt {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  padding: 6px 4px;
  border-radius: 3px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: border-color 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-slowmode-pop__opt:hover {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 35%, var(--border2));
  color: var(--text-bright);
}
.kcc-slowmode-pop__opt.is-on {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 12%, transparent);
}

/* ── Admin posting popovers (system notice + announcement) ─────────
   Built on top of .kcc-slowmode-pop (same shell, border, animation,
   close button). The .kcc-postpop modifier adds the body inputs,
   facts editor, and footer with char-count + send button. The wide
   variant gives the announcement form a bit more breathing room
   inside the rail's narrow column. */
.kcc-postpop {
  padding: 12px 12px 10px;
}
.kcc-postpop--wide { /* hook for future width tweaks if needed */ }
.kcc-postpop__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 8px;
}
.kcc-postpop__chip {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  padding: 4px 7px;
  border-radius: 3px;
  cursor: pointer;
  letter-spacing: 0.04em;
  transition: border-color 100ms ease, color 100ms ease;
}
.kcc-postpop__chip:hover {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 35%, var(--border2));
  color: var(--text-bright);
}
.kcc-postpop__body {
  width: 100%;
  background: var(--bg, #0f0f14);
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--text);
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  font-size: 12px;
  line-height: 1.45;
  padding: 7px 9px;
  resize: vertical;
  min-height: 60px;
  box-sizing: border-box;
  transition: border-color 100ms ease;
}
.kcc-postpop__body:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 45%, var(--border2));
}
.kcc-postpop__field {
  display: block;
  margin: 0 0 8px;
}
.kcc-postpop__field:last-child { margin-bottom: 0; }
.kcc-postpop__lbl {
  display: block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  text-transform: uppercase;
  margin: 0 0 4px;
}
.kcc-postpop__lbl-aux {
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--text-muted);
}
.kcc-postpop__lbl-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 4px;
}
.kcc-postpop__grid {
  display: grid;
  grid-template-columns: 1fr 70px;
  gap: 8px;
  margin: 0 0 8px;
}
.kcc-postpop__input {
  width: 100%;
  background: var(--bg, #0f0f14);
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--text);
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  font-size: 12px;
  padding: 6px 8px;
  box-sizing: border-box;
  transition: border-color 100ms ease;
}
.kcc-postpop__input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 45%, var(--border2));
}
.kcc-postpop__input--center { text-align: center; text-transform: uppercase; }
.kcc-postpop__input--fact     { font-size: 11px; }
.kcc-postpop__input--fact-val { font-size: 11px; font-family: 'Space Mono', monospace; }
.kcc-postpop__facts {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.kcc-postpop__facts-empty {
  font-size: 10px;
  color: var(--text-muted);
  padding: 6px 0 2px;
  font-style: italic;
}
.kcc-postpop__fact-row {
  display: grid;
  grid-template-columns: 1fr 1fr 22px;
  gap: 4px;
  align-items: center;
}
.kcc-postpop__fact-rm {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1;
  border-radius: 3px;
  cursor: pointer;
  padding: 0;
  height: 26px;
  transition: color 100ms ease, border-color 100ms ease;
}
.kcc-postpop__fact-rm:hover {
  color: var(--down, #d47070);
  border-color: var(--down, #d47070);
}
.kcc-postpop__add {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: 3px;
  cursor: pointer;
  letter-spacing: 0.04em;
  transition: border-color 100ms ease, color 100ms ease;
}
.kcc-postpop__add:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 35%, var(--border2));
  color: var(--text-bright);
}
.kcc-postpop__add:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.kcc-postpop__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border2);
}
.kcc-postpop__count {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  color: var(--text-muted);
}
.kcc-postpop__count.is-warn { color: var(--warn, #d4a335); }
.kcc-postpop__count.is-bad  { color: var(--down, #d47070); }
.kcc-postpop__send {
  background: var(--kcc-self, var(--brass, #d4a335));
  color: var(--bg, #0f0f14);
  border: 0;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 3px;
  cursor: pointer;
  transition: opacity 100ms ease, transform 100ms ease;
}
.kcc-postpop__send:hover:not(:disabled) { opacity: 0.92; }
.kcc-postpop__send:active:not(:disabled) { transform: scale(0.97); }
.kcc-postpop__send:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ── House composer — full-screen two-pane modal (Option A) ────────────
   Replaces the old rail popover. data-kc="post-call-popover" stays on the
   overlay so the existing toggle/close/send handlers keep working. */
.kcc-callmodal-overlay {
  position: fixed; inset: 0; z-index: 1200;
  display: grid; place-items: center;
  background: color-mix(in srgb, #000 62%, transparent);
  padding: 24px; animation: kcCallModalIn 160ms ease;
}
.kcc-callmodal-overlay[hidden] { display: none; }
@keyframes kcCallModalIn { from { opacity: 0; } to { opacity: 1; } }
.kcc-callmodal {
  width: min(860px, 96vw); max-height: 88vh; overflow: auto;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 24px 70px rgba(0,0,0,0.55);
}
.kcc-callmodal__head {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 18px; border-bottom: 1px solid var(--border);
}
.kcc-callmodal__title {
  font-family: 'Space Mono', monospace; font-size: 12.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--brass, #d4a335);
  white-space: nowrap;
}
.kcc-callmodal__hint { font-size: 11px; color: var(--muted); flex: 1 1 auto; }
.kcc-callmodal__close {
  appearance: none; border: 0; background: transparent; color: var(--muted);
  font-size: 20px; line-height: 1; cursor: pointer; width: 30px; height: 30px;
  border-radius: 8px; flex: 0 0 auto;
}
.kcc-callmodal__close:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.kcc-callmodal__body { display: grid; grid-template-columns: 260px 1fr; }
.kcc-callmodal__source {
  border-right: 1px solid var(--border); padding: 14px;
  display: flex; flex-direction: column; gap: 10px; min-height: 340px;
}
.kcc-callmodal__srctabs { display: flex; gap: 6px; }
.kcc-callmodal__srctabs button {
  flex: 1; appearance: none; cursor: pointer;
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 7px 8px; border-radius: 8px;
  border: 1px solid var(--border); background: transparent; color: var(--text-mid);
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.kcc-callmodal__srctabs button.is-on {
  background: var(--brass, #d4a335); border-color: var(--brass, #d4a335);
  color: #1a1710; font-weight: 700;
}
.kcc-callmodal__picker { flex: 1; overflow: auto; display: flex; flex-direction: column; gap: 6px; }
.kcc-callmodal__pickempty {
  font-size: 12px; color: var(--muted); font-style: italic;
  padding: 20px 6px; text-align: center;
}
.kcc-callmodal__manualnote { font-size: 11.5px; color: var(--muted); line-height: 1.5; }
/* picker rows */
.kcc-pickrow {
  appearance: none; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; gap: 3px;
  padding: 8px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: transparent; color: var(--text-mid);
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-pickrow:hover { border-color: color-mix(in srgb, var(--brass, #d4a335) 55%, var(--border)); }
.kcc-pickrow.is-sel { border-color: var(--brass, #d4a335); background: color-mix(in srgb, var(--brass, #d4a335) 10%, transparent); }
.kcc-pickrow__l1 { display: flex; align-items: center; gap: 7px; }
.kcc-pickrow__l1 b { color: var(--text-bright); font-size: 12.5px; }
.kcc-pickrow__meta { font-size: 10.5px; color: var(--muted); }
.kcc-pickrow__side { font-family: 'Space Mono', monospace; font-size: 8.5px; font-weight: 700; letter-spacing: 0.06em; padding: 1px 5px; border-radius: 4px; margin-left: auto; }
.kcc-pickrow__side.is-long { color: #6fcf8e; background: color-mix(in srgb, #6fcf8e 16%, transparent); }
.kcc-pickrow__side.is-short { color: #e08a8a; background: color-mix(in srgb, #e08a8a 16%, transparent); }
.kcc-pickrow__l2 { font-family: 'Space Mono', monospace; font-size: 10.5px; color: var(--muted); }
/* TP1-3 row + conviction */
.kcc-callmodal__form .kcc-postpop__grid { grid-template-columns: 1fr 1fr; }
.kcc-callmodal__form .kcc-callmodal__tps { grid-template-columns: repeat(3, 1fr); }
.kcc-conv { display: flex; align-items: center; gap: 7px; }
.kcc-conv__dot {
  appearance: none; cursor: pointer; width: 16px; height: 16px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 50%, var(--border));
  background: transparent; padding: 0; transition: background 120ms ease, transform 100ms ease;
}
.kcc-conv__dot:hover { transform: scale(1.12); }
.kcc-conv__dot.is-on { background: var(--brass, #d4a335); border-color: var(--brass, #d4a335); }
.kcc-conv__lbl {
  font-family: 'Space Mono', monospace; font-size: 10.5px; letter-spacing: 0.04em;
  color: var(--text-mid); margin-left: 4px;
}
/* Chart snapshot field — upload button + "or" + paste-link input. */
.kcc-callmodal__snap { display: flex; align-items: center; gap: 8px; }
.kcc-callmodal__snapbtn { flex-shrink: 0; cursor: pointer; }
.kcc-callmodal__snapbtn-inner {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--brass, #d4a335); color: var(--brass, #d4a335);
  border-radius: 4px; padding: 7px 11px;
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; white-space: nowrap;
  transition: background 120ms ease, color 120ms ease;
}
.kcc-callmodal__snapbtn:hover .kcc-callmodal__snapbtn-inner { background: var(--brass, #d4a335); color: #0a0a0a; }
.kcc-callmodal__snapor { font-size: 10px; color: var(--text3, #6c665d); flex-shrink: 0; }
.kcc-callmodal__snapurl { flex: 1; min-width: 0; }
.kcc-callmodal__snapstatus {
  display: block; margin-top: 5px; min-height: 13px;
  font-family: 'Space Mono', monospace; font-size: 10px; letter-spacing: 0.03em;
  color: var(--text3, #6c665d);
}
.kcc-callmodal__snapstatus.is-busy { color: var(--text-mid, #9a948a); }
.kcc-callmodal__snapstatus.is-ok   { color: var(--up, #1d9e75); }
.kcc-callmodal__snapstatus.is-err  { color: var(--red, #d05a4a); }
/* mode switching */
.kcc-callmodal:not(.is-manual) .kcc-callmodal__manualnote { display: none; }
.kcc-callmodal.is-manual .kcc-callmodal__picker { display: none; }
.kcc-callmodal__form { padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.kcc-callmodal__foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px; border-top: 1px solid var(--border);
}
.kcc-callmodal__rr { font-family: 'Space Mono', monospace; font-size: 12px; color: var(--text-mid); }
.kcc-callmodal__rr b { color: var(--brass, #d4a335); font-weight: 700; }
/* Unlock-price control — numeric input + quick-pick chips + note.
   Free chip (cost 0) flips to the up/green accent; typing a custom
   value deselects the chips. Mirrors the admin-popover chip pattern. */
.kcc-callmodal__unlock { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.kcc-callmodal__unlockinput {
  width: 72px; flex: 0 0 auto; text-align: center;
  font-family: 'Space Mono', monospace; font-weight: 700;
}
.kcc-callmodal__unlockchip {
  appearance: none; cursor: pointer;
  background: transparent; border: 1px solid var(--border2);
  color: var(--text-muted);
  font-family: 'Space Mono', monospace; font-size: 10px; font-weight: 700;
  letter-spacing: 0.04em; padding: 5px 9px; border-radius: 3px;
  transition: border-color 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-callmodal__unlockchip:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border2));
  color: var(--text-bright);
}
.kcc-callmodal__unlockchip.is-on {
  border-color: var(--brass, #d4a335); color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 12%, transparent);
}
.kcc-callmodal__unlockchip--free.is-on {
  border-color: var(--up, #6fcf8e); color: var(--up, #6fcf8e);
  background: color-mix(in srgb, var(--up, #6fcf8e) 12%, transparent);
}
.kcc-callmodal__unlocknote {
  margin-left: auto; font-size: 10.5px; color: var(--text3, #6c665d); font-style: italic;
}
.kcc-callmodal__unlocknote.is-free {
  font-family: 'Space Mono', monospace; font-size: 10px; font-style: normal;
  color: var(--up, #6fcf8e);
}
@media (max-width: 760px) {
  .kcc-callmodal__body { grid-template-columns: 1fr; }
  .kcc-callmodal__source { border-right: 0; border-bottom: 1px solid var(--border); min-height: 0; }
}

/* Presence list — scrolls within the rail when many users are online. */
.kcc-presence {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 2px;
  /* The online list is the rail's scroll region: flex:1 fills the space
     between the head and the pinned settings cluster; min-height:0 lets
     it shrink below content height so overflow-y actually scrolls
     instead of the list growing and pushing the cluster off the bottom. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.kcc-presence::-webkit-scrollbar { width: 6px; }
.kcc-presence::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}
.kcc-presence-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 4px;
  border-radius: 6px;
  transition: background 0.12s ease;
}
.kcc-presence-row:hover {
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
.kcc-presence-row.is-me .kcc-presence-handle {
  color: var(--accent);
}
.kcc-presence-avatar {
  position: relative;
  flex-shrink: 0;
}
.kcc-presence-initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  /* Style C — dark fill, colored ring. Default ring is brass;
     hue rules below override per-user. */
  background: var(--card, #13131f);
  border: 1.5px solid var(--accent, #d4a335);
  color: var(--accent, #d4a335);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  box-sizing: border-box;
}
.kcc-presence-dot {
  position: absolute;
  bottom: -1px;
  right: -1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #3aa372;
  border: 2px solid var(--card);
  /* Soft 2s breathing ring — communicates "alive". A box-shadow
     pseudo-ring expands + fades, never offsetting the dot itself. */
  animation: kcc-presence-pulse 2.4s ease-in-out infinite;
}
@keyframes kcc-presence-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, #3aa372 45%, transparent); }
  50%      { box-shadow: 0 0 0 4px color-mix(in srgb, #3aa372 0%, transparent); }
}
/* When someone speaks (just sent a message), their avatar dot
   flashes brass briefly. JS adds .kcc-presence-row--speaking for
   ~1.2s on incoming messages from that user. */
.kcc-presence-row--speaking .kcc-presence-dot {
  background: var(--kcc-self, var(--brass, #d4a335));
  animation: kcc-presence-speaks 1.2s ease-out 1;
}
@keyframes kcc-presence-speaks {
  0%   { box-shadow: 0 0 0 0   color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 70%, transparent); }
  60%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 0%,  transparent); }
  100% { box-shadow: 0 0 0 0   color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 0%,  transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-presence-dot,
  .kcc-presence-row--speaking .kcc-presence-dot {
    animation: none;
  }
}
.kcc-presence-handle {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
/* ── The Floor · Board button (rail head) ─────────────────── */
.kcc-rail-board-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: 5px;
  padding: 3px 6px;
  cursor: pointer;
  transition: background 0.12s ease;
}
.kcc-rail-board-btn:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }
.kcc-rail-board-btn svg { width: 11px; height: 11px; }

/* ── The Floor · Board modal ──────────────────────────────── */
.kcc-board-scrim {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}
.kcc-board-scrim[hidden] { display: none; }
.kcc-board {
  width: 100%;
  max-width: 480px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border2);
  border-radius: 11px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.5);
  overflow: hidden;
}
.kcc-board__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
}
.kcc-board__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-bright);
}
.kcc-board__title svg { width: 15px; height: 15px; color: var(--accent); }
.kcc-board__x {
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 17px; line-height: 1; padding: 2px 4px;
}
.kcc-board__x:hover { color: var(--text-bright); }
.kcc-board__tabs { display: flex; gap: 6px; padding: 11px 16px 0; }
.kcc-board__tab {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 7px 13px; border-radius: 6px 6px 0 0; cursor: pointer;
  color: var(--text-muted); background: none;
  border: 1px solid transparent; border-bottom: none;
}
.kcc-board__tab.is-on {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-color: var(--border);
}
.kcc-board__subbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 16px 6px;
}
.kcc-board__sublbl { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--text-muted); }
.kcc-board__seg { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; flex-shrink: 0; }
.kcc-board__seg button {
  font-family: 'Space Mono', monospace; font-size: 9.5px;
  padding: 4px 9px; cursor: pointer; color: var(--text-muted);
  background: none; border: none;
}
.kcc-board__seg button.is-on { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.kcc-board__body { padding: 4px 14px 16px; overflow-y: auto; }
.kcc-board__empty { text-align: center; color: var(--text-muted); font-size: 12px; padding: 22px 8px; }
.kcc-board__row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 9px; margin-bottom: 5px;
  border: 1px solid var(--border); border-radius: 6px;
  background: color-mix(in srgb, var(--text) 1.5%, transparent);
}
.kcc-board__row.is-you {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.kcc-board__rk {
  width: 22px; text-align: center; flex-shrink: 0;
  font-family: 'Space Mono', monospace; font-size: 13px; font-weight: 700;
  color: var(--text-muted);
}
.kcc-board__rk--1 { color: var(--accent); }
.kcc-board__rk--2 { color: #cdb98a; }
.kcc-board__rk--3 { color: #b9925a; }
.kcc-board__avatar { position: relative; flex-shrink: 0; }
.kcc-board__initials {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--card); border: 1.5px solid var(--accent); color: var(--accent);
  font-family: 'Space Mono', monospace; font-size: 10px; font-weight: 700;
  box-sizing: border-box;
}
.kcc-board__avatar[data-kcc-hue="1"] .kcc-board__initials { border-color: #e08a8a; color: #e08a8a; }
.kcc-board__avatar[data-kcc-hue="2"] .kcc-board__initials { border-color: #7fc9a8; color: #7fc9a8; }
.kcc-board__avatar[data-kcc-hue="3"] .kcc-board__initials { border-color: #a89dd9; color: #a89dd9; }
.kcc-board__avatar[data-kcc-hue="4"] .kcc-board__initials { border-color: #d9b766; color: #d9b766; }
.kcc-board__avatar[data-kcc-hue="5"] .kcc-board__initials { border-color: #7aa4c9; color: #7aa4c9; }
.kcc-board__avatar[data-kcc-hue="6"] .kcc-board__initials { border-color: #d98ab0; color: #d98ab0; }
.kcc-board__avatar[data-kcc-hue="7"] .kcc-board__initials { border-color: #a4adb8; color: #a4adb8; }
.kcc-board__name {
  flex: 1; min-width: 0;
  font-size: 13px; color: var(--text-bright);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Clickable handle + avatar — open the profile modal (parity with chat). */
.kcc-board__name[data-kc-board-profile],
.kcc-board__avatar[data-kc-board-profile] { cursor: pointer; }
.kcc-board__name[data-kc-board-profile]:hover { color: var(--accent); }
.kcc-board__avatar[data-kc-board-profile]:hover .kcc-board__initials {
  filter: brightness(1.18);
}
.kcc-board__name[data-kc-board-profile]:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent, #d4a335) 55%, transparent);
  outline-offset: 2px; border-radius: 3px;
}
.kcc-board__meta { flex-shrink: 0; display: inline-flex; align-items: center; }
.kcc-board__score, .kcc-board__ret {
  flex-shrink: 0; font-family: 'Space Mono', monospace; font-size: 14px; font-weight: 700;
  text-align: right; min-width: 54px;
}
.kcc-board__score { color: var(--accent); }
.kcc-board__ret--pos { color: var(--up); }
.kcc-board__ret--neg { color: var(--red); }
.kcc-board__calls { flex-shrink: 0; font-family: 'Space Mono', monospace; font-size: 11px; color: var(--text-mid); }
/* avg R is the primary metric (.kcc-board__ret, 14px/700, coloured). Win% is
   now a SECONDARY read: smaller, muted, neutral weight — and NOT forced green
   (a high win-rate can sit next to a negative R, e.g. a call that only reached
   a target below its share price). Keeps R the headline per the Board layout. */
.kcc-board__wr {
  flex-shrink: 0; font-family: 'Space Mono', monospace; font-size: 11px; font-weight: 400;
  text-align: right; min-width: 36px; color: var(--text-mid);
}
.kcc-board__depth {
  flex-shrink: 0; font-family: 'Space Mono', monospace; font-size: 10px; font-weight: 700;
  letter-spacing: .02em; color: var(--accent);
  padding: 2px 7px; border-radius: 5px; white-space: nowrap;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.kcc-board__trend { flex-shrink: 0; font-family: 'Space Mono', monospace; font-size: 10px; text-align: right; min-width: 30px; }
.kcc-board__trend--up   { color: var(--up); }
.kcc-board__trend--dn   { color: var(--red); }
.kcc-board__trend--flat { color: var(--text-muted); }
.kcc-board__trend--new  { color: var(--accent); }
@media (max-width: 640px) { .kcc-board { max-height: 88vh; } }

.kcc-presence-empty {
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
  padding: 8px 4px;
  text-align: center;
}

/* ─── App / system messages ──────────────────────────────────
   kind='app' messages (whale alerts, scanner bots, system
   announcements). Brass-bordered card with a 3px left rule and
   an APP chip next to the sender name. The sender identity
   replaces the user handle (no @-prefix). Reactions still work.
   kind='system' is similar but quieter (no chip, slimmer border). */
.kcc-msg[data-kcc-kind="app"] {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 4%, transparent);
  border: 1px solid var(--kcc-self, var(--brass, #d4a335));
  border-left-width: 3px;
  border-radius: 4px;
  padding: 8px 12px 10px;
  margin: 6px 0;
}
.kcc-msg__avatar--app {
  background: var(--card, #13131f) !important;
  color: var(--kcc-self, var(--brass, #d4a335)) !important;
  border: 1px solid var(--kcc-self, var(--brass, #d4a335));
  font-weight: 700;
  letter-spacing: 0.02em;
}
.kcc-msg__handle--app {
  color: var(--kcc-self, var(--brass, #d4a335)) !important;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11px;
}
.kcc-msg__app-chip {
  display: inline-block;
  background: var(--kcc-self, var(--brass, #d4a335));
  color: #1a1408;
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 1px 5px;
  border-radius: 2px;
  margin-left: 4px;
  line-height: 1.4;
  vertical-align: middle;
}
.kcc-msg__app-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  color: var(--text-muted);
}
.kcc-msg__app-fact-lbl {
  margin-right: 4px;
}
.kcc-msg__app-fact-val {
  color: var(--text);
}

/* System messages — quieter than app. Subtle border, no chip,
   monochrome. Used for admin/system announcements. */
.kcc-msg[data-kcc-kind="system"] {
  background: color-mix(in srgb, var(--text-muted, #888) 5%, transparent);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted, #888);
  border-radius: 4px;
  padding: 8px 12px 10px;
  margin: 6px 0;
}

/* ─── House-call TP notice — one-row system line ─────────────────
   kind='system' rows carrying payload.note.t='house_tp': the desk
   reporting back when a House call clears a rung or takes its stop.
   No avatar, no handle, no card — one line, tinted by outcome, with
   the symbol acting as a jump-back link to the call itself.

   SPECIFICITY: the .kcc-msg[data-kcc-kind="system"] rule directly
   above is (0,2,0). This selector has to carry the attribute too or
   the tone colour and the tighter padding never land — a note row
   would silently paint as a generic grey system card.

   The level shown here is resolved client-side from cached geometry
   the viewer is entitled to; when there is none the renderer emits
   ▓▓▓▓ and an unlock button, so the paywall holds without this
   stylesheet knowing anything about it. */
.kcc-msg[data-kcc-kind="system"].kcc-msg--note{
  display: block;                 /* collapses the avatar column */
  padding: 6px 11px;
  margin: 5px 0;
  border: 1px solid var(--border);
  border-left: 3px solid var(--kcc-fu, var(--text-muted, #8a857a));
  border-radius: 4px;
  background: color-mix(in srgb, var(--kcc-fu, var(--text-muted, #8a857a)) 6%, transparent);
}
.kcc-msg--note.t-hit,
.kcc-msg--note.t-full { --kcc-fu: var(--up, #6dd99c); }
.kcc-msg--note.t-stop { --kcc-fu: var(--red, #a83232); }

.kcc-fu-note{
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  line-height: 1.6;
}
.kcc-fu-note__tag{
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 2px 7px;
  border-radius: 3px;
  color: var(--kcc-fu, var(--text-muted, #8a857a));
  border: 1px solid color-mix(in srgb, var(--kcc-fu, var(--text-muted, #8a857a)) 45%, transparent);
  background: color-mix(in srgb, var(--kcc-fu, var(--text-muted, #8a857a)) 14%, transparent);
}
/* Oxblood is dark enough that tag text on the tinted chip goes muddy —
   lift it toward the loss-pink used elsewhere for negative values. */
.kcc-msg--note.t-stop .kcc-fu-note__tag{ color: #d0655a; }

/* Back-reference to the call. A real <button> so it's keyboard
   reachable; the click is handled by the same delegated
   data-kc="reply-scroll" branch the reply quote-block uses. */
.kcc-fu-note__ref{
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--text-muted);
  cursor: pointer;
  text-align: left;
  transition: color 120ms ease;
}
.kcc-fu-note__ref:hover{ color: var(--text); }
.kcc-fu-note__ref:hover .kcc-fu-note__arrow{ color: var(--brass, #d4a335); }
.kcc-fu-note__ref:focus-visible{
  outline: 2px solid var(--brass, #d4a335);
  outline-offset: 2px;
  border-radius: 2px;
}
.kcc-fu-note__arrow{ color: var(--text3, #6c665d); flex-shrink: 0; }
.kcc-fu-note__sym{ color: var(--text-bright); font-weight: 700; }
.kcc-fu-note__side{
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
}
.kcc-fu-note__side--long { color: var(--kcc-long-fg, var(--up, #6dd99c)); }
.kcc-fu-note__side--short{ color: var(--kcc-short-fg, var(--down, #d05a4a)); }
.kcc-fu-note__px{ color: var(--text-mid, #c8c2b4); }
/* Redacted level — same ▓ glyphs the locked signal card uses, dimmed
   so they read as withheld rather than as a value. */
.kcc-fu-note__px--locked{
  color: var(--text3, #6c665d);
  letter-spacing: -0.06em;
}
.kcc-fu-note__pos{ color: var(--up, #6dd99c); }
.kcc-fu-note__neg{ color: #d0655a; }
.kcc-fu-note__r{ color: var(--brass, #d4a335); font-weight: 700; }
.kcc-fu-note__r--neg{ color: #d0655a; }
.kcc-fu-note__dim{ color: var(--text3, #6c665d); }
.kcc-fu-note__dot{ color: var(--text3, #6c665d); opacity: 0.55; }

/* Unlock hook — only rendered when the level is actually withheld.
   Underlined rather than boxed: it's a link inside a sentence, not a
   competing CTA against the locked card's own button. */
.kcc-fu-note__unlock{
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 10.5px;
  color: var(--brass, #d4a335);
  border-bottom: 1px dashed color-mix(in srgb, var(--brass, #d4a335) 50%, transparent);
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease;
}
.kcc-fu-note__unlock:hover{
  color: var(--text-bright);
  border-bottom-color: var(--brass, #d4a335);
}
.kcc-fu-note__unlock:focus-visible{
  outline: 2px solid var(--brass, #d4a335);
  outline-offset: 2px;
  border-radius: 2px;
}

/* The call's own clock — how long it took to get here, not how long
   ago the row posted (that's in the title tooltip). Pinned right on
   a wide row; drops into the flow once the line wraps. */
.kcc-fu-note__time{
  margin-left: auto;
  flex-shrink: 0;
  font-size: 10px;
  color: var(--text3, #6c665d);
}
@media (max-width: 600px){
  .kcc-fu-note{ gap: 6px; font-size: 10.5px; }
  .kcc-fu-note__time{ margin-left: 0; }
}

/* Chronicle theme: app/system rows already have their own border
   inside the card frame — let our border replace Chronicle's left
   edge by suppressing the inherited rules on app/system kinds. */
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-kind="app"],
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-kind="system"] {
  border-top: 1px solid var(--kcc-self, var(--brass, #d4a335));
  border-bottom: 1px solid var(--kcc-self, var(--brass, #d4a335));
}
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-kind="system"] {
  border-top-color: var(--text-muted, #888);
  border-bottom-color: var(--text-muted, #888);
}

/* ─── Filter tabs ─────────────────────────────────────────────
   Peaky pill buttons above the stream. Uppercase mono, sharp 3px
   corners, hairline border. Active tab gets brass border + tint.
   Sits flush against the panel-calls strip above. */
.kcc-filter-tabs {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--bg2, transparent);
  flex-shrink: 0;
  overflow-x: auto;
  scrollbar-width: thin;
}
.kcc-filter-tabs::-webkit-scrollbar { height: 4px; }
.kcc-filter-tab {
  background: transparent;
  border: 1px solid var(--border2);
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 3px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  transition: border-color 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-filter-tab:hover {
  color: var(--text-bright);
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 30%, var(--border2));
}
.kcc-filter-tab.is-on {
  color: var(--kcc-self, var(--brass, #d4a335));
  border-color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
}
.kcc-filter-tab svg {
  width: 11px;
  height: 11px;
  display: block;
  flex-shrink: 0;
}
.kcc-filter-tab__lbl {
  white-space: nowrap;
}
.kcc-filter-tab__badge {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 30%, transparent);
  color: var(--kcc-self, var(--brass, #d4a335));
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 8px;
  line-height: 1.2;
  font-family: 'Space Mono', monospace;
}
.kcc-filter-tab__badge[hidden] { display: none; }
/* The test-room flask (.kcc-room-toggle) ships with the `hidden` attribute
   and _renderFilterTabs() toggles it via btn.hidden based on the testRoom
   cap (admins / mods / testers). Without this rule the UA `[hidden]`
   (display:none, spec 0,1,0) loses to `.kcc-filter-tab{display:inline-flex}`
   (also 0,1,0) on author-origin precedence — so the flask leaked to EVERY
   user (regular + partners included) and the JS hide was a visual no-op.
   `.kcc-filter-tab[hidden]` is (0,2,0) → wins, restoring the gate. Only the
   flask ever carries [hidden]; the other tabs are unaffected. */
.kcc-filter-tab[hidden] { display: none !important; }
.kcc-filter-tab.is-on .kcc-filter-tab__badge {
  background: var(--kcc-self, var(--brass, #d4a335));
  color: #1a1408;
}
/* House tab paid marker (◈) — always brass so the premium tab reads as
   "costs razors to unlock" regardless of active state. */
.kcc-filter-tab__paid {
  color: var(--kcc-self, var(--brass, #d4a335));
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  line-height: 1;
  margin-left: 1px;
}

/* ─── New-messages pill ─────────────────────────────────────────
   Floating brass pill that appears above the composer when the
   viewer is scrolled up + new messages have arrived. Click → snap
   to bottom. Drops in from below on appearance via a small slide. */
.kcc-stream__pill {
  position: absolute;
  left: 50%;
  bottom: 110px;   /* sits above composer + toolbar */
  transform: translateX(-50%) translateY(0);
  background: var(--kcc-self, var(--brass, #d4a335));
  color: #1a1408;
  border: 0;
  border-radius: 999px;
  padding: 5px 14px;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  z-index: 6;
  animation: kcc-pill-rise 220ms ease-out;
}
.kcc-stream__pill[hidden] { display: none; }
.kcc-stream__pill:hover {
  filter: brightness(1.08);
}
@keyframes kcc-pill-rise {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0);   }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-stream__pill { animation: none; }
}

/* ─── Quiet "jump to present" FAB ──────────────────────────────────
   Shown when the viewer has scrolled up past JUMP_PRESENT_MSG_THRESHOLD
   messages (default 10) even WITHOUT new activity. Bottom-right so it
   sits out of the way while reading older messages — visually quieter
   than the brass N-NEW pill, which always wins the center position
   when both would qualify. Same offset from the composer as the brass
   pill for visual rhythm. Sibling of .kcc-stream (lives in
   .kcc-inline__main / .kcc-panel), so it anchors to the chat shell,
   not the stream itself. */
.kcc-stream__jump {
  position: absolute;
  right: 18px;
  bottom: 110px;
  width: 36px;
  height: 36px;
  background: var(--card);
  color: var(--brass, #d4a335);
  border: 1px solid var(--border2, #2a241a);
  border-radius: 50%;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  z-index: 5;
  /* Reuse the same rise animation — same easing as the brass pill so
     both feel like the same family. */
  animation: kcc-pill-rise-y 220ms ease-out;
  transition: transform 120ms ease, filter 120ms ease;
}
.kcc-stream__jump[hidden] { display: none; }
.kcc-stream__jump:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}
.kcc-stream__jump:active {
  transform: translateY(0);
}
/* Separate keyframe because the brass pill uses translateX(-50%) in
   its transform — we don't want to inherit that horizontal shift. */
@keyframes kcc-pill-rise-y {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0);   }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-stream__jump { animation: none; }
}

/* ─── Floor Razor AI: /ai card (B-A) + Catch Me Up FAB (C-C) ───────
   The dock is a sibling of the stream (survives _renderStream's innerHTML
   wipe). Cards are PRIVATE — dashed brass + "ONLY YOU" tag, deliberately
   distinct from the solid-brass "Razor Ask" room-question card. */
.kcc-floor-ai {
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 6px;
}
.kcc-floor-ai[hidden] { display: none; }
.kcc-fai-card {
  border: 1px dashed var(--brass, #d4a335);
  border-radius: 9px;
  background: linear-gradient(180deg, rgba(212,163,53,.06), rgba(212,163,53,.015));
  padding: 10px 13px;
  animation: kccFaiIn .18s ease;
}
@keyframes kccFaiIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.kcc-fai-head { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.kcc-fai-glyph { color: var(--brass, #d4a335); font-size: 13px; line-height: 1; }
.kcc-fai-lbl {
  font: 700 9px 'Space Mono', monospace; letter-spacing: 1.6px;
  color: var(--brass, #d4a335);
}
.kcc-fai-only {
  font: 9px 'Space Mono', monospace; letter-spacing: 1px;
  color: var(--text-muted, #82858d);
  border: 1px solid var(--border2, #2a241a); border-radius: 99px; padding: 1px 7px;
}
.kcc-fai-x {
  margin-left: auto; background: none; border: none; cursor: pointer;
  color: var(--text-muted, #82858d); font-size: 15px; line-height: 1; padding: 0 2px;
}
.kcc-fai-x:hover { color: var(--text-bright, #ecebe6); }
.kcc-fai-q {
  font-size: 12px; color: var(--text-bright, #ecebe6);
  margin-bottom: 6px; opacity: .9;
}
.kcc-fai-card--digest .kcc-fai-q { display: none; }
.kcc-fai-body { font-size: 12.5px; color: var(--kcc-text, var(--text, #d7d5cf)); line-height: 1.55; }
.kcc-fai-body strong { color: var(--text-bright, #ecebe6); }
.kcc-fai-err { color: var(--negative, #c75050); }
/* loading dots */
.kcc-fai-dots { display: inline-flex; gap: 4px; align-items: center; height: 14px; }
.kcc-fai-dots i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--brass, #d4a335); opacity: .4;
  animation: kccFaiDot 1s infinite ease-in-out;
}
.kcc-fai-dots i:nth-child(2) { animation-delay: .15s; }
.kcc-fai-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes kccFaiDot { 0%,80%,100% { opacity: .25; } 40% { opacity: 1; } }

/* Catch Me Up FAB (C-C) — brass chip, bottom-right above the composer,
   sits a little higher than the jump/new-msgs FABs so they don't overlap. */
.kcc-catchup-fab {
  position: absolute;
  right: 18px;
  bottom: 150px;
  display: inline-flex; align-items: center; gap: 6px;
  font: 600 11px 'Space Grotesk', system-ui, sans-serif;
  color: #1a1406;
  background: var(--brass, #d4a335);
  border: none; border-radius: 99px;
  padding: 7px 13px; cursor: pointer;
  box-shadow: 0 3px 16px rgba(212,163,53,.32);
  z-index: 4;
  animation: kccFaiIn .2s ease;
}
.kcc-catchup-fab[hidden] { display: none; }
.kcc-catchup-fab:hover { filter: brightness(1.06); }
.kcc-catchup-fab__glyph { font-size: 12px; }
.kcc-catchup-fab__n {
  background: rgba(0,0,0,.18); border-radius: 99px;
  padding: 0 6px; font-family: 'Space Mono', monospace; font-size: 10px;
}
@media (max-width: 720px) {
  .kcc-catchup-fab { bottom: 138px; right: 12px; }
}

/* ─── Admin/Mod styling ─────────────────────────────────────────
   Section break in the ONLINE list when both admins and regular
   members are present. The header is the smallest visual signal —
   compact uppercase Space Mono in the muted-text tone, with a
   hairline rule. */
.kcc-presence-section-lbl {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 8px 4px 4px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
.kcc-presence-section-lbl:first-child {
  border-top: 0;
  margin-top: 0;
  padding-top: 2px;
}

/* Admin shield glyph — sits right of the handle in both presence
   list and message stream. Brass, ~10px, slight opacity so it
   anchors but doesn't shout. */
.kcc-presence-admin-badge,
.kcc-msg__admin-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--kcc-self, var(--brass, #d4a335));
  flex-shrink: 0;
  opacity: 0.85;
  transition: opacity 100ms ease;
}
.kcc-presence-admin-badge svg,
.kcc-msg__admin-badge svg {
  width: 10px;
  height: 10px;
  display: block;
}
.kcc-presence-row.is-admin .kcc-presence-handle {
  color: var(--kcc-self, var(--brass, #d4a335));
  font-weight: 500;
}
.kcc-presence-row:hover .kcc-presence-admin-badge,
.kcc-msg:hover .kcc-msg__admin-badge {
  opacity: 1;
}
.kcc-msg__admin-badge {
  margin-left: 2px;
}

/* ─── Tier chip in chat message rows (Phase 6) ──────────────────────
   Inline pill that sits beside the @handle, populated lazily from
   KCTier.profile() on row paint. Mirrors .kc-profile-tier (same
   per-tier color-mix recipe) but trimmed for the denser meta row —
   8px text, 2px padding, slightly tighter border alpha so it sits
   behind the handle visually rather than competing with it.

   The slot (.kcc-msg__tier-slot) is always rendered for non-system,
   non-app rows so the post-render sweep has a stable host to patch.
   It has zero footprint until populated.

   Self rows pick up the brass-toned chip via --kcc-self in the same
   way the admin badge does — the colored chip then overrides via
   --kc-tier-color set inline. */
.kcc-msg__tier-slot {
  /* Hidden in chat: the badge flair now carries inline identity, so the
     tier chip (SCOUT etc.) was redundant clutter next to it. The slot
     still renders in the DOM so the shared tier+flair resolve sweep has
     its host; it's just not shown. Tier chips remain visible on the board
     and profile (different classes). */
  display: none;
}
.kcc-msg__tier {
  font-family: 'Space Mono', monospace;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 1px 5px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--kc-tier-color, #888780) 14%, transparent);
  color: var(--kc-tier-color, #888780);
  border: 1px solid color-mix(in srgb, var(--kc-tier-color, #888780) 26%, transparent);
  white-space: nowrap;
  line-height: 1.5;
  /* Sit slightly above the handle baseline so the pill doesn't drop
     below the row's optical line. The 8px text in a baseline-aligned
     meta row otherwise reads as floating low. */
  align-self: center;
  position: relative;
  top: -1px;
}
.kcc-msg__tier[data-kc-tier="peaky_boss"] {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--brass, #d4a335) 28%, transparent) inset,
              0 0 6px color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
}
/* Continuation rows in Classic / Chronicle / Guild themes hide the
   meta entirely — but if a theme keeps it (Bubbles, edits showing
   timestamps on self), the chip still sits cleanly with the rest. */

/* ── Primary-flair chip ──────────────────────────────────────────────
   One earned badge shown inline beside the handle (twin of the tier
   slot). Slightly larger than the 8px tier chip so the icon reads, but
   still compact enough to sit in a dense meta row. Rarity → colour via
   data-kc-rarity; the glyph inherits currentColor. Razor tier gets a
   static brass glow (no animation — a shimmering chip on every razor row
   would pull focus in a live stream; the shimmer is reserved for the
   profile badge case). */
.kcc-msg__flair-slot {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.kcc-msg__flair-slot:empty {
  display: none;
}
.kcc-msg__flair {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  padding: 2px 6px 2px 5px;
  border-radius: 4px;
  white-space: nowrap;
  border: 1px solid transparent;
  align-self: center;
  position: relative;
  top: -1px;
}
.kcc-msg__flair svg {
  width: 11px;
  height: 11px;
  flex: 0 0 auto;
}
.kcc-msg__flair-lbl { padding-top: 1px; }

/* Chat rows show the badge ICON ONLY — the label is noise inline. The
   full name still surfaces on hover via the chip's native title="".
   Scoped to the chat flair slot so the profile badge grid
   (.kc-profile-case) keeps its labels. */
.kcc-msg__flair-slot .kcc-msg__flair-lbl { display: none; }
.kcc-msg__flair-slot .kcc-msg__flair {
  gap: 0;
  padding: 3px;
}

.kcc-msg__flair[data-kc-rarity="iron"] {
  background: color-mix(in srgb, #8a96a3 12%, transparent);
  color: #aab0b8;
  border-color: color-mix(in srgb, #8a96a3 28%, transparent);
}
.kcc-msg__flair[data-kc-rarity="iron"] svg { color: #8a96a3; }

.kcc-msg__flair[data-kc-rarity="brass"] {
  background: color-mix(in srgb, var(--accent, #d4a335) 13%, transparent);
  color: var(--accent, #d4a335);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 34%, transparent);
}
.kcc-msg__flair[data-kc-rarity="brass"] svg { color: var(--accent, #d4a335); }

.kcc-msg__flair[data-kc-rarity="oxblood"] {
  background: color-mix(in srgb, var(--red, #a83232) 16%, transparent);
  color: #e08a8a;
  border-color: color-mix(in srgb, var(--red, #a83232) 42%, transparent);
}
.kcc-msg__flair[data-kc-rarity="oxblood"] svg { color: #d06060; }

.kcc-msg__flair[data-kc-rarity="razor"] {
  background: linear-gradient(120deg,
    color-mix(in srgb, var(--accent, #d4a335) 22%, transparent),
    color-mix(in srgb, var(--red, #a83232) 18%, transparent));
  color: var(--text-bright, #faf6ec);
  border-color: color-mix(in srgb, var(--accent, #d4a335) 60%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #d4a335) 16%, transparent) inset,
              0 0 8px color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
}
.kcc-msg__flair[data-kc-rarity="razor"] svg { color: var(--yellow, #e8c560); }

/* Sign-in nudge — shown by mountInline() when no session. */
.kcc-inline-signin {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 48px 28px;
  text-align: center;
  max-width: 460px;
  margin: 40px auto;
}
.kcc-inline-signin__title {
  font-size: 16px;
  color: var(--text-bright);
  margin-bottom: 8px;
  font-weight: 500;
}
.kcc-inline-signin__sub {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.55;
  margin-bottom: 22px;
}
.kcc-inline-signin__btn {
  display: inline-block;
  background: var(--accent);
  color: #0b0a09;
  text-decoration: none;
  padding: 10px 22px;
  border-radius: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: filter 0.12s ease;
}
.kcc-inline-signin__btn:hover { filter: brightness(1.08); }

/* Tablet — narrow desktop, ~960–1100px range. Drop the left
   sidebar (Active Calls lives in the right rail OR the chat header
   on this size) since cramming three rails leaves the chat column
   under-width. The left modules hide; right rail + main stay. */
@media (max-width: 1100px) and (min-width: 761px) {
  .kcc-inline {
    grid-template-columns: minmax(0, 1fr) 240px;
  }
  .kcc-inline__sidebar {
    display: none;
  }
}

/* Mobile: collapse rail under the stream, drop sticky behaviour so the
   page scrolls naturally on a phone. */
@media (max-width: 760px) {
  /* Conversation is primary. The shell fills the viewport below the
     fixed 48px mobile topbar; only .kcc-stream scrolls and the composer
     stays pinned to the floor. --kcc-mob-inset is the single knob:
     48px topbar + 24px container pad + bottom dock clearance. Tune it
     once on-device if the composer doesn't sit flush above the dock. */
  .kcc-inline {
    --kcc-mob-inset: 140px;
    display: flex;
    flex-direction: column;
    /* vh fallback first, then dvh (dynamic viewport — shrinks when
       Safari's toolbar is shown). Subtract the home-indicator safe area
       so the pinned composer never tucks under the toolbar / gesture bar.
       --kcc-mob-inset is the single knob: 48px topbar + 24px container
       pad + bottom breathing room. */
    height: calc(100vh - var(--kcc-mob-inset) - var(--kcc-nudge-h, 0px));
    height: calc(100dvh - var(--kcc-mob-inset) - var(--kc-safe-b) - var(--kcc-nudge-h, 0px));
    gap: 0;
  }
  .kcc-inline__main {
    order: 0;
    flex: 1 1 auto;
    min-height: 0;
  }
  .kcc-inline__main .kcc-stream { flex: 1 1 auto; min-height: 0; }

  /* The mobile header appears; it carries the rails toggle + online count. */
  .kcc-mob-head { display: flex; }

  /* Rails wrapper becomes a right-hand off-canvas panel holding the
     module sidebar + the online/settings rail, stacked and scrolling. */
  .kcc-inline__rails {
    display: flex;
    flex-direction: column;
    gap: 12px;
    position: fixed;
    top: 48px; right: 0; bottom: 0;
    width: min(86vw, 360px);
    background: var(--kcc-surface, var(--card));
    border-left: 1px solid var(--kcc-edge, var(--border));
    z-index: 60;
    transform: translateX(100%);
    transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 16px;
  }
  .kcc-inline.is-rail-open .kcc-inline__rails { transform: translateX(0); }
  /* The floating dock (z 840) sits over this panel (z 60), so the last
     rows (Online / Admins) ended under the pill. Same clearance the
     dock gives every other page's body. */
  html[data-kc-dock] .kcc-inline__rails {
    padding-bottom: calc(96px + var(--kc-safe-b, 0px));
  }

  .kcc-mob-rail-head { display: flex; order: 1; }
  .kcc-inline__sidebar { order: 2; }
  .kcc-inline__rail    { order: 3; }

  /* Inside the panel both rails drop their card chrome + fixed heights
     and simply flow with the panel's own scroll. */
  .kcc-inline__sidebar,
  .kcc-inline__rail {
    position: static;
    width: auto;
    height: auto;
    max-height: none;
    overflow: visible;
    border: 0;
    border-radius: 0;
    padding: 0 14px;
  }
  /* The rail's bottom spacer is only there to push settings down in the
     fixed-height desktop column — not needed in a flowing panel. */
  .kcc-rail-spacer { display: none; }

  /* On mobile the rail flows inside the scrolling off-canvas panel, so
     the online list must NOT be its own scroll region — let it grow
     naturally and scroll with the panel. */
  .kcc-presence {
    flex: 0 0 auto;
    min-height: 0;
    overflow: visible;
  }

  /* Dim + catch taps behind the open panel. */
  .kcc-mob-rail-backdrop {
    position: fixed;
    inset: 48px 0 0 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 55;
  }
  .kcc-inline.is-rail-open .kcc-mob-rail-backdrop { display: block; }
}
/* ─── Chat — link previews & in-text links ──────────────────────────
   Anchors inside .kcc-msg__text get a subtle brass tint matching the
   rest of the platform's interactive language. The preview card sits
   directly below the text, indented to the same body column so it
   aligns with the message author's content (avatar column stays
   clear). Allow-list domains only — see KCChat PREVIEW_ALLOW.
*/
.kcc-msg__link {
  color: var(--accent, #d4a335);
  text-decoration: none;
  word-break: break-all;
}
.kcc-msg__link:hover {
  text-decoration: underline;
}

/* ─── Mention pill ──────────────────────────────────────────────
   @handle tokens render as inline pills with a hairline border and
   a subtle tint of the palette accent. Self-mentions ([data-self])
   light up brighter so the viewer notices at a glance. */
.kcc-mention {
  display: inline;
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
  padding: 1px 4px;
  border-radius: 3px;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
}
.kcc-mention[data-self="1"] {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 22%, transparent);
  font-weight: 600;
}

/* When a message tags the current viewer, give the whole row a soft
   brass left rule + subtle tint so it stands out in scrollback. The
   accent uses the palette's self color so it adapts cleanly to every
   theme. Tail/cont rules in Chronicle override left-edge already on
   self runs — mentions-of-me are by definition NOT self runs, so
   they take precedence over the neutral edge on Chronicle. */
.kcc-msg[data-kcc-mentions-me="1"] {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 6%, transparent);
  box-shadow: inset 2px 0 0 var(--kcc-self, var(--brass, #d4a335));
}
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-mentions-me="1"] {
  /* Chronicle's card already carries its own borders + left edge;
     keep the inset shadow but tone down the tint so the card surface
     stays readable. */
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 5%, var(--kcc-surface, var(--surface)));
  box-shadow: inset 2px 0 0 var(--kcc-self, var(--brass, #d4a335));
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-mentions-me="1"] {
  /* Bubbles puts text inside its own pill — the row tint conflicts
     with the bubble's own background. Drop the surface tint here
     and rely on a brighter bubble border + the inline mention pill. */
  background: transparent;
  box-shadow: none;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-mentions-me="1"] .kcc-msg__text {
  border: 1px solid color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 55%, transparent);
}

/* ─── Mention picker popover ───────────────────────────────────
   Sits above the composer input on `@`-typing, same anchoring as
   the emoji popover but narrower (handles are short). One row per
   handle; active row (keyboard-highlighted or hover) is tinted. */
.kcc-mention-popover {
  position: absolute;
  bottom: 100%;
  left: 12px;
  max-width: 220px;
  margin-bottom: 8px;
  z-index: 11;            /* one above the emoji popover */
  padding: 4px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  max-height: 240px;
  overflow-y: auto;
}
.kcc-mention-popover[hidden] { display: none; }
.kcc-mention-popover::-webkit-scrollbar { width: 6px; }
.kcc-mention-popover::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}
.kcc-mention-popover__item {
  padding: 6px 10px;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
  border-radius: 3px;
  transition: background 80ms ease, color 80ms ease;
}
.kcc-mention-popover__item:hover,
.kcc-mention-popover__item.is-active {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 14%, transparent);
  color: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-mention-popover__empty {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}

/* Slash-command popover — opens above the composer when the user
   types `/` at the start of the input. Mirrors .kcc-mention-popover
   structurally but is a touch wider (commands need room for a short
   description after the verb). Each item is a row: <command> on the
   left in Space Mono brass, <description> on the right in body text.
   Disabled commands ("coming soon") render dimmed and can't be picked. */
.kcc-slash-popover {
  position: absolute;
  bottom: 100%;
  left: 12px;
  right: 12px;
  max-width: 320px;
  margin-bottom: 8px;
  z-index: 11;
  padding: 4px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  max-height: 240px;
  overflow-y: auto;
  animation: kcc-slash-rise 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes kcc-slash-rise {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0);   }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-slash-popover { animation: none; }
}
.kcc-slash-popover[hidden] { display: none; }
.kcc-slash-popover::-webkit-scrollbar { width: 6px; }
.kcc-slash-popover::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}
.kcc-slash-popover__item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 10px;
  font-size: 12px;
  cursor: pointer;
  border-radius: 3px;
  transition: background 80ms ease, color 80ms ease;
}
.kcc-slash-popover__item:hover:not(.is-disabled),
.kcc-slash-popover__item.is-active:not(.is-disabled) {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 14%, transparent);
}
.kcc-slash-popover__cmd {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  color: var(--kcc-self, var(--brass, #d4a335));
  min-width: 70px;
  flex-shrink: 0;
}
.kcc-slash-popover__desc {
  color: var(--text);
  font-size: 11.5px;
  line-height: 1.35;
  flex: 1;
  min-width: 0;
}
.kcc-slash-popover__item.is-disabled {
  cursor: default;
  opacity: 0.45;
}
.kcc-slash-popover__item.is-disabled .kcc-slash-popover__cmd {
  color: var(--text-muted);
}
.kcc-slash-popover__soon {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 1px 5px;
  border-radius: 2px;
  background: var(--border2);
  color: var(--text-muted);
  flex-shrink: 0;
  align-self: center;
}
.kcc-slash-popover__empty {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
}

.kcc-msg__preview {
  display: flex;
  gap: 10px;
  margin-top: 8px;
  padding: 8px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
  max-width: 460px;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-msg__preview:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 4%, var(--bg2));
}

.kcc-msg__preview-img {
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 4px;
  background-color: var(--bg);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.kcc-msg__preview-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.kcc-msg__preview-site {
  font-size: 10px;
  font-family: 'Space Mono', monospace;
  color: var(--text-muted);
  text-transform: lowercase;
  letter-spacing: 0.02em;
}
.kcc-msg__preview-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-bright);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  line-height: 1.35;
  /* 2-line clamp — long titles truncate so the card stays compact. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kcc-msg__preview-desc {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.4;
  /* 2-line clamp on description too. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Pending messages dim the preview the same way they dim the body. */
.kcc-msg--pending .kcc-msg__preview {
  opacity: 0.65;
}

/* ─── Chat — image attachments ───────────────────────────────────
   The attach button sits in the composer row left of the input. The
   staged-image strip drops in above the row when a file is picked,
   and rendered messages get inline <img> thumbnails under their body.
   All chrome leans on the same brass-on-bg2 tokens as the rest of the
   chat surface so it reads as one component, not a bolt-on.
*/
.kcc-composer__attach {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  width: 28px;
  height: 28px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: color .12s ease, background .12s ease;
}
.kcc-composer__attach:hover {
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--text-bright, #fff) 5%, transparent);
}
.kcc-composer__attach:focus-visible {
  outline: none;
  color: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-composer__attach .kc-ic { display: inline-flex; }
.kcc-composer__emoji .kc-ic { display: inline-flex; }

/* ── Composer "+" disclosure + tools wrapper (Layout B) ──────────────
   Desktop is unchanged: the "+" is hidden and the secondary controls
   (attach · emoji · bias) sit inline in the bar, just as before. On
   phones the bar collapses to [+] [input] [send]; tapping "+" sets
   .is-tools-open on the card, which drops the tools row and the chip
   toolbar in as a sheet beneath the bar. Keeps the typing target wide
   and stops the chip row from overflowing. */
.kcc-composer__more {
  flex: 0 0 auto;
  display: none;            /* shown only at the phone breakpoint */
  width: 30px;
  height: 30px;
  border-radius: 7px;
  border: 1px solid var(--kcc-edge, var(--border2));
  background: transparent;
  color: var(--kcc-self, var(--brass, #d4a335));
  cursor: pointer;
  align-items: center;
  justify-content: center;
  transition: background .12s ease, color .12s ease;
}
.kcc-composer__more:hover {
  color: var(--text-bright);
  background: color-mix(in srgb, var(--text-bright, #fff) 5%, transparent);
}
.kcc-composer__more-glyph {
  font-size: 19px;
  line-height: 1;
  transition: transform 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-composer__card.is-tools-open .kcc-composer__more-glyph { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) {
  .kcc-composer__more-glyph { transition: none; }
}

/* Tools wrapper — inline group on desktop (visually identical to the
   old loose buttons), becomes a wrapping sheet line on mobile. */
.kcc-composer__tools {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

@media (max-width: 760px) {
  /* The bar can wrap so the tools sheet drops to its own line. */
  /* iOS Safari auto-zooms when a focused input's font-size is < 16px.
     That zoom rescales the visual viewport and breaks the keyboard-aware
     column sizing (composer balloons + pins to the top). 16px is the
     threshold that prevents it. Applies to both chat surfaces. */
  .kcc-composer__input { font-size: 16px; }

  /* Reclaim width for the input so "say something to the floor…" shows in
     full: SEND collapses to its arrow only, the row tightens, and the +
     shrinks a touch. The "send" word is hidden (arrow carries the intent;
     aria-label still reads "send"). */
  .kcc-composer__send { padding: 8px 11px; }
  .kcc-composer__send > span:not(.kcc-composer__send-arrow) { display: none; }
  .kcc-composer__send-arrow { font-size: 15px; }
  .kcc-composer__row { gap: 5px; padding: 6px 7px; }
  .kcc-composer__more { width: 28px; height: 28px; }

  .kcc-composer__row { flex-wrap: wrap; }
  .kcc-composer__more { display: flex; }
  /* Collapsed: tools + chip toolbar tuck away behind "+". */
  .kcc-composer__tools   { display: none; }
  .kcc-composer__toolbar { display: none; }

  /* Open: reveal the sheet. Tools wrap onto a full-width line under the
     [+]/input/send row; the chip toolbar follows as the second sheet
     line, now wrapping so chips + counter never overflow. */
  .kcc-composer__card.is-tools-open .kcc-composer__tools {
    display: flex;
    order: 5;
    flex-basis: 100%;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
  }
  .kcc-composer__card.is-tools-open .kcc-composer__toolbar {
    display: flex;
    flex-wrap: wrap;
    row-gap: 6px;
  }
  /* Bigger tap targets for the sheet's icon buttons. */
  .kcc-composer__card.is-tools-open .kcc-composer__attach,
  .kcc-composer__card.is-tools-open .kcc-composer__emoji,
  .kcc-composer__card.is-tools-open .kcc-composer__bias {
    width: 36px;
    height: 36px;
  }
  /* Roomier chips in the sheet. */
  .kcc-composer__card.is-tools-open .kcc-composer__tool { padding: 6px 9px; }
}

/* ── Composer bias picker ─────────────────────────────────────────
   Optional author sentiment. Neutral = both glyphs dimmed; once a
   side is picked, only that arrow shows, colored. Popover mirrors the
   emoji popover. Stream rows with payload.bias get a colored left
   rail (squared left corners) + a small meta tag. Untagged rows are
   untouched. Colors reuse --up (sage) / --red (oxblood). */
.kcc-composer__bias {
  background: transparent;
  border: 0;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: background .12s ease;
}
.kcc-composer__bias:hover {
  background: color-mix(in srgb, var(--text-bright, #fff) 5%, transparent);
}
.kcc-composer__bias[aria-expanded="true"] {
  background: color-mix(in srgb, var(--text-bright, #fff) 6%, transparent);
}
.kcc-bias-glyph { font-size: 8px; line-height: 1; }
.kcc-composer__bias[data-bias=""] .kcc-bias-glyph--up { color: var(--up, #6dd99c); opacity: .8; }
.kcc-composer__bias[data-bias=""] .kcc-bias-glyph--dn { color: var(--red, #a83232); opacity: .8; }
.kcc-composer__bias[data-bias=""]:hover .kcc-bias-glyph { opacity: 1; }
.kcc-composer__bias[data-bias="bull"] .kcc-bias-glyph--dn,
.kcc-composer__bias[data-bias="bear"] .kcc-bias-glyph--up { display: none; }
.kcc-composer__bias[data-bias="bull"] .kcc-bias-glyph--up { font-size: 12px; color: var(--up, #6dd99c); }
.kcc-composer__bias[data-bias="bear"] .kcc-bias-glyph--dn { font-size: 12px; color: var(--red, #a83232); }

.kcc-bias-popover {
  position: absolute;
  bottom: 100%;
  left: 8px;
  margin-bottom: 8px;
  z-index: 10;
  padding: 5px;
  min-width: 144px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  font-family: 'Space Mono', monospace;
}
.kcc-bias-popover[hidden] { display: none; }
.kcc-bias-opt {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 12px;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 5px;
  cursor: pointer;
}
.kcc-bias-opt:hover { background: color-mix(in srgb, var(--text-bright, #fff) 5%, transparent); }
.kcc-bias-opt span { width: 12px; text-align: center; font-size: 13px; }
.kcc-bias-opt--bull { color: var(--up, #6dd99c); }
.kcc-bias-opt--bear { color: var(--red, #a83232); }

/* Author bias tag — small inline chip at the head of the message text.
   Renders per-message in every theme (Classic / Guild / Bubbles); no
   stream rail (it duplicated the tag and couldn't follow bubbles). */
.kcc-msg__bias-tag {
  display: inline-block;
  vertical-align: middle;
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 3px;
  margin-right: 6px;
  white-space: nowrap;
  position: relative;
  top: -1px;
}
.kcc-msg__bias-tag--bull {
  background: color-mix(in srgb, var(--up, #6dd99c) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--up, #6dd99c) 32%, transparent);
  color: var(--up, #6dd99c);
}
.kcc-msg__bias-tag--bear {
  background: color-mix(in srgb, var(--red, #a83232) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--red, #a83232) 42%, transparent);
  color: #e07a7a;
}

/* ── Featured spotlight strip ─────────────────────────────────────
   Promoted headline view of MY PINNED, mounted above the stream on
   the Floor page. Reuses the pinned-card markup; these rules give it
   a prominent, brass-edged, full-width presence distinct from the
   compact sidebar version. Hidden entirely when nothing is pinned. */
.kcc-spotlight {
  margin: 0 0 10px;
  padding: 9px 11px 10px;
  background: color-mix(in srgb, var(--brass, #d4a335) 4%, var(--card, #171513));
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 28%, transparent);
  border-radius: 10px;
}
.kcc-spotlight[hidden] { display: none; }
.kcc-spotlight__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}
.kcc-spotlight__label {
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: var(--kcc-self, var(--brass, #d4a335));
}
.kcc-spotlight__label svg { width: 11px; height: 11px; }
.kcc-spotlight__tabs { display: inline-flex; gap: 4px; }
.kcc-spotlight__tab {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: color 100ms ease, background 100ms ease;
}
.kcc-spotlight__tab:hover { color: var(--text-bright); }
.kcc-spotlight__tab.is-active {
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 10%, transparent);
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 30%, transparent);
}

/* Mobile — tab strips scroll horizontally with a right-edge fade so they
   read as "swipe for more" instead of looking truncated (CHALLENGES /
   SENTIMENT were getting clipped at the edge). Tabs keep their size; the
   strip hides its scrollbar and masks its trailing edge. */
@media (max-width: 760px) {
  .kcc-filter-tabs,
  .kcc-spotlight__tabs {
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
            mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent);
  }
  .kcc-filter-tabs::-webkit-scrollbar,
  .kcc-spotlight__tabs::-webkit-scrollbar { display: none; }
  .kcc-filter-tab,
  .kcc-spotlight__tab { flex-shrink: 0; }
  /* The featured sub-tabs share a row with the FEATURED label — let them
     take the remaining width and scroll within it. */
  .kcc-spotlight__tabs { min-width: 0; flex-shrink: 1; }
}
.kcc-spotlight__tab-count {
  font-size: 9px;
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
}
/* Promote the reused pinned card: full surface, bigger type. */
.kcc-spotlight__body .kcc-mypinned__card {
  background: var(--card, #171513);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
  border-left-width: 3px;
  border-radius: 8px;
  padding: 10px 12px;
}
.kcc-spotlight__body .kcc-mypinned__card:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, var(--card, #171513));
}
.kcc-spotlight__body .kcc-actcall__head { gap: 8px; margin-bottom: 4px; }
.kcc-spotlight__body .kcc-actcall__symbol { font-size: 14px; }
.kcc-spotlight__body .kcc-actcall__prices { font-size: 12px; }
.kcc-spotlight__body .kcc-actcall__delta { font-size: 14px; }
.kcc-spotlight__more {
  display: block;
  margin-top: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.kcc-spotlight__src {
  font-family: 'Space Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.08em;
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 7px;
}
.kcc-spotlight__src--house {
  background: color-mix(in srgb, var(--brass, #d4a335) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 36%, transparent);
  color: var(--brass, #d4a335);
}
.kcc-spotlight__src--live {
  background: color-mix(in srgb, var(--text-muted) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--text-muted) 30%, transparent);
  color: var(--text-muted);
}
.kcc-spotlight__tab.is-empty { opacity: 0.4; }
.kcc-spotlight__tab.is-empty.is-active { opacity: 0.7; }
.kcc-spotlight__empty {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-muted);
  padding: 14px 4px;
  text-align: center;
}

/* ── Featured (spotlight) rich cards — challenge + bet ──────────
   The compact MY PINNED tiles looked empty stretched across the wide
   FEATURED strip; these fill it with a head row (status/venue + subject
   + side + countdown) and a data row (matchup / numbers + pot|delta),
   mirroring the Calls card rhythm. Self-contained so the sidebar tile
   stays untouched. */
.kcc-feat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  padding: 2px 0;
}
.kcc-feat__head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.kcc-feat__status,
.kcc-feat__venue {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  border-radius: 4px;
  padding: 2px 7px;
  border: 1px solid var(--border, rgba(212,163,53,0.2));
  color: var(--text-muted, #9a8f78);
  white-space: nowrap;
}
.kcc-feat__status--locked {
  color: #5fcf9c;
  background: rgba(95,207,156,0.12);
  border-color: rgba(95,207,156,0.35);
}
.kcc-feat__status--open {
  color: var(--brass, #d4a335);
  background: rgba(212,163,53,0.10);
  border-color: rgba(212,163,53,0.30);
}
.kcc-feat__venue {
  color: #c8b27a;
  background: rgba(212,163,53,0.10);
  border-color: rgba(212,163,53,0.30);
}
.kcc-feat__subj {
  font-size: 13px;
  color: var(--text, #e9e3d5);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kcc-feat__subj b { color: var(--text, #e9e3d5); font-weight: 700; }
.kcc-feat__side {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  border-radius: 4px;
  padding: 1px 6px;
  border: 1px solid;
  white-space: nowrap;
}
.kcc-feat__side--long, .kcc-feat__side--yes { color: #6dd99c; border-color: rgba(109,217,156,0.35); }
.kcc-feat__side--short, .kcc-feat__side--no { color: #e0a0a0; border-color: rgba(168,50,50,0.40); }
.kcc-feat__time {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: var(--text-faint, #8a8071);
  white-space: nowrap;
}
.kcc-feat__matchup {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  font-family: 'Space Mono', monospace;
  font-size: 11.5px;
  color: var(--text-dim, #c7bda8);
}
.kcc-feat__party { color: var(--text-dim, #c7bda8); }
.kcc-feat__party b { color: var(--text, #e9e3d5); font-weight: 700; }
.kcc-feat__party--empty { color: var(--text-faint, #8a8071); font-style: italic; }
.kcc-feat__lbl { text-transform: uppercase; letter-spacing: 0.03em; }
.kcc-feat__r { color: #6dd99c; }
.kcc-feat__r--pos { color: #6dd99c; }
.kcc-feat__r--neg { color: #e0a0a0; }
.kcc-feat__vs {
  color: var(--text-faint, #6b6555);
  letter-spacing: 0.1em;
  font-size: 10px;
}
.kcc-feat__nums { color: var(--text-dim, #c7bda8); }
.kcc-feat__win { color: #6dd99c; }
.kcc-feat__pot {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  color: #241a06;
  background: var(--brass, #d4a335);
  border-radius: 5px;
  padding: 3px 9px;
  white-space: nowrap;
}
.kcc-feat__pot-lbl {
  font-weight: 400;
  opacity: 0.8;
  text-transform: uppercase;
  font-size: 9px;
  letter-spacing: 0.06em;
}
.kcc-feat__delta {
  margin-left: auto;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  border-radius: 5px;
  padding: 2px 8px;
  white-space: nowrap;
}
.kcc-feat__delta--pos { color: #241a06; background: #6dd99c; }
.kcc-feat__delta--neg { color: #2a0d0d; background: #e0a0a0; }
.kcc-spotlight__min {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  padding: 3px;
  border-radius: 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  transition: color 0.12s ease, background 0.12s ease;
}
.kcc-spotlight__min:hover {
  color: var(--text-bright);
  background: color-mix(in srgb, var(--text-bright, #fff) 6%, transparent);
}
.kcc-spotlight__min svg { width: 12px; height: 12px; transition: transform 0.18s ease; }
/* Collapsed: hide tabs + body, flip the chevron, slim the bar. */
.kcc-spotlight[data-min="1"] .kcc-spotlight__tabs,
.kcc-spotlight[data-min="1"] .kcc-spotlight__body { display: none; }
.kcc-spotlight[data-min="1"] .kcc-spotlight__head { margin-bottom: 0; }
.kcc-spotlight[data-min="1"] .kcc-spotlight__min svg { transform: rotate(180deg); }

/* ── Sentiment gauge (SENTIMENT tab body) ───────────────────────── */
.kcc-sent__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 11px;
}
.kcc-sent__title {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--text-muted);
}
.kcc-sent__wins { display: inline-flex; gap: 4px; }
.kcc-sent__win {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  padding: 3px 9px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-muted);
  border: 1px solid var(--border);
  background: transparent;
  transition: color 0.12s ease, background 0.12s ease;
}
.kcc-sent__win:hover { color: var(--text-bright); }
.kcc-sent__win.is-active {
  color: var(--text-bright);
  background: var(--card2, #23211d);
  border-color: var(--border2, #3a352c);
}
.kcc-sent__net { margin-bottom: 9px; }
.kcc-sent__net-label { font-family: 'Space Mono', monospace; font-size: 9px; letter-spacing: 0.1em; }
.kcc-sent__net-row { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
.kcc-sent__net-pct { font-family: 'Space Mono', monospace; font-size: 28px; font-weight: 700; line-height: 1; }
.kcc-sent__net-sub { font-family: 'Space Mono', monospace; font-size: 10px; color: var(--text-muted); }
.kcc-sent__bar {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--card2, #23211d);
  margin-bottom: 8px;
}
.kcc-sent__bar-seg { transition: width 0.25s ease; }
.kcc-sent__bar-seg--bull { background: var(--up, #6dd99c); }
.kcc-sent__bar-seg--bear { background: var(--red, #a83232); }
.kcc-sent__counts {
  display: flex;
  justify-content: space-between;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
}
.kcc-sent__c--bull { color: var(--up, #6dd99c); }
.kcc-sent__c--bear { color: #e07a7a; }
.kcc-sent__empty {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-muted);
  padding: 14px 4px;
  text-align: center;
}

/* Staged-image strip — shown above the composer row when a file is
   picked but before send. Sits flush with the row above so it reads
   as part of the composer, not a floating chip. */
.kcc-composer__staged {
  margin-bottom: 8px;
}
.kcc-composer__staged[hidden] { display: none; }
.kcc-staged {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 6px 6px 8px;
  max-width: 100%;
}
.kcc-staged__thumb {
  width: 36px;
  height: 36px;
  border-radius: 4px;
  background-color: var(--card);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  flex-shrink: 0;
}
.kcc-staged__thumb--placeholder {
  /* Subtle striped texture while data URL is still being read. Read
     completes in ~50ms for 5MB so this is rarely seen. */
  background-image: linear-gradient(45deg,
    var(--border) 25%,
    transparent 25%,
    transparent 50%,
    var(--border) 50%,
    var(--border) 75%,
    transparent 75%);
  background-size: 8px 8px;
}
.kcc-staged__meta {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  padding-right: 4px;
}
.kcc-staged__name {
  font-size: 11px;
  color: var(--text-bright);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}
.kcc-staged__size {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.kcc-staged__remove {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 6px;
  font-size: 14px;
  line-height: 1;
  border-radius: 4px;
  transition: color .12s ease, background .12s ease;
}
.kcc-staged__remove:hover {
  color: var(--accent-danger, #ff7a7a);
  background: color-mix(in srgb, var(--accent-danger, #ff7a7a) 12%, transparent);
}

/* Message attachment — inline image thumbnail under the message body.
   Click → opens full image in a new tab. Cap dimensions to keep the
   stream compact; brass-tinted hover border matches the rest of the
   platform's interactive language. */
.kcc-msg__attach {
  display: inline-block;
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  text-decoration: none;
  line-height: 0;
  transition: border-color .12s ease;
  max-width: 320px;
  /* Reserve a sensible box for legacy attachments missing width/
     height in the payload (records sent before client-side decode
     was added). Without this, the wrapper has 0 height until the
     image bytes arrive, growing the row mid-load and shoving every
     message above it upward (visible drift on Safari, which doesn't
     compensate scrollTop via overflow-anchor).
     For messages WITH width/height, _renderAttachments emits an
     inline style on this element with the exact reserved dimensions
     — that wins over this fallback. */
  aspect-ratio: 4 / 3;
  width: 320px;
  height: auto;
}
/* When the wrapper has an explicit width+height inline style
   (emitted by _renderAttachments for messages with known dims),
   drop the fallback aspect-ratio so the explicit box wins cleanly. */
.kcc-msg__attach[style*="width"] {
  aspect-ratio: auto;
  width: auto;
}
.kcc-msg__attach:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
}
.kcc-msg__attach-img {
  display: block;
  width: 100%;
  height: 100%;
  /* contain — portrait images letterbox inside the reserved box
     rather than getting cropped. Visually nicer than cover for chat
     attachments where the full image matters. */
  object-fit: contain;
  background: var(--bg2);
}

/* Pending dim treatment for attachment thumbnails matches the body. */
.kcc-msg--pending .kcc-msg__attach {
  opacity: 0.65;
}

/* ─── Chat — admin moderation (delete) ───────────────────────────
   Trash button rendered only when KC.isAdmin() is true on this
   browser. Sits in the top-right of each message, hidden until the
   row is hovered. On touch devices (hover: none) the affordance is
   always visible at half opacity since hover isn't a thing there.
   Worker re-checks admin status server-side — the UI flag here just
   controls whether the affordance shows.
*/
.kcc-msg__delete {
  position: absolute;
  top: 6px;
  right: 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, color .12s ease, border-color .12s ease, background .12s ease;
  flex-shrink: 0;
}
.kcc-msg:hover .kcc-msg__delete,
.kcc-msg__delete:focus-visible {
  opacity: 1;
}
.kcc-msg__delete:hover {
  color: var(--oxblood-text, #d4787a);
  border-color: color-mix(in srgb, var(--oxblood, #a83232) 40%, var(--border));
  background: color-mix(in srgb, var(--oxblood, #a83232) 10%, var(--bg2));
}
.kcc-msg__delete:focus-visible {
  outline: none;
  border-color: var(--oxblood, #a83232);
}
.kcc-msg__delete.is-busy,
.kcc-msg__delete:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* On touch (no hover), reveal the trash at half opacity so admins
   on mobile can still moderate. */
@media (hover: none) {
  .kcc-msg__delete { opacity: 0.5; }
}

/* ─── Chat — poll card (/poll Question | A | B [| C [| D]]) ──────
   When /poll is used in the composer, the resulting message carries
   payload.poll = { question, options[], expires_at } and renders as
   a tappable poll card instead of a plain-text body. Votes piggyback
   on chat_message_reactions using POLL_VOTE_EMOJIS (1️⃣..4️⃣) — each
   option row carries [data-kc-react-toggle] so the standard
   reaction-toggle click handler picks them up.

   Single-choice + expiry are enforced server-side in handleChatReact
   (with client mirror for snappy UX). When expires_at passes, the
   card flips to .is-closed: rows lose tap targets, a CLOSED pill
   appears in the head, hint copy changes.

   Visual lineage: same shell idiom as .kcc-msg__signal (brass left-
   stripe, asymmetric radius) so all "actionable inline cards" feel
   like family.
*/
.kcc-poll {
  display: block;
  margin-top: 8px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 3%, var(--card, var(--surface)));
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent, var(--brass, #d4a335));
  border-radius: 0 6px 6px 0;
  max-width: 460px;
}
.kcc-poll.is-closed {
  /* Dim the closed card slightly so the room can scan past it. */
  border-left-color: var(--muted);
  background: var(--card, var(--surface));
}

.kcc-poll__head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
}
.kcc-poll__head-ic {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: var(--accent, var(--brass, #d4a335));
}
.kcc-poll.is-closed .kcc-poll__head-ic {
  color: var(--muted);
}
.kcc-poll__head-lbl {
  font-weight: 500;
}
.kcc-poll__closed-pill {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  padding: 1px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 22%, transparent);
  color: var(--text-mid, var(--text));
  margin-left: auto;
  text-transform: uppercase;
  font-weight: 500;
}

.kcc-poll__q {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-bright, var(--text));
  margin-bottom: 10px;
  line-height: 1.35;
}

.kcc-poll__opts {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.kcc-poll__opt {
  position: relative;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 120ms ease, background 120ms ease;
  user-select: none;
}
.kcc-poll__opt:hover {
  border-color: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 40%, var(--border));
}
.kcc-poll__opt:focus-visible {
  outline: 2px solid var(--accent, var(--brass, #d4a335));
  outline-offset: 1px;
}
.kcc-poll__opt[aria-disabled="true"],
.kcc-poll__opt.is-closed {
  cursor: default;
  pointer-events: none;
}
.kcc-poll__opt.is-closed:hover,
.kcc-poll__opt[aria-disabled="true"]:hover {
  border-color: var(--border);
}
.kcc-poll__opt.is-closed {
  opacity: 0.85;
}

.kcc-poll__opt.is-mine {
  border-color: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 55%, var(--border));
  background: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 6%, var(--surface));
}
/* Closed + mine — keep "this is what I voted" legible but desaturated. */
.kcc-poll.is-closed .kcc-poll__opt.is-mine {
  border-color: color-mix(in srgb, var(--muted) 50%, var(--border));
  background: color-mix(in srgb, var(--muted) 8%, var(--surface));
}

.kcc-poll__opt.is-winning .kcc-poll__opt-meta {
  color: var(--text-bright, var(--text));
  font-weight: 500;
}

.kcc-poll__opt-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 12%, transparent);
  transition: width 240ms ease;
  pointer-events: none;
}
.kcc-poll__opt.is-mine .kcc-poll__opt-fill {
  background: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 20%, transparent);
}
.kcc-poll.is-closed .kcc-poll__opt-fill {
  /* Neutral fill on closed cards — the brass tint feels too "live". */
  background: color-mix(in srgb, var(--muted) 14%, transparent);
}
.kcc-poll.is-closed .kcc-poll__opt.is-mine .kcc-poll__opt-fill {
  background: color-mix(in srgb, var(--muted) 24%, transparent);
}

.kcc-poll__opt-body {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text);
  z-index: 1;
}

.kcc-poll__opt-num {
  font-size: 13px;
  flex-shrink: 0;
  width: 18px;
  text-align: center;
  line-height: 1;
}

.kcc-poll__opt-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kcc-poll__opt.is-mine .kcc-poll__opt-label {
  font-weight: 500;
  color: var(--text-bright, var(--text));
}

.kcc-poll__opt-mine {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  padding: 1px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent, var(--brass, #d4a335)) 18%, transparent);
  color: var(--accent, var(--brass, #d4a335));
  flex-shrink: 0;
  text-transform: uppercase;
}
.kcc-poll.is-closed .kcc-poll__opt-mine {
  background: color-mix(in srgb, var(--muted) 20%, transparent);
  color: var(--text-mid, var(--text));
}

.kcc-poll__opt-meta {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.kcc-poll__hint {
  margin-top: 8px;
  font-size: 10px;
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.02em;
}

.kcc-msg--pending .kcc-poll {
  opacity: 0.7;
}
.kcc-msg--pending .kcc-poll__opt {
  pointer-events: none;
}

/* ─── Chat — signal card (Share to The Floor) ────────────────────
   When a scanner setup is shared via the chart toolbar SHARE pill →
   "Send to chat", the resulting message gets a card block attached
   under the body text.
   Card mirrors the scanner-card aesthetic — brass left-stripe,
   scanner pill + symbol header, prices row, R/R + click-through
   footer — so the visual lineage between the source row and the
   shared chip is obvious.

   The whole card is one big <a>; the click-through opens
   scanners.html with the symbol pre-filtered. Hover lifts the
   border and tints the bg slightly, matching the link-preview
   behavior so all "actionable inline cards" feel related.
*/
.kcc-msg__signal {
  display: block;
  margin-top: 8px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 3%, var(--bg2));
  border: 1px solid var(--border);
  border-left: 2px solid var(--kcc-self, var(--brass, #d4a335));
  /* Single-sided accent border — corners on that side should NOT round,
     otherwise the stripe ends inside a curve and looks broken. */
  border-radius: 0 6px 6px 0;
  text-decoration: none;
  color: inherit;
  max-width: 360px;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-msg__signal:hover {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 50%, var(--border));
  border-left-color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 6%, var(--bg2));
}

/* Head row: scanner pill · $TICKER · LONG/SHORT · TF · pattern. */
.kcc-msg__sig-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
  flex-wrap: wrap;
}
.kcc-msg__sig-scanner {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  color: var(--brass, #d4a335);
  font-weight: 500;
  flex-shrink: 0;
}
.kcc-msg__sig-symbol {
  font-weight: 600;
  color: var(--text-bright);
  font-size: 13px;
}
.kcc-msg__sig-side {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.kcc-msg__sig-side--long  { color: var(--kcc-long-fg, var(--up, #1d9e75)); }
.kcc-msg__sig-side--short { color: var(--kcc-short-fg, var(--red, #d05a4a)); }
/* Waiting-for-entry pill on the in-stream signal card. Pewter, matching
   the Active Calls rail card and the platform's locked/waiting colour. */
.kcc-msg__sig-wait {
  display: inline-flex;
  align-items: center;
  gap: 0;
  line-height: 1;
  padding: 3px;
  border-radius: 5px;
  color: var(--blue, #8a96a3);
  border: 1px solid color-mix(in srgb, var(--blue, #8a96a3) 45%, transparent);
  background: color-mix(in srgb, var(--blue, #8a96a3) 14%, transparent);
}
.kcc-msg__sig-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-left: auto;
  text-align: right;
}

/* Prices row: entry · stop · T1/T2. Labels muted, values bright. */
.kcc-msg__sig-prices {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.55;
  margin-bottom: 8px;
}
.kcc-msg__sig-px {
  color: var(--text-bright);
  font-family: 'Space Mono', monospace;
}

/* TP ladder line — "TP <t1> → <t2> → <t3>" sitting just under the
   entry/stop prices row. Label is a muted mono tag; arrows take the
   brass accent so the sequence reads as a progression. */
.kcc-msg__sig-tps {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.55;
  margin-top: -4px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
}
.kcc-msg__sig-tps-lbl {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text3, #6c665d);
}
.kcc-msg__sig-tps-arrow { color: var(--brass, #d4a335); }

/* Chart snapshot thumbnail on the unlocked card — admin-attached image.
   Sits between the head row and the prices. Clicking the card (the
   parent link) opens the full chart, so this is a teaser, not its own
   control. Cap the height so a tall screenshot doesn't blow out the
   card; cover-crop keeps the aspect tidy. */
.kcc-msg__sig-chart {
  position: relative;
  margin-bottom: 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg, #0f0e0c);
  line-height: 0;
  cursor: zoom-in;
  transition: border-color 120ms ease;
  /* Reserve the full box BEFORE the lazy image loads. Without this the
     container is 0px tall and jumps ~150px on load — with object-fit:
     cover the loaded image always fills exactly 150px anyway, so a
     fixed height is layout-identical post-load but shift-free pre-load.
     (This was the biggest contributor to the "stream drifts while
     scrolling up through history the first time" bug.) */
  height: 150px;
}
.kcc-msg__sig-chart:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 55%, var(--border));
}
.kcc-msg__sig-chart:focus-visible {
  outline: 2px solid var(--brass, #d4a335);
  outline-offset: 1px;
}
.kcc-msg__sig-chart:hover .kcc-msg__sig-chart-exp {
  background: color-mix(in srgb, var(--bg, #0f0e0c) 55%, transparent);
  color: var(--brass, #d4a335);
}
.kcc-msg__sig-chart img {
  display: block;
  width: 100%;
  height: 150px;
  object-fit: cover;
}
.kcc-msg__sig-chart-exp {
  position: absolute;
  bottom: 4px;
  right: 6px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 8.5px;
  letter-spacing: 0.06em;
  color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--bg, #0f0e0c) 72%, transparent);
  padding: 1px 5px;
  border-radius: 3px;
  line-height: 1.4;
  pointer-events: none;
}

/* LEGACY — .kcc-msg__sig-now and .kcc-msg__sig-now-lbl are no longer
   emitted by _renderSignalCard. The "now + delta" pair now renders
   inline inside .kcc-msg__sig-foot-now (see signal-foot rules below).
   Kept here for any cached HTML in the stream. .kcc-msg__sig-delta
   is still used — it's the delta-% span and now rides in the foot. */
.kcc-msg__sig-now {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  margin-bottom: 4px;
}
.kcc-msg__sig-now-lbl {
  color: var(--text-muted);
}
.kcc-msg__sig-delta {
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
/* Sits after the settled delta. Deliberately quiet — it is context for the
   number beside it, not a competing headline. It exists because the card's %
   is measured from the signal's entry while the caller's R is graded from the
   price at share time, and a call posted after its own entry makes those two
   read like a contradiction unless something says how late it was. */
.kcc-msg__sig-late {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: var(--text3, #5a5550);
  margin-left: 8px;
  white-space: nowrap;
}
/* Legacy alignment — inside the dropped .kcc-msg__sig-now row, delta
   pushed to the right via auto-margin. The new foot puts delta
   inline next to the price with a normal gap, so we only restore
   that auto-margin inside the legacy parent. */
.kcc-msg__sig-now .kcc-msg__sig-delta {
  margin-left: auto;
}
.kcc-msg__sig-delta--pos {
  color: var(--kcc-long, var(--up, #1d9e75));
}
.kcc-msg__sig-delta--neg {
  color: var(--kcc-short, var(--down, #d05a4a));
}
.kcc-msg__sig-delta--wait {
  color: var(--blue, #8a96a3);
}

/* Sparkline strip — full-width below the prices/now row. Tiny
   "N candles · TF" caption sits flush right below the SVG. */
.kcc-msg__sig-spark {
  margin: 4px 0 8px;
}
.kcc-msg__sig-spark svg {
  display: block;
  width: 100%;
  height: 28px;
}
.kcc-msg__sig-spark-caption {
  font-family: 'Space Mono', monospace;
  font-size: 8.5px;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-top: 2px;
  text-align: right;
}

/* Footer row: R/R left, click-through right, with a thin divider. */
.kcc-msg__sig-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  gap: 8px;
}
/* Foot-left wrapper groups the now+delta and R/R into one inline
   block (left-justified) so the CTA can stay anchored on the right.
   Each child stays inline; flex on the wrapper just lets gap handle
   the spacing without breaking line height. */
.kcc-msg__sig-foot-left {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
  font-family: 'Space Mono', monospace;
  color: var(--text-muted);
}
.kcc-msg__sig-foot-now {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.kcc-msg__sig-foot-sep {
  color: var(--text-muted);
  opacity: 0.6;
}
.kcc-msg__sig-rr {
  color: var(--brass, #d4a335);
  font-weight: 600;
  font-family: 'Space Mono', monospace;
}
.kcc-msg__sig-rr--empty {
  /* Keeps the foot height stable when R/R is missing. */
  visibility: hidden;
}
.kcc-msg__sig-cta {
  color: var(--text-muted);
  font-size: 11px;
  transition: color 120ms ease;
}
.kcc-msg__signal:hover .kcc-msg__sig-cta {
  color: var(--brass, #d4a335);
}

/* Pending messages dim the signal card the same way they dim the
   body, so the optimistic send reads as "in flight" consistently. */
.kcc-msg--pending .kcc-msg__signal {
  opacity: 0.65;
}

/* ─── Locked signal card (paywall) ──────────────────────────────────
   Non-payers see this shell in place of the full signal card. It's
   rendered inside the same .kcc-msg__signal slot, so most of the
   parent card's layout/margin still applies — these rules override
   the visual style (replace the brass left-stripe with a hazard-stripe
   top accent and a darker sealed-dossier background) and add the
   internal locked elements (blurred chart, redacted stat cells,
   full-width unlock button).

   Color tokens used:
     --brass (#d4a335) — primary CTA + accent
     --bg2             — dossier inner bg
     --border          — outer ring
     --text2 / --text3 — muted labels
*/
.kcc-msg__signal--locked {
  /* Reset the base card's accented border + width — locked card is
     a "sealed envelope" with stripes, not a left-stripe pill. */
  display: block;
  margin-top: 8px;
  padding: 0;
  max-width: 360px;
  background: var(--bg, #0f0e0c);
  border: 1px solid var(--border, #2a2722);
  border-left: 1px solid var(--border, #2a2722);
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  cursor: default;            /* not a link; only the button reacts */
  text-decoration: none;
  color: inherit;
  transition: border-color 120ms ease;
}
.kcc-msg__signal--locked:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border));
  background: var(--bg, #0f0e0c);  /* no hover-tint — too busy with stripes */
}

/* Solid brass top accent — 3px brass band along the top edge of
   the locked card. Reads as a "sealed" banner without the busy
   hazard-stripe pattern. */
.kcc-locked-stripes {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--brass, #d4a335);
  pointer-events: none;
}

.kcc-locked-inner {
  padding: 14px 12px 10px;   /* extra top to clear the 3px stripe */
}

/* ── Official (House) call — Option D: double brass frame + header bar.
   Inset ring guarantees the inner frame line even though the locked card
   clips overflow; the outer ring + glow add depth when not clipped. */
.kcc-msg__signal.is-official,
.kcc-msg__signal--locked.is-official {
  border-color: var(--brass, #d4a335);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--brass, #d4a335) 30%, transparent),
    0 0 0 2px color-mix(in srgb, var(--brass, #d4a335) 16%, transparent),
    0 4px 18px color-mix(in srgb, var(--brass, #d4a335) 12%, transparent);
}
.kcc-official-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  /* Wrap instead of squeezing: on a card-width bar the label + handle +
     5-dot meter + "VERY HIGH" didn't fit and the handle collapsed to
     "b…". Now the meter drops to a second line when it must. */
  flex-wrap: wrap; row-gap: 4px;
  margin-bottom: 9px; padding: 5px 9px; border-radius: 7px;
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 30%, transparent);
}
.kcc-official-bar__l {
  font-family: 'Space Mono', monospace; font-size: 9.5px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--brass, #d4a335);
  white-space: nowrap;
}
.kcc-official-bar__by { font-size: 10px; color: var(--text-mid, #9a948a); white-space: nowrap; }
/* Left cluster holds the label + handle; the conviction meter takes
   the right edge via the bar's space-between. min-width:0 lets a long
   handle truncate rather than shove the meter off the card. */
.kcc-official-bar__lwrap {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex-shrink: 0;   /* keep "by @handle" whole; the meter wraps instead */
  max-width: 100%;  /* a very long handle still truncates (ellipsis below) */
}
.kcc-official-bar__lwrap .kcc-official-bar__by {
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Conviction meter — 5 dots (filled ≤ level) + word label, brass to
   read as the House's confidence statement. Shows on locked + unlocked
   official cards (on the locked card it doubles as an unlock hook). */
.kcc-official-bar__conv {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.kcc-conv-meter { display: flex; gap: 3px; }
.kcc-conv-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  box-sizing: border-box;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 40%, transparent);
}
.kcc-conv-dot--on {
  background: var(--brass, #d4a335);
  border-color: var(--brass, #d4a335);
}
.kcc-conv-lbl {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brass, #d4a335);
  white-space: nowrap;
}
/* On the unlocked card (an <a>), keep the bar non-interactive-looking. */
.kcc-msg__signal.is-official .kcc-official-bar { text-decoration: none; }

/* Head row mirrors the unlocked card's structure but never wraps —
   ticker + direction + scanner tag must stay one line for visual
   parity with the unlocked card. */
.kcc-locked-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 12px;
}
.kcc-locked-scanner {
  margin-left: auto;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--text3, #9a948c);
  text-transform: uppercase;
}

/* Unlock-count chip on the locked card — sits in the header row
   between the side pill and the scanner tag. Brass tint signals it
   belongs to the paywall layer (vs the muted gray scanner tag).
   margin-left:auto pushes it (and the scanner tag that trails it)
   to the right edge of the header row. */
.kcc-locked-unlocks {
  margin-left: auto;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--brass, #d4a335);
  white-space: nowrap;
}
/* When the unlocks chip IS present, the scanner tag no longer needs
   its own margin-left:auto — the chip already pushed everything
   right, scanner just sits to the chip's right with a small gap. */
.kcc-locked-head .kcc-locked-unlocks + .kcc-locked-scanner {
  margin-left: 6px;
}

/* Unlock-count chip on the UNLOCKED card — sits inline in the head
   row, occupying the slot the OPINION tier tag would otherwise hold.
   The JS renders one OR the other: when there are real unlocks,
   social proof wins over sentiment label. Brass-tinted to match the
   locked-card variant so the counter reads as the same "thing" in
   both card states. */
.kcc-sig-unlocks {
  margin-left: auto;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--brass, #d4a335);
  white-space: nowrap;
}

/* Blurred placeholder chart — sits behind the redaction overlay.
   The chart SVG uses currentColor; we set it to brass on this
   wrapper so all locked cards share one accent regardless of the
   palette context. */
.kcc-locked-chart {
  position: relative;
  height: 70px;
  margin: 0 -2px 10px;
  background: color-mix(in srgb, var(--bg, #0a0a0a) 80%, var(--brass, #d4a335) 4%);
  border-radius: 3px;
  overflow: hidden;
  color: var(--brass, #d4a335);
}
.kcc-locked-chart-blur {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: blur(8px);
  opacity: 0.55;
  pointer-events: none;
}
.kcc-locked-chart-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  z-index: 1;
}
.kcc-locked-chart-text {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: var(--text3, #9a948c);
  text-transform: uppercase;
}
.kcc-locked-lock-svg {
  color: var(--brass, #d4a335);
  flex-shrink: 0;
}

/* 4 redacted stat cells — Entry · Stop · T1 · R:R */
.kcc-locked-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.kcc-locked-stat {
  background: color-mix(in srgb, var(--bg2, #1a1816) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--border, #2a2722) 70%, transparent);
  padding: 5px 6px;
  border-radius: 3px;
  text-align: center;
}
.kcc-locked-stat-label {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 8px;
  letter-spacing: 0.12em;
  color: var(--text3, #5a5550);
  text-transform: uppercase;
}
.kcc-locked-stat-val {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--text3, #5a5550) 60%, var(--border, #2a2722));
  margin-top: 2px;
}

/* Outline brass unlock button — sits quietly inside the locked card
   as a brass-outline ghost. On hover it fills with brass (existing
   filled state) so the affordance is unmistakable, but the resting
   state doesn't dominate the chat scroll. Split into label/cost
   halves separated by a thin brass divider that mirrors the outer
   border. */
.kcc-locked-unlock-btn {
  display: flex;
  align-items: stretch;
  width: 100%;
  background: transparent;
  border: 1px solid var(--brass, #d4a335);
  border-radius: 3px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: background 120ms ease, color 120ms ease, opacity 120ms ease;
  font-family: 'Space Mono', ui-monospace, monospace;
  color: var(--brass, #d4a335);
}
.kcc-locked-unlock-btn:hover:not([disabled]) {
  background: var(--brass, #d4a335);
  color: #0a0a0a;
}
.kcc-locked-unlock-btn:active:not([disabled]) {
  background: color-mix(in srgb, var(--brass, #d4a335) 88%, #0a0a0a);
  color: #0a0a0a;
}
.kcc-locked-unlock-btn[disabled] {
  cursor: progress;
  opacity: 0.6;
}
/* Free House call — recolor the whole affordance to the up/green
   accent so "open free" reads distinctly from the paid brass state. */
.kcc-locked-unlock-btn--free {
  border-color: var(--up, #6fcf8e);
  color: var(--up, #6fcf8e);
}
.kcc-locked-unlock-btn--free:hover:not([disabled]) {
  background: var(--up, #6fcf8e);
  color: #0a0a0a;
}
.kcc-locked-unlock-btn--free:active:not([disabled]) {
  background: color-mix(in srgb, var(--up, #6fcf8e) 88%, #0a0a0a);
  color: #0a0a0a;
}
.kcc-locked-unlock-btn--free .kcc-locked-unlock-right {
  border-left-color: color-mix(in srgb, var(--up, #6fcf8e) 40%, transparent);
}
.kcc-locked-unlock-left {
  flex: 1;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-align: left;
  color: inherit;            /* follow button state (brass → black on hover) */
}
.kcc-locked-unlock-left .kcc-locked-lock-svg {
  color: inherit;
}
.kcc-locked-unlock-right {
  padding: 8px 12px;
  border-left: 1px solid color-mix(in srgb, var(--brass, #d4a335) 40%, transparent);
  background: transparent;
  font-size: 10px;
  font-weight: 700;
  color: inherit;
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-locked-unlock-btn:hover:not([disabled]) .kcc-locked-unlock-right {
  /* On hover the whole button fills brass; the divider needs to
     stay legible against the new bg — bump to near-black + give it
     a subtle inset tint so the price feels like a sub-pill. */
  border-left-color: rgba(0, 0, 0, 0.25);
  background: rgba(0, 0, 0, 0.12);
}

/* ─── Resolved-state Option A: faded body + corner stamp ───────────
   Applied to bet, signal, and challenge cards once they hit a terminal
   state (won / lost / void / cancelled / expired / refunded / settled).
   The card stays readable so users can review what happened, but loses
   the visual weight of a live actionable card — and any inline action
   buttons (Tail, Challenge, Take, Cancel) are gated off in the JS so
   they don't render at all. */

/* Anchor so the corner stamp can position itself. The base cards
   already have padding; we keep their original layout intact. */
.kcc-msg__bet,
.kcc-msg__signal,
.kcc-msg__chal {
  position: relative;
}

.kcc-msg__bet.is-settled,
.kcc-msg__signal.is-settled,
.kcc-msg__chal.is-settled {
  opacity: 0.55;
}
.kcc-msg__bet.is-settled:hover,
.kcc-msg__signal.is-settled:hover,
.kcc-msg__chal.is-settled:hover {
  opacity: 0.7;
}

/* Corner stamp — top-right, monospace, colored by outcome.
   The parent card has opacity:0.55 when settled, so the stamp must
   use color-mix-with-bg fills strong enough to remain legible at
   ~55% effective opacity. We can't escape the parent's opacity from
   inside the DOM, so we just lean on stronger color values and a
   tinted background. */
.kcc-card-stamp {
  position: absolute;
  top: 8px;
  right: 8px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 2px;
  z-index: 2;
  pointer-events: none;
  line-height: 1;
}
/* Official House cards carry the brass bar at the same height as the
   stamp — reserve the stamp's corner so it no longer covers the
   conviction meter ("▲ HIT T2" sat on top of "MEDIUM"). */
.kcc-msg__signal.is-official:has(.kcc-card-stamp) .kcc-official-bar {
  margin-right: 88px;
}
.kcc-card-stamp--won {
  background: color-mix(in srgb, var(--up, #4dd99a) 22%, var(--bg, #0e0d0b));
  color: var(--up, #4dd99a);
  border: 1px solid color-mix(in srgb, var(--up, #4dd99a) 50%, transparent);
}
.kcc-card-stamp--lost {
  background: color-mix(in srgb, var(--red, #d05a4a) 22%, var(--bg, #0e0d0b));
  color: var(--red, #d05a4a);
  border: 1px solid color-mix(in srgb, var(--red, #d05a4a) 50%, transparent);
}
.kcc-card-stamp--void {
  background: color-mix(in srgb, var(--text-muted, #828a96) 25%, var(--bg, #0e0d0b));
  color: var(--text, #e8e6df);
  border: 1px solid color-mix(in srgb, var(--text-muted, #828a96) 50%, transparent);
}

/* Safety net: hide any stray inline action buttons inside a settled
   card. JS already gates render of Tail/Challenge/Take/Cancel for
   terminal states, but a stale row that slipped through (e.g. from
   a backwards-compat path) would still be visually neutralised. */
.kcc-msg__bet.is-settled .kcc-msg__bet-actions,
.kcc-msg__chal.is-settled .kcc-msg__chal-actions,
.kcc-msg__chal.is-settled .kcc-msg__chal-take,
.kcc-msg__chal.is-settled .kcc-msg__chal-cancel {
  display: none !important;
}

/* ══════════════════════════════════════════════════════════════════
   RAZOR ASK CARDS — paid Q&A
   Source: handoff_razor_request_feature.md + Round 1 spec.

   Layout (style B — brass rail + amount medallion):
     · 3px brass left border (matches signal/bet rail convention)
     · Head row: asker meta + target on left, amount medallion right
     · Body: question text
     · Foot: stats + action buttons (REPLY / CANCEL)

   State variants:
     · default            — brass rail, open + actionable
     · --accepted         — sage rail, payout stamp
     · --expired          — gray rail, 55% dim (same as is-settled)
     · --cancelled        — gray rail, 55% dim
     · --loading          — minimal stub while sidecar hydrates

   The reply-chip is the small banner above the body text of any
   message replying to an ask. Brass-tinted, two-line format with
   the ACCEPT action when the viewer is the asker.
   ══════════════════════════════════════════════════════════════════ */

.kcc-msg__ask {
  position: relative;
  background: var(--bg-elev, #15151a);
  border: 1px solid var(--border, #2a2924);
  border-left: 3px solid var(--brass, #d4a335);
  border-radius: 4px;
  padding: 10px 12px;
  margin-top: 8px;
  max-width: 520px;
}
.kcc-msg__ask--loading {
  padding: 10px 14px;
  color: var(--muted, #8a8678);
}
.kcc-msg__ask--accepted {
  border-left-color: var(--ok, #2d6a4f);
}
.kcc-msg__ask--expired,
.kcc-msg__ask--cancelled {
  border-left-color: var(--muted, #8a8678);
}
.kcc-msg__ask--dim {
  opacity: 0.55;
}
.kcc-msg__ask--dim:hover {
  opacity: 0.7;
}

/* Top row: asker meta on left, stamp + amount on right */
.kcc-msg__ask-row1 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}
.kcc-msg__ask-eyebrow {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted, #6b6a62);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  min-width: 0;
}
.kcc-msg__ask-eyebrow strong {
  color: var(--ink, #c9c4b5);
  font-weight: 400;
}
.kcc-msg__ask-tag {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  color: var(--brass, #d4a335);
  padding: 2px 7px;
  border-radius: 2px;
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: 10px;
}
.kcc-msg__ask-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.kcc-msg__ask-amt-inline {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 14px;
  font-weight: 700;
  color: var(--brass, #d4a335);
  letter-spacing: 0.02em;
}
.kcc-msg__ask--accepted .kcc-msg__ask-amt-inline {
  color: var(--ok, #2d6a4f);
}
.kcc-msg__ask-amt-inline-lbl {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  color: var(--muted, #6b6a62);
  letter-spacing: 0.1em;
  margin-left: 1px;
  font-weight: 700;
}

/* Inline state chips that live in the eyebrow row.
   Replaces the old block-level kcc-msg__ask-target that took a
   dedicated row — the balanced layout puts target + time-left
   inline alongside @asker so the question doesn't have a dead-zone
   below it when the body is short. */
.kcc-msg__ask-sep {
  color: var(--muted, #3a3631);
  margin: 0 -2px;
}
.kcc-msg__ask-when {
  color: var(--muted, #8a8678);
}
.kcc-msg__ask-target-inline {
  color: var(--brass, #d4a335);
  font-weight: 700;
}
.kcc-msg__ask-target-inline--ok {
  color: var(--ok, #2d6a4f);
}
.kcc-msg__ask-target-inline--mute {
  color: var(--muted, #8a8678);
  font-weight: 400;
}
.kcc-msg__ask-time-inline {
  color: var(--muted, #8a8678);
}

.kcc-msg__ask-q {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text, #e8e3d4);
  margin: 6px 0 0;
  word-break: break-word;
}

.kcc-msg__ask-stamp {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.2em;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 2px;
  text-transform: uppercase;
}
.kcc-msg__ask-stamp--paid {
  color: var(--ok, #2d6a4f);
  border: 1px solid var(--ok, #2d6a4f);
}
.kcc-msg__ask-stamp--expired,
.kcc-msg__ask-stamp--cancelled {
  color: var(--muted, #8a8678);
  border: 1px solid var(--muted, #8a8678);
}

.kcc-msg__ask-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px solid var(--border, #232220);
  gap: 12px;
}
.kcc-msg__ask-stats {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  color: var(--muted, #6b6a62);
}
.kcc-msg__ask-actions {
  display: flex;
  gap: 8px;
}
.kcc-msg__ask-btn {
  background: transparent;
  border: 1px solid var(--brass, #d4a335);
  color: var(--brass, #d4a335);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  padding: 7px 14px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 700;
  transition: background-color 0.12s, color 0.12s;
}
.kcc-msg__ask-btn:hover {
  background: var(--brass, #d4a335);
  color: var(--ink-on-brass, #1a1610);
}
.kcc-msg__ask-btn--cancel {
  border-color: var(--muted, #3a3631);
  color: var(--muted, #8a8678);
}
.kcc-msg__ask-btn--cancel:hover {
  background: var(--red, #a83232);
  border-color: var(--red, #a83232);
  color: var(--ink-on-red, #f5d4d4);
}
.kcc-msg__ask-btn--decline {
  border-color: var(--muted, #3a3631);
  color: var(--muted, #8a8678);
}
.kcc-msg__ask-btn--decline:hover {
  background: var(--red, #a83232);
  border-color: var(--red, #a83232);
  color: var(--ink-on-red, #f5d4d4);
}

/* ── Reply-to-ask chip (sits above the body of a reply message) ── */
.kcc-msg__ask-reply-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 30%, transparent);
  border-radius: 4px;
  padding: 8px 12px;
  margin-bottom: 6px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  /* Share the same width cap as .kcc-msg__ask so the right edges of
     the ask card and its replies align visually in the stream. */
  max-width: 520px;
}
.kcc-msg__ask-reply-chip--loading {
  color: var(--muted, #8a8678);
  justify-content: flex-start;
}
.kcc-msg__ask-reply-chip--accepted {
  background: color-mix(in srgb, var(--ok, #2d6a4f) 10%, transparent);
  border-color: color-mix(in srgb, var(--ok, #2d6a4f) 35%, transparent);
}
.kcc-msg__ask-reply-chip-head {
  color: var(--brass, #d4a335);
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.kcc-msg__ask-reply-chip--accepted .kcc-msg__ask-reply-chip-head {
  color: var(--ok, #2d6a4f);
}
.kcc-msg__ask-reply-chip-amt {
  font-weight: 700;
}
.kcc-msg__ask-reply-chip-preview {
  color: var(--muted, #8a8678);
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 240px;
}
.kcc-msg__ask-reply-chip-btn {
  background: var(--brass, #d4a335);
  color: var(--ink-on-brass, #1a1610);
  border: none;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  padding: 6px 12px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 700;
  flex-shrink: 0;
}
.kcc-msg__ask-reply-chip-btn:hover {
  filter: brightness(1.1);
}
.kcc-msg__ask-reply-chip-stamp {
  color: var(--ok, #2d6a4f);
  letter-spacing: 0.2em;
  font-weight: 700;
  font-size: 10px;
  flex-shrink: 0;
}

/* Right-cluster wrapper inside the chip — holds rating UI + accept
   button or PAID stamp side-by-side. Lets the cluster wrap if the
   chip gets narrow (rare; chip max-width caps this). */
.kcc-msg__ask-reply-chip-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

/* LIKE / DISLIKE buttons — asker only, pre-rating. Neutral border
   at rest, brass on like-hover, oxblood on dislike-hover. */
.kcc-msg__ask-rate-btn {
  background: transparent;
  border: 1px solid var(--border, #3a3631);
  color: var(--muted, #6b6a62);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 2px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: color 100ms ease, border-color 100ms ease, background 100ms ease;
}
.kcc-msg__ask-rate-btn svg {
  width: 10px;
  height: 10px;
}
.kcc-msg__ask-rate-btn--like:hover {
  color: var(--brass, #d4a335);
  border-color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
}
.kcc-msg__ask-rate-btn--dislike:hover {
  color: var(--oxblood-text, #c47373);
  border-color: var(--oxblood-text, #c47373);
  background: color-mix(in srgb, var(--oxblood, #a83232) 10%, transparent);
}

/* Permanent rating badges — shown post-stamp, no buttons after. */
.kcc-msg__ask-rating {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 2px;
}
.kcc-msg__ask-rating svg {
  width: 10px;
  height: 10px;
}
.kcc-msg__ask-rating--liked {
  color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
}
.kcc-msg__ask-rating--disliked {
  color: var(--oxblood-text, #c47373);
  background: color-mix(in srgb, var(--oxblood, #a83232) 16%, transparent);
}

/* Disliked message body — dimmed to ~65% so the room can scan past
   without losing the content entirely. Applied via class on the
   text bubble in _renderMessageRow when payload.ask_rating === 'disliked'. */
.kcc-msg__text--ask-disliked {
  opacity: 0.65;
}

/* ══════════════════════════════════════════════════════════════════
   ASK POPOVER — creation UI (composer toolbar + profile modal)
   Floats above the composer (or profile modal). Brass border to
   signal a money action, mirroring the tip popover convention.
   ══════════════════════════════════════════════════════════════════ */

.kcc-askpop {
  position: absolute;
  z-index: 9500;            /* above .kc-dlg-overlay (9400) — JS sets this inline too; keep in sync */
  width: 380px;
  max-width: calc(100vw - 16px);
  background: var(--bg-elev, #15151a);
  border: 1px solid var(--brass, #d4a335);
  border-radius: 6px;
  padding: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  font-family: var(--kc-font-ui, 'Space Grotesk'), -apple-system, sans-serif;
  color: var(--text, #d8d4c8);
}

.kcc-askpop__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border, #2a2924);
}
.kcc-askpop__head-title {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--brass, #d4a335);
  font-weight: 700;
}
.kcc-askpop__close {
  background: transparent;
  border: none;
  color: var(--muted, #6b6a62);
  cursor: pointer;
  font-size: 16px;
  padding: 0;
  line-height: 1;
}
.kcc-askpop__close:hover { color: var(--text, #d8d4c8); }

.kcc-askpop__section {
  margin-bottom: 12px;
}
.kcc-askpop__section--two-col {
  /* Originally a two-col grid (1fr auto) to put bounty + expiry on
     the same row, but the 5-chip bounty row crowds out the 3-chip
     expiry column at the 380px popover width — last chip got
     clipped. Stacking vertically gives both rows full breathing
     room and reads cleanly. */
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.kcc-askpop__section--two-col > div {
  min-width: 0;
}
.kcc-askpop__label {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted, #8a8678);
  text-transform: uppercase;
  margin-bottom: 6px;
}

/* OPEN | USER toggle */
.kcc-askpop__target-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.kcc-askpop__toggle {
  display: flex;
  background: var(--bg, #1a1a1f);
  border: 1px solid var(--border, #2a2924);
  border-radius: 3px;
  padding: 2px;
  flex-shrink: 0;
}
.kcc-askpop__toggle-btn {
  background: transparent;
  border: none;
  color: var(--muted, #6b6a62);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  padding: 6px 10px;
  border-radius: 2px;
  cursor: pointer;
  font-weight: 700;
}
.kcc-askpop__toggle-btn.is-on {
  background: var(--brass, #d4a335);
  color: var(--ink-on-brass, #1a1610);
}
.kcc-askpop__target-input {
  flex: 1;
  background: var(--bg, #1a1a1f);
  border: 1px solid var(--border, #2a2924);
  color: var(--text, #d8d4c8);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  padding: 6px 10px;
  border-radius: 3px;
  outline: none;
  min-width: 0;
}
.kcc-askpop__target-input:focus {
  border-color: var(--brass, #d4a335);
}
.kcc-askpop__target-input[readonly] {
  cursor: default;
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
  color: var(--brass, #d4a335);
}
.kcc-askpop__target-hint {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted, #6b6a62);
  flex: 1;
}

/* Chips — bounty + expiry */
.kcc-askpop__chips {
  display: flex;
  gap: 4px;
}
.kcc-askpop__chip {
  background: transparent;
  border: 1px solid var(--border, #3a3631);
  color: var(--ink, #c9c4b5);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  padding: 8px 12px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 700;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.kcc-askpop__chip:hover {
  border-color: var(--brass, #d4a335);
  color: var(--brass, #d4a335);
}
.kcc-askpop__chip.is-on {
  background: var(--brass, #d4a335);
  color: var(--ink-on-brass, #1a1610);
  border-color: var(--brass, #d4a335);
}
.kcc-askpop__chip--sm {
  padding: 6px 10px;
  font-size: 11px;
}
/* Custom chip — same shape as the preset chips but with a smaller
   label font since 'custom' is longer than '10'/'25' etc. Renders
   alongside the preset chips so the chip row reads as 6 options. */
.kcc-askpop__chip--custom {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  padding: 8px 10px;
}
/* Inline numeric input shown when custom is on. Brass border to
   match the chip's is-on state. */
.kcc-askpop__custom-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
.kcc-askpop__custom-input {
  flex: 1;
  min-width: 0;
  background: var(--bg, #1a1a1f);
  border: 1px solid var(--brass, #d4a335);
  color: var(--brass, #d4a335);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 14px;
  font-weight: 700;
  padding: 6px 10px;
  border-radius: 3px;
  outline: none;
}
.kcc-askpop__custom-input::-webkit-outer-spin-button,
.kcc-askpop__custom-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.kcc-askpop__custom-input { -moz-appearance: textfield; }
.kcc-askpop__custom-unit {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted, #8a8678);
  letter-spacing: 0.08em;
}

/* Question textarea */
.kcc-askpop__q {
  width: 100%;
  background: var(--bg, #1a1a1f);
  border: 1px solid var(--border, #2a2924);
  color: var(--text, #d8d4c8);
  font-family: inherit;
  font-size: 13px;
  padding: 10px;
  border-radius: 3px;
  resize: none;
  outline: none;
  line-height: 1.5;
  box-sizing: border-box;
}
.kcc-askpop__q:focus { border-color: var(--brass, #d4a335); }
.kcc-askpop__q::placeholder { color: var(--muted, #5a5852); }
.kcc-askpop__counter {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  color: var(--muted, #6b6a62);
  text-align: right;
  margin-top: 4px;
}

/* Foot — fee preview + actions */
.kcc-askpop__foot {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--border, #2a2924);
}
.kcc-askpop__econ {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--muted, #8a8678);
  line-height: 1.5;
}
.kcc-askpop__econ strong {
  color: var(--brass, #d4a335);
  font-weight: 700;
}
.kcc-askpop__actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.kcc-askpop__cancel {
  background: transparent;
  border: 1px solid var(--border, #3a3631);
  color: var(--muted, #8a8678);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  padding: 8px 14px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 700;
}
.kcc-askpop__cancel:hover { color: var(--text, #d8d4c8); }
.kcc-askpop__post {
  background: var(--brass, #d4a335);
  color: var(--ink-on-brass, #1a1610);
  border: none;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  padding: 8px 16px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 700;
}
.kcc-askpop__post:hover:not(:disabled) {
  filter: brightness(1.08);
}
.kcc-askpop__post:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Composer toolbar — commitment-tier coloring.
   Same convention as signal/bet/challenge CARDS in the chat stream:
     · signal    = brass    (--brass)  = opinion (free)
     · bet       = cornflower (#8caaff) = virtual USD on the line
     · challenge = oxblood  (--red)    = razors at stake (P2P)
     · ask       = brass    (--brass)  = razors out (paid Q&A)
   Brass appears twice because signal + ask are both "razors-related"
   actions on the spectrum (one earns razors by being good, one pays
   razors to ask). Users quickly learn the convention. */

/* Composer toolbar SIGNAL button — green tint (--up). Signals
   are opinion/calls, distinct from the razor-money tier (ask is
   brass, challenge is oxblood, bet is cornflower). Green ties to
   the gains/up direction signals usually communicate. */
.kcc-composer__tool[data-kc="share-signal"] {
  color: var(--up, #6dd99c);
}
.kcc-composer__tool[data-kc="share-signal"]:hover {
  background: color-mix(in srgb, var(--up, #6dd99c) 10%, transparent);
}

/* Composer toolbar CHALLENGE button — oxblood tint. The pill is
   injected by KCChallengesUI with class=kcc-composer__tool (no
   modifier), so we target the data-kc attribute. */
.kcc-composer__tool[data-kc="open-challenge"] {
  color: var(--red, #a83232);
}
.kcc-composer__tool[data-kc="open-challenge"]:hover {
  background: color-mix(in srgb, var(--red, #a83232) 10%, transparent);
  color: #c47373;
}

/* Composer toolbar ASK button — brass tint to flag it as a money
   action (vs the gray "share signal" pill it sits next to). Uses
   the existing .kcc-composer__tool base styles for layout. */
.kcc-composer__tool--ask {
  color: var(--brass, #d4a335);
}
.kcc-composer__tool--ask:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, transparent);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, transparent);
}

/* Composer toolbar BET button — cornflower blue, matches the
   --blue: #8caaff token used by .wl-book.bet and .cp-* in the
   bet/waiting hue family. Pewter (#8a96a3) read as plain gray
   next to the other tool buttons, so we use the more saturated
   bet-family hex directly. */
.kcc-composer__tool--bet {
  color: #8caaff;
}
.kcc-composer__tool--bet:hover {
  background: color-mix(in srgb, #8caaff 10%, transparent);
  color: #b6c5ff;
}

/* Profile modal ASK button — mirrors .kc-profile-btn.tip styling
   so the two money actions sit side-by-side at the same visual
   weight. */
.kc-profile-btn.ask {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--brass, #d4a335);
}
.kc-profile-btn.ask:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, transparent);
}
.kcp-ask-glyph {
  display: inline-flex;
  align-items: center;
}

/* ══════════════════════════════════════════════════════════════════
   COMMITMENT-TIER STYLING — signal / bet / challenge
   Source: handoff_signal_bet_challenge_audit.md, items A + D.

   Three card types in chat, three commitment levels:
     · signal    = brass (--brass / --accent)    = "opinion"
     · bet       = pewter blue (--blue)          = "virtual USD on the line"
     · challenge = oxblood (--red)               = "razors at stake"

   Each open card carries a top-left tier pill naming the commitment
   type and amount; the top-right corner stays available for the
   resolution stamp once the card settles. Challenge cards additionally
   get a full oxblood border (not just a left bar) and an optional
   "tether" wrapper that ties the message body to the card via a
   shared left border.
   ══════════════════════════════════════════════════════════════════ */

/* Tier tag — inline marker at the right end of each card's head row.
   Format: "● word" (e.g. ● opinion, ● bet · $1000, ⚔ challenge · 100r).
   The dot is a single-glyph ::before so the ramp is locked to the
   tag color, not the surrounding text. The whole tag is non-clickable
   and pushed to the right edge via margin-left:auto inside the head
   flex row — it sits AFTER the existing meta (TF, countdown, etc.)
   rather than replacing it. Hidden when the card settles: the corner
   stamp takes over the right side. */
.kcc-tier-tag {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  flex-shrink: 0;
}
.kcc-tier-tag::before {
  content: "●";
  font-size: 6px;
  line-height: 1;
}
.kcc-tier-tag--signal    { color: var(--accent, var(--brass, #d4a335)); }
.kcc-tier-tag--bet       { color: var(--blue, #8a96a3); }
.kcc-tier-tag--challenge { color: var(--red, #d05a4a); }
/* Market call — a bet-less prediction. Muted gold marks it apart from a
   blue "bet · $X" position tag while staying in the predict family. */
.kcc-tier-tag--call      { color: var(--accent2, #b88b1f); }

/* Head-row defense: when a tag sits next to existing meta (signal's
   ".kcc-msg__sig-meta" or bet's ".kcc-msg__bet-meta"), that meta is
   already pushing right via margin-left:auto. Two flex children both
   claiming auto-margin cancel each other — the LATER one wins on the
   right, the earlier one stays inline. So the tag (later) anchors
   right, meta sits next to it with a small gap. Override gap on the
   tag so it never crowds meta. */
.kcc-msg__sig-head .kcc-msg__sig-meta + .kcc-tier-tag,
.kcc-msg__bet-head .kcc-msg__bet-meta + .kcc-tier-tag,
.kcc-msg__bet-head .kcc-msg__bet-outcome + .kcc-tier-tag,
.kcc-msg__chal-head .kcc-msg__chal-eyebrow + .kcc-tier-tag,
.kcc-msg__chal-head .kcc-msg__chal-time + .kcc-tier-tag {
  margin-left: 8px;
}

/* ── Item D · option 2: body-to-challenge tether ─────────────────
   When a message carries a challenge card, the chat body sits ABOVE
   the card and the two together form one visual unit. The tether
   wrapper supplies the shared oxblood left border that connects the
   body's thesis text to the card below it.

   Cosmetic: the body text gets a small left-padding so its text
   indents off the tether border by the same amount the card's
   content already indents off its own border. The card's existing
   3px left bar visually continues the tether. */
.kcc-msg__chal-tether {
  border-left: 2px solid color-mix(in srgb, var(--red, #a83232) 45%, transparent);
  padding-left: 10px;
  margin: 4px 0 0;
}
.kcc-msg__chal-tether .kcc-msg__text {
  margin-top: 0;
  margin-bottom: 6px;
}
/* The challenge card already has its own border, so when wrapped by
   the tether we tuck the card's left edge tight against the tether
   border and drop its own margin-top — the tether already supplies
   the gap to the body above. */
.kcc-msg__chal-tether .kcc-msg__chal {
  margin-top: 0;
  margin-left: -2px;        /* overlap the tether so the borders merge */
}

/* ─── Chat — theme picker (rail section + drawer popover) ─────────
   Three themes — Classic (default), Guild, Bubbles. Picker lives in
   two places:
     · chat.html right rail (always visible under ONLINE)
     · drawer panel header (palette button → popover)
   Both use the same .kcc-theme-picker markup; only the wrapper
   chrome differs.
*/

/* Right-rail section header — second copy of .kcc-rail-head with a
   little extra top spacing to set it apart from ONLINE block. */
.kcc-rail-head--theme {
  margin-top: 22px;
}

/* Picker grid — three rows of buttons. */
.kcc-theme-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
}

.kcc-theme-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  color: var(--text);
  font-family: inherit;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-theme-btn:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 30%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 3%, transparent);
}
.kcc-theme-btn.is-selected {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 50%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
}

.kcc-theme-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.kcc-theme-name {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-bright);
  font-family: 'Space Grotesk', system-ui, sans-serif;
}
.kcc-theme-sub {
  font-size: 10px;
  color: var(--text-muted);
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.02em;
}
.kcc-theme-check {
  color: var(--brass, #d4a335);
  font-size: 14px;
  font-weight: 600;
  opacity: 0;
  transition: opacity 120ms ease;
  flex-shrink: 0;
}
.kcc-theme-btn.is-selected .kcc-theme-check { opacity: 1; }

/* Swatch — small visual hint of what the theme looks like.
   Three different layouts, one per theme — see below. */
.kcc-theme-swatch {
  width: 32px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
/* Classic: stacked horizontal lines (handle, text, time) */
.kcc-theme-swatch--classic {
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
}
.kcc-theme-swatch--classic .sw-line {
  height: 3px;
  border-radius: 1px;
  background: var(--border2);
}
.kcc-theme-swatch--classic .sw-line--1 { width: 18px; background: var(--brass, #d4a335); }
.kcc-theme-swatch--classic .sw-line--2 { width: 22px; background: var(--text-bright); }
.kcc-theme-swatch--classic .sw-line--3 { width: 14px; background: var(--text-muted); }

/* Guild: single circle (the big-avatar look) */
.kcc-theme-swatch--guild .sw-circle {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--brass, #d4a335);
}

/* Bubbles: two offset pill shapes (right + left aligned) */
.kcc-theme-swatch--bubbles {
  flex-direction: column;
  gap: 2px;
}
.kcc-theme-swatch--bubbles .sw-bubble {
  height: 6px;
  border-radius: 6px;
}
.kcc-theme-swatch--bubbles .sw-bubble--right {
  width: 18px;
  background: var(--brass, #d4a335);
  align-self: flex-end;
  border-bottom-right-radius: 2px;
}
.kcc-theme-swatch--bubbles .sw-bubble--left {
  width: 14px;
  background: var(--bg2);
  align-self: flex-start;
  border-bottom-left-radius: 2px;
}

/* Chronicle: two stacked card-shaped rectangles with a brass left
   edge on the top one (= own run), neutral on the bottom (= others).
   Evokes the card-stack identity of the theme at a glance. */
.kcc-theme-swatch--chronicle {
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
}
.kcc-theme-swatch--chronicle .sw-card {
  width: 22px;
  height: 8px;
  border-radius: 2px;
  border: 1px solid var(--border2);
  border-left-width: 2px;
}
.kcc-theme-swatch--chronicle .sw-card--1 {
  border-left-color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, var(--surface));
}
.kcc-theme-swatch--chronicle .sw-card--2 {
  border-left-color: var(--border2);
  background: var(--surface);
}

/* Drawer header palette button — sits next to ⤢/× */
.kcc-panel-theme {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 120ms ease, background 120ms ease;
}
.kcc-panel-theme:hover {
  color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
}

/* Popover floats below the header on the right side of the drawer. */
.kcc-theme-popover {
  position: absolute;
  top: 56px;
  right: 14px;
  z-index: 5;
  width: 220px;
  padding: 10px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.kcc-theme-popover[hidden] { display: none; }
.kcc-theme-popover .kcc-theme-picker { margin-top: 0; }

/* ════════════════════════════════════════════════════════════════
   THEME: Guild — Discord-style.
   · 40px avatars (was 30px)
   · Grouped runs — continuation rows hide avatar + handle + time,
     and the run sits as one visual chunk with reduced top padding
   · Row-hover tint
   · Wider body — message text gets more horizontal room
   ════════════════════════════════════════════════════════════════ */
[data-kcc-theme="guild"] .kcc-stream {
  padding-top: 6px;
}

[data-kcc-theme="guild"] .kcc-msg {
  padding: 4px 8px;
  margin: 0 -8px;
  gap: 12px;
  border-radius: 4px;
  transition: background 80ms ease;
}
[data-kcc-theme="guild"] .kcc-msg:hover {
  background: color-mix(in srgb, var(--text-bright, #fff) 2%, transparent);
}

/* First row in a run — bigger avatar, slightly more top space. */
[data-kcc-theme="guild"] .kcc-msg:not([data-kcc-cont]) {
  padding-top: 10px;
}
[data-kcc-theme="guild"] .kcc-msg__avatar {
  width: 38px;
  height: 38px;
  font-size: 12px;
}
[data-kcc-theme="guild"] .kcc-msg__handle {
  font-size: 14px;
  font-weight: 600;
}
[data-kcc-theme="guild"] .kcc-msg__time {
  margin-left: 6px;
}
[data-kcc-theme="guild"] .kcc-msg__text {
  font-size: 14px;
  margin-top: 1px;
}

/* Continuation rows — hide avatar and meta entirely; keep a
   placeholder column matching the avatar width so the body still
   aligns with the first row above. */
[data-kcc-theme="guild"] .kcc-msg[data-kcc-cont] {
  padding-top: 1px;
  padding-bottom: 1px;
}
[data-kcc-theme="guild"] .kcc-msg[data-kcc-cont] .kcc-msg__avatar {
  visibility: hidden;
  height: 0;
  width: 38px;     /* reserve the column */
}
[data-kcc-theme="guild"] .kcc-msg[data-kcc-cont] .kcc-msg__meta {
  display: none;
}

/* Signal card under Guild — tighter top spacing since we're already
   in a denser layout, and a hair wider since the body column is bigger. */
[data-kcc-theme="guild"] .kcc-msg__signal,
[data-kcc-theme="guild"] .kcc-msg__bet,
[data-kcc-theme="guild"] .kcc-msg__chal {
  margin-top: 6px;
  max-width: 420px;
}

/* ─── Sender-change divider (Classic + Guild) ─────────────────────
   Hairline at the top of every message that starts a new sender's
   run — i.e. every non-continuation row, except the very first one
   in the stream (which would otherwise paint a stray border at the
   top of the chat). Continuations stay tight (no divider) because
   they don't match :not([data-kcc-cont]).

   Skipped under Bubbles — the bubble shape already provides visual
   separation, and a line over a bubble row would feel busy. */
[data-kcc-theme="classic"] .kcc-msg:not([data-kcc-cont]):not(:first-child),
[data-kcc-theme="guild"]   .kcc-msg:not([data-kcc-cont]):not(:first-child) {
  border-top: 1px solid color-mix(in srgb, var(--text-bright, #fff) 5%, transparent);
  margin-top: 4px;
}

/* Classic — add a touch of extra top padding above the divider so
   the new sender's avatar doesn't sit flush against the line. */
[data-kcc-theme="classic"] .kcc-msg:not([data-kcc-cont]):not(:first-child) {
  padding-top: 10px;
}

/* Guild — increase the run-starter's top padding (was 10px) so the
   divider has breathing room above the avatar. */
[data-kcc-theme="guild"] .kcc-msg:not([data-kcc-cont]):not(:first-child) {
  padding-top: 12px;
}

/* ════════════════════════════════════════════════════════════════
   THEME: Chronicle — card-stack.

   Every run of consecutive same-author messages (5-min window, no
   interruptions, decided in shared.js via _messageCtx → data-kcc-cont)
   renders as a single bordered card with internal entries.

   Mechanics:
   · Run head  — first row of a run, matched by :not([data-kcc-cont])
                 Gets top border + top corner radius, full meta row.
   · Run mid   — interior rows, matched by [data-kcc-cont] that also
                 has a following continuation sibling. Side borders
                 only; dotted internal separator above.
   · Run tail  — last row of a run, matched by
                 [data-kcc-cont]:not(:has(+ [data-kcc-cont])).
                 Bottom border + bottom corner radius.
   · Run solo  — single-row "run" (no continuation followers).
                 Matched by :not([data-kcc-cont]):not(:has(+ [data-kcc-cont])).
                 All four corners rounded, all borders.

   Self-coloring: [data-kcc-self] paints the left edge brass; everyone
   else gets a neutral edge. Per-user hue still tints the handle + avatar
   inside the card (handled by the universal hue palette below).

   Signal cards, attachments, scanner pings, and chart previews keep
   their own identity inside the card — Chronicle just paints around
   them. Trade-object frame (memory: parked design direction 1) lives
   here as a natural consequence.

   :has() is required. Supported in Chrome 105+, Safari 15.4+, Firefox
   121+ — i.e. every browser our users are on.
   ════════════════════════════════════════════════════════════════ */
[data-kcc-theme="chronicle"] .kcc-stream {
  padding-top: 10px;
}

/* Card baseline — every message row carries side borders. The top,
   bottom, and corner-radii are set conditionally below based on
   position within the run. */
[data-kcc-theme="chronicle"] .kcc-msg {
  background: var(--kcc-surface, var(--surface, #1a1714));
  border-left: 1px solid var(--kcc-edge, var(--border2));
  border-right: 1px solid var(--kcc-edge, var(--border2));
  border-left-width: 3px;            /* the edge-as-state stripe */
  border-left-color: var(--kcc-edge, var(--border2)); /* default — overridden by self */
  padding: 8px 12px;
  margin: 0;
  gap: 10px;
  transition: background 80ms ease;
}

/* Run head — first row of a run (or only row, both match). */
[data-kcc-theme="chronicle"] .kcc-msg:not([data-kcc-cont]) {
  border-top: 1px solid var(--kcc-edge, var(--border2));
  border-top-right-radius: 6px;
  padding-top: 9px;
  /* Air between cards: separation comes from margin-top here, not
     from a global stream gap, so continuation rows can still butt
     directly up against their head. */
  margin-top: 8px;
}
[data-kcc-theme="chronicle"] .kcc-msg:not([data-kcc-cont]):first-child {
  margin-top: 0;
}

/* Run tail — last row of a run. Either:
   · :not([data-kcc-cont]):not(:has(+ [data-kcc-cont]))  → solo card
   · [data-kcc-cont]:not(:has(+ [data-kcc-cont]))         → real tail
   Both get bottom border + bottom rounding. */
[data-kcc-theme="chronicle"] .kcc-msg:not(:has(+ [data-kcc-cont])) {
  border-bottom: 1px solid var(--kcc-edge, var(--border2));
  border-bottom-right-radius: 6px;
  padding-bottom: 9px;
}

/* Last-in-stream also closes the card — even if no following sibling
   exists at all, the row has no `+ [data-kcc-cont]` so the rule above
   already covers it. No extra selector needed. */

/* Run-head left-edge — own message accent. Uses the palette's self
   color (Brass = brass, Slate = ice-blue, Eclipse = lavender, etc). */
[data-kcc-theme="chronicle"] .kcc-msg:not([data-kcc-cont])[data-kcc-self] {
  border-left-color: var(--kcc-self, var(--brass, #d4a335));
}
/* Continuation rows inherit the head's edge color via the same
   selector — every row in a self-run has data-kcc-self, so painting
   the edge on every self row gives the visual run a continuous stripe. */
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-self] {
  border-left-color: var(--kcc-self, var(--brass, #d4a335));
}

/* Internal separator between entries — dotted hairline above every
   continuation row. Inside the card, not outside it, so it reads as
   "next entry from the same author" not "new card". */
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-cont] {
  padding-top: 6px;
  padding-bottom: 4px;
  border-top: 1px dotted color-mix(in srgb, var(--text-bright, #fff) 6%, transparent);
}

/* Avatar — full size only on run heads. Continuation rows hide the
   avatar but keep the column reserved so body text stays aligned
   with the head row. */
[data-kcc-theme="chronicle"] .kcc-msg__avatar {
  width: 28px;
  height: 28px;
  font-size: 11px;
}
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-cont] .kcc-msg__avatar {
  visibility: hidden;
  height: 0;
  width: 28px;          /* reserve the column */
}

/* Meta row — full on heads, compressed on continuations. Continuation
   rows show only the timestamp (no repeated handle), small and dim,
   sitting on the same line as the body text via float-style layout. */
[data-kcc-theme="chronicle"] .kcc-msg__handle {
  font-size: 13px;
  font-weight: 500;
}
[data-kcc-theme="chronicle"] .kcc-msg__time {
  font-size: 11px;
  margin-left: 6px;
}
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-cont] .kcc-msg__handle {
  display: none;
}
[data-kcc-theme="chronicle"] .kcc-msg[data-kcc-cont] .kcc-msg__meta {
  margin-bottom: 2px;
  opacity: 0.8;
}

/* Body text sizing — matches the rest of the chrome (a hair smaller
   than Guild's 14px so the card feels purposeful, not airy). */
[data-kcc-theme="chronicle"] .kcc-msg__text {
  font-size: 13px;
  margin-top: 2px;
}

/* Signal card under Chronicle — sits naturally inside the message
   card. Pull margins so it doesn't double up on the outer frame, and
   let it stretch the body column. The signal's own brass left rule
   tells the eye "this is a trade object" inside the Chronicle card. */
[data-kcc-theme="chronicle"] .kcc-msg__signal,
[data-kcc-theme="chronicle"] .kcc-msg__bet,
[data-kcc-theme="chronicle"] .kcc-msg__chal {
  margin-top: 5px;
  max-width: 440px;
}

/* Hover affordance — subtle lift on the whole card row, since the
   card IS the unit. Continuation rows tint the same so the entire
   card lifts as one when any entry is hovered. */
[data-kcc-theme="chronicle"] .kcc-msg:hover {
  background: color-mix(in srgb, var(--text-bright, #fff) 2.5%, var(--kcc-surface, var(--surface, #1a1714)));
}

/* ════════════════════════════════════════════════════════════════
   THEME: Bubbles — SMS / Telegram-style.
   · Own messages right-aligned in brass bubble
   · Other messages left-aligned in slate bubble, avatar visible
   · Avatar shown on FIRST message of each side's run only
   · Per-user hue (data-kcc-hue 1..7) tints the avatar + handle so
     speakers are distinguishable at a glance — bubble body stays
     neutral slate so the stream doesn't feel like a rainbow.
   · Own messages = data-kcc-hue 0 (brass).
   · Signal card sits in the bubble flow, aligned to the bubble side.
   ════════════════════════════════════════════════════════════════ */
[data-kcc-theme="bubbles"] .kcc-stream {
  padding-top: 6px;
}

[data-kcc-theme="bubbles"] .kcc-msg {
  padding: 2px 0;
  gap: 8px;
  align-items: flex-start;
}

/* Body container becomes a column flex so meta → bubble → time stack
   vertically and we can align them to the row side. flex:1 lets the
   body claim the full row width so flex-end can actually push the
   bubble to the right edge for own messages. */
[data-kcc-theme="bubbles"] .kcc-msg__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex: 1;
  min-width: 0;
}

/* Avatar — tinted by per-user hue. */
[data-kcc-theme="bubbles"] .kcc-msg__avatar {
  width: 28px;
  height: 28px;
  font-size: 10px;
  font-weight: 600;
  flex-shrink: 0;
  border: none;
}

/* Meta = handle row above the bubble (no time here — time goes
   below the bubble in its own row). */
[data-kcc-theme="bubbles"] .kcc-msg__meta {
  font-size: 11px;
  margin: 0 0 3px;
  padding: 0 2px;
  gap: 6px;
}
[data-kcc-theme="bubbles"] .kcc-msg__handle {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
}
[data-kcc-theme="bubbles"] .kcc-msg__time {
  display: block;
  font-size: 10px;
  color: var(--muted);
  margin: 3px 2px 0;
  order: 99;          /* push the time element AFTER everything in body */
  align-self: inherit;
}

/* The bubble itself — solid fill. Across the 12 themes --surface is
   sometimes nearly identical to --bg (e.g. Razor: bg #0b0a09 vs
   surface #121110), so we lighten it with a small white mix so the
   bubble is visible on every theme without per-theme overrides. A
   faint border catches the cases where lightening still isn't quite
   enough on already-light themes. */
[data-kcc-theme="bubbles"] .kcc-msg__text {
  display: inline-block;
  background: color-mix(in srgb, var(--surface) 88%, #ffffff 12%);
  color: var(--text);
  padding: 8px 12px;
  border-radius: 4px 14px 14px 14px;
  border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
  font-size: 13px;
  line-height: 1.45;
  max-width: 75%;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}

/* Continuation rows from same person on the LEFT — hide avatar +
   meta, round the top-left of the bubble (run feels like one unit). */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-cont]:not([data-kcc-self]) .kcc-msg__avatar {
  visibility: hidden;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-cont]:not([data-kcc-self]) .kcc-msg__meta {
  display: none;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-cont]:not([data-kcc-self]) .kcc-msg__text {
  border-radius: 14px;
}
/* Continuation rows hide their own time — only the last in a run
   really benefits from a timestamp, but for v1 we hide them all
   except the first message of the run to keep the layout calm. */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-cont] .kcc-msg__time {
  display: none;
}

/* Own messages — right aligned, brass bubble, no avatar. The body
   flexbox does the alignment work; we keep flex-direction normal so
   reactions/replies/signal cards inside body all align right too. */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__avatar {
  display: none;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__body {
  align-items: flex-end;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__meta {
  display: none;   /* your own handle doesn't repeat */
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__text {
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 22%, var(--surface));
  color: var(--text-bright);
  border: 1px solid color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 28%, transparent);
  border-radius: 14px 14px 4px 14px;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self][data-kcc-cont] .kcc-msg__text {
  border-radius: 14px;
}

/* Signal card — keep the existing card shape but constrain width
   and align to the bubble side. */
[data-kcc-theme="bubbles"] .kcc-msg__signal,
[data-kcc-theme="bubbles"] .kcc-msg__bet,
[data-kcc-theme="bubbles"] .kcc-msg__chal,
[data-kcc-theme="bubbles"] .kcc-msg__chal-tether {
  margin-top: 4px;
  max-width: 280px;
  align-self: flex-start;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__signal,
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__bet,
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__chal,
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__chal-tether {
  align-self: flex-end;
}

/* Attachments / preview cards inside bubble flow — right-align for
   own messages, keep left-align for others. */
[data-kcc-theme="bubbles"] .kcc-msg__attach,
[data-kcc-theme="bubbles"] .kcc-msg__preview {
  align-self: flex-start;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__attach,
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__preview {
  align-self: flex-end;
}

/* ─── Per-user hue palette (data-kcc-hue 1..7) ───────────────────
   Universal across all themes — Classic, Guild, and Bubbles all
   use the same palette so a user's colour is consistent regardless
   of which theme is active. Style C: each hue tints the avatar's
   ring + initials AND the handle text, leaving the avatar fill
   dark. The wax-seal feel — initials stamped through a colored ring.
   Hue 0 = self (brass) is handled by per-theme self rules; the
   selectors below apply to all non-self messages on every theme.
   Colours are deliberately desaturated so they read as "this person"
   not "warning / success / alert". */

/* h1 — coral/red */
.kcc-msg[data-kcc-hue="1"] .kcc-msg__avatar  { border-color: #e08a8a; color: #e08a8a; }
.kcc-msg[data-kcc-hue="1"] .kcc-msg__handle { color: #e08a8a; }

/* h2 — teal/sage */
.kcc-msg[data-kcc-hue="2"] .kcc-msg__avatar  { border-color: #7fc9a8; color: #7fc9a8; }
.kcc-msg[data-kcc-hue="2"] .kcc-msg__handle { color: #7fc9a8; }

/* h3 — purple */
.kcc-msg[data-kcc-hue="3"] .kcc-msg__avatar  { border-color: #a89dd9; color: #a89dd9; }
.kcc-msg[data-kcc-hue="3"] .kcc-msg__handle { color: #a89dd9; }

/* h4 — amber/honey */
.kcc-msg[data-kcc-hue="4"] .kcc-msg__avatar  { border-color: #d9b766; color: #d9b766; }
.kcc-msg[data-kcc-hue="4"] .kcc-msg__handle { color: #d9b766; }

/* h5 — blue */
.kcc-msg[data-kcc-hue="5"] .kcc-msg__avatar  { border-color: #7aa4c9; color: #7aa4c9; }
.kcc-msg[data-kcc-hue="5"] .kcc-msg__handle { color: #7aa4c9; }

/* h6 — pink/rose */
.kcc-msg[data-kcc-hue="6"] .kcc-msg__avatar  { border-color: #d98ab0; color: #d98ab0; }
.kcc-msg[data-kcc-hue="6"] .kcc-msg__handle { color: #d98ab0; }

/* h7 — pewter */
.kcc-msg[data-kcc-hue="7"] .kcc-msg__avatar  { border-color: #a4adb8; color: #a4adb8; }
.kcc-msg[data-kcc-hue="7"] .kcc-msg__handle { color: #a4adb8; }

/* ─── Presence-row hue parity ────────────────────────────────
   Same 7-hue palette as chat messages so a user looks identical
   in the right-rail ONLINE list and in their messages. */
.kcc-presence-row[data-kcc-hue="1"] .kcc-presence-initials { border-color: #e08a8a; color: #e08a8a; }
.kcc-presence-row[data-kcc-hue="1"] .kcc-presence-handle   { color: #e08a8a; }
.kcc-presence-row[data-kcc-hue="2"] .kcc-presence-initials { border-color: #7fc9a8; color: #7fc9a8; }
.kcc-presence-row[data-kcc-hue="2"] .kcc-presence-handle   { color: #7fc9a8; }
.kcc-presence-row[data-kcc-hue="3"] .kcc-presence-initials { border-color: #a89dd9; color: #a89dd9; }
.kcc-presence-row[data-kcc-hue="3"] .kcc-presence-handle   { color: #a89dd9; }
.kcc-presence-row[data-kcc-hue="4"] .kcc-presence-initials { border-color: #d9b766; color: #d9b766; }
.kcc-presence-row[data-kcc-hue="4"] .kcc-presence-handle   { color: #d9b766; }
.kcc-presence-row[data-kcc-hue="5"] .kcc-presence-initials { border-color: #7aa4c9; color: #7aa4c9; }
.kcc-presence-row[data-kcc-hue="5"] .kcc-presence-handle   { color: #7aa4c9; }
.kcc-presence-row[data-kcc-hue="6"] .kcc-presence-initials { border-color: #d98ab0; color: #d98ab0; }
.kcc-presence-row[data-kcc-hue="6"] .kcc-presence-handle   { color: #d98ab0; }
.kcc-presence-row[data-kcc-hue="7"] .kcc-presence-initials { border-color: #a4adb8; color: #a4adb8; }
.kcc-presence-row[data-kcc-hue="7"] .kcc-presence-handle   { color: #a4adb8; }

/* Self (hue 0) — keep handle in brass across Classic and Guild so
   own messages still feel distinct. (Bubbles overrides the bubble
   itself to brass-tinted, and hides the handle entirely, so this
   only affects Classic + Guild.) */
.kcc-msg[data-kcc-hue="0"] .kcc-msg__avatar { background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 22%, var(--surface)); color: var(--kcc-self, var(--brass, #d4a335)); }
.kcc-msg[data-kcc-hue="0"] .kcc-msg__handle { color: var(--kcc-self, var(--brass, #d4a335)); }

/* ─── KC Avatar badge — wrapper overrides for monogram SVG ────────
   The legacy initials wrappers (.kcc-presence-initials,
   .kcc-topcallers__initials, .kcc-msg__avatar) draw a circular
   border + dark fill around their text content. When we swap that
   text for a monogram SVG, the badge has its own cut-corner shape
   and stroke — so we strip the wrapper's circle border, background
   and border-radius so the SVG's silhouette can be seen.

   :has(svg) only matches when a child SVG was injected. App rows
   (.kcc-msg__avatar--app) keep text initials, so their wrapper
   continues using the legacy circle styling untouched. */
.kcc-presence-initials:has(svg),
.kcc-topcallers__initials:has(svg),
.kcc-msg__avatar:has(svg) {
  border: 0;
  background: transparent;
  border-radius: 0;
  padding: 0;
  overflow: visible;
}
/* Self-row gets a brass-tinted monogram (matches hue 0 handle color)
   without the soft brass background fill — the badge itself supplies
   surface. */
.kcc-msg[data-kcc-hue="0"] .kcc-msg__avatar:has(svg) {
  background: transparent;
  color: var(--kcc-self, var(--brass, #d4a335));
}

/* ─── Photo avatar (HTML <img> + scalable clip) ───────────────────
   Photos render as a real <img> clipped to the frame "card" by a shared
   objectBoundingBox clipPath, with the stroke/rivet/foil decor drawn in an
   absolutely-positioned overlay SVG. This replaces the old inline SVG
   <image>, which WebKit re-rasterized (blank-then-pop) on every DOM change.
   The wrapper fills its host avatar box (.kcc-msg__avatar / -presence-
   initials / -topcallers__initials / .kcc-board__initials / .kch-av etc.),
   which already supplies size + border-radius. NOTE: distinct from the
   avatar-picker's own `.kca-photo` grid-cell class. */
.kc-photoav {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  line-height: 0;
}
.kc-photoav__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  -webkit-clip-path: url(#kcaCardClip_single);
          clip-path: url(#kcaCardClip_single);
}
.kc-photoav__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  overflow: visible;
}

/* ─── Chat — emoji picker (composer button + popover) ─────────────
   Emoji button sits between the attach button and the input. Clicks
   open a popover above the composer row showing categorized native
   unicode emojis. :shortcode: typer also expands inline — no
   special UI for that, just a JS hook on the input event.
*/

.kcc-composer__emoji {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease;
  flex-shrink: 0;
}
.kcc-composer__emoji:hover {
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--text-bright, #fff) 5%, transparent);
}
.kcc-composer__emoji[aria-expanded="true"] {
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 12%, transparent);
}
/* Native emoji on the button — make it sized like an icon. */
.kcc-emoji-btn-glyph {
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
}

/* Popover lives inside .kcc-composer (which has staged + row).
   Positions itself above the input row. */
.kcc-composer { position: relative; }
.kcc-emoji-popover {
  position: absolute;
  bottom: 100%;
  left: 12px;
  right: 12px;
  max-width: 340px;
  margin-bottom: 8px;
  z-index: 10;
  padding: 8px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  max-height: 280px;
  overflow-y: auto;
}
.kcc-emoji-popover[hidden] { display: none; }

/* Custom scrollbar matches .kcc-stream */
.kcc-emoji-popover::-webkit-scrollbar { width: 6px; }
.kcc-emoji-popover::-webkit-scrollbar-thumb {
  background: var(--border2);
  border-radius: 3px;
}

.kcc-emoji-grid {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.kcc-emoji-cat {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  text-transform: uppercase;
  padding: 2px 4px;
  margin-top: 4px;
}
.kcc-emoji-cat:first-child { margin-top: 0; }

.kcc-emoji-row {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
}

.kcc-emoji-cell {
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  padding: 4px;
  font-size: 18px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 80ms ease, border-color 80ms ease;
  /* Keep native emoji rendering on every platform. */
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.kcc-emoji-cell:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, var(--bg2));
  border-color: color-mix(in srgb, var(--brass, #d4a335) 30%, var(--border));
}
.kcc-emoji-cell:focus-visible {
  outline: none;
  border-color: var(--brass, #d4a335);
}

/* On narrow widths (drawer is ~360px wide), the popover spans the
   composer; shrink the grid to fit. */
@media (max-width: 480px) {
  .kcc-emoji-row { grid-template-columns: repeat(6, 1fr); }
  .kcc-emoji-cell { font-size: 16px; padding: 3px; }
}

/* ─── Chat — hover toolbar + reactions ─────────────────────────────
   Every .kcc-msg gets a hover-revealed action toolbar in the top-right
   corner: a "react" button (😊 → opens picker) and (for admins only)
   a delete button. Hover-reveal on desktop, half-opacity on touch.
*/

.kcc-msg__toolbar {
  position: absolute;
  top: 4px;
  right: 0;
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px;
  opacity: 0;
  /* Slide in 6px from the right, plus the fade. Reads as a small
     menu animating into place on hover. */
  transform: translateX(6px);
  transition: opacity 140ms ease, transform 140ms ease;
  pointer-events: none;
}
.kcc-msg:hover .kcc-msg__toolbar,
.kcc-msg__toolbar:focus-within {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}
@media (prefers-reduced-motion: reduce) {
  .kcc-msg__toolbar { transform: none; }
}

.kcc-msg__tb-btn {
  width: 26px;
  height: 24px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color .12s ease, background .12s ease;
  flex-shrink: 0;
  padding: 0;
}
.kcc-msg__tb-btn:hover {
  color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 12%, transparent);
}
.kcc-msg__tb-btn--danger:hover {
  color: var(--oxblood-text, #d4787a);
  background: color-mix(in srgb, var(--oxblood, #a83232) 14%, transparent);
}
.kcc-msg__tb-btn:focus-visible {
  outline: none;
  background: color-mix(in srgb, var(--brass, #d4a335) 16%, transparent);
}
.kcc-msg__tb-btn.is-busy,
.kcc-msg__tb-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
.kcc-msg__tb-emoji {
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}

/* On touch (no hover) the toolbar is tap-to-reveal instead of an
   always-on translucent overlay that sat over the message text and
   clipped at the screen edge. JS toggles .is-actions-open on the tapped
   row; revealed, it's a solid pill inset from the edge. One row open at
   a time. */
@media (hover: none) {
  .kcc-msg__toolbar {
    opacity: 0;
    pointer-events: none;
    transform: none;
    right: 6px;
    top: 6px;
  }
  .kcc-msg.is-actions-open .kcc-msg__toolbar {
    opacity: 1;
    pointer-events: auto;
  }
}

/* Reaction picker — small popover that appears below the react button
   when clicked. Anchored inside .kcc-msg__toolbar so it positions
   relative to the toolbar's right edge. */
/* ─── Reaction picker ─────────────────────────────────────────
   Anchored to the smile button (left edge of the hover toolbar)
   so it never overflows past the right edge of narrow streams.
   Two modes: quick (7 emojis + "+") and full (14 emojis, 2 rows).
   Switching is a data-attr swap on the picker root. */
.kcc-rx-picker {
  position: absolute;
  top: 100%;
  /* Anchor LEFT of the toolbar (which is right-aligned on the row).
     With the toolbar's `right: 0`, left: 0 of the picker means it
     starts at the toolbar's left edge and extends rightward — but
     since the toolbar is already at the right edge of the message,
     "rightward" overflow is what we had. Instead, anchor right:0
     so the picker's RIGHT edge aligns to the toolbar's right edge
     and the picker extends LEFTWARD (inside the message). The
     quick variant is narrow enough to fit comfortably. */
  right: 0;
  margin-top: 4px;
  /* High enough to clear adjacent .kcc-msg stacking contexts (each
     row has position:relative so they form their own stacks; without
     this, the picker drops behind the next message's body). */
  z-index: 50;
  padding: 4px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  opacity: 1;
}
.kcc-rx-picker[hidden] { display: none; }

/* Flip the picker to open UPWARD when a downward open (top:100%) would
   spill past the .kcc-stream scroll edge — i.e. the last messages that
   sit just above the composer, where overflow-y:auto was clipping it.
   JS (_positionRxPicker) measures on open + on quick↔full toggle and
   toggles this class only when there's room above. */
.kcc-rx-picker.kcc-rx-picker--up {
  top: auto;
  bottom: 100%;
  margin-top: 0;
  margin-bottom: 4px;
}

/* When the picker is open on a message, lift the whole row above its
   neighbours so the dropdown isn't covered by the next message. The
   :has() guard means inactive rows stay at their default z-order. */
.kcc-msg:has(.kcc-rx-picker:not([hidden])) {
  z-index: 40;
}

/* Mode toggle — show quick OR full, never both. */
.kcc-rx-picker[data-mode="quick"] .kcc-rx-picker__full  { display: none; }
.kcc-rx-picker[data-mode="full"]  .kcc-rx-picker__quick { display: none; }

.kcc-rx-picker__quick {
  display: flex;
  gap: 1px;
  align-items: center;
}
.kcc-rx-picker__divider {
  display: inline-block;
  width: 1px;
  height: 16px;
  background: var(--border);
  margin: 0 2px;
}
.kcc-rx-picker__full {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  max-width: 220px;
}

.kcc-rx-picker-cell {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 4px;
  font-size: 16px;
  line-height: 1;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
  transition: background 80ms ease;
}
.kcc-rx-picker-cell:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, var(--bg2));
}
.kcc-rx-picker-more {
  background: transparent;
  border: none;
  cursor: pointer;
  width: 24px;
  height: 24px;
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  border-radius: 4px;
  transition: background 80ms ease, color 80ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.kcc-rx-picker-more:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, var(--bg2));
  color: var(--brass, #d4a335);
}

/* Report-reason popover — vertical menu, anchored like the reaction
   picker (right edge to the toolbar, extends leftward/down). */
.kcc-rp-picker {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 4px;
  z-index: 50;
  min-width: 168px;
  padding: 4px;
  background: var(--card, #13131f);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.kcc-rp-picker[hidden] { display: none; }
.kcc-msg:has(.kcc-rp-picker:not([hidden])) { z-index: 40; }
.kcc-rp-picker__head {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 5px 8px 3px;
}
.kcc-rp-picker-cell {
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  padding: 7px 9px;
  border-radius: 4px;
  font: inherit;
  font-size: 12.5px;
  color: var(--text, #e8e1cf);
  transition: background 80ms ease, color 80ms ease;
}
.kcc-rp-picker-cell:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, var(--bg2));
  color: var(--brass, #d4a335);
}

/* Reaction pills under the message body. Click to toggle your own
   reaction. "Mine" gets a brass accent so it's obvious which you've
   already added. */
.kcc-rx-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.kcc-rx-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 6px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 11px;
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.kcc-rx-pill:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 4%, var(--bg2));
}
.kcc-rx-pill--mine {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 55%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 12%, var(--bg2));
  color: var(--text-bright);
}
.kcc-rx-pill--mine:hover {
  border-color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 18%, var(--bg2));
}
.kcc-rx-pill.is-busy {
  opacity: 0.6;
  pointer-events: none;
}
/* Pop animation — applied for ~250ms when a reaction is freshly
   added (either by us or another user). 0 → 1.2 → 1.0 scale, plus
   a brief brass tint pulse on the count for "+1" feedback. */
@keyframes kcc-rx-pop {
  0%   { transform: scale(0.6);  }
  55%  { transform: scale(1.18); }
  100% { transform: scale(1);    }
}
.kcc-rx-pill--pop {
  animation: kcc-rx-pop 220ms ease-out;
  transform-origin: center center;
}
@media (prefers-reduced-motion: reduce) {
  .kcc-rx-pill--pop { animation: none; }
}

/* Reaction burst — 5 brass sparks fly outward from the pill center
   when WE add a new reaction (not when someone else adds it, not
   when we remove our own). JS appends a transient .kcc-rx-burst
   overlay with 5 spark children to the pill; CSS does the rest.
   The container is position:absolute pinned to the pill so sparks
   originate from its center. Removed by JS after ~700ms.

   Variables --sx/--sy hold each spark's outbound vector (in px) —
   JS sets them inline so 5 sparks fan out at distinct angles. */
.kcc-rx-pill {
  /* Make sure the pill anchors absolutely-positioned burst overlays. */
  position: relative;
}
.kcc-rx-burst {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
  z-index: 1;
}
.kcc-rx-burst__spark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: var(--kcc-self, var(--brass, #d4a335));
  opacity: 0;
  animation: kcc-rx-spark 620ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes kcc-rx-spark {
  0%   { opacity: 1; transform: translate(0, 0) scale(0.6); }
  60%  { opacity: 1; }
  100% {
    opacity: 0;
    transform: translate(var(--sx, 0px), var(--sy, 0px)) scale(1.1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .kcc-rx-burst { display: none; }
}
.kcc-rx-pill-emoji {
  font-size: 13px;
  line-height: 1;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.kcc-rx-pill-count {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 500;
}

/* In Bubbles theme, the reaction row is aligned to match the bubble
   (right-aligned for self, left for others). */
[data-kcc-theme="bubbles"] .kcc-rx-row { justify-content: flex-start; }
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-rx-row {
  justify-content: flex-end;
}

/* ─── Chat — replies ──────────────────────────────────────────────
   Two surfaces:
     1. Reply chip in the composer — appears above input when the user
        is replying to a message. Shows target handle + body preview
        + × to cancel.
     2. Reply quote-block on a message — small "↳ @handle · preview"
        block above the body, clickable to scroll to the original.

   Plus a flash-highlight on the targeted row when the quote is
   clicked, so the user knows what they jumped to.
*/

/* Reply chip — lives at the top of .kcc-composer, above staged image
   chip and input row. */
.kcc-reply-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin-bottom: 8px;
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, var(--bg2));
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border));
  border-left: 2px solid var(--brass, #d4a335);
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  color: var(--text-muted);
  line-height: 1.3;
}
.kcc-reply-chip-arrow {
  color: var(--brass, #d4a335);
  font-size: 14px;
  flex-shrink: 0;
}
.kcc-reply-chip-text {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
  overflow: hidden;
}
.kcc-reply-chip-handle {
  color: var(--brass, #d4a335);
  font-weight: 500;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  flex-shrink: 0;
}
.kcc-reply-chip-preview {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kcc-reply-chip-x {
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px 6px;
  font-size: 14px;
  border-radius: 3px;
  flex-shrink: 0;
  transition: color 120ms ease, background 120ms ease;
}
.kcc-reply-chip-x:hover {
  color: var(--oxblood-text, #d4787a);
  background: color-mix(in srgb, var(--oxblood, #a83232) 12%, transparent);
}

/* Ask-reply variant — slightly stronger brass tint than the regular
   reply chip since this is a money action (a reply that may earn
   razors if accepted). The strong tag inside the preview lights up
   the bounty amount. */
.kcc-reply-chip--ask {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, var(--bg2));
  border-color: color-mix(in srgb, var(--brass, #d4a335) 45%, var(--border));
}
.kcc-reply-chip--ask .kcc-reply-chip-handle {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  font-weight: 700;
}
.kcc-reply-chip--ask .kcc-reply-chip-preview strong {
  color: var(--brass, #d4a335);
  font-weight: 700;
}

/* Reply quote-block — small clickable summary above the body of a
   reply message. */
.kcc-reply-quote {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 2px 8px;
  margin: 0 0 4px;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 11px;
  font-family: inherit;
  line-height: 1.3;
  max-width: 100%;
  border-left: 2px solid var(--border2);
  text-align: left;
  transition: color 120ms ease, border-color 120ms ease;
}
.kcc-reply-quote:hover {
  color: var(--text);
  border-left-color: var(--brass, #d4a335);
}
.kcc-reply-quote-arrow {
  color: var(--text-muted);
  flex-shrink: 0;
}
.kcc-reply-quote:hover .kcc-reply-quote-arrow {
  color: var(--brass, #d4a335);
}
.kcc-reply-quote-handle {
  color: var(--brass, #d4a335);
  font-weight: 500;
  flex-shrink: 0;
}
.kcc-reply-quote-preview {
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.kcc-reply-quote--missing {
  font-style: italic;
  border-left-color: var(--border);
}
.kcc-reply-quote--missing:hover {
  /* Missing target — clicking scrolls to where the row would be but
     doesn't find anything. Still allow the hover state for affordance. */
  color: var(--text-muted);
  border-left-color: var(--border2);
  cursor: default;
}

/* Flash-highlight on the targeted row after a scroll-to-message.
   Brief brass tint that fades back to default. */
.kcc-msg--flash {
  animation: kcc-flash 1.2s ease-out;
}
@keyframes kcc-flash {
  0%   { background: color-mix(in srgb, var(--brass, #d4a335) 20%, transparent); }
  100% { background: transparent; }
}

/* In Bubbles theme, the reply quote sits inside the bubble so its
   left-stripe shouldn't be visible — replace the stripe with a
   subtle indent instead. Also right-align for own messages. */
[data-kcc-theme="bubbles"] .kcc-reply-quote {
  border-left: none;
  padding-left: 0;
  opacity: 0.85;
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-reply-quote {
  align-self: flex-end;
}

/* ═══════════════════════════════════════════════════════════════════
   CHAT POLISH v2 — depth, glass, animation, refined hover toolbar
   Applies across all three themes; theme-specific overrides scope
   themselves with [data-kcc-theme="X"] where needed.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── Message fade-in animation ─────────────────────────────────────
   Applied via .kcc-msg--new (added by JS on freshly-arrived rows,
   removed ~300ms later so re-renders don't re-trigger). History
   backfill does NOT get this class — only optimistic + realtime
   new arrivals.

   Two-part: (a) the row itself fades + slides up 6px in 220ms;
   (b) a 2px brass left-edge pseudo sweeps in from opacity 0.6 to 0,
   peaking right after the slide settles. Reads as "this just landed
   in The Floor". */
@keyframes kcc-msg-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0);   }
}
@keyframes kcc-msg-edge-sweep {
  0%   { opacity: 0; }
  20%  { opacity: 0.85; }
  100% { opacity: 0; }
}
.kcc-msg.kcc-msg--new {
  animation: kcc-msg-in 220ms ease-out;
  position: relative;
}
.kcc-msg.kcc-msg--new::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--kcc-self, var(--brass, #d4a335));
  pointer-events: none;
  animation: kcc-msg-edge-sweep 720ms ease-out;
  opacity: 0;
}
/* Chronicle already has its own left edge — suppress the sweep
   pseudo there so they don't double up. The row fade still plays. */
[data-kcc-theme="chronicle"] .kcc-msg.kcc-msg--new::before {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .kcc-msg.kcc-msg--new,
  .kcc-msg.kcc-msg--new::before {
    animation: none;
  }
}

/* ─── Bubbles: width consistency + glass depth ──────────────────────
   - Long lines cap at 560px so they don't sprawl on wide viewports
   - Short lines hug the text (display: inline-block already does this)
   - Subtle vertical gradient fill (light top → slightly darker bottom)
   - Hairline inner highlight at the top edge (1px inset shadow)
   - Soft drop shadow underneath for layering
   - 1px translucent border catches the bubble edge against any bg
   - Hover lifts 1px and grows the shadow */
[data-kcc-theme="bubbles"] .kcc-msg__text {
  max-width: min(560px, 75%);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--surface) 80%, #ffffff 20%),
    color-mix(in srgb, var(--surface) 92%, #ffffff 8%));
  border: 1px solid color-mix(in srgb, var(--text-bright, #fff) 8%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text-bright, #fff) 5%, transparent),
    0 2px 6px rgba(0, 0, 0, 0.22);
  transition: transform 140ms ease, box-shadow 140ms ease;
}
[data-kcc-theme="bubbles"] .kcc-msg__text:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text-bright, #fff) 7%, transparent),
    0 4px 10px rgba(0, 0, 0, 0.32);
}

/* Self-bubble keeps the brass tint but gains the same depth/gradient. */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__text {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--brass, #d4a335) 28%, var(--surface)),
    color-mix(in srgb, var(--brass, #d4a335) 18%, var(--surface)));
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 38%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--brass, #d4a335) 25%, transparent),
    0 2px 8px rgba(0, 0, 0, 0.28);
}

/* Classic + Guild: subtle row hover so messages feel "alive" without
   needing a full glass treatment. Bubbles does its own bubble-hover. */
[data-kcc-theme="classic"] .kcc-msg,
[data-kcc-theme="guild"] .kcc-msg {
  transition: background 120ms ease;
}

/* ─── Timestamp: dim across all themes ──────────────────────────────
   Was full opacity, now 0.55 — the timestamp is contextual, not
   primary information. */
.kcc-msg__time {
  opacity: 0.55;
}

/* In Bubbles, the timestamp is even more contextual since the bubble
   shape already does the speaker-anchoring work. */
[data-kcc-theme="bubbles"] .kcc-msg__time {
  opacity: 0.5;
  font-size: 9.5px;
}

/* ─── Hover toolbar: glass treatment + better anchoring ─────────────
   The toolbar is anchored to the message row's top-right corner.
   Tighter buttons, glass background with backdrop blur, soft shadow
   so it floats above the bubble rather than competing with it. */
.kcc-msg__toolbar {
  top: -10px;
  right: 6px;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--text-bright, #fff) 10%, transparent);
  border-radius: 8px;
  padding: 3px;
  gap: 1px;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  /* Smoother reveal: fade + tiny scale */
  transform: translateY(2px) scale(0.96);
  transform-origin: top right;
  transition: opacity 120ms ease, transform 120ms ease;
}
.kcc-msg:hover .kcc-msg__toolbar,
.kcc-msg__toolbar:focus-within {
  transform: translateY(0) scale(1);
}
.kcc-msg__tb-btn {
  width: 24px;
  height: 24px;
  border-radius: 5px;
}
.kcc-msg__tb-emoji {
  font-size: 13px;
}

/* In Bubbles, anchor the toolbar to the bubble itself rather than the
   row — for own messages it should sit on the LEFT of the bubble
   (since the bubble is right-aligned), and for others' bubbles on
   the RIGHT. Position-relative ensures the bubble is the anchor. */
[data-kcc-theme="bubbles"] .kcc-msg {
  /* The toolbar's existing position:absolute uses .kcc-msg as the
     anchor — we just need to keep it anchored correctly. */
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__toolbar {
  right: auto;
  left: 6px;
  transform-origin: top left;
}

/* ─── Reactions: smaller + tighter ──────────────────────────────────
   Was 11px / 13px emoji / 2px-8px padding. New: 10.5px / 11px emoji /
   1px-6px padding. Pills feel like annotations, not buttons. */
.kcc-rx-row {
  gap: 3px;
  margin-top: 4px;
}
.kcc-rx-pill {
  padding: 1px 6px 1px 5px;
  font-size: 10.5px;
  border-radius: 9px;
  gap: 3px;
}
.kcc-rx-pill-emoji {
  font-size: 11px;
}
.kcc-rx-pill-count {
  font-size: 10.5px;
}

/* In Bubbles, reaction pills get a glass tint matching the bubble. */
[data-kcc-theme="bubbles"] .kcc-rx-pill {
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  border-color: color-mix(in srgb, var(--text-bright, #fff) 10%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* ─── Chat — inline message editor ────────────────────────────────
   When state.editingId matches a message, renderMessage swaps the
   text bubble for a textarea + action bar. Keep the same visual
   container as the bubble (gradient + border) so the editor feels
   like the message becomes editable in place rather than spawning
   a separate modal. */

.kcc-msg__text--editing {
  display: block;            /* fill the bubble column width */
  max-width: 100%;
  padding: 8px 10px;
  cursor: default;
}

.kcc-msg__edit-input {
  width: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: inherit;             /* inherit bubble text colour */
  font: inherit;
  line-height: inherit;
  resize: none;
  padding: 0;
  margin: 0;
  min-height: 1.6em;
  /* Auto-size via rows; tall messages get a small max-height + scroll. */
  max-height: 200px;
  overflow-y: auto;
}
.kcc-msg__edit-input:focus { outline: none; }

.kcc-msg__edit-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid color-mix(in srgb, var(--text-bright, #fff) 8%, transparent);
}
.kcc-msg__edit-hint {
  font-size: 10px;
  color: var(--text-mid, #c8c2b4);
  opacity: 0.65;
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.02em;
}
.kcc-msg__edit-actions {
  display: flex;
  gap: 4px;
}
.kcc-msg__edit-btn {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--text-bright, #fff) 15%, transparent);
  color: var(--text-mid, #c8c2b4);
  font-size: 11px;
  font-weight: 500;
  padding: 3px 10px;
  border-radius: 5px;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.kcc-msg__edit-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--text-bright, #fff) 6%, transparent);
  border-color: color-mix(in srgb, var(--text-bright, #fff) 25%, transparent);
  color: var(--text, #f1ece1);
}
.kcc-msg__edit-btn--primary {
  background: var(--brass, #d4a335);
  border-color: var(--brass, #d4a335);
  color: var(--bg, #1c1a17);
  font-weight: 600;
}
.kcc-msg__edit-btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--brass, #d4a335) 88%, #ffffff 12%);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 88%, #ffffff 12%);
  color: var(--bg, #1c1a17);
}
.kcc-msg__edit-btn:disabled,
.kcc-msg__edit-btn.is-busy {
  opacity: 0.55;
  cursor: not-allowed;
}

/* (edited) indicator — small italic after the timestamp in the meta
   row. Low-contrast so it doesn't compete with content. */
.kcc-msg__edited {
  font-size: 10px;
  font-style: italic;
  color: var(--text-mid, #c8c2b4);
  opacity: 0.55;
  margin-left: 2px;
}

/* In Bubbles, the meta row is hidden for own messages, but the
   (edited) tag still needs to show somewhere. Reveal the meta row
   ONLY when it contains an edited tag (via :has()), and inside it
   keep handle + time hidden — just the tag shows. :has() has solid
   support in all evergreen browsers as of 2024; if a browser
   doesn't support it, the (edited) tag stays hidden on self
   messages in Bubbles, which is a graceful fallback. */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__meta:has(.kcc-msg__edited) {
  display: block;
  margin: 0;
  padding: 4px 4px 0;
  text-align: right;
  font-size: 10px;
  order: 99;                  /* push to bottom of body flex */
}
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__meta:has(.kcc-msg__edited) > .kcc-msg__handle,
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__meta:has(.kcc-msg__edited) > .kcc-msg__time {
  display: none;
}

/* Bubbles non-self — meta row is shown normally above the bubble.
   The (edited) tag rides along after the handle. No extra rules. */

/* ─── Chat — hover toolbar anchored to the bubble ────────────────
   When the message has a text body, the toolbar is rendered INSIDE
   .kcc-msg__text so it anchors to the bubble's corner. This is
   correct across all themes because the bubble is narrower than
   the row in Bubbles (so the row-right anchor floats far away),
   and even in Classic/Guild it puts the toolbar closer to the
   content rather than out at the row's right edge.

   When the message is body-less (image/signal-only), the toolbar
   stays at the row level — the rules at the start of this section
   handle that case via .kcc-msg > .kcc-msg__toolbar. */
.kcc-msg__text {
  position: relative;
}

/* Toolbar inside the bubble — overrides the row-level top/right
   from the v2 polish block. Default position is top-right corner
   of the bubble (good for incoming/non-self bubbles). */
.kcc-msg__text > .kcc-msg__toolbar {
  top: -14px;
  right: -4px;
  left: auto;
  transform-origin: top right;
}

/* In Bubbles for OWN messages, flip the toolbar to the bubble's
   top-left so it doesn't cover the bubble's "tail" corner on the
   right. (Self bubble has the inward corner on the bottom-right;
   toolbar at top-left avoids overlap with the right rail nicely.) */
[data-kcc-theme="bubbles"] .kcc-msg[data-kcc-self] .kcc-msg__text > .kcc-msg__toolbar {
  right: auto;
  left: -4px;
  transform-origin: top left;
}

/* In Classic/Guild, the bubble has no background, so a toolbar
   sitting at top-right of the inline text would float over the
   message. Push it slightly outside the text on the right edge
   for those themes — visually it lands near the row's right side
   but anchored to the text's actual width, not the row's. */
[data-kcc-theme="classic"] .kcc-msg__text > .kcc-msg__toolbar,
[data-kcc-theme="guild"]   .kcc-msg__text > .kcc-msg__toolbar {
  top: -10px;
  right: -6px;
}

/* ─── Chat page — hide the floating quick-launch dock ────────────
   On the dedicated /chat page, the QC dock (Writer / Assistant /
   Capture) clutters the bottom-right corner right where the
   composer sits. The composer is the primary action on this page,
   so the dock has nowhere useful to live without overlapping it.
   Hide it entirely — users navigate to those features from the
   sidebar nav instead. The dock continues to show on every other
   page. */
body[data-kc-page="chat"] .kc-qc-pill {
  display: none !important;
}

/* With the dock hidden on chat, the body's 60px bottom dock-clearance
   pad (from `body.kc-page { padding: 0 0 60px }`) is dead space. The
   chat column already fills `100vh - 32px` and the container adds
   24px on top — so leaving the 60px below produces a scrollable
   tail under the composer (24 + (100vh - 32) + 60 = 100vh + 52).
   Reclaim it on desktop. The mobile chat block lower down sets the
   same value inside its @media query; both paths now agree. */
body[data-kc-page="chat"] {
  padding-bottom: 0 !important;
}

/* Belt-and-suspenders: the chat column is JS-sized (KCChat._sizeChatColumns)
   to fill the viewport with the composer pinned to the bottom edge. Small
   residual document overshoot — e.g. the nudge/tips bar's height accounting
   adding a dozen-odd px below the column — would otherwise surface as a
   scrollable gap under the composer (independent of browser; it showed on
   Safari AND Chrome whenever the tips bar was open). The column is sized
   with ample headroom (composer sits well above the fold), so locking the
   desktop chat body to no-scroll clips that overshoot harmlessly. The
   ≤760px block already does this for mobile; scope this to >760px so the
   two never fight. */
@media (min-width: 761px) {
  body[data-kc-page="chat"] { overflow: hidden; }
}

/* ─── Chat page — wider canvas + readable text cap ───────────────
   The chat page expands to fill the viewport (set inline by
   chat.html's pre-paint script to min(96vw, 1700px) when no user
   override is present). The right rail eats ~240px and the chat
   column should be generous.

   On wide chat layouts, Bubbles theme messages stay constrained
   by their own max-width rule (min(560px, 75%)). Classic and Guild
   don't have a bubble shape — a single long line could stretch
   the full chat-column width and become unreadable. Cap their
   text at a readable ~75ch. */
[data-kcc-theme="classic"] .kcc-msg__text,
[data-kcc-theme="guild"]   .kcc-msg__text {
  max-width: 75ch;
}

/* On the chat page specifically, the default kcc-inline height
   (100vh - 104px) was tuned to leave room for the floating dock
   below — which we hide on this page. Reclaim that ~80px so the
   card fills the viewport edge-to-edge. ~28px top (24px from the
   .kc-hero+* padding rule + 4px buffer) + 8px breathing room at
   the bottom. */
body[data-kc-page="chat"] .kcc-inline {
  height: calc(100vh - 32px - var(--kcc-nudge-h, 0px));   /* fallback */
  height: calc(100dvh - 32px - var(--kcc-nudge-h, 0px));  /* Safari/iOS: dvh
                                      tracks the dynamic viewport so the
                                      retracting URL bar can't leave a gap.
                                      --kcc-nudge-h gives back the tips-bar
                                      height when the nudge ticker is shown,
                                      otherwise the column overflows below. */
}
body[data-kc-page="chat"] .kcc-inline__rail {
  max-height: calc(100vh - 32px - var(--kcc-nudge-h, 0px));
  max-height: calc(100dvh - 32px - var(--kcc-nudge-h, 0px));
}
/* Left rail mirrors the right rail's chat-page height so both
   rails' bottom edges line up with the composer row. Without this
   override the left rail keeps the generic 100vh - 104px height
   and ends ~72px above the right rail — which both (a) leaves a
   misaligned bottom edge and (b) squeezes the pins module out of
   visible space at the bottom of the rail. */
body[data-kc-page="chat"] .kcc-inline__sidebar {
  height:     calc(100vh - 32px - var(--kcc-nudge-h, 0px));
  height:     calc(100dvh - 32px - var(--kcc-nudge-h, 0px));
  max-height: calc(100vh - 32px - var(--kcc-nudge-h, 0px));
  max-height: calc(100dvh - 32px - var(--kcc-nudge-h, 0px));
}

/* ─── Chat page — MOBILE keyboard-aware height ───────────────────────
   The desktop chat-page rule above pins the column to `100vh - 32px`.
   That selector (0,2,1) outranks the generic mobile `.kcc-inline` rule,
   so on phones the chat column was sized by the *large* iOS viewport,
   which ignores both the Safari toolbar and the on-screen keyboard —
   leaving the composer stranded with a dead strip below it, and letting
   the keyboard scroll the whole page away.

   The real sizing happens in JS (KCChat._sizeChatColumns): it measures
   the column's true top and sets an explicit px height down to the live
   window.visualViewport bottom, re-running on every viewport change.
   That inline height wins over the rule above. These CSS rules just
   (a) lock the body so only .kcc-stream scrolls — the keyboard can no
   longer drag the page off-screen — (b) reclaim the body's 60px dock
   pad (the dock is hidden on chat), and (c) provide a sane height before
   the JS measure lands. */
@media (max-width: 760px) {
  body[data-kc-page="chat"] {
    overflow: hidden;
    padding-bottom: 0 !important;
  }

  /* The quick-capture bar (#kcQcBar) is appended to <body> on every page
     and parked off-screen with position:fixed; bottom:0; translateY(100%).
     iOS yanks fixed bottom:0 elements into view when the keyboard opens,
     and with the body now scroll-locked it lands right over the composer
     (z-index 1500). Its opener — the dock pill — is already hidden on
     chat, and there's no ⌘I on a phone, so it has no business here. Kill
     it outright on mobile chat. (Desktop chat keeps ⌘I capture.) */
  body[data-kc-page="chat"] #kcQcBar { display: none !important; }

  /* Same story when the chat DRAWER is open over another page: it opens a
     keyboard, iOS yanks #kcQcBar up over the composer. The drawer sets
     body.kc-chat-drawer-open while open (KCChat.openPanel) — hide it then,
     just like on the chat page. */
  body.kc-chat-drawer-open #kcQcBar { display: none !important; }

  body[data-kc-page="chat"] .kcc-inline {
    /* Pinned out of the document flow so the iOS keyboard can't scroll
       the column (and the composer) away. KCChat._sizeChatColumns measures
       the in-flow chat host and feeds these vars so the fixed column lands
       exactly where the in-flow one did, then shrinks to the live visual
       viewport when the keyboard opens. Fallbacks cover the pre-JS paint. */
    position: fixed;
    top: var(--kcc-top, 96px);
    left: var(--kcc-left, 16px);
    width: var(--kcc-width, calc(100vw - 32px));
    height: var(--kcc-col-h, calc(100dvh - 96px));
    max-height: none;
    z-index: 5;
  }

  /* Inside the off-canvas rails panel the rails flow with the panel's
     own scroll — drop the desktop fixed heights the chat-page rules
     above forced on them. */
  body[data-kc-page="chat"] .kcc-inline__rail,
  body[data-kc-page="chat"] .kcc-inline__sidebar {
    height: auto;
    max-height: none;
  }
}

/* ─── Right-rail SOUND toggle ────────────────────────────────────
   Single-button on/off control below the theme picker. Matches the
   theme button chrome (border, padding, hover) for visual rhythm,
   with an "on/off" state pill on the right edge that lights up in
   brass when active. Default state is ON. */
.kcc-rail-head--sound {
  margin-top: 22px;
}
.kcc-sound-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 8px 10px;
  margin-top: 10px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-sound-toggle:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 4%, transparent);
}
.kcc-sound-toggle__label {
  font-weight: 500;
}
.kcc-sound-toggle__state {
  font-size: 10px;
  font-family: 'Space Mono', monospace;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--text) 8%, transparent);
  color: var(--muted);
  transition: background 120ms ease, color 120ms ease;
}
.kcc-sound-toggle.is-on .kcc-sound-toggle__state {
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  color: var(--brass, #d4a335);
}

/* ─── Right-rail admin moderation — admin icons live in
   .kcc-rail-head__icon at the top, next to the count chip. The
   labeled MODERATION block was removed in favor of compact icons.
   Styles for those icons are in the .kcc-rail-head section above. */

/* ════════════════════════════════════════════════════════════════
   CHAT SETTINGS CLUSTER — right-rail pinned-to-bottom panel.

   Three inline rows (Theme / Color / Sound), each with a small
   uppercase label on the left and compact controls on the right.
   The cluster is the rail's last flex child (flex:0 0 auto) and the
   online list above it (.kcc-presence) is flex:1, so the list fills the
   space and the cluster is always pinned to the bottom of the rail —
   the list scrolls internally when it overflows.
   ════════════════════════════════════════════════════════════════ */

/* Spacer — retired. The flex:1 online list now fills the space above
   the pinned cluster, so no spacer is needed. Kept as a zero-impact
   node (display:none) so any JS querying it still finds it. */
.kcc-rail-spacer {
  display: none;
}

/* Cluster shell — bordered panel with internal row dividers. */
.kcc-settings {
  background: color-mix(in srgb, var(--bg2, #14110f) 60%, transparent);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  flex: 0 0 auto;
}

/* One row per setting. Label (fixed width) on the left, controls
   right-aligned via margin-left:auto inside .kcc-set-row__opts. */
.kcc-set-row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
.kcc-set-row:last-child { border-bottom: none; }
.kcc-set-row__lbl {
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  min-width: 38px;
  flex-shrink: 0;
}
.kcc-set-row__opts {
  display: flex;
  gap: 4px;
  margin-left: auto;
  align-items: center;
}

/* ─── Theme icon buttons ─────────────────────────────────────────
   Square 26px buttons with the theme glyph centered. Unselected =
   muted color + neutral border. Selected = brass (palette self) +
   subtle tinted background. */
.kcc-set-btn {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border2);
  border-radius: 4px;
  color: var(--text-muted);
  padding: 0;
  cursor: pointer;
  transition: border-color 100ms ease, color 100ms ease, background 100ms ease;
}
.kcc-set-btn:hover {
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 30%, var(--border2));
  color: var(--text-bright);
}
.kcc-set-btn.is-on {
  border-color: var(--kcc-self, var(--brass, #d4a335));
  color: var(--kcc-self, var(--brass, #d4a335));
  background: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 6%, transparent);
}
.kcc-set-btn svg {
  width: 14px;
  height: 14px;
  display: block;
}

/* ─── Palette swatches ───────────────────────────────────────────
   Flat 22px squares with sharp 2px corners and a hairline border.
   Background is the palette's self color, full flat — no gradients,
   no radial blobs. Mirrors the .kcc-set-btn shape on its left so
   theme + color rows read as one coherent control strip.

   Selected swatch swaps to a darker self-tone background and shows a
   ✓ in the surface color, so the chip itself communicates which
   palette is active without an extra ring. */
.kcc-set-color {
  width: 22px;
  height: 22px;
  border-radius: 2px;
  border: 1px solid var(--border2);
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  position: relative;
  transition: border-color 100ms ease, transform 80ms ease;
}
.kcc-set-color:hover {
  transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--kcc-self, var(--brass, #d4a335)) 40%, var(--border2));
}
.kcc-set-color.is-on {
  border-color: var(--text-bright, #fff);
}
.kcc-set-color.is-on::after {
  content: '✓';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  color: rgba(0, 0, 0, 0.75);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  pointer-events: none;
}

/* Per-palette swatch backgrounds — single flat fill = the palette's
   self color. The ✓ on the selected chip flips to a contrasting tone
   per chip so it reads on every background. */
.kcc-set-color--brass    { background: #d4a335; }
.kcc-set-color--slate    { background: #6db6e8; }
.kcc-set-color--midnight { background: #7eb8e8; }
.kcc-set-color--sage     { background: #c0b86a; }
.kcc-set-color--oxblood  { background: #e09a8a; }

/* ─── Sound row — reuses .kcc-set-btn from the theme row (same 26px
   square chips), so no new styles needed. The OFF button is just
   the first .kcc-set-btn in the row; selection follows the same
   .is-on convention. ────────────────────────────────────────────── */

/* ─── Bulk-select mode: per-message checkbox + selection state ───
   When body.kcc-select-mode is active, every .kcc-msg shows a
   leading checkbox column. Selected rows get a brass tint and
   subtle inset to feel "lifted". The hover toolbar is suppressed
   for the duration (its actions are irrelevant in select mode). */
.kcc-msg__checkbox {
  display: flex;
  align-items: flex-start;
  padding-top: 4px;
  flex-shrink: 0;
  cursor: pointer;
  user-select: none;
}
.kcc-msg__checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--brass, #d4a335);
}

/* Make the whole row clickable in select mode — cursor signals it. */
body.kcc-select-mode .kcc-msg[data-kcc-selectable] {
  cursor: pointer;
}
/* Selected row — soft brass background + left rail accent. */
.kcc-msg--selected {
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
  border-radius: 6px;
}
.kcc-msg--selected .kcc-msg__text {
  /* Slight border boost so the selection is obvious even on Bubbles
     where the row bg sits behind the bubble. */
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border)) !important;
}

/* In Bubbles theme, place the checkbox in the avatar column for
   non-self messages, and replace the avatar with the checkbox
   visually (avatar is non-essential in admin mode). */
[data-kcc-theme="bubbles"].kcc-select-mode .kcc-msg .kcc-msg__avatar,
body.kcc-select-mode [data-kcc-theme="bubbles"] .kcc-msg .kcc-msg__avatar {
  /* In select mode, hide the avatar so the checkbox can take its
     spot. Keep the width so layout stays stable. */
  visibility: hidden;
}

/* ─── Moderation action bar (sticky, bottom of chat column) ──────
   Appears when select mode is on. Sits ABOVE the composer (which
   is inside .kcc-inline__main) — the bar is appended to the main
   column after the composer. Renders as a fixed-position pill at
   the bottom-center of the chat column. */
.kcc-mod-bar {
  position: sticky;
  bottom: 12px;
  margin: 0 14px 12px;
  padding: 8px 12px;
  background: color-mix(in srgb, var(--card) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 45%, var(--border));
  border-radius: 10px;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
  z-index: 10;
  animation: kcc-mod-bar-in 160ms ease-out;
}
@keyframes kcc-mod-bar-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.kcc-mod-bar.is-busy {
  opacity: 0.6;
  pointer-events: none;
}
.kcc-mod-bar__count {
  display: flex;
  align-items: baseline;
  gap: 5px;
}
.kcc-mod-bar__count-n {
  font-size: 14px;
  font-weight: 600;
  color: var(--brass, #d4a335);
}
.kcc-mod-bar__count-label {
  color: var(--text-mid, #c8c2b4);
}
.kcc-mod-bar__actions {
  display: flex;
  gap: 6px;
}
.kcc-mod-bar__btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  padding: 5px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.kcc-mod-bar__btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border-color: color-mix(in srgb, var(--text) 25%, var(--border));
}
.kcc-mod-bar__btn--danger {
  background: var(--red, #a83232);
  border-color: var(--red, #a83232);
  color: #ffffff;
  font-weight: 600;
}
.kcc-mod-bar__btn--danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--red, #a83232) 88%, #ffffff 12%);
  border-color: color-mix(in srgb, var(--red, #a83232) 88%, #ffffff 12%);
}
.kcc-mod-bar__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Hide the moderation bar host element entirely when empty so it
   doesn't take up sticky space when select mode is off. */
[data-kc="moderation-bar"]:empty {
  display: none;
}

/* ════════════════════════════════════════════════════════════════════
   KCSignalChart — modal chart view for shared signals in The Floor.
   Opens when a user clicks a .kcc-msg__signal card in chat.
   Layout mirrors the in-stream signal card (scanner pill, symbol,
   side, levels, action footer) but expanded to fit a 360px chart and
   action buttons. Singleton overlay (#kccChartModal); see shared.js
   KCSignalChart module for the lifecycle.
   ════════════════════════════════════════════════════════════════════ */
.kcc-chart-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(5, 5, 10, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  /* Above kc-dlg-overlay (2400) so confirm dialogs from inside the
     modal (e.g. tracking a setup) layer correctly. */
  z-index: 2500;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s;
}
.kcc-chart-modal-overlay.show {
  opacity: 1;
  pointer-events: auto;
}
.kcc-chart-modal {
  width: 100%;
  max-width: 880px;
  max-height: calc(96vh / var(--kc-font-scale, 1));
  background: #0e1217;
  border: 1px solid #2a323e;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.55);
  transform: translateY(8px) scale(0.98);
  transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
.kcc-chart-modal-overlay.show .kcc-chart-modal {
  transform: translateY(0) scale(1);
}

/* ── Head ─────────────────────────────────────────────────── */
.kcc-chart-modal__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid #1f2731;
  background: #11161c;
  flex-shrink: 0;
}
.kcc-chart-modal__scanner {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brass, #d4a335);
  padding: 3px 8px;
  border: 1px solid rgba(212, 163, 53, 0.35);
  border-radius: 3px;
  white-space: nowrap;
}
.kcc-chart-modal__symbol {
  font-family: 'Space Mono', monospace;
  font-size: 17px;
  font-weight: 500;
  color: #e5e7eb;
  letter-spacing: 0.02em;
}
.kcc-chart-modal__side {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 3px 8px;
  border-radius: 3px;
  border: 1px solid transparent;
}
.kcc-chart-modal__side:empty {
  display: none;
}
.kcc-chart-modal__side--long {
  color: var(--up, #1D9E75);
  background: rgba(29, 158, 117, 0.12);
  border-color: rgba(29, 158, 117, 0.35);
}
.kcc-chart-modal__side--short {
  color: var(--down, #d05a4a);
  background: rgba(208, 90, 74, 0.12);
  border-color: rgba(208, 90, 74, 0.35);
}
.kcc-chart-modal__meta {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  color: var(--text-mid, #888780);
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Inline pattern + PRZ chip inside the header meta line. The pattern
   gets a slightly lighter weight; the PRZ chip is a brass-bordered pill
   right after, so the eye reads "tf · pattern [PRZ x – y]". */
.kcc-chart-modal__meta-pat {
  color: #e5e7eb;
  font-weight: 500;
}
.kcc-chart-modal__meta-prz {
  font-size: 9px;
  color: var(--brass, #d4a335);
  padding: 2px 6px;
  border: 1px solid rgba(212, 163, 53, 0.3);
  border-radius: 3px;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.kcc-chart-modal__head-spacer {
  flex: 1;
}
.kcc-chart-modal__shared {
  font-size: 11px;
  color: var(--text-mid, #888780);
}
.kcc-chart-modal__shared:empty {
  display: none;
}
.kcc-chart-modal__shared-handle {
  color: var(--brass, #d4a335);
}
.kcc-chart-modal__close {
  background: transparent;
  border: none;
  color: var(--text-mid, #888780);
  font-size: 22px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
  transition: color 0.15s;
}
.kcc-chart-modal__close:hover {
  color: #e5e7eb;
}

/* ── Chart area ───────────────────────────────────────────── */
.kcc-chart-modal__chart {
  position: relative;
  height: 360px;
  background: #0e1217;
  border-bottom: 1px solid #1f2731;
  flex-shrink: 0;
}
.kcc-chart-modal__canvas {
  position: absolute;
  inset: 0;
}

/* ── DOM overlay layer ──────────────────────────────────────
   Sits on top of the LWC canvas. pointer-events: none so the
   user can still pan/zoom the chart through it. Children are
   absolutely positioned via priceToCoordinate / timeToCoordinate
   in the modal's repaint loop. */
.kcc-chart-modal__overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}

/* Pivot pill — brass-filled circle with the letter (X/A/B/C/D).
   24px × 24px so the letter is legible at standard chart density.
   Centered on the pivot's price coordinate. */
.kcc-chart-modal__pivot {
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  background: var(--brass, #d4a335);
  color: #0e1217;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  z-index: 3;
}
/* Projected D pivot — hollow box with dashed border, so the viewer
   reads it as "target zone" rather than "established pivot". */
.kcc-chart-modal__pivot--projected {
  background: rgba(212, 163, 53, 0.08);
  color: var(--brass, #d4a335);
  border: 1px dashed var(--brass, #d4a335);
  box-shadow: none;
}
/* PRZ SVG layer — sits inside the chart overlay, under labels and
   target chips. The rect element is positioned + sized by JS. */
.kcc-chart-modal__prz { z-index: 1; }

/* Pattern-name pill — sits below D (or above for bear setups).
   Brass background, dark text, slightly wider radius than the
   pivot pills so the eye reads it as a label, not a node. */
.kcc-chart-modal__name-pill {
  position: absolute;
  background: var(--brass, #d4a335);
  color: #0e1217;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 4px 9px;
  border-radius: 4px;
  white-space: nowrap;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  z-index: 3;
}

/* Target chip — anchored to the right end of each fan line.
   Two-part: small label ("T1") + price value. Teal-tinted so
   they read as "what you're projecting toward". */
.kcc-chart-modal__target-chip {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 3px;
  background: rgba(29, 158, 117, 0.18);
  border: 1px solid rgba(29, 158, 117, 0.45);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  white-space: nowrap;
  z-index: 3;
}
.kcc-chart-modal__target-lbl {
  color: var(--up, #1d9e75);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.kcc-chart-modal__target-val {
  color: #e5e7eb;
}

/* Ratio labels — visual KILL SWITCH. Even if a future code path
   resurrects them, or if an old cached signal payload somehow
   triggers a render, the labels stay hidden. The XAB/ABC/BCD/XAD
   Fib ratios are workbench-only diagnostic content; they have no
   business in the chat-shared signal modal. */
.kcc-chart-modal__ratio-lbl {
  display: none !important;
}

/* Last-price chip — floating pill on the right edge of the chart
   at the current closing price. Direction-tinted (teal up, oxblood
   down) like the scanner. */
.kcc-chart-modal__last-chip {
  position: absolute;
  padding: 3px 7px;
  border-radius: 3px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  color: #0e1217;
  white-space: nowrap;
  z-index: 3;
}
.kcc-chart-modal__last-chip--up   { background: var(--up,   #1d9e75); }
.kcc-chart-modal__last-chip--down { background: var(--down, #d05a4a); }

/* Level chips — entry/stop/target. Same right-edge anchor as the
   last-price chip but pinned to the level's price coordinate.
   Two-part: lowercase label + value, separated by a 1px divider
   so they read like the scanner's chips. */
.kcc-chart-modal__level-chip {
  position: absolute;
  display: flex;
  align-items: center;
  padding: 3px 0;
  border-radius: 3px;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  white-space: nowrap;
  z-index: 3;
  overflow: hidden;
}
.kcc-chart-modal__level-chip-lbl {
  padding: 0 6px 0 7px;
  color: rgba(14, 18, 23, 0.85);
  border-right: 1px solid rgba(14, 18, 23, 0.25);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.kcc-chart-modal__level-chip-val {
  padding: 0 7px 0 6px;
  color: #ffffff;
  font-weight: 700;
}
.kcc-chart-modal__level-chip--entry {
  background: var(--brass, #d4a335);
}
.kcc-chart-modal__level-chip--entry .kcc-chart-modal__level-chip-val {
  color: #0e1217;
}
.kcc-chart-modal__level-chip--stop {
  background: var(--down, #d05a4a);
}
.kcc-chart-modal__level-chip--target {
  background: var(--up, #1d9e75);
}
.kcc-chart-modal__level-chip--target .kcc-chart-modal__level-chip-val {
  color: #0e1217;
}
.kcc-chart-modal__loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-mid, #888780);
  pointer-events: none;
  /* Subtle pulse so the user knows something's happening on slow
     networks. */
  animation: kcc-chart-modal-pulse 1.4s ease-in-out infinite;
}
@keyframes kcc-chart-modal-pulse {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.85; }
}
.kcc-chart-modal__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 24px;
}
.kcc-chart-modal__fallback-icon {
  font-size: 22px;
  color: var(--amber, #f59e0b);
  opacity: 0.7;
}
.kcc-chart-modal__fallback-msg {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #e5e7eb;
}
.kcc-chart-modal__fallback-sub {
  font-size: 11px;
  color: var(--text-mid, #888780);
}

/* ── Levels strip (4 cells: entry / stop / target / R-R + PnL) ─ */
.kcc-chart-modal__levels {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid #1f2731;
  flex-shrink: 0;
}
.kcc-chart-modal__level-cell {
  padding: 10px 14px;
  border-right: 1px solid #1f2731;
}
.kcc-chart-modal__level-cell:last-child {
  border-right: none;
}
.kcc-chart-modal__level-lbl {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-mid, #888780);
  text-transform: uppercase;
  margin-bottom: 4px;
}
.kcc-chart-modal__level-val {
  font-family: 'Space Mono', monospace;
  font-size: 14px;
  color: #e5e7eb;
}
/* Per-cell value tints — match the scanner aesthetic so the eye can
   parse them at a glance without reading the label. */
[data-kc="cell-entry"] .kcc-chart-modal__level-val {
  color: var(--brass, #d4a335);
}
[data-kc="cell-stop"] .kcc-chart-modal__level-val {
  color: var(--down, #d05a4a);
}
[data-kc="cell-target"] .kcc-chart-modal__level-val {
  color: var(--up, #1D9E75);
}
.kcc-chart-modal__pnl--pos { color: var(--up, #1D9E75); margin-left: 8px; }
.kcc-chart-modal__pnl--neg { color: var(--down, #d05a4a); margin-left: 8px; }

/* ── Info strip (pattern · PRZ · grade) ───────────────────── */
.kcc-chart-modal__info {
  padding: 10px 16px;
  background: rgba(212, 163, 53, 0.03);
  border-bottom: 1px solid #1f2731;
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  font-size: 11px;
  flex-shrink: 0;
}
/* `[hidden]` is normally `display:none`, but our `display: flex` rule
   above overrides it. Reassert display:none for the hidden state so
   the strip collapses to zero height when empty (Dean: "that space is
   still there"). The strip is hidden by JS whenever infoBits is empty,
   which on harmonics is now always (pattern + PRZ moved to header). */
.kcc-chart-modal__info[hidden] { display: none; }
/* These overlays use display:flex/block as their base, which beats the
   UA [hidden] rule — so a plain hidden attribute won't hide them. Without
   these, hiding loading/fallback (e.g. once the snapshot image loads)
   silently fails and the "loading"/"chart unavailable" text paints on
   top of the image. Mirror the __info[hidden] pattern above. */
.kcc-chart-modal__loading[hidden],
.kcc-chart-modal__fallback[hidden],
.kcc-chart-modal__hudcard[hidden] { display: none !important; }
.kcc-chart-modal__info span {
  color: #e5e7eb;
}
.kcc-chart-modal__info em {
  color: var(--text-mid, #888780);
  font-style: normal;
  margin-right: 6px;
}
.kcc-chart-modal__info b {
  color: var(--brass, #d4a335);
  font-weight: 700;
}

/* ── Action row ───────────────────────────────────────────── */
.kcc-chart-modal__actions {
  /* Tighter top padding so the row sits flush against the levels
     row above (Dean's "remove empty space between ENTRY and TRACK
     SETUP" feedback). The visual separation comes from the levels
     row's border-bottom rather than padding. */
  padding: 8px 16px 12px;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.kcc-chart-modal__btn {
  background: transparent;
  color: #e5e7eb;
  border: 1px solid #2a323e;
  padding: 8px 14px;
  border-radius: 3px;
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  white-space: nowrap;
}
.kcc-chart-modal__btn:hover {
  background: rgba(255, 255, 255, 0.03);
  border-color: #3a424e;
}
.kcc-chart-modal__btn--primary {
  background: var(--brass, #d4a335);
  color: #0e1217;
  border-color: var(--brass, #d4a335);
  font-weight: 700;
}
.kcc-chart-modal__btn--primary:hover {
  background: #c19529;
  border-color: #c19529;
  color: #0e1217;
}
/* Track gated off while the Wallet is pre-launch. */
.kcc-chart-modal__btn.is-disabled,
.kcc-chart-modal__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
.kcc-chart-modal__actions-spacer {
  flex: 1;
  min-width: 8px;
}
.kcc-chart-modal__esc-hint {
  font-size: 10px;
  color: #5F5E5A;
  letter-spacing: 0.04em;
}

/* ── Snap-driven Option A extras ──────────────────────────────────
   Added when the sender's scanner stamped a sig.snap snapshot at
   share-time. Each block is independently rendered — HUD card when
   snap.setup is set, HUD strip when snap.hud has ≥2 fields,
   TP pillcolumn + labels when snap.targets has rungs, RTE SVG when
   snap.rte has points.
   ──────────────────────────────────────────────────────────────── */

/* Top-left HUD card — overlays the chart, sits inside .kcc-chart-modal__chart
   (which is position:relative). */
.kcc-chart-modal__hudcard {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 3;
  background: rgba(11, 14, 18, 0.85);
  border: 1px solid #2a323e;
  border-radius: 6px;
  padding: 7px 9px;
  min-width: 165px;
  font-family: 'Space Mono', monospace;
  pointer-events: none;
}
.kcc-chart-modal__hudcard-pills {
  display: flex;
  gap: 4px;
  margin-bottom: 5px;
}
.kcc-chart-modal__hudcard-pill {
  padding: 2px 5px;
  border: 1px solid #4b5563;
  border-radius: 3px;
  font-size: 8px;
  color: #9ca3af;
  letter-spacing: 0.06em;
}
.kcc-chart-modal__hudcard-pill.is-brass {
  color: #d4a335;
  border-color: rgba(212, 163, 53, 0.4);
}
.kcc-chart-modal__hudcard-pill.is-live {
  color: #4ec79f;
  border-color: rgba(78, 199, 159, 0.4);
}
.kcc-chart-modal__hudcard-name {
  font-size: 9px;
  color: #9ca3af;
  letter-spacing: 0.06em;
  margin: 2px 0;
}
.kcc-chart-modal__hudcard-name b { color: #e5e7eb; font-weight: 500; }
.kcc-chart-modal__hudcard-price {
  font-size: 13px;
  color: #e5e7eb;
  margin: 2px 0;
}
.kcc-chart-modal__hudcard-meta {
  display: flex;
  gap: 10px;
  font-size: 8px;
  color: #6b7280;
  padding-top: 5px;
  border-top: 1px solid #1f2731;
  margin-top: 5px;
  white-space: nowrap;
}
.kcc-chart-modal__hudcard-stop { color: #e24b4a; }
.kcc-chart-modal__hudcard-t    { color: #4ec79f; }

/* TP ladder pricebox — two-part pill on the right edge.
   Position is set inline via JS (top/right). */
.kcc-chart-modal__tp-pricebox {
  position: absolute;
  display: flex;
  align-items: stretch;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  pointer-events: none;
  transform: translateY(-50%);
}
.kcc-chart-modal__tp-px {
  padding: 2px 6px;
  background: #1d2129;
  color: #e5e7eb;
  border: 1px solid;
  border-right: none;
  border-radius: 3px 0 0 3px;
}
.kcc-chart-modal__tp-pct {
  padding: 2px 5px;
  border-radius: 0 3px 3px 0;
  font-weight: 700;
}

/* TP ladder left-side label — "TP1 · LIQUIDITY" plus R/R subline.
   Lives in DOM overlay; positioned inline by JS. */
.kcc-chart-modal__tp-label {
  position: absolute;
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.05em;
  line-height: 1.1;
  pointer-events: none;
  white-space: nowrap;
}
.kcc-chart-modal__tp-label-kn { display: block; font-weight: 700; }
.kcc-chart-modal__tp-label-rr { display: block; font-size: 8px; opacity: 0.7; margin-top: 1px; }

/* RTE SVG layer — sits over candles, under labels/pills. */
.kcc-chart-modal__rte {
  z-index: 1;
}

/* ── Mobile / narrow viewports ────────────────────────────── */
@media (max-width: 600px) {
  .kcc-chart-modal-overlay { padding: 12px; }
  .kcc-chart-modal__head { gap: 6px; padding: 10px 12px; flex-wrap: wrap; }
  .kcc-chart-modal__symbol { font-size: 15px; }
  .kcc-chart-modal__meta { width: 100%; order: 5; }
  .kcc-chart-modal__shared { display: none; }
  .kcc-chart-modal__chart { height: 260px; }
  .kcc-chart-modal__levels { grid-template-columns: repeat(2, 1fr); }
  .kcc-chart-modal__level-cell:nth-child(2) { border-right: none; }
  .kcc-chart-modal__level-cell:nth-child(1),
  .kcc-chart-modal__level-cell:nth-child(2) {
    border-bottom: 1px solid #1f2731;
  }
  .kcc-chart-modal__actions { padding: 10px 12px; }
  .kcc-chart-modal__btn { padding: 7px 10px; font-size: 10px; }
  .kcc-chart-modal__esc-hint { display: none; }

  /* ── Snap extras on mobile ─────────────────────────────────
     HUD card shrinks. */
  .kcc-chart-modal__hudcard {
    top: 6px;
    left: 6px;
    min-width: 130px;
    padding: 5px 7px;
  }
  .kcc-chart-modal__hudcard-price { font-size: 12px; }
  .kcc-chart-modal__hudcard-meta { gap: 6px; }
  /* TP labels overflow on tight viewports — clip with ellipsis
     instead of wrapping over the candles. */
  .kcc-chart-modal__tp-label {
    font-size: 8px;
    max-width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ══════════════════════════════════════════════════════════════════
   CHALLENGES — issuing modal + composer pill state + signal-card action
   ──────────────────────────────────────────────────────────────────
   Modal opens from:
     1. Composer "open challenge" pill (empty)
     2. Shared signal card → "challenge this" action (pre-filled)
   ══════════════════════════════════════════════════════════════════ */

/* ─── Composer "open challenge" pill ──────────────────────────────
   Sits next to the existing share-signal pill in .kcc-composer__toolbar.
   Same shape, brass tint already comes from the [data-state="on"] rule
   when KCChallenges modal is open. */
.kcc-composer__tool[data-kc="open-challenge"] svg {
  /* Swords icon — inline SVG sized via the existing 10x10 rule. */
}

/* ─── Modal overlay & shell ──────────────────────────────────────── */
.kcch-overlay {
  position: fixed; inset: 0;
  z-index: 9000;
  background: color-mix(in srgb, #000 70%, transparent);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 60px 20px 20px;
  overflow-y: auto;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.kcch-overlay.show {
  display: flex;
  animation: kcch-fadeIn 120ms ease;
}
@keyframes kcch-fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.kcch-modal {
  background: var(--panel, #13110d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 12px;
  width: 100%;
  max-width: 440px;
  overflow: hidden;
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  color: var(--text, #e8e3d4);
  animation: kcch-slideIn 160ms cubic-bezier(.2,.7,.3,1);
}
@keyframes kcch-slideIn {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ─── Modal header ───────────────────────────────────────────────── */
.kcch-mhead {
  display: flex;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 0.5px solid var(--border, #2a2620);
}
.kcch-mhead__title {
  font-size: 13px;
  color: var(--text, #e8e3d4);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
}
.kcch-mhead__title svg {
  width: 14px; height: 14px;
  color: var(--brass, #d4a335);
}
.kcch-mhead__help,
.kcch-mhead__close {
  background: none;
  border: 0;
  color: var(--text-muted, #6e6b63);
  cursor: pointer;
  width: 24px; height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-family: inherit;
  font-size: 14px;
}
.kcch-mhead__help { margin-left: auto; }
.kcch-mhead__help:hover,
.kcch-mhead__close:hover {
  color: var(--brass, #d4a335);
  background: color-mix(in srgb, var(--brass, #d4a335) 8%, transparent);
}
.kcch-mhead__close svg,
.kcch-mhead__help svg { width: 14px; height: 14px; display: block; }

/* ─── Modal body ─────────────────────────────────────────────────── */
.kcch-mbody { padding: 14px 16px; }

.kcch-f { margin-bottom: 14px; }
.kcch-f:last-child { margin-bottom: 0; }
.kcch-fl {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-muted, #8a8780);
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
.kcch-fl b {
  color: var(--text, #cfcdc4);
  font-weight: 500;
}

/* ─── Segmented control (wager type, side, expiry) ──────────────── */
.kcch-seg {
  display: flex;
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 7px;
  padding: 2px;
}
.kcch-seg button {
  flex: 1;
  background: none;
  border: 0;
  color: var(--text-muted, #8a8780);
  padding: 7px 8px;
  font-size: 12px;
  border-radius: 5px;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms ease, color 120ms ease;
}
.kcch-seg button:hover { color: var(--text, #cfcdc4); }
.kcch-seg button.on {
  background: var(--panel-deep-2, #1f1a14);
  color: var(--text, #e8e3d4);
}
/* Side seg gets up/down semantic colors when picked */
.kcch-seg--side button.on[data-side="fires"],
.kcch-seg--side button.on[data-side="yes"] {
  color: var(--up, #5acf7a);
}
.kcch-seg--side button.on[data-side="stops"],
.kcch-seg--side button.on[data-side="no"] {
  color: var(--down, #e2786a);
}
/* Target seg — which TP the wager resolves at. Selected chip goes brass;
   the price label below the T-number stays dim + mono. */
.kcch-seg--tgt button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  line-height: 1.15;
  font-weight: 700;
}
.kcch-seg--tgt button.on {
  color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
}
.kcch-seg__px {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 400;
  color: var(--text-muted, #8a8780);
}
.kcch-seg--tgt button.on .kcch-seg__px {
  color: color-mix(in srgb, var(--accent, #d4a335) 75%, var(--text, #e8e3d4));
}

/* ─── Attached signal / market chip ──────────────────────────────── */
.kcch-attach {
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.kcch-attach--empty {
  cursor: pointer;
  border-style: dashed;
  color: var(--text-muted, #6e6b63);
  font-size: 12px;
  justify-content: center;
  padding: 16px;
  text-align: center;
  gap: 8px;
  min-height: 0;
}
.kcch-attach--empty svg {
  width: 14px;
  height: 14px;
  flex: none;
}
.kcch-attach--empty:hover {
  border-color: var(--brass-dim, #3a2a18);
  color: var(--brass, #d4a335);
}
.kcch-attach__ic {
  width: 30px; height: 30px;
  border-radius: 6px;
  background: var(--panel-deep-2, #1f1a14);
  color: var(--brass, #d4a335);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.kcch-attach__ic svg { width: 14px; height: 14px; }
.kcch-attach__body { flex: 1; min-width: 0; }
.kcch-attach__line1 {
  font-size: 12.5px;
  color: var(--text, #e8e3d4);
  margin-bottom: 2px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.kcch-attach__line1 b { font-weight: 500; }
.kcch-attach__line1 .dim {
  color: var(--text-muted, #8a8780);
  font-size: 11px;
}
.kcch-attach__line2 {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-attach__change {
  background: none; border: 0;
  color: var(--text-muted, #6e6b63);
  font-size: 11px;
  cursor: pointer;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: inherit;
}
.kcch-attach__change:hover { color: var(--brass, #d4a335); }
.kcch-pill-long {
  font-size: 10px;
  background: color-mix(in srgb, var(--up, #5acf7a) 18%, transparent);
  color: var(--up, #5acf7a);
  padding: 1px 6px;
  border-radius: 3px;
  letter-spacing: 0.04em;
}
.kcch-pill-short {
  font-size: 10px;
  background: color-mix(in srgb, var(--down, #e2786a) 18%, transparent);
  color: var(--down, #e2786a);
  padding: 1px 6px;
  border-radius: 3px;
  letter-spacing: 0.04em;
}

/* ─── Stake input ────────────────────────────────────────────────── */
.kcch-stake {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 8px;
  padding: 10px 12px;
}
.kcch-stake input {
  flex: 1;
  background: none;
  border: 0;
  color: var(--text, #e8e3d4);
  font-size: 18px;
  font-family: inherit;
  outline: none;
  font-weight: 500;
  min-width: 0;
}
.kcch-stake input::-webkit-outer-spin-button,
.kcch-stake input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.kcch-stake__unit {
  font-size: 11px;
  color: var(--text-muted, #8a8780);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.kcch-quick {
  display: flex;
  gap: 5px;
  margin-top: 7px;
}
.kcch-quick button {
  flex: 1;
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  color: var(--text-muted, #8a8780);
  font-size: 11px;
  padding: 5px 0;
  border-radius: 5px;
  cursor: pointer;
  font-family: inherit;
}
.kcch-quick button:hover {
  border-color: var(--brass-dim, #3a2a18);
  color: var(--brass, #d4a335);
}
.kcch-quick button.on {
  border-color: var(--brass-dim, #3a2a18);
  background: var(--brass-bg, #1a1410);
  color: var(--brass, #d4a335);
}

/* ─── Audience (@handle) input ──────────────────────────────────── */
.kcch-aud {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 8px;
  padding: 8px 10px;
}
.kcch-aud__ic {
  color: var(--text-muted, #6e6b63);
}
.kcch-aud__ic svg { width: 13px; height: 13px; display: block; }
.kcch-aud input {
  flex: 1;
  background: none;
  border: 0;
  color: var(--text, #e8e3d4);
  font-size: 13px;
  font-family: inherit;
  outline: none;
  min-width: 0;
}
.kcch-aud input::placeholder { color: var(--text-muted, #5f5c54); }

/* ─── Pot summary ────────────────────────────────────────────────── */
.kcch-pot {
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 8px;
  padding: 10px 12px;
  margin-top: 14px;
}
.kcch-pot__row {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-muted, #8a8780);
  margin-bottom: 3px;
}
.kcch-pot__row span:last-child {
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-pot__row.big {
  font-size: 13px;
  color: var(--text, #e8e3d4);
  font-weight: 500;
  margin-top: 6px;
  padding-top: 7px;
  border-top: 0.5px solid var(--border, #2a2620);
}
.kcch-pot__row.big .v {
  color: var(--brass, #d4a335);
}

/* ─── Balance line + footer ──────────────────────────────────────── */
.kcch-balance {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  text-align: right;
  padding: 0 16px 8px;
  margin-top: -4px;
}
.kcch-balance b {
  color: var(--brass, #d4a335);
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-balance--low { color: var(--down, #e2786a); }
.kcch-balance--low b { color: var(--down, #e2786a); }

.kcch-mfoot {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  border-top: 0.5px solid var(--border, #2a2620);
  background: var(--panel-foot, #0e0c0a);
}
.kcch-btn {
  flex: 1;
  background: var(--brass, #d4a335);
  color: #1a1410;
  border: 0;
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 10px;
  border-radius: 7px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: opacity 120ms ease;
}
.kcch-btn:hover:not(:disabled) {
  opacity: 0.92;
}
.kcch-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.kcch-btn--ghost {
  background: none;
  border: 0.5px solid var(--border, #2a2620);
  color: var(--text-muted, #8a8780);
}
.kcch-btn--ghost:hover:not(:disabled) {
  border-color: var(--brass-dim, #3a2a18);
  color: var(--text, #e8e3d4);
}
.kcch-btn svg { width: 12px; height: 12px; }

/* Posting/Loading spinner inside button */
.kcch-btn--loading {
  pointer-events: none;
}
.kcch-btn--loading::after {
  content: "";
  width: 11px; height: 11px;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  display: inline-block;
  animation: kcch-spin 600ms linear infinite;
  margin-left: 5px;
}
@keyframes kcch-spin { to { transform: rotate(360deg); } }

/* ─── Inline error message ──────────────────────────────────────── */
.kcch-error {
  background: color-mix(in srgb, var(--down, #e2786a) 12%, transparent);
  border: 0.5px solid color-mix(in srgb, var(--down, #e2786a) 30%, transparent);
  color: var(--down, #e2786a);
  font-size: 11.5px;
  padding: 8px 10px;
  border-radius: 6px;
  margin: 0 16px 8px;
}

/* ─── Sub-picker overlay (select tracked signal) ─────────────────── */
.kcch-picker {
  background: var(--panel, #13110d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 12px;
  width: 100%;
  max-width: 440px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  color: var(--text, #e8e3d4);
}
.kcch-picker__head {
  display: flex;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 0.5px solid var(--border, #2a2620);
}
.kcch-picker__title {
  font-size: 12.5px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
}
.kcch-picker__back {
  background: none;
  border: 0;
  color: var(--text-muted, #6e6b63);
  font-size: 13px;
  cursor: pointer;
  padding: 4px 6px;
  margin-right: 4px;
  font-family: inherit;
  display: inline-flex; align-items: center;
}
.kcch-picker__back:hover { color: var(--brass, #d4a335); }
.kcch-picker__back svg { width: 12px; height: 12px; }
.kcch-picker__body {
  overflow-y: auto;
  padding: 6px 0;
}
.kcch-picker__section-label {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted, #6e6b63);
  padding: 10px 14px 4px;
}
.kcch-picker__row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  cursor: pointer;
}
.kcch-picker__row:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
}
.kcch-picker__row-body {
  flex: 1;
  min-width: 0;
}
.kcch-picker__row-line1 {
  font-size: 12.5px;
  color: var(--text, #e8e3d4);
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 1px;
}
.kcch-picker__row-line2 {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-picker__empty {
  padding: 24px 14px;
  text-align: center;
  font-size: 11.5px;
  color: var(--text-muted, #6e6b63);
}

/* ─── In-chat "challenge this" action on signal messages ─────────
   Sits in the existing .kcc-msg__toolbar alongside react / reply. */
.kcc-msg__tb-btn[data-kc="challenge-open"] {
  /* Hook for hover-tinting if needed; inherits .kcc-msg__tb-btn defaults */
}


/* ══════════════════════════════════════════════════════════════════
   IN-CHAT CHALLENGE CARD — rendered inside .kcc-msg__body via
   _renderChallengeCard. Three states: open / locked / settled
   (+ void/expired/refunded fallback).
   ══════════════════════════════════════════════════════════════════ */
.kcc-msg__chal {
  margin-top: 6px;
  max-width: 380px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--red, #a83232) 7%, transparent) 0%,
    color-mix(in srgb, var(--red, #a83232) 2%, transparent) 100%);
  border: 1px solid color-mix(in srgb, var(--red, #a83232) 35%, var(--border, #2a2620));
  border-left: 3px solid var(--red, #a83232);
  border-radius: 6px;
  padding: 8px 10px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  transition: border-color 120ms ease, background 120ms ease;
}
.kcc-msg__chal:hover {
  border-color: color-mix(in srgb, var(--red, #a83232) 55%, var(--border, #2a2620));
  border-left-color: var(--red, #a83232);
}
.kcc-msg__chal--locked {
  border-color: color-mix(in srgb, var(--up, #5acf7a) 30%, var(--border, #2a2620));
  border-left-color: var(--up, #5acf7a);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--up, #5acf7a) 5%, transparent) 0%,
    transparent 100%);
}
.kcc-msg__chal--settled {
  border-color: color-mix(in srgb, var(--up, #5acf7a) 25%, var(--border, #2a2620));
  border-left-color: var(--up, #5acf7a);
  opacity: 0.96;
}
.kcc-msg__chal--void {
  border-color: color-mix(in srgb, var(--text-muted, #6e6b63) 30%, var(--border, #2a2620));
  border-left-color: var(--text-muted, #6e6b63);
  opacity: 0.85;
}
.kcc-msg__chal--loading {
  opacity: 0.6;
}

.kcc-msg__chal-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.kcc-msg__chal-icon {
  color: var(--red, #d05a4a);
  flex: none;
}
.kcc-msg__chal--locked .kcc-msg__chal-icon { color: var(--up, #5acf7a); }
.kcc-msg__chal--settled .kcc-msg__chal-icon { color: var(--up, #5acf7a); }
.kcc-msg__chal--void .kcc-msg__chal-icon { color: var(--text-muted, #6e6b63); }

.kcc-msg__chal-eyebrow {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--red, #d05a4a);
  font-weight: 500;
}
.kcc-msg__chal-eyebrow--locked  { color: var(--up, #5acf7a); }
.kcc-msg__chal-eyebrow--settled { color: var(--up, #5acf7a); }
.kcc-msg__chal-eyebrow--void    { color: var(--text-muted, #6e6b63); }

.kcc-msg__chal-dot {
  color: var(--text-muted, #3a3a3f);
  font-size: 10px;
}
.kcc-msg__chal-time {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  margin-left: auto;
}

/* Target row (subject + side label) */
.kcc-msg__chal-target-row {
  font-size: 11.5px;
  color: var(--text, #e8e3d4);
  margin-bottom: 6px;
  line-height: 1.4;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
}
.kcc-msg__chal-target-row b {
  color: var(--brass, #d4a335);
  font-weight: 500;
}
.kcc-msg__chal-subj {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.kcc-msg__chal-target {
  color: var(--text-muted, #cfcdc4);
  font-size: 12px;
}

/* Direction pills */
.kcc-msg__chal-pill {
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  letter-spacing: 0.04em;
  font-weight: 500;
}
.kcc-msg__chal-pill--long {
  background: color-mix(in srgb, var(--up, #5acf7a) 18%, transparent);
  color: var(--up, #5acf7a);
}
.kcc-msg__chal-pill--short {
  background: color-mix(in srgb, var(--down, #e2786a) 18%, transparent);
  color: var(--down, #e2786a);
}

/* Tag-lock notice */
.kcc-msg__chal-tagnote {
  font-size: 10px;
  color: var(--text-muted, #8a8780);
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
  padding: 3px 7px;
  border-radius: 3px;
  margin-bottom: 5px;
}
.kcc-msg__chal-tagnote b { color: var(--brass, #d4a335); font-weight: 500; }

/* Pot row — single line. Label run on the left (allowed to truncate
   if exceptionally long), value on the right in mono. Padding is
   smaller than the old two-line block since there's only one row of
   content to breathe around. */
.kcc-msg__chal-pot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 5px;
  padding: 5px 10px;
  margin-bottom: 6px;
}
.kcc-msg__chal-pot-lbl {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted, #8a8780);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* LEGACY — .kcc-msg__chal-pot-sub is no longer emitted (the pot row
   collapsed to a single inline label). Kept defined for any cached
   stream HTML so it paints sanely until rotated out. */
.kcc-msg__chal-pot-sub {
  font-size: 9.5px;
  color: var(--text-muted, #6e6b63);
  margin-top: 1px;
}
.kcc-msg__chal-pot-val {
  font-size: 14px;
  color: var(--red, #d05a4a);
  font-weight: 500;
  font-family: 'Space Mono', ui-monospace, monospace;
  flex-shrink: 0;
}
.kcc-msg__chal--locked .kcc-msg__chal-pot-val { color: var(--up, #5acf7a); }
.kcc-msg__chal--settled .kcc-msg__chal-pot-val { color: var(--up, #5acf7a); }
.kcc-msg__chal--settled .kcc-msg__chal-pot-lbl { color: var(--brass, #d4a335); }
.kcc-msg__chal--settled .kcc-msg__chal-pot {
  background: color-mix(in srgb, var(--up, #5acf7a) 5%, transparent);
  border-color: color-mix(in srgb, var(--up, #5acf7a) 20%, transparent);
}

/* Sides row — original two-column grid layout. The --line variant
   (set on locked / open / settled sides rows) collapses to a single
   horizontal "@A SIDE · 100r  vs  @B SIDE · 100r" line. The state
   tinting (--taken / --won / --lost / --empty) still applies inline
   via color overrides on the side spans. */
.kcc-msg__chal-sides {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
  margin-bottom: 6px;
}
.kcc-msg__chal-sides--line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 0;
  font-size: 11.5px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), system-ui, sans-serif;
  line-height: 1.4;
  flex-wrap: wrap;
}
/* "vs" separator — muted, mono, sits centered between the two sides
   and shrinks first if the row wraps. */
.kcc-msg__chal-vs {
  color: var(--text-muted, #6e6b63);
  font-size: 10px;
  font-family: 'Space Mono', ui-monospace, monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  flex: 0 0 auto;
  opacity: 0.8;
}
/* Side cell — keeps original panel styling for the two-column
   layout, but in --line context the panel chrome is stripped via
   the descendant override below. The state classes (--taken,
   --won, --lost) keep their color logic in both layouts. */
.kcc-msg__chal-side {
  background: var(--panel-deep, #0b0b0d);
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 5px;
  padding: 5px 8px;
  text-align: center;
}
/* --line override: drop panel chrome, let the side flow inline. */
.kcc-msg__chal-sides--line .kcc-msg__chal-side {
  background: transparent;
  border: 0;
  padding: 0;
  text-align: left;
  flex: 1 1 0;
  min-width: 0;
  color: var(--text, #e8e3d4);
}
/* Right-side cell on the line layout right-aligns its text so the
   row reads symmetrically with "vs" in the middle. */
.kcc-msg__chal-sides--line .kcc-msg__chal-side + .kcc-msg__chal-vs + .kcc-msg__chal-side {
  text-align: right;
}
.kcc-msg__chal-side--taken {
  border-color: color-mix(in srgb, var(--red, #a83232) 28%, transparent);
  background: color-mix(in srgb, var(--red, #a83232) 6%, transparent);
}
.kcc-msg__chal--locked .kcc-msg__chal-side--taken {
  border-color: color-mix(in srgb, var(--up, #5acf7a) 28%, transparent);
  background: color-mix(in srgb, var(--up, #5acf7a) 6%, transparent);
}
.kcc-msg__chal-side--won {
  border-color: color-mix(in srgb, var(--up, #5acf7a) 30%, transparent);
  background: color-mix(in srgb, var(--up, #5acf7a) 8%, transparent);
}
.kcc-msg__chal-side--lost {
  opacity: 0.55;
}
.kcc-msg__chal-side-lbl {
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted, #8a8780);
  margin-bottom: 1px;
}
/* In --line layout, the side-lbl ("YES"/"NO"/"FIRES"/etc.) sits
   inline between the handle and the amount, not stacked above. */
.kcc-msg__chal-sides--line .kcc-msg__chal-side-lbl {
  display: inline;
  margin-bottom: 0;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 10px;
  font-weight: 600;
}
.kcc-msg__chal--locked .kcc-msg__chal-sides--line .kcc-msg__chal-side-lbl {
  color: var(--up, #5acf7a);
}
.kcc-msg__chal-sides--line .kcc-msg__chal-side--won .kcc-msg__chal-side-lbl {
  color: var(--up, #5acf7a);
}
.kcc-msg__chal-sides--line .kcc-msg__chal-side--lost .kcc-msg__chal-side-lbl {
  color: var(--text-muted, #8a8780);
}
.kcc-msg__chal-side--won .kcc-msg__chal-side-lbl { color: var(--up, #5acf7a); }
.kcc-msg__chal-side-who {
  font-size: 11px;
  color: var(--text, #e8e3d4);
  font-weight: 500;
}
.kcc-msg__chal-side-who--empty {
  color: var(--text-muted, #5f5c54);
  font-style: italic;
  font-weight: 400;
}
.kcc-msg__chal-side-who .pos { color: var(--up, #5acf7a); }
.kcc-msg__chal-side-who .neg { color: var(--down, #e2786a); }
/* --line layout: pos/neg classes live directly on the side span. */
.kcc-msg__chal-sides--line .pos { color: var(--up, #5acf7a); font-family: 'Space Mono', ui-monospace, monospace; }
.kcc-msg__chal-sides--line .neg { color: var(--down, #e2786a); font-family: 'Space Mono', ui-monospace, monospace; }
/* Handle bold weight uses 500 not 700 — sits on a tinted background,
   doesn't need to shout. */
.kcc-msg__chal-sides--line .kcc-msg__chal-side b {
  font-weight: 500;
  color: var(--text-bright, var(--text));
}

/* Actions row */
.kcc-msg__chal-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}
/* When the actions row sits right after a single-line sides row,
   the sides row has margin-bottom:0 (it doesn't separate the way the
   two-column grid did). Restore a small top inset on the buttons. */
.kcc-msg__chal-sides--line + .kcc-msg__chal-actions {
  margin-top: 6px;
}
.kcc-msg__chal-take,
.kcc-msg__chal-cancel {
  flex: 1;
  background: var(--brass, #d4a335);
  color: #1a1410;
  border: 0;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 5px 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: opacity 120ms ease;
}
.kcc-msg__chal-take:hover:not(:disabled),
.kcc-msg__chal-cancel:hover:not(:disabled) { opacity: 0.92; }
.kcc-msg__chal-take:disabled,
.kcc-msg__chal-cancel:disabled { opacity: 0.5; cursor: not-allowed; }
.kcc-msg__chal-cancel {
  background: none;
  border: 0.5px solid color-mix(in srgb, var(--down, #e2786a) 30%, transparent);
  color: var(--down, #e2786a);
}
.kcc-msg__chal-cancel:hover:not(:disabled) {
  background: color-mix(in srgb, var(--down, #e2786a) 8%, transparent);
}
.kcc-msg__chal-await {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  text-align: center;
  flex: 1;
  padding: 4px 0;
  font-style: italic;
}

/* ── Odds strip — open PREDICT challenges only. One divided container,
   two halves of equal (side pill + price + implied %) rows so a third-
   party viewer can see whether the open side is the favourite or the
   underdog. Naturally balanced — no stake rows to mismatch. Signal
   challenges + locked/settled states keep the .kcc-msg__chal-sides--line
   row above. ─────────────────────────────────────────────────────── */
.kcc-msg__chal-strip {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  border: 0.5px solid var(--border, #2a2620);
  border-radius: 6px;
  overflow: hidden;
  background: var(--panel-deep, #0b0b0d);
  margin-bottom: 0;
}
.kcc-msg__chal-strip + .kcc-msg__chal-actions {
  margin-top: 6px;
}
.kcc-msg__chal-strip-half {
  padding: 8px 11px;
  min-width: 0;
}
.kcc-msg__chal-strip-div {
  background: var(--border, #2a2620);
}
/* The open (takeable) side gets a faint oxblood wash so the eye lands
   on the slot the viewer would fill — the Take button names it too. */
.kcc-msg__chal-strip-half--open {
  background: color-mix(in srgb, var(--down, #e2786a) 6%, transparent);
}
.kcc-msg__chal-lcell-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-bottom: 5px;
}
/* Side pills — reuse .kcc-msg__chal-pill sizing; yes/no tints mirror
   the in-chat bet card (.kcc-msg__bet-side.yes / .no). */
.kcc-msg__chal-pill--yes {
  background: color-mix(in srgb, var(--up, #5acf7a) 16%, transparent);
  color: var(--up, #5acf7a);
}
.kcc-msg__chal-pill--no {
  background: color-mix(in srgb, var(--down, #e2786a) 16%, transparent);
  color: var(--down, #e2786a);
}
.kcc-msg__chal-lcell-imp {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  flex: 0 0 auto;
}
.kcc-msg__chal-lcell-imp--yes { color: var(--up, #5acf7a); }
.kcc-msg__chal-lcell-imp--no  { color: var(--down, #e2786a); }
.kcc-msg__chal-lcell-mid {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-bright, var(--text));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kcc-msg__chal-lcell-impd {
  color: var(--text-muted, #8a8780);
  font-weight: 400;
  font-size: 10px;
}

/* "even money" qualifier in the pot label (open predict only). Wrapped
   in a left group beside the ellipsizing label so the flex row still
   reads label-left / value-right. */
.kcc-msg__chal-pot-lblwrap {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}
.kcc-msg__chal-evenmoney {
  flex: 0 0 auto;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--text-mid, #c8c2b4);
  background: color-mix(in srgb, var(--text, #f1ece1) 5%, transparent);
  border-radius: 4px;
  padding: 1px 6px;
}



/* ══════════════════════════════════════════════════════════════════
   IN-CHAT BET CARD — rendered inside .kcc-msg__body via _renderBetCard.
   Four states: open (brass) / won (green) / lost (red) / void (muted).
   Action row (Tail + Challenge) lives OUTSIDE the <a> so button clicks
   don't trigger venue navigation. Mirrors .kcc-msg__signal shape — the
   eye doesn't have to relearn the card layout when bets land alongside
   signals.
   ══════════════════════════════════════════════════════════════════ */
.kcc-msg__bet {
  display: block;
  margin-top: 8px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--blue, #8a96a3) 5%, var(--bg2, var(--bg)));
  border: 1px solid var(--border);
  border-left: 2px solid var(--blue, #8a96a3);
  border-radius: 0 6px 6px 0;
  text-decoration: none;
  color: inherit;
  max-width: 380px;
  transition: border-color 120ms ease, background 120ms ease;
  cursor: pointer;
}
.kcc-msg__bet:hover {
  border-color: color-mix(in srgb, var(--blue, #8a96a3) 50%, var(--border));
  background: color-mix(in srgb, var(--blue, #8a96a3) 9%, var(--bg2, var(--bg)));
}
.kcc-msg__bet.is-won {
  border-left-color: var(--up, #4dd99a);
  background: color-mix(in srgb, var(--up, #4dd99a) 4%, var(--bg2, var(--bg)));
}
.kcc-msg__bet.is-won:hover {
  background: color-mix(in srgb, var(--up, #4dd99a) 7%, var(--bg2, var(--bg)));
  border-color: color-mix(in srgb, var(--up, #4dd99a) 50%, var(--border));
}
.kcc-msg__bet.is-lost {
  border-left-color: var(--red, #d05a4a);
  background: color-mix(in srgb, var(--red, #d05a4a) 4%, var(--bg2, var(--bg)));
}
.kcc-msg__bet.is-lost:hover {
  background: color-mix(in srgb, var(--red, #d05a4a) 7%, var(--bg2, var(--bg)));
  border-color: color-mix(in srgb, var(--red, #d05a4a) 50%, var(--border));
}
.kcc-msg__bet.is-void {
  border-left-color: var(--text-muted, #828a96);
  background: var(--bg2, var(--bg));
  opacity: 0.92;
}

/* Head row: venue · side · meta/outcome */
.kcc-msg__bet-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
  flex-wrap: wrap;
}
.kcc-msg__bet-venue {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--brass, #d4a335) 14%, transparent);
  color: var(--brass, #d4a335);
  font-weight: 500;
  flex-shrink: 0;
  text-transform: uppercase;
}
.kcc-msg__bet-side {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.kcc-msg__bet-side.yes { color: var(--up, #4dd99a); }
.kcc-msg__bet-side.no  { color: var(--red, #d05a4a); }
.kcc-msg__bet-meta {
  font-size: 11px;
  color: var(--text-muted, #828a96);
  margin-left: auto;
  text-align: right;
  font-family: 'Space Mono', monospace;
}
.kcc-msg__bet-outcome {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 700;
  text-transform: uppercase;
  margin-left: auto;
}
.kcc-msg__bet-outcome.won {
  background: color-mix(in srgb, var(--up, #4dd99a) 20%, transparent);
  color: var(--up, #4dd99a);
}
.kcc-msg__bet-outcome.lost {
  background: color-mix(in srgb, var(--red, #d05a4a) 20%, transparent);
  color: var(--red, #d05a4a);
}
.kcc-msg__bet-outcome.void {
  background: color-mix(in srgb, var(--text-muted, #828a96) 15%, transparent);
  color: var(--text-muted, #828a96);
}

/* Question line */
.kcc-msg__bet-q {
  font-size: 13px;
  color: var(--text-bright, var(--text));
  font-weight: 500;
  line-height: 1.35;
  margin-bottom: 6px;
}
/* Inline strike suffix — when the question template doesn't have an
   underscore placeholder to substitute into, we tack the strike on
   at the end of the question line in muted mono. The leading " · "
   is part of the rendered text so spacing matches naturally. */
.kcc-msg__bet-q-strike {
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
  font-weight: 400;
  font-size: 11.5px;
}

/* Legacy strike sub-line — kept defined for any pre-existing rows
   in the stream that were rendered with the old layout. New rows
   no longer emit .kcc-msg__bet-strike; the rule survives so old
   cached HTML doesn't paint a default font. */
.kcc-msg__bet-strike {
  font-size: 11px;
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
  margin: -4px 0 8px;
}

/* Prices row — entry · exit/stake · payout/pnl/refund */
.kcc-msg__bet-prices {
  font-size: 11px;
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
  display: flex;
  gap: 10px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.kcc-msg__bet-px {
  color: var(--text-bright, var(--text));
}
.kcc-msg__bet-pnl--pos { color: var(--up, #4dd99a); }
.kcc-msg__bet-pnl--neg { color: var(--red, #d05a4a); }

/* LEGACY — .kcc-msg__bet-now / .kcc-msg__bet-delta / .kcc-msg__bet-bar
   are no longer emitted. The "now mid + bar" indicator was dropped
   in the minimal layout (the live price lives on the chart, not in
   the chat card). Rules kept so cached HTML in the stream paints
   correctly until rotated out. */
.kcc-msg__bet-now {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11px;
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
  margin-bottom: 4px;
}
.kcc-msg__bet-delta {
  font-weight: 700;
  font-size: 12px;
  margin-left: auto;
}
.kcc-msg__bet-delta.pos { color: var(--up, #4dd99a); }
.kcc-msg__bet-delta.neg { color: var(--red, #d05a4a); }

/* Progress bar — mid as 0–100¢ position. Filled green if winning, red if losing. */
.kcc-msg__bet-bar {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 8px;
}
.kcc-msg__bet-bar-fill {
  height: 100%;
  background: var(--up, #4dd99a);
  border-radius: 2px;
  transition: width 200ms ease;
}
.kcc-msg__bet-bar-fill.neg { background: var(--red, #d05a4a); }

/* Foot row: status (with state dot) + venue CTA */
.kcc-msg__bet-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
  margin-top: 4px;
}
.kcc-msg__bet-foot-status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* Payout label in the open-bet foot — replaces the old status row.
   Brass-on-blue mix is fine: payout is an outcome figure, not a tier
   signal, so it stays neutral. */
.kcc-msg__bet-foot-payout {
  color: var(--text-muted, #828a96);
  font-family: 'Space Mono', monospace;
}
.kcc-msg__bet-foot-payout b {
  color: var(--text-bright, #f3eee2);
  font-weight: 500;
}
.kcc-msg__bet-foot-status .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--brass, #d4a335);
  box-shadow: 0 0 6px color-mix(in srgb, var(--brass, #d4a335) 60%, transparent);
}
.kcc-msg__bet.is-won .kcc-msg__bet-foot-status .dot {
  background: var(--up, #4dd99a);
  box-shadow: 0 0 6px color-mix(in srgb, var(--up, #4dd99a) 60%, transparent);
}
.kcc-msg__bet.is-lost .kcc-msg__bet-foot-status .dot {
  background: var(--red, #d05a4a);
  box-shadow: none;
}
.kcc-msg__bet.is-void .kcc-msg__bet-foot-status .dot {
  background: var(--text-muted, #828a96);
  box-shadow: none;
}
.kcc-msg__bet-cta {
  color: var(--blue, #8a96a3);
  opacity: 0.7;
}
.kcc-msg__bet:hover .kcc-msg__bet-cta { opacity: 1; }
.kcc-msg__bet.is-won .kcc-msg__bet-cta  { color: var(--up, #4dd99a); }
.kcc-msg__bet.is-lost .kcc-msg__bet-cta { color: var(--red, #d05a4a); }
.kcc-msg__bet.is-void .kcc-msg__bet-cta { color: var(--text-muted, #828a96); }

/* Action row — Tail + Challenge. Lives OUTSIDE the <a> so button
   clicks don't trigger the venue navigation. Renders only for OPEN
   bets viewed by non-authors (handled in JS). */
.kcc-msg__bet-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  max-width: 380px;
}
.kcc-msg__bet-act {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border2, var(--border));
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--text-bright, var(--text));
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.kcc-msg__bet-act:hover {
  background: var(--bg2, var(--bg));
}
.kcc-msg__bet-act.tail .glyph { color: var(--up, #4dd99a); }
.kcc-msg__bet-act.challenge .glyph { color: var(--red, #d05a4a); }
.kcc-msg__bet-act.tail:hover {
  border-color: color-mix(in srgb, var(--up, #4dd99a) 40%, var(--border));
}
.kcc-msg__bet-act.challenge:hover {
  border-color: color-mix(in srgb, var(--red, #a83232) 40%, var(--border));
}
.kcc-msg__bet-act.taken {
  background: color-mix(in srgb, var(--up, #4dd99a) 10%, var(--bg));
  border-color: color-mix(in srgb, var(--up, #4dd99a) 35%, var(--border));
  color: var(--up, #4dd99a);
  cursor: default;
}
.kcc-msg__bet-act.taken:hover {
  background: color-mix(in srgb, var(--up, #4dd99a) 10%, var(--bg));
}
.kcc-msg__bet-act:disabled,
.kcc-msg__bet-act.is-disabled {
  cursor: not-allowed;
}
/* Tip variant on bet cards — brass tint, mirrors .kcc-msg__sig-act.tip
   so the chip reads the same way on signal and bet cards. The glyph
   wrapper kcc-tip-glyph centers the inline SVG razor-blade icon. */
.kcc-msg__bet-act.tip .glyph,
.kcc-msg__bet-act.tip .kcc-tip-glyph { color: var(--brass, #d4a335); }
.kcc-msg__bet-act.tip:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
}
.kcc-msg__bet-act .kcc-tip-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 11px;
  height: 11px;
}

/* ── Signal action row — Track + Challenge + Tip ──────────────────
   Mirrors .kcc-msg__bet-actions shape so users learn one language
   for action chips on both cards. Lives OUTSIDE the <a> so button
   clicks don't open the chart.  Renders only for OPEN signals
   viewed by non-authors (JS gate in _renderSignalCard). The locked-
   signal render path returns early, so by the time this row paints
   the viewer has unlocked the signal (or is the author/admin/
   time-decayed viewer).

   Class names parallel the bet rules — sig-actions / sig-act —
   rather than reusing bet-* selectors. Keeps the semantic seam
   between bet cards and signal cards intact for future divergence. */
.kcc-msg__sig-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  /* Match .kcc-msg__signal max-width (360px) so the action row
     aligns with the card's right edge. Bet cards stretch to their
     container so .kcc-msg__bet-actions uses 380px — different setup. */
  max-width: 360px;
}
.kcc-msg__sig-act {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border2, var(--border));
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--text-bright, var(--text));
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.kcc-msg__sig-act:hover {
  background: var(--bg2, var(--bg));
}
/* Track gated off while the Wallet is pre-launch — see _isTrackLocked. */
.kcc-msg__sig-act.is-locked,
.kcc-msg__sig-act:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
/* Glyph tints — Track green like Tail; Challenge oxblood like the
   bet challenge action; Tip brass to match the razor-blade aesthetic.
   The .glyph wrapper is shared with bet-act so the inline SVG inside
   the Tip button inherits currentColor from the .kcc-tip-glyph
   wrapper at brass. */
.kcc-msg__sig-act.track .glyph     { color: var(--up, #4dd99a); }
.kcc-msg__sig-act.challenge .glyph { color: var(--red, #d05a4a); }
.kcc-msg__sig-act.tip .glyph,
.kcc-msg__sig-act.tip .kcc-tip-glyph { color: var(--brass, #d4a335); }
.kcc-msg__sig-act.track:hover {
  border-color: color-mix(in srgb, var(--up, #4dd99a) 40%, var(--border));
}
.kcc-msg__sig-act.challenge:hover {
  border-color: color-mix(in srgb, var(--red, #a83232) 40%, var(--border));
}
.kcc-msg__sig-act.tip:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
}
/* Tracked state — green tint, mirrors .kcc-msg__bet-act.taken so
   "we already did this" reads the same on both cards. But unlike
   bet's .taken (which is non-interactive), the signal Track chip
   STAYS clickable when tracked — a second click untracks. We keep
   the green tint, keep the cursor: pointer (default for buttons),
   and add a subtle hover border lift so users get feedback the
   chip is still actionable. */
.kcc-msg__sig-act.track.taken {
  background: color-mix(in srgb, var(--up, #4dd99a) 10%, var(--bg));
  border-color: color-mix(in srgb, var(--up, #4dd99a) 35%, var(--border));
  color: var(--up, #4dd99a);
}
.kcc-msg__sig-act.track.taken:hover {
  background: color-mix(in srgb, var(--up, #4dd99a) 16%, var(--bg));
  border-color: color-mix(in srgb, var(--up, #4dd99a) 55%, var(--border));
}
.kcc-msg__sig-act:disabled,
.kcc-msg__sig-act.is-disabled {
  cursor: not-allowed;
  opacity: 0.6;
}
/* The tip glyph is an inline SVG so it doesn't inherit the same
   line-box adjustments as the unicode glyphs (★ ⚔). Nudge it 1px
   for vertical centering. */
.kcc-msg__sig-act .kcc-tip-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 11px;
  height: 11px;
}
/* Settled signals — hide the action row entirely. Mirrors the bet
   rule above (`.kcc-msg__bet.is-settled .kcc-msg__bet-actions`).
   The is-settled modifier comes from _renderSignalCard's resState
   ≠ 'open' branch via settledMod. We can't use a :has() selector
   here cleanly (sig-actions is a sibling of the .kcc-msg__signal
   anchor, not a descendant), so we let JS suppress it via the
   resState gate -- same as bets do for is-settled, which works
   because actionsHtml is only assigned when state==='open'. This
   rule is here only as a safety net for any future render path
   that emits actionsHtml on a settled card. */
.kcc-msg__signal.is-settled + .kcc-msg__sig-actions {
  display: none;
}

/* ── Tips recognition footer (variant H) ──────────────────────────
   Brass pill + tipper avatar stack rendered INSIDE the signal card
   <a>, above the foot row. Empty string when message has no tips,
   so the footer collapses out of the layout cleanly.

   Avatar stack is the same hue palette as presence rail + message
   row avatars — keeps tipper identity consistent across surfaces.
   The first 4 tippers show; "and N more" appears when count > 4.

   The container sits above .kcc-msg__sig-foot which already has
   its own border-top hairline, so we don't add one here -- avoids
   a double line. We DO add a margin-top so the footer breathes
   away from the prices row above.
*/
.kcc-msg__sig-tippers {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  color: var(--muted);
  letter-spacing: 0.4px;
}
.kcc-msg__sig-tippers-stack {
  display: inline-flex;
  align-items: center;
}
.kcc-msg__sig-tippers-av {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg);
  border: 1.5px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 8px;
  font-weight: 700;
  color: var(--text-bright, var(--text));
  letter-spacing: 0;
  /* Overlap stack — each subsequent avatar slides 5px left over the
     previous one, with z-index ordering so the first tipper sits
     on top. Mirrors the presence rail's avatar stack pattern. */
  margin-left: -5px;
}
.kcc-msg__sig-tippers-av:first-child {
  margin-left: 0;
}
/* Per-hue border + text color — same palette as .kcc-msg[data-kcc-hue]
   so a given user is identified by the same color on every surface.
   This block intentionally mirrors the message-row hue rules; if
   those change, update both. */
.kcc-msg__sig-tippers-av[data-kcc-hue="1"] { border-color: #f0997b; color: #f0997b; }
.kcc-msg__sig-tippers-av[data-kcc-hue="2"] { border-color: #5dcaa5; color: #5dcaa5; }
.kcc-msg__sig-tippers-av[data-kcc-hue="3"] { border-color: #a89dd9; color: #a89dd9; }
.kcc-msg__sig-tippers-av[data-kcc-hue="4"] { border-color: var(--brass, #d4a335); color: var(--brass, #d4a335); }
.kcc-msg__sig-tippers-av[data-kcc-hue="5"] { border-color: #7aa4c9; color: #7aa4c9; }
.kcc-msg__sig-tippers-av[data-kcc-hue="6"] { border-color: #d59ab8; color: #d59ab8; }
.kcc-msg__sig-tippers-av[data-kcc-hue="7"] { border-color: #b4b2a9; color: #b4b2a9; }

.kcc-msg__sig-tippers-meta {
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  color: var(--muted);
  letter-spacing: 0.4px;
}
.kcc-msg__sig-tippers-meta b {
  color: var(--brass, #d4a335);
  font-weight: 700;
}

/* ── Tip popover ───────────────────────────────────────────────────
   Floating element anchored under the Tip chip. Single instance
   appended to <body> (escapes any overflow:hidden ancestors), free
   to float over the message stream. Position is JS-computed; the
   only positioning here is `position: absolute` so the JS top/left
   actually applies. Width is a compact 240px; tall enough to fit
   four amount chips + optional note + econ line + send button.
*/
.kcc-tippop {
  width: 240px;
  background: var(--card, var(--bg));
  border: 1px solid color-mix(in srgb, var(--brass, #d4a335) 45%, var(--border));
  border-radius: 6px;
  padding: 10px;
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.5);
  font-family: inherit;
}
.kcc-tippop__head {
  font-family: 'Space Mono', monospace;
  font-size: 9px;
  letter-spacing: 1.4px;
  color: var(--brass, #d4a335);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.kcc-tippop__chips {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 4px;
  margin-bottom: 8px;
}
.kcc-tippop__chip {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 500;
  padding: 6px 0;
  border-radius: 3px;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
}
.kcc-tippop__chip:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 40%, var(--border));
}
.kcc-tippop__chip.is-on {
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, var(--bg));
  border-color: var(--brass, #d4a335);
  color: var(--brass, #d4a335);
  font-weight: 700;
}
.kcc-tippop__note {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  color: var(--text);
  font-family: inherit;
  font-size: 11px;
  padding: 6px 8px;
  resize: none;
  margin-bottom: 8px;
  box-sizing: border-box;
  /* Subtle focus ring in brass to match the chip selection color. */
  transition: border-color 120ms;
}
.kcc-tippop__note:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--brass, #d4a335) 55%, var(--border));
}
.kcc-tippop__note::placeholder {
  color: var(--muted);
  font-family: 'Space Mono', monospace;
  font-size: 10px;
}
.kcc-tippop__econ {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 6px 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: 'Space Mono', monospace;
  font-size: 9.5px;
  margin-bottom: 8px;
  gap: 6px;
}
.kcc-tippop__econ-fee {
  color: var(--muted);
}
.kcc-tippop__econ-net {
  color: var(--text-mid, var(--muted));
}
.kcc-tippop__econ-net b {
  color: var(--up, #4dd99a);
  font-weight: 500;
}
.kcc-tippop__send {
  width: 100%;
  background: var(--brass, #d4a335);
  color: var(--bg);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  padding: 7px 0;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: filter 120ms;
}
.kcc-tippop__send:hover {
  filter: brightness(1.08);
}
.kcc-tippop__send:disabled {
  opacity: 0.6;
  cursor: wait;
  filter: none;
}



/* ══════════════════════════════════════════════════════════════════
   CHALLENGES INBOX — renders inside the KCInbox drawer as a third tab.
   Stats header + sub-tabs + scrollable row list, all under #kciList.
   ══════════════════════════════════════════════════════════════════ */

/* Stats strip */
.kcch-inbox-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 0.5px solid var(--border, #2a2620);
  background: var(--panel-foot, #0e0c0a);
  flex: none;
}
.kcch-inbox-stat {
  padding: 10px 12px;
  border-right: 0.5px solid var(--border, #2a2620);
}
.kcch-inbox-stat:last-child { border-right: 0; }
.kcch-inbox-stat-lbl {
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted, #6e6b63);
  margin-bottom: 3px;
}
.kcch-inbox-stat-val {
  font-size: 16px;
  color: var(--text, #e8e3d4);
  font-weight: 500;
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-inbox-stat-val.pos  { color: var(--up, #5acf7a); }
.kcch-inbox-stat-val.neg  { color: var(--down, #e2786a); }
.kcch-inbox-stat-val.gold { color: var(--brass, #d4a335); }

/* Sub-tabs */
.kcch-inbox-subtabs {
  display: flex;
  padding: 0 14px;
  border-bottom: 0.5px solid var(--border, #2a2620);
  background: var(--panel-foot, #0e0c0a);
  flex: none;
}
.kcch-inbox-subtab {
  padding: 9px 12px;
  font-size: 11.5px;
  color: var(--text-muted, #6e6b63);
  background: none;
  border: 0;
  border-bottom: 1.5px solid transparent;
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.kcch-inbox-subtab:hover { color: var(--text, #cfcdc4); }
.kcch-inbox-subtab.on {
  color: var(--brass, #d4a335);
  border-bottom-color: var(--brass, #d4a335);
}
.kcch-inbox-subtab-cnt {
  background: var(--panel-deep-2, #2a2620);
  color: var(--text-muted, #8a8780);
  font-size: 10px;
  padding: 0 5px;
  border-radius: 8px;
  font-family: 'Space Mono', ui-monospace, monospace;
}
.kcch-inbox-subtab.on .kcch-inbox-subtab-cnt {
  background: color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
  color: var(--brass, #d4a335);
}

/* Rows container */
.kcch-inbox-rows {
  padding: 6px;
}
.kcch-inbox-empty {
  padding: 30px 16px;
  text-align: center;
  font-size: 12px;
  color: var(--text-muted, #6e6b63);
  line-height: 1.6;
}

/* Row */
.kcch-inbox-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 7px;
  border: 0.5px solid transparent;
  cursor: pointer;
  margin-bottom: 1px;
}
.kcch-inbox-row:hover {
  background: var(--panel-foot, #0e0c0a);
  border-color: var(--border, #2a2620);
}
.kcch-inbox-row--urgent {
  background: color-mix(in srgb, var(--brass, #d4a335) 6%, transparent);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 22%, transparent);
}
.kcch-inbox-row--urgent:hover {
  background: color-mix(in srgb, var(--brass, #d4a335) 10%, transparent);
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, transparent);
}

.kcch-inbox-row-pill {
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 3px;
  flex: none;
  font-weight: 500;
}
.kcch-inbox-row-pill--open {
  background: color-mix(in srgb, var(--brass, #d4a335) 18%, transparent);
  color: var(--brass, #d4a335);
}
.kcch-inbox-row-pill--live,
.kcch-inbox-row-pill--won {
  background: color-mix(in srgb, var(--up, #5acf7a) 14%, transparent);
  color: var(--up, #5acf7a);
}
.kcch-inbox-row-pill--lost {
  background: color-mix(in srgb, var(--down, #e2786a) 14%, transparent);
  color: var(--down, #e2786a);
}
.kcch-inbox-row-pill--tag {
  background: color-mix(in srgb, #b48fe2 16%, transparent);
  color: #b48fe2;
}
.kcch-inbox-row-pill--void,
.kcch-inbox-row-pill--settled {
  background: color-mix(in srgb, var(--text-muted, #6e6b63) 18%, transparent);
  color: var(--text-muted, #8a8780);
}

.kcch-inbox-row-body { flex: 1; min-width: 0; }
.kcch-inbox-row-title {
  font-size: 12px;
  color: var(--text, #e8e3d4);
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kcch-inbox-row-title b { color: var(--brass, #d4a335); font-weight: 500; }
.kcch-inbox-row-sub {
  font-size: 10.5px;
  color: var(--text-muted, #6e6b63);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kcch-inbox-row-sub .sep {
  margin: 0 5px;
  color: var(--panel-deep-2, #3a3a3f);
}
.kcch-inbox-row-val {
  font-size: 12px;
  font-family: 'Space Mono', ui-monospace, monospace;
  color: var(--text, #cfcdc4);
  text-align: right;
  flex: none;
  font-weight: 500;
}
.kcch-inbox-row-val .pos     { color: var(--up, #5acf7a); }
.kcch-inbox-row-val .neg     { color: var(--down, #e2786a); }
.kcch-inbox-row-val .gold    { color: var(--brass, #d4a335); }
.kcch-inbox-row-val .neutral { color: var(--text-muted, #8a8780); }
.kcch-inbox-row-val small {
  display: block;
  font-size: 9px;
  color: var(--text-muted, #6e6b63);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 1px;
  font-family: var(--kc-font-ui, 'Space Grotesk'), sans-serif;
  font-weight: 400;
}


/* ════════════════════════════════════════════════════════════════
   ║  KCBetModal — shared bet modal lifted from predict.html        ║
   ║                                                                ║
   ║  Owns its own overlay frame (.kcbm-overlay/.kcbm-modal/        ║
   ║  .kcbm-head/.kcbm-close) so it doesn't depend on predict's     ║
   ║  page-local .pd-pop-* classes (still in use by the cross-      ║
   ║  venue arb popover). Everything in this block uses the kcbm-   ║
   ║  prefix and lives on shared.css so chat.html, compete.html,    ║
   ║  any future surface can open the modal with no extra page CSS. ║
   ║                                                                ║
   ║  Color tokens fall through to the same vars predict was using  ║
   ║  (--up, --red, --yellow, --muted, --text-bright, etc.) so      ║
   ║  themes carry over without rewiring.                           ║
   ╚════════════════════════════════════════════════════════════════ */

/* Frame — modal overlay (centered, fade in via .show) */
.kcbm-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.55);
  display: none; align-items: center; justify-content: center; z-index: 1320;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.kcbm-overlay.show { display: flex; }
.kcbm-modal {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; padding: 18px 20px;
  width: min(520px, 92vw); max-height: 86vh; overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.kcbm-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
  margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.kcbm-head h3 {
  font-size: 14px; color: var(--text-bright); font-weight: var(--w-semibold);
  margin: 0; line-height: 1.35;
}
.kcbm-close {
  background: transparent; border: none; color: var(--muted);
  font-size: 22px; cursor: pointer; line-height: 1; padding: 0 4px;
  flex-shrink: 0;
}
.kcbm-close:hover { color: var(--text-bright); }
.kcbm-sub {
  font-size: 11px; color: var(--muted); margin-top: 4px;
}

/* ── Quick-actions strip (Track / Ask AI / Share to chat) ───── */
.kcbm-quick-actions {
  display: grid;
  grid-template-columns: repeat(var(--kcbm-cols, 2), 1fr);
  gap: 6px;
  padding: 10px 14px; margin: -2px -2px 12px;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,0.015);
}
.kcbm-quick-actions[data-cols="1"] { --kcbm-cols: 1; }
.kcbm-quick-actions[data-cols="2"] { --kcbm-cols: 2; }
.kcbm-quick-actions[data-cols="3"] { --kcbm-cols: 3; }
.kcbm-quick-actions[data-cols="4"] { --kcbm-cols: 4; }
.kcbm-quick {
  display: flex; align-items: center; justify-content: center;
  gap: 6px; padding: 7px 10px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text); border-radius: 5px; font-size: 11.5px; cursor: pointer;
  font-family: inherit; transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.kcbm-quick:hover { border-color: var(--border2); color: var(--text-bright); }
.kcbm-quick.tracked { color: var(--accent2); border-color: rgba(168,85,247,0.4); }
.kcbm-quick.share {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 35%, var(--border));
  background: color-mix(in srgb, var(--brass, #d4a335) 5%, transparent);
}
.kcbm-quick.share:hover {
  border-color: color-mix(in srgb, var(--brass, #d4a335) 55%, var(--border));
  color: var(--brass, #d4a335);
}
.kcbm-quick.share-test {
  border-color: rgba(168,50,50,0.45);
  background: rgba(168,50,50,0.08);
  color: #c75c5c;
}
.kcbm-quick.share-test:hover {
  border-color: rgba(168,50,50,0.7);
  color: #d96b6b;
}
.kcbm-quick-icon { font-size: 13px; line-height: 1; }

/* ── Broadcast bar (Challenge / Share-call — no $1k bet required) ──
   Social actions that don't depend on a placed bet, sitting below the
   bet section. Step 1 ships the Challenge button (oxblood); Share-call
   joins it later. Mirrors the chat bet-card action row's weight so the
   surfaces read as one language. */
.kcbm-bcast {
  display: flex; gap: 8px; margin-top: 12px;
}
.kcbm-bcast-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; padding: 10px 12px; border-radius: 7px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: var(--w-semibold);
  border: 1px solid var(--border); background: transparent; color: var(--text);
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.kcbm-bcast-btn .kcbm-bcast-ic { display: inline-flex; line-height: 1; }
.kcbm-bcast-btn.chal {
  border-color: color-mix(in srgb, var(--red) 50%, var(--border));
  background: color-mix(in srgb, var(--red) 9%, transparent);
  color: color-mix(in srgb, var(--red) 70%, var(--text-bright));
}
.kcbm-bcast-btn.chal:hover {
  border-color: color-mix(in srgb, var(--red) 80%, var(--border));
  background: color-mix(in srgb, var(--red) 15%, transparent);
  color: color-mix(in srgb, var(--red) 85%, var(--text-bright));
}
.kcbm-bcast-btn.share {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  color: var(--accent);
}
.kcbm-bcast-btn.share:hover {
  border-color: color-mix(in srgb, var(--accent) 70%, var(--border));
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}
.kcbm-bcast-btn:disabled,
.kcbm-bcast-btn[aria-disabled="true"] {
  opacity: 0.4; cursor: not-allowed; filter: grayscale(0.35);
}
.kcbm-bcast-btn.chal:disabled:hover,
.kcbm-bcast-btn.chal[aria-disabled="true"]:hover {
  border-color: color-mix(in srgb, var(--red) 50%, var(--border));
  background: color-mix(in srgb, var(--red) 9%, transparent);
  color: color-mix(in srgb, var(--red) 70%, var(--text-bright));
}

/* ── Binary bet form pills ──────────────────────────────────── */
.kcbm-pills { display: flex; gap: 8px; margin-bottom: 12px; }
.kcbm-pill {
  flex: 1; min-height: 60px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text); padding: 10px 12px; border-radius: 8px;
  font-size: 13px; cursor: pointer; font-family: inherit;
  text-align: center; transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.kcbm-pill .kcbm-pill-label {
  font-size: 11px; color: var(--muted); font-weight: var(--w-medium);
  text-transform: uppercase; letter-spacing: 0.5px; line-height: 1;
}
.kcbm-pill .kcbm-pill-price {
  font-family: 'Space Mono', monospace; font-size: 22px;
  font-weight: var(--w-semibold); line-height: 1.1;
}
.kcbm-pill .kcbm-pill-arm-label {
  font-size: 10.5px; color: inherit; opacity: 0.85; font-weight: var(--w-medium);
  text-transform: uppercase; letter-spacing: 0.5px; line-height: 1;
}
.kcbm-pill .kcbm-pill-arm-val {
  font-family: 'Space Mono', monospace; font-size: 13px;
  font-weight: var(--w-semibold); line-height: 1.2;
}
.kcbm-pill.yes:hover { border-color: rgba(109,217,156,0.45); color: var(--up); }
.kcbm-pill.yes:hover .kcbm-pill-label { color: var(--up); opacity: 0.75; }
.kcbm-pill.no:hover  { border-color: rgba(239,106,106,0.45); color: var(--red); }
.kcbm-pill.no:hover  .kcbm-pill-label { color: var(--red); opacity: 0.75; }
.kcbm-pill.yes.armed {
  background: var(--up); border-color: var(--up); color: #0d0e0f;
}
.kcbm-pill.no.armed {
  background: var(--red); border-color: var(--red); color: #0d0e0f;
}
.kcbm-pill.armed:hover { filter: brightness(1.08); }
.kcbm-pill.armed.disabled {
  opacity: 0.45; cursor: not-allowed; filter: none;
}

/* ── Stake row + balance ────────────────────────────────────── */
.kcbm-stake-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 6px;
}
.kcbm-stake-row label {
  font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: var(--w-medium);
}
.kcbm-stake-row .kcbm-balance {
  font-size: 11px; color: var(--muted);
}
.kcbm-stake-row .kcbm-balance b {
  color: var(--text); font-family: 'Space Mono', monospace; font-weight: var(--w-medium);
}
.kcbm-stake-control { display: flex; gap: 8px; align-items: stretch; margin-bottom: 8px; }
.kcbm-stake-input-wrap { flex: 1; position: relative; }
.kcbm-stake-input-wrap > .kcbm-currency {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--muted); font-family: 'Space Mono', monospace; font-size: 14px;
  pointer-events: none;
}
.kcbm-stake-input {
  width: 100%; background: var(--card2); border: 1px solid var(--border);
  color: var(--text); padding: 9px 12px 9px 24px; border-radius: 6px;
  font-size: 14px; font-family: 'Space Mono', monospace;
  -webkit-appearance: none; appearance: none;
}
.kcbm-stake-input:focus { outline: none; border-color: var(--yellow); }
.kcbm-quicks { display: flex; gap: 4px; }
.kcbm-quick-stake {
  background: var(--card2); border: 1px solid var(--border); color: var(--text);
  padding: 0 10px; border-radius: 6px; font-size: 11px; cursor: pointer;
  font-family: inherit; min-width: 38px;
}
.kcbm-quick-stake:hover { border-color: var(--border2); }
.kcbm-quick-stake.active { border-color: var(--yellow); color: var(--yellow); background: rgba(255,176,69,0.05); }

/* ── Inline payout strip ────────────────────────────────────── */
.kcbm-payout-strip {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-family: 'Space Mono', monospace; font-size: 12px;
  padding: 6px 0; min-height: 22px;
}
.kcbm-payout-strip .kcbm-payout-hint  { color: var(--muted); font-style: italic; font-family: inherit; font-size: 11px; }
.kcbm-payout-strip .kcbm-payout-win   { color: var(--up); font-weight: var(--w-semibold); }
.kcbm-payout-strip .kcbm-payout-loss  { color: var(--red); font-weight: var(--w-semibold); }
.kcbm-payout-strip .kcbm-payout-sep   { color: var(--muted); }
.kcbm-payout-strip .kcbm-payout-armed { color: var(--text-bright); font-weight: var(--w-medium); }

/* ── Ladder (group markets — multi-strike) ──────────────────── */
.kcbm-ladder {
  max-height: 320px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px;
  margin-bottom: 12px;
  background: var(--card2);
}
.kcbm-ladder-head {
  display: flex; justify-content: space-between;
  padding: 6px 10px;
  font-size: 9.5px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.5px;
  font-family: 'Space Mono', monospace;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,0.015);
  position: sticky; top: 0; z-index: 1;
}
.kcbm-ladder-row {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  border-left: 2px solid transparent;
}
.kcbm-ladder-row:last-child { border-bottom: 0; }
.kcbm-ladder-row.contested {
  border-left-color: var(--yellow);
  background: rgba(255,176,69,0.03);
}
.kcbm-ladder-strike {
  display: flex; align-items: center; gap: 6px;
  font-family: 'Space Mono', monospace; font-size: 12px;
  margin-bottom: 6px;
}
.kcbm-ladder-strike .kcbm-venue-badge { font-size: 9px; padding: 1px 4px; }
.kcbm-ladder-label { color: var(--text); flex: 1; }
.kcbm-ladder-vol { color: var(--muted); font-size: 10.5px; }
.kcbm-ladder-pills { display: flex; gap: 6px; }
.kcbm-ladder-pill {
  flex: 1; min-height: 30px;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 6px 8px; border-radius: 5px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text); font-family: inherit; font-size: 11px;
  cursor: pointer; transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.kcbm-ladder-pill .kcbm-ladder-pill-side {
  font-size: 10.5px; color: var(--muted); font-weight: var(--w-medium);
}
.kcbm-ladder-pill .kcbm-ladder-pill-price {
  font-family: 'Space Mono', monospace; font-size: 12px;
  font-weight: var(--w-semibold);
}
.kcbm-ladder-pill .kcbm-ladder-pill-arm {
  font-size: 11px; font-weight: var(--w-semibold); letter-spacing: 0.2px;
}
.kcbm-ladder-pill.yes:hover { border-color: rgba(109,217,156,0.45); color: var(--up); }
.kcbm-ladder-pill.yes:hover .kcbm-ladder-pill-side { color: var(--up); opacity: 0.75; }
.kcbm-ladder-pill.no:hover  { border-color: rgba(239,106,106,0.45); color: var(--red); }
.kcbm-ladder-pill.no:hover  .kcbm-ladder-pill-side { color: var(--red); opacity: 0.75; }
.kcbm-ladder-pill.yes.armed {
  background: var(--up); border-color: var(--up); color: #0d0e0f;
}
.kcbm-ladder-pill.no.armed {
  background: var(--red); border-color: var(--red); color: #0d0e0f;
}
.kcbm-ladder-pill.armed:hover { filter: brightness(1.08); }
.kcbm-ladder-pill.armed.disabled {
  opacity: 0.45; cursor: not-allowed; filter: none;
}
.kcbm-ladder-alt {
  margin-top: 5px;
  font-size: 10px; color: var(--muted);
  font-family: 'Space Mono', monospace;
  padding-left: 4px;
}

/* ── Disclaimer + error ─────────────────────────────────────── */
.kcbm-disclaimer {
  margin-top: 4px;
  padding: 6px 10px;
  border-left: 2px solid rgba(255,176,69,0.45);
  background: rgba(255,176,69,0.04);
  border-radius: 0 4px 4px 0;
  font-size: 10.5px; color: rgba(255,176,69,0.78); line-height: 1.5;
}
.kcbm-error {
  font-size: 11px; color: var(--red); min-height: 14px;
}

/* ── Per-venue links footer ─────────────────────────────────── */
.kcbm-venue-footer {
  margin-top: 14px; padding: 10px 14px;
  border-top: 1px solid var(--border);
  background: rgba(255,255,255,0.015);
}
.kcbm-venue-footer-label {
  font-size: 9.5px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-bottom: 6px;
}
.kcbm-venue-links { display: flex; flex-wrap: wrap; gap: 6px; }
.kcbm-venue-link {
  flex: 1 1 130px; min-width: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px;
  background: transparent; border: 1px solid var(--border);
  border-radius: 5px;
  text-decoration: none; color: var(--text); font-size: 11px;
  transition: border-color 0.12s, color 0.12s;
}
.kcbm-venue-link:hover { border-color: var(--border2); color: var(--text-bright); }
.kcbm-venue-link-meta {
  display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kcbm-venue-link-arrow { color: var(--muted); flex-shrink: 0; }
.kcbm-venue-link:hover .kcbm-venue-link-arrow { color: var(--text-bright); }

/* Yes/No tint inside venue link meta (mirrors .pd-yes / .pd-no usage) */
.kcbm-yes { color: var(--up); }
.kcbm-no  { color: var(--red); }

/* ── Venue badges (POLY / KALSHI / LIMITLESS) ───────────────── */
.kcbm-venue-badge {
  font-size: 9.5px; padding: 2px 6px; border-radius: 4px;
  font-weight: var(--w-semibold); letter-spacing: 0.4px;
  font-family: 'Space Mono', monospace;
}
.kcbm-venue-poly {
  background: rgba(168,85,247,0.15); color: #c89af7;
  border: 1px solid rgba(168,85,247,0.3);
}
.kcbm-venue-kalshi {
  background: rgba(74,158,255,0.15); color: #87b8ff;
  border: 1px solid rgba(74,158,255,0.3);
}
.kcbm-venue-limitless {
  background: rgba(34,211,238,0.15); color: #67e8f9;
  border: 1px solid rgba(34,211,238,0.3);
}

/* ── Locked-bet placeholder (open or settled) ───────────────── */
.kcbm-locked {
  padding: 14px 16px; margin: 6px 0 12px;
  background: rgba(255,255,255,0.025); border: 1px solid var(--border);
  border-radius: 6px;
}
.kcbm-locked.open    { border-color: rgba(255,176,69,0.35); background: rgba(255,176,69,0.05); }
.kcbm-locked.settled { border-color: var(--border); }
.kcbm-locked-icon {
  font-size: 16px; line-height: 1; margin-right: 8px;
  display: inline-block; vertical-align: middle;
}
.kcbm-locked.open    .kcbm-locked-icon { color: var(--yellow); }
.kcbm-locked.settled .kcbm-locked-icon { color: var(--muted); }
.kcbm-locked-title {
  display: inline-block; vertical-align: middle;
  font-size: 12.5px; color: var(--text-bright);
  font-weight: var(--w-semibold);
}
.kcbm-locked-sub {
  margin-top: 6px;
  font-size: 11px; color: var(--muted); line-height: 1.4;
}
.kcbm-locked-cta {
  display: inline-block; margin-top: 8px;
  padding: 6px 10px;
  background: transparent; border: 1px solid var(--border);
  border-radius: 5px;
  text-decoration: none; color: var(--text); font-size: 11px;
  transition: border-color 0.12s, color 0.12s;
}
.kcbm-locked-cta:hover { border-color: var(--border2); color: var(--text-bright); }

/* ════════════════════════════════════════════════════════════════
   Compact settings drawer (Option A). Scoped to .kc-settings-compact
   so page-shipped overlays without that class keep their old layout.
   ════════════════════════════════════════════════════════════════ */
.kc-settings-compact .kc-settings-body { gap: 0; }
.kc-settings-compact .settings-section {
  margin: 0;
  padding: 11px 0;
  border-top: 1px solid var(--border, #2a2b30);
}
.kc-settings-compact .settings-section:first-child { border-top: 0; padding-top: 2px; }
.kc-settings-compact .settings-label {
  font-size: 12px;
  margin: 0;
  text-transform: none;
  letter-spacing: 0;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 600;
  color: var(--text-bright, #faf6ec);
}

/* One-line preference rows */
.kc-settings-compact .kc-srow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.kc-srow-l { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kc-srow-sub {
  font-size: 10.5px; color: var(--muted, #8a857a);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kc-srow-r { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.kc-settings-compact .kc-srow-r .settings-btn { margin: 0; }
.kc-srow-icon { padding: 6px 9px; line-height: 1; }
.kc-srow-text { padding: 6px 14px; font-size: 12px; }
.kc-srow-status { font-size: 10px; }
.kc-settings-compact .kc-srow-status:empty { display: none; }

/* Account compact card */
.kc-settings-compact .kc-acc-section { padding-top: 2px; }
.kc-acc-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--card, #171513); border: 1px solid var(--border, #2a2b30);
  border-radius: 10px; padding: 10px 12px;
}
.kc-acc-card-id { min-width: 0; }
.kc-acc-card-id .kc-acc-handle-cell { display: inline-flex; align-items: center; gap: 8px; }
.kc-acc-card-id #kcAccHandle {
  font-family: 'Space Mono', ui-monospace, monospace; font-size: 13px;
  color: var(--text-bright, #faf6ec);
}
.kc-acc-email {
  display: block; font-size: 10.5px; color: var(--muted, #8a857a); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
}
.kc-acc-bal { white-space: nowrap; text-align: right; flex-shrink: 0; }
.kc-settings-compact .kc-acc-actions { display: flex; gap: 8px; margin-top: 8px; }
.kc-settings-compact .kc-acc-actions .settings-btn { flex: 1; }
.kc-settings-compact .kc-acc-status:empty { display: none; }

/* Razor profile + injected sections tightened in compact mode */
.kc-settings-compact .kp-settings-desc { display: none; }
.kc-settings-compact .kp-settings-row { gap: 10px; align-items: center; }

/* Tighten the two rich sections so they read as part of the compact list */
.kc-settings-compact .kp-settings-title { font-size: 13px; }
.kc-settings-compact #kcXvIntro { display: none; }          /* intro → section title tooltip */
.kc-settings-compact #kcXvRow .settings-helper { font-size: 11px; line-height: 1.4; }
.kc-settings-compact .kp-summary-card { padding: 8px 10px; }
.kc-settings-compact .kp-preset-chips { margin-top: 8px; }
.kc-settings-compact .kp-settings-meta { min-width: 0; }

/* Razor profile collapse chevron / header (compact shared template) */
.kp-collapse-chev { display: inline-flex; align-items: center; color: var(--ra-muted, #8a8578); cursor: pointer; transition: transform .15s ease; margin-right: 2px; }
.kp-collapse-chev.is-open { transform: rotate(90deg); }
.kp-collapse-chev svg { width: 14px; height: 14px; display: block; }
.kp-collapse-sub { font-size: 11px; color: var(--ra-muted, #8a8578); font-weight: 400; margin-left: 2px; }
.kp-collapse-body { padding-top: 2px; }


/* ═══ Volume Pulse card (payload.pulse · Card A) ═══════════════════
   Rides the .kcc-msg__bet base (block card, 380px cap); the modifier
   re-skins it into the brass app-card family: brass rail + soft brass
   wash, no pointer (the only interactive element is the footer link). */
.kcc-msg__pulse {
  border-left: 2px solid var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 6%, var(--bg2, var(--bg)));
  cursor: default;
}
.kcc-msg__pulse:hover {
  border-color: color-mix(in srgb, var(--accent, #d4a335) 55%, var(--border));
  background: color-mix(in srgb, var(--accent, #d4a335) 8%, var(--bg2, var(--bg)));
}
.kcc-pu-head {
  display: flex; align-items: center; gap: 7px;
  font-family: 'Space Mono', monospace;
  font-size: 9px; letter-spacing: 1.2px;
  color: var(--accent, #d4a335);
  padding-bottom: 7px; margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.kcc-pu-head svg { width: 13px; height: 13px; color: #e85858; flex: 0 0 auto; }
.kcc-pu-age { margin-left: auto; color: var(--muted); letter-spacing: .5px; }
.kcc-pu-main { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.kcc-pu-sym { font-weight: 700; font-size: 15px; min-width: 0; }
.kcc-pu-sym small {
  display: block; font-family: 'Space Mono', monospace; font-weight: 400;
  font-size: 9px; color: var(--muted); margin-top: 2px; letter-spacing: .5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kcc-pu-chip {
  font-family: 'Space Mono', monospace; font-size: 8.5px; letter-spacing: .7px;
  border-radius: 5px; padding: 2.5px 6px; white-space: nowrap; flex: 0 0 auto;
}
.kcc-pu-chip--ign  { background: color-mix(in srgb, var(--up, #6dd99c) 14%, transparent); color: var(--up, #6dd99c); }
.kcc-pu-chip--coil { background: color-mix(in srgb, var(--accent, #d4a335) 15%, transparent); color: var(--accent, #d4a335); }
.kcc-pu-chip--sqz,
.kcc-pu-chip--dump { background: color-mix(in srgb, #e85858 15%, transparent); color: #e85858; }
.kcc-pu-chip--dist { background: color-mix(in srgb, #f0a040 14%, transparent); color: #f0a040; }
.kcc-pu-score { margin-left: auto; text-align: right; flex: 0 0 auto; }
.kcc-pu-score b { display: block; font-family: 'Space Mono', monospace; font-size: 20px; color: var(--accent, #d4a335); line-height: 1; }
.kcc-pu-score i { font-style: normal; font-family: 'Space Mono', monospace; font-size: 8px; letter-spacing: 1px; color: var(--muted); }
.kcc-pu-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--border); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden; margin-bottom: 9px;
}
.kcc-pu-cell { background: var(--bg2, var(--bg)); padding: 7px 9px; }
.kcc-pu-cell-l {
  font-size: 8px; letter-spacing: .8px; color: var(--muted);
  text-transform: uppercase; margin-bottom: 2px;
}
.kcc-pu-cell-v { font-family: 'Space Mono', monospace; font-size: 12.5px; font-weight: 700; }
.kcc-pu--up { color: var(--up, #6dd99c); }
.kcc-pu--dn { color: #e85858; }
.kcc-pu-foot { display: flex; align-items: center; gap: 8px; }
.kcc-pu-by {
  font-family: 'Space Mono', monospace; font-size: 9px; color: var(--muted);
  letter-spacing: .4px; min-width: 0; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
}
.kcc-pu-open {
  margin-left: auto; flex: 0 0 auto; font-size: 11px; font-weight: 600;
  color: var(--accent, #d4a335); text-decoration: none;
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 40%, transparent);
  border-radius: 7px; padding: 4px 9px;
}
.kcc-pu-open:hover { border-color: var(--accent, #d4a335); background: color-mix(in srgb, var(--accent, #d4a335) 10%, transparent); }

/* ═══════════════════════════════════════════════════════════════
   MOBILE APP SHELL · FLOATING PILL DOCK  (Option C · 2026-07)
   ───────────────────────────────────────────────────────────────
   A detached glass pill floating over content — the mobile app
   nav. Rendered by renderDock() in shared.js ONLY on pages in its
   DOCK_PAGES rollout allowlist, and only ≤900px (same breakpoint
   as the drawer). html[data-kc-dock] is stamped when the dock is
   live so body clearance + any page CSS can key off it.

   Structure:
     .kc-dock-wrap  — fixed, centered, pointer-events:none shell
       .kc-dock     — the pill (pointer-events back on)
         .kc-dock-item        — icon-only tab (a/button)
         .kc-dock-item.active — expands to icon+label, brass tint

   The More sheet (.kc-dock-sheet-*) is a standard bottom sheet:
   scrim + slide-up panel + app-launcher grid of the remaining nav
   pages. Swipe-dismiss reuses KC._attachSheetSwipe (same handler
   as KCDialog / profile sheets); the drag transform contract is
   identical (--kc-sheet-drag + .is-dragging).

   Zoom-aware sizing: the body runs zoom:var(--kc-font-scale), so
   the fixed bottom inset and the sheet's dvh max-height divide by
   the scale — same rule as the composer / theme menu (see the
   mobile-optimization handoff, primitive #2).
   ═══════════════════════════════════════════════════════════ */
.kc-dock-wrap { display: none; }
.kc-dock-sheet-overlay { display: none; }

@media (max-width: 900px) {
  html[data-kc-dock] .kc-dock-wrap {
    display: flex;
    position: fixed;
    left: 0; right: 0;
    bottom: calc((14px + var(--kc-safe-b, 0px)) / var(--kc-font-scale, 1));
    justify-content: center;
    z-index: 840;            /* under topbar (850) + drawer scrim */
    pointer-events: none;
  }
  /* Content clearance so nothing hides behind the pill. */
  html[data-kc-dock] body.kc-page {
    /* !important: store.html sets `body.kc-page{padding-bottom:0 !important}`
       to kill a legacy bottom-bar inset — the dock clearance must outrank it
       (higher specificity + !important) or the legal strip hides under the
       pill. Harmless elsewhere: on dock pages this clearance is always right. */
    padding-bottom: calc(96px + var(--kc-safe-b, 0px)) !important;
  }
  /* Flush pages (chat) own their floor — the viewport-locked card makes
     its own room for the dock via --kcc-mob-inset, so the body clearance
     would only push the composer up and reopen the dead strip. */
  html[data-kc-dock][data-kc-dock-flush] body.kc-page {
    padding-bottom: 0 !important;
  }
  /* Composer focused (typing): the dock slides off the floor so the
     keyboard gets the space. Transform+opacity so it animates; inert. */
  html[data-kc-dock-hidden] .kc-dock-wrap {
    transform: translateY(140%);
    opacity: 0;
    pointer-events: none;
  }
  .kc-dock-wrap { transition: transform .22s ease, opacity .18s ease; will-change: transform; }
  @media (prefers-reduced-motion: reduce) { .kc-dock-wrap { transition: none; } }
  /* The quick-actions pill (#kcQcPill — Razor AI / Support) is fixed
     bottom-right at 16px and lands exactly on the dock's More button.
     On dock pages it rides above the dock instead (FAB-above-tab-bar):
     dock inset 14px + pill height ~60px + 8px gap ≈ 82px. */
  html[data-kc-dock] .kc-qc-pill {
    bottom: calc((82px + var(--kc-safe-b, 0px)) / var(--kc-font-scale, 1));
  }
  /* On flush pages the raised pill lands on the composer — hide it there.
     Razor AI / Support stay reachable from every other dock page. */
  html[data-kc-dock-flush] .kc-qc-pill { display: none; }
  /* index's transient SYNCING chip (inline-styled, bottom-right) lands
     under the dock — hide it on dock pages; it's background-sync
     feedback with no mobile value. !important beats its cssText. */
  html[data-kc-dock] #syncIndicator { display: none !important; }

  .kc-dock {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 3px;
    padding: 8px 12px;
    border-radius: 30px;
    /* No backdrop-filter: a blurred fixed layer over a scrolling stream
       (inside the body-zoom context) is the single most expensive thing
       iOS Safari can composite — it was the chat-page jank. Near-opaque
       surface reads almost identically. */
    background: color-mix(in srgb, var(--surface, #121110) 97%, #000);
    border: 1px solid var(--border2, var(--border, #2a2b30));
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
  }

  .kc-dock-item {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    min-width: 48px;
    height: 44px;
    padding: 0 12px;
    border: none;
    border-radius: 23px;
    background: transparent;
    color: var(--muted, #8a857a);
    text-decoration: none;
    font-family: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform .12s ease, background .15s ease, color .15s ease;
  }
  .kc-dock-item:active { transform: scale(.94); }
  .kc-dock-item svg { display: block; flex-shrink: 0; }
  .kc-dock-item span {
    display: none;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .3px;
    line-height: 1;
  }
  .kc-dock-item.active {
    color: var(--accent, #d4a335);
    background: color-mix(in srgb, var(--accent, #d4a335) 14%, transparent);
    gap: 7px;
  }
  .kc-dock-item.active span { display: inline; }
  /* Admins carry six items (Home·Chat·Store·Desk·Admin·More); with the
     active label expanded that overruns a 375px phone. Tighten spacing
     at six and drop the label under 380px so nothing ever clips. */
  .kc-dock[data-count="6"] .kc-dock-item { min-width: 42px; padding: 0 9px; }
  .kc-dock[data-count="6"] .kc-dock-item.active { padding: 0 11px; }
  @media (max-width: 380px) {
    .kc-dock[data-count="6"] .kc-dock-item.active span { display: none; }
    .kc-dock[data-count="6"] .kc-dock-item.active { gap: 0; }
  }

  /* ── More sheet ── */
  .kc-dock-sheet-overlay {
    position: fixed;
    inset: 0;
    z-index: 980;
    background: rgba(0, 0, 0, .55);
    display: none;
    align-items: flex-end;
    animation: kcDockFade .18s ease;
  }
  .kc-dock-sheet-overlay[data-open="1"] { display: flex; }

  .kc-dock-sheet {
    width: 100%;
    background: var(--surface, #121110);
    border: 1px solid var(--border, #2a2b30);
    border-bottom: none;
    border-radius: 20px 20px 0 0;
    padding: 10px 16px calc(22px + var(--kc-safe-b, 0px));
    max-height: calc((100dvh - 60px) / var(--kc-font-scale, 1));
    overflow-y: auto;
    animation: kcDockRise .22s cubic-bezier(.3, .9, .4, 1);
  }
  /* Drag contract shared with KCDialog sheets (_attachSheetSwipe). */
  .kc-dock-sheet.is-dragging {
    transition: none;
    animation: none;
    transform: translateY(var(--kc-sheet-drag, 0px));
  }
  /* Handle style — the global .kc-sheet-handle rule lives inside the
     ≤640px dialog block; restate here so it renders up to 900px. */
  .kc-dock-sheet .kc-sheet-handle {
    width: 38px;
    height: 4px;
    border-radius: 4px;
    background: var(--border2, #3a342d);
    margin: 2px auto 14px;
  }
  .kc-dock-sheet-title {
    font-family: var(--font-mono, 'Space Mono'), monospace;
    font-size: 10px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--muted, #8a857a);
    margin: 0 0 12px;
  }
  .kc-dock-sheet-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px 4px;
  }
  .kc-dock-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 10px 2px;
    border-radius: 12px;
    color: var(--text, #f1ece1);
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
  }
  .kc-dock-tile:active { background: var(--card, #171513); }
  .kc-dock-tile-ic {
    position: relative;
    width: 42px;
    height: 42px;
    border-radius: 13px;
    background: var(--card, #171513);
    border: 1px solid var(--border, #2a2b30);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent, #d4a335);
  }
  .kc-dock-tile span { font-size: 10px; line-height: 1.2; text-align: center; }
  /* Launch gate — mirrors sidebar treatment: regular users get a dim,
     inert tile with a Soon pill; staff get clickable + oxblood draft dot. */
  .kc-dock-tile-locked { opacity: .45; pointer-events: none; }
  .kc-dock-tile-soon {
    position: absolute;
    top: -5px; right: -8px;
    font-size: 7.5px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--muted, #8a857a);
    background: var(--surface, #121110);
    border: 1px solid var(--border, #2a2b30);
    border-radius: 7px;
    padding: 1.5px 5px;
  }
  .kc-dock-tile-draft {
    position: absolute;
    top: -3px; right: -3px;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--red, #a83232);
    border: 1.5px solid var(--surface, #121110);
  }
}

@keyframes kcDockFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes kcDockRise { from { transform: translateY(28px); opacity: .6; } to { transform: translateY(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .kc-dock-sheet, .kc-dock-sheet-overlay { animation: none; }
  .kc-dock-item { transition: none; }
}

/* ── Dock pages, mobile: the drawer is GONE. The pill dock + More
   sheet replace the slide-over sidebar entirely — hamburger hidden,
   sidebar/scrim/edge-swipe-catcher display:none (openMobileSidebar()
   is also JS-guarded on data-kc-dock so the edge-swipe can't reopen
   it). The sidebar stays in the DOM: KCRazors / KCInbox / theme
   modules keep painting their (hidden) nodes, which the sheet + the
   topbar bell mirror as their source of truth. Desktop + non-dock
   pages keep the drawer untouched. ── */
@media (max-width: 900px) {
  html[data-kc-dock] .kc-nav-hamburger { display: none; }
  html[data-kc-dock] .kc-sidebar,
  html[data-kc-dock] .kc-sb-scrim,
  html[data-kc-dock] .kc-sb-edge { display: none; }

  /* Topbar bell (Option B): merged Inbox/Alerts trigger, pushed to
     the right edge. Pip reuses the .kc-inbox-pip chassis; display is
     driven by .has-unread/.has-update on the button — the same
     contract KCInbox paints on the sidebar bell, mirrored over. */
  html[data-kc-dock] .kc-topbar-bell {
    margin-left: auto;
    position: relative;
    width: 36px;
    height: 36px;
    border: 1px solid var(--border2, var(--border, #2a2b30));
    border-radius: 50%;
    background: var(--card, #171513);
    color: var(--muted, #8a857a);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    flex-shrink: 0;
  }
  html[data-kc-dock] .kc-topbar-bell:active { transform: scale(.94); }
  html[data-kc-dock] .kc-topbar-bell.has-unread { color: var(--text, #f1ece1); border-color: color-mix(in srgb, var(--accent, #d4a335) 45%, transparent); }
  .kc-topbar-bell.has-unread .kc-inbox-pip { display: flex; }
  .kc-topbar-bell.has-update .kc-inbox-pip {
    display: flex;
    background: var(--accent, #d4a335);
    min-width: 8px; height: 8px;
    border-radius: 50%;
    padding: 0;
    top: -2px; right: -2px;
  }

  /* Razors balance row at the top of the More sheet. */
  .kc-dock-rz {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    background: var(--card, #171513);
    border: 1px solid var(--border, #2a2b30);
    border-radius: 13px;
    padding: 11px 13px;
    color: var(--text, #f1ece1);
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    -webkit-tap-highlight-color: transparent;
    margin-bottom: 4px;
  }
  .kc-dock-rz:active { background: var(--surface, #121110); }
  .kc-dock-rz-glyph {
    width: 30px; height: 30px;
    border-radius: 9px;
    background: color-mix(in srgb, var(--accent, #d4a335) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 35%, transparent);
    display: flex; align-items: center; justify-content: center;
    color: var(--accent, #d4a335);
    flex-shrink: 0;
  }
  .kc-dock-rz-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .kc-dock-rz-amount {
    font-family: var(--font-mono, 'Space Mono'), monospace;
    font-size: 13px; font-weight: 700; line-height: 1;
  }
  .kc-dock-rz-amount .unit {
    font-size: 9px; color: var(--muted, #8a857a); font-weight: 400; margin-left: 4px;
  }
  .kc-dock-rz-sub {
    font-family: var(--font-mono, 'Space Mono'), monospace;
    font-size: 9px; color: var(--muted, #8a857a);
  }
  .kc-dock-rz-chev { margin-left: auto; color: var(--muted, #8a857a); }

  /* Tools grid: 5-up, neutral (text-colored) icons so the row reads
     as utilities, distinct from the brass page tiles below. */
  .kc-dock-tools { grid-template-columns: repeat(5, 1fr); }
  .kc-dock-tool { border: none; background: transparent; font-family: inherit; cursor: pointer; }
  .kc-dock-tool .kc-dock-tile-ic { color: var(--text, #f1ece1); }
}

/* ═══ CHAT × DOCK FLOOR NEGOTIATION (2026-07) ═══════════════════════
   No CSS knob here on purpose. On mobile the chat column is
   position:fixed and sized in JS (KCChat._sizeChatColumns), which now
   subtracts the dock's measured rect from the column height while the
   dock is visible and reclaims it while typing (data-kc-dock-hidden).
   An earlier --kcc-mob-inset override lived here — it was dead code on
   the chat page (the fixed column ignores that var) and was removed. */

/* ═══════════════════════════════════════════════════════════════════════
   DRAWER FLOOR CLEARANCE  (mobile safe area)
   ──────────────────────────────────────────────────────────────────────
   Every full-height slide-over is `height: 100dvh` pinned to the viewport
   bottom, and each one ends in a bar the person actually has to reach:
   the assistant composer, the bug-report submit, the support reply box,
   the inbox footer. On a phone with a home indicator the last ~34px of
   the viewport is the gesture bar, so those bars sat half under it.

   One rule instead of seven: pad the PANEL, not each bar. box-sizing is
   border-box globally and the panel is a flex column, so the padding
   shortens the content area and every child — including the pinned
   bottom bar — lifts clear. The panel's own background still paints
   through the padding, so it reads as one surface, not a gap.

   No-op on desktop: env(safe-area-inset-bottom) resolves to 0px there.

   Stacking, for the record: these all sit at z 1500–1901, well above the
   mobile dock (840), so the dock is correctly covered while a drawer is
   open and needs no hiding of its own.
   ═══════════════════════════════════════════════════════════════════ */
.ka-panel,
.kbr-panel,
.krz-panel,
.kcs-panel,
.kcc-panel,
.kc-settings-panel,
.kci-drawer {
  padding-bottom: var(--kc-safe-b, 0px);
}

/* ════════════════════════════════════════════════════════════════════
   KCRead — Razor Read modal (⚡ Read from the ticker popover)
   ════════════════════════════════════════════════════════════════════ */
.kc-read-ov {
  position: fixed; inset: 0; z-index: 10010;
  background: rgba(8, 7, 6, 0.72);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity 0.18s ease, visibility 0s linear 0.18s;
  padding: 20px;
}
.kc-read-ov.show {
  opacity: 1; visibility: visible;
  transition: opacity 0.18s ease, visibility 0s linear 0s;
}
.kc-read {
  width: min(680px, 100%);
  max-height: min(86vh, 900px);
  overflow-y: auto;
  background: var(--card, #171513);
  border: 1px solid var(--border, #2a2b30);
  border-radius: 14px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6),
    0 0 0 1px color-mix(in srgb, var(--kc-brass, #d4a335) 18%, transparent);
  position: relative;
}
.kc-read-head {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 12px;
  padding: 13px 18px;
  background: var(--card2, #100f0d);
  border-bottom: 1px solid var(--border, #2a2b30);
}
.kc-read-sym { font-family: 'Space Mono', monospace; font-size: 15px; font-weight: 700; }
.kc-read-sym small { color: var(--muted, #8a857a); font-weight: 400; font-size: 11.5px; margin-left: 8px; }
.kc-read-meta { margin-left: auto; font-family: 'Space Mono', monospace; font-size: 10.5px; color: var(--muted, #8a857a); }
.kc-read-x {
  border: none; background: transparent; color: var(--muted, #8a857a);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 2px 4px;
}
.kc-read-x:hover { color: var(--text, #f1ece1); }

/* ── scan (loading) state ── */
.kc-read-scan {
  min-height: 280px; display: flex; align-items: center; justify-content: center;
  transition: opacity 0.35s ease; padding: 30px 20px;
}
.kc-read-scan.gone { opacity: 0; pointer-events: none;
  /* Out of flow the instant the exit starts. The scan is 280px tall and in
     normal flow; without this, the revealed body rendered BELOW an invisible
     280px block for 400ms and then jumped up when display:none landed. As an
     absolute overlay it crossfades over the incoming content instead. */
  position: absolute; inset: 0; }
.kc-read-scan-box { width: min(380px, 92%); font-family: 'Space Mono', monospace; }
.kc-read-scan-head {
  font-size: 10.5px; letter-spacing: 0.16em; color: var(--kc-brass, #d4a335);
  margin-bottom: 16px; display: flex; align-items: center; gap: 9px;
}
.kc-read-blink {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--kc-brass, #d4a335); animation: kcReadBlink 1s infinite;
}
@keyframes kcReadBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }
.kc-read-scan-lines { display: flex; flex-direction: column; gap: 8px; min-height: 138px; }
.kc-read-scan-l {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 11.5px; color: var(--text-mid, #c8c2b4);
  opacity: 0; transform: translateX(-7px); transition: all 0.22s ease;
}
.kc-read-scan-l.in { opacity: 1; transform: none; }
.kc-read-scan-l em { font-style: normal; color: var(--muted, #8a857a); }
.kc-read-scan-l .ok { color: var(--up, #6dd99c); }
.kc-read-scan-l .run { color: var(--kc-brass, #d4a335); animation: kcReadBlink 0.6s infinite; }
.kc-read-scan-prog { height: 3px; background: var(--border, #2a2b30); border-radius: 2px; margin-top: 18px; overflow: hidden; }
.kc-read-scan-prog i {
  display: block; height: 100%; width: 0; border-radius: 2px;
  background: linear-gradient(90deg, var(--kc-brass, #d4a335), var(--up, #6dd99c));
  transition: width 0.3s ease;
}

/* ── shared reveal primitives ── */
.kc-read-rv { opacity: 0; transform: translateY(9px); transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }
.kc-read-rv.in { opacity: 1; transform: none; }

/* ── ticket ── */
.kc-read-ticket {
  margin: 18px;
  border: 1px solid color-mix(in srgb, var(--kc-brass, #d4a335) 30%, transparent);
  border-radius: 12px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--kc-brass, #d4a335) 6%, transparent), transparent 55%), var(--card2, #100f0d);
  padding: 17px 18px;
}
.kc-read-ticket-top { display: flex; align-items: baseline; gap: 15px; flex-wrap: wrap; }
.kc-read-word {
  font-family: 'Space Mono', monospace; font-size: 34px; font-weight: 700;
  letter-spacing: 0.05em; line-height: 1;
  opacity: 0; transform: scale(1.5);
}
.kc-read-word.up { color: var(--up, #6dd99c); }
.kc-read-word.dn { color: var(--down, #a83232); }
.kc-read-word.fl { color: var(--muted, #8a857a); }
.kc-read-word.in { animation: kcReadStamp 0.5s cubic-bezier(0.2, 1.6, 0.4, 1) forwards; }
@keyframes kcReadStamp {
  0% { opacity: 0; transform: scale(1.5); }
  60% { opacity: 1; transform: scale(0.96); }
  100% { opacity: 1; transform: scale(1); }
}
.kc-read-conv { display: flex; flex-direction: column; gap: 4px; }
.kc-read-conv .n { font-family: 'Space Mono', monospace; font-size: 11.5px; color: var(--kc-brass, #d4a335); }
.kc-read-conv .n b { font-weight: 700; }
.kc-read-conv .cbar { width: 120px; height: 5px; border-radius: 3px; background: var(--border, #2a2b30); overflow: hidden; }
.kc-read-conv .cbar i {
  display: block; height: 100%; width: 0; border-radius: 3px;
  background: linear-gradient(90deg, var(--kc-brass, #d4a335), var(--up, #6dd99c));
  transition: width 1.1s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.kc-read-plain { font-size: 13.5px; line-height: 1.6; color: var(--text, #f1ece1); margin: 11px 0 0; }
.kc-read-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 9px; margin-top: 14px; }
.kc-read-tk {
  background: rgba(8, 7, 6, 0.5); border: 1px solid var(--border, #2a2b30);
  border-radius: 8px; padding: 8px 10px; text-align: center;
  opacity: 0; transform: translateY(9px);
  transition: opacity 0.4s cubic-bezier(0.2, 0.9, 0.3, 1), transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.kc-read-tk.in { opacity: 1; transform: none; }
.kc-read-tk.hl { border-color: color-mix(in srgb, var(--kc-brass, #d4a335) 40%, transparent); animation: kcReadGlow 3s infinite 2.4s; }
@keyframes kcReadGlow {
  0%, 100% { background: rgba(8, 7, 6, 0.5); }
  50% { background: color-mix(in srgb, var(--kc-brass, #d4a335) 9%, rgba(8, 7, 6, 0.5)); }
}
.kc-read-tk .k { font-family: 'Space Grotesk', sans-serif; font-size: 9px; color: var(--muted, #8a857a); letter-spacing: 0.1em; text-transform: uppercase; }
.kc-read-tk .v { font-family: 'Space Mono', monospace; font-size: 12.5px; margin-top: 4px; font-weight: 600; }
.kc-read-tk .v em { font-style: normal; color: var(--muted, #8a857a); font-size: 9.5px; }
.kc-read-tk .v.up { color: var(--up, #6dd99c); }
.kc-read-tk .v.dn { color: #e07a7a; }
.kc-read-tk .v.br { color: var(--kc-brass, #d4a335); }
.kc-read-clocks { display: flex; gap: 7px; align-items: center; margin-top: 14px; flex-wrap: wrap; }
.kc-read-clock {
  font-family: 'Space Mono', monospace; font-size: 10.5px; padding: 5px 10px;
  border-radius: 7px; border: 1px solid var(--border, #2a2b30);
  background: var(--card, #171513); color: var(--muted, #8a857a);
  opacity: 0; transform: rotateX(80deg);
  transition: all 0.4s cubic-bezier(0.2, 1.4, 0.4, 1);
}
.kc-read-clock.in { opacity: 1; transform: none; }
.kc-read-clock b { margin-left: 5px; font-size: 12px; }
.kc-read-clock.u { border-color: color-mix(in srgb, var(--up, #6dd99c) 30%, transparent); }
.kc-read-clock.u b { color: var(--up, #6dd99c); }
.kc-read-clock.d { border-color: color-mix(in srgb, var(--red, #a83232) 35%, transparent); }
.kc-read-clock.d b { color: #e07a7a; }
.kc-read-clock.f b { color: var(--muted, #8a857a); }

/* ── late gauge ── */
.kc-read-late {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 14px 18px; border-top: 1px solid var(--border, #2a2b30); margin-top: 4px;
}
.kc-read-late .lt { font-family: 'Space Mono', monospace; font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; }
.kc-read-late .mid { flex: 1; min-width: 200px; }
.kc-read-late .bar {
  height: 8px; border-radius: 4px; position: relative;
  background: linear-gradient(90deg, var(--up, #6dd99c) 0 40%, var(--kc-brass, #d4a335) 40% 72%, var(--red, #a83232) 72% 100%);
}
.kc-read-late .pin {
  position: absolute; top: -4px; width: 3px; height: 16px;
  background: #fff; border-radius: 2px; left: 0;
  transition: left 1.1s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.kc-read-late .scale { display: flex; justify-content: space-between; font-family: 'Space Mono', monospace; font-size: 9px; color: var(--muted, #8a857a); margin-top: 6px; letter-spacing: 0.05em; }
.kc-read-late .say { font-size: 11.5px; color: var(--text-mid, #c8c2b4); line-height: 1.5; margin: 0; max-width: 100%; }

/* ── case ── */
.kc-read-sec { padding: 15px 18px; border-top: 1px solid var(--border, #2a2b30); }
.kc-read-sec-t {
  font-family: 'Space Mono', monospace; font-size: 10.5px; color: var(--kc-brass, #d4a335);
  letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 12px;
}
.kc-read-sec-t span { color: var(--muted, #8a857a); letter-spacing: 0; text-transform: none; margin-left: 7px; }
.kc-read-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }
.kc-read-col .ch { font-family: 'Space Mono', monospace; font-size: 9.5px; letter-spacing: 0.12em; margin-bottom: 8px; }
.kc-read-col.for .ch { color: var(--up, #6dd99c); }
.kc-read-col.against .ch { color: #e07a7a; }
.kc-read-ev {
  display: flex; gap: 10px; padding: 7px 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--border, #2a2b30) 65%, transparent);
  cursor: pointer;
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.kc-read-ev.in { opacity: 1; transform: none; }
.kc-read-ev:last-child { border-bottom: none; }
.kc-read-col.for .m { color: var(--up, #6dd99c); }
.kc-read-col.against .m { color: #e07a7a; }
.kc-read-ev .m { font-family: 'Space Mono', monospace; font-size: 11.5px; flex: none; width: 13px; text-align: center; }
.kc-read-ev .say { font-size: 12.5px; line-height: 1.5; flex: 1; }
.kc-read-ev:hover .say { color: var(--text-bright, #faf6ec); }
.kc-read-ev .say small {
  display: block; font-family: 'Space Mono', monospace; font-size: 9.5px;
  color: var(--kc-brass, #d4a335);
  max-height: 0; overflow: hidden; opacity: 0; margin-top: 0;
  transition: all 0.32s ease;
}
.kc-read-ev.open .say small { max-height: 44px; opacity: 1; margin-top: 4px; }
.kc-read-ev .chev { margin-left: auto; color: var(--muted, #8a857a); font-size: 9px; align-self: center; transition: transform 0.3s; }
.kc-read-ev.open .chev { transform: rotate(180deg); }

/* ── fleet ── */
.kc-read-fleet {
  display: flex; align-items: center; gap: 11px; font-size: 12.5px; padding: 6px 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--border, #2a2b30) 65%, transparent);
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.kc-read-fleet.in { opacity: 1; transform: none; }
.kc-read-fleet:last-of-type { border-bottom: none; }
.kc-read-fleet .nm { font-family: 'Space Mono', monospace; width: 100px; font-size: 12px; }
.kc-read-fleet .nt { color: var(--muted, #8a857a); font-size: 11.5px; margin-left: auto; text-align: right; }
.kc-read-tag {
  font-family: 'Space Mono', monospace; font-size: 9.5px; padding: 2px 7px;
  border-radius: 4px; letter-spacing: 0.05em;
}
.kc-read-tag.up { background: color-mix(in srgb, var(--up, #6dd99c) 12%, transparent); color: var(--up, #6dd99c); border: 1px solid color-mix(in srgb, var(--up, #6dd99c) 30%, transparent); }
.kc-read-tag.dn { background: color-mix(in srgb, var(--red, #a83232) 14%, transparent); color: #e07a7a; border: 1px solid color-mix(in srgb, var(--red, #a83232) 40%, transparent); }
.kc-read-fsum {
  margin-top: 10px; padding: 9px 12px; font-size: 11.5px; color: var(--text-mid, #c8c2b4);
  background: var(--card2, #100f0d); border: 1px solid var(--border, #2a2b30); border-radius: 8px;
}
.kc-read-fsum b { color: var(--up, #6dd99c); font-family: 'Space Mono', monospace; }
.kc-read-fempty { font-size: 12px; color: var(--muted, #8a857a); }

/* ── Share pill (full reads only — render() never paints previews).
   One row under the fleet section: brass-outline pill + the promise
   that makes sharing feel safe to the buyer. */
.kc-read-actions {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px 18px;
  border-top: 1px solid var(--border, #2a2a24);
}
.kc-read-share {
  font-family: 'Space Mono', monospace; font-size: 11px; letter-spacing: .6px;
  color: var(--accent, #d4a335); background: transparent; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--accent, #d4a335) 45%, transparent);
  border-radius: 7px; padding: 6px 12px;
}
.kc-read-share:hover {
  border-color: var(--accent, #d4a335);
  background: color-mix(in srgb, var(--accent, #d4a335) 10%, transparent);
}
.kc-read-share:disabled { opacity: .5; cursor: default; }
.kc-read-share-note {
  font-family: 'Space Mono', monospace; font-size: 9px; letter-spacing: .5px;
  color: var(--muted, #8a857a);
}

/* ── ⚡ Read button in the popover ── */
.kc-sym-pop-act.kc-sym-pop-read {
  color: var(--kc-brass, #d4a335);
  border-color: color-mix(in srgb, var(--kc-brass, #d4a335) 45%, transparent);
  background: color-mix(in srgb, var(--kc-brass, #d4a335) 7%, transparent);
  font-weight: 600;
}
.kc-sym-pop-act.kc-sym-pop-read:hover {
  background: color-mix(in srgb, var(--kc-brass, #d4a335) 14%, transparent);
}

/* ── Razor Read: free preview ────────────────────────────────────────
   The pre-purchase state. Everything here is either real (clock arrows, the
   two counts, one case line) or an explicit skeleton — there is no blurred
   prose, because the server never sends the other case lines and inventing
   sentences to blur would ship text that is false to anyone who inspects it.
   The ghost below is abstract shapes for that reason: it says "a verdict, a
   sentence and five boxes live here" without claiming to know their values. */
.kc-read-pv { opacity: 0; transform: translateY(8px);
  transition: opacity .38s ease, transform .38s cubic-bezier(.2,.8,.25,1); }
.kc-read-pv.in { opacity: 1; transform: none; }
.kc-read-pv-lockwrap { position: relative; margin: 12px 14px 0; }
/* Match the lockwrap's gutter — .kc-read-clocks has no side margin of its own
   because in the paid modal it sits inside the padded ticket. */
.kc-read-pv .kc-read-clocks { margin: 13px 14px 15px; }
.kc-read-pv-ghost {
  border: 1px solid color-mix(in srgb, var(--kc-brass, #d4a335) 22%, transparent);
  border-radius: 10px; padding: 14px; pointer-events: none; user-select: none;
}
.kc-read-pv-ghost > * { background: color-mix(in srgb, var(--border, #2a2b30) 70%, transparent);
  border-radius: 5px; }
.kc-read-pvword { height: 30px; width: 132px; margin-bottom: 12px; }
.kc-read-pvline { height: 9px; width: 96%; margin-bottom: 6px; }
.kc-read-pvline.s { width: 72%; margin-bottom: 13px; }
.kc-read-pvgrid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;
  background: none !important; }
.kc-read-pvgrid i { display: block; height: 40px; border-radius: 7px;
  background: color-mix(in srgb, var(--border, #2a2b30) 70%, transparent); }
/* The lock sits ON the ghost rather than blurring it: a blur filter is
   reversible in devtools, a value that was never sent is not. */
.kc-read-pv-lock {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 9px; text-align: center;
  padding: 12px; border-radius: 10px;
  /* Light enough that the ghost's shapes and brass border read through —
     the lock should say "a locked report lives here", not "empty panel".
     (Was 96%: at that opacity the ghost vanished and the whole lockwrap
     looked like dead space.) */
  background: color-mix(in srgb, var(--card, #171513) 80%, transparent);
  backdrop-filter: blur(1.5px);
}
.kc-read-pv-lock small { font-family: 'Space Mono', monospace; font-size: 9.5px;
  letter-spacing: .07em; color: var(--muted, #8a857a); }
.kc-read-buy {
  background: var(--kc-brass, #d4a335); color: #141210; border: none;
  border-radius: 999px; padding: 10px 20px; cursor: pointer;
  font-family: 'Space Mono', monospace; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; transition: filter .12s ease, opacity .12s ease;
}
.kc-read-buy:hover { filter: brightness(1.08); }
.kc-read-buy:disabled { opacity: .55; cursor: default; }
/* One real case line, marked as the free one. */
.kc-read-freetag {
  font-family: 'Space Mono', monospace; font-size: 8px; letter-spacing: .12em;
  color: var(--up, #6dd99c); margin-left: 7px; padding: 1px 5px; border-radius: 3px;
  border: 1px solid color-mix(in srgb, var(--up, #6dd99c) 35%, transparent);
  background: color-mix(in srgb, var(--up, #6dd99c) 10%, transparent);
}
.kc-read-ev.is-free { cursor: default; }
/* Skeleton stand-ins: one per withheld case line, so the count you are told
   and the number of rows you can see always agree. */
.kc-read-pvbar {
  height: 9px; margin: 13px 0; border-radius: 5px;
  background: color-mix(in srgb, var(--border, #2a2b30) 70%, transparent);
  opacity: 0; transform: translateY(6px);
  transition: opacity .3s ease, transform .3s ease;
}
.kc-read-pvbar.in { opacity: 1; transform: none; }
@media (max-width: 640px) {
  .kc-read-pvgrid { grid-template-columns: repeat(3, 1fr); }
}

/* ── mobile: full-width sheet ── */
@media (max-width: 640px) {
  /* Dynamic viewport, not vh. On iOS Safari `vh` means the LARGE viewport —
     the height the page would have if the URL bar were retracted — so with
     the bar and toolbar on screen, 94vh is taller than what you can actually
     see. The sheet is bottom-anchored (align-items: flex-end), so the excess
     came off the TOP: the header, and with it the × that closes the modal,
     sat above the visible area and could not be reached or scrolled to (it is
     position:sticky, but sticky pins to the top of its scroll container, and
     the container itself was off-screen).
     `dvh` tracks the viewport as the browser chrome comes and goes. The vh
     line stays first as the fallback for engines without dvh. */
  .kc-read-ov { padding: 0; align-items: flex-end; height: 100vh; height: 100dvh; }
  .kc-read {
    width: 100%;
    max-height: 94vh;
    max-height: 94dvh;
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    /* Clear the home indicator so the last row isn't under it. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .kc-read-grid { grid-template-columns: repeat(2, 1fr); }
  .kc-read-cols { grid-template-columns: 1fr; }
  .kc-read-word { font-size: 29px; }
}
@media (prefers-reduced-motion: reduce) {
  .kc-read-ov *, .kc-read-ov { animation: none !important; transition: none !important; }
}


/* ── Razor Read: WAIT state, lean chip, empty case column ── */
/* WAIT is neither a buy nor a sell word — brass keeps it visually distinct
   from the green LONG / oxblood SHORT so it can't be skim-read as either. */
.kc-read-word.wt { color: var(--kc-brass, #d4a335); }
/* The FLAT no-call chip wears the same chip as the WAIT lean chip on purpose:
   both sit beside the verdict word saying "here is the qualifier". They can
   never appear together (FLAT is dir === 0, WAIT is dir !== 0), so one rule
   serves both and the two states can't drift apart. */
.kc-read-lean,
.kc-read-nocall {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted, #8a857a);
  border: 1px solid var(--border, #2a2b30);
  border-radius: 5px;
  padding: 3px 8px;
  align-self: center;
}
.kc-read-cempty {
  font-size: 12px;
  color: var(--muted, #8a857a);
  padding: 7px 0;
  font-style: italic;
}

/* ── Mobile: clear the docked quick-chat pill (2026-09-24 audit) ────────
   The dock reserves 96px, but the quick-chat pill docks ABOVE the nav
   (bottom ~84px, 45px tall), so the last content on a page ended under
   the pill. Reserve room for both whenever the pill is docked. Flush
   pages keep their own zero padding. */
@media (max-width: 900px) {
  html[data-kc-dock]:not([data-kc-dock-flush]) body.kc-page:has(.kc-qc-pill.kc-qc-dock) {
    /* !important to match the dock rule it overrides (also !important). */
    padding-bottom: calc(144px + var(--kc-safe-b, 0px)) !important;
  }
}
