/*!******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../tokens/dist/tokens.css ***!
  \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/**
 * Do not edit directly
 */

[data-sovereign] {
  /* origin: step-09 — wordmark multicolor · cyan */
  --sov-wordmark-hopkins-d: #90e0ff;
  /* origin: step-09 — wordmark multicolor · gold */
  --sov-wordmark-hopkins-c: #ffcb57;
  /* origin: step-09 — wordmark multicolor · red */
  --sov-wordmark-hopkins-b: #ff333d;
  /* origin: step-09 — wordmark multicolor · violet */
  --sov-wordmark-hopkins-a: #a960ee;
  --sov-component-mobile-flyout-width: 320px;
  --sov-component-mobile-page-header-height: 56px;
  --sov-component-mobile-bottom-nav-height: 64px;
  --sov-component-home-surface-max-shelf-sections: 6;
  --sov-component-section-limit-max-sections: 10;
  --sov-component-section-limit-max-catalog-items: 12;
  --sov-component-section-limit-max-spark-items: 6;
  --sov-component-section-limit-max-bookcast-items: 6;
  --sov-component-section-limit-max-shelf-items: 8;
  --sov-component-section-limit-max-hero-tiles: 3;
  --sov-component-pill-row-max-total-items: 12;
  --sov-component-pill-row-max-buttons: 6;
  --sov-component-code-artifact-label-size: 11px;
  --sov-component-code-artifact-tint: 4%;
  --sov-component-focus-pill-size: 44px;
  --sov-component-toast-stack-max: 3;
  --sov-component-record-list-item-time-col-width: 64px;
  --sov-component-chapter-mark-border-width: 3px;
  --sov-component-bookmark-gutter-dot-size: 6px;
  --sov-component-bookmark-gutter-width: 3px;
  --sov-component-transport-dock-scrub-height: 3px;
  --sov-component-transport-dock-control-size: 36px;
  --sov-component-composer-padding-x: 18px;
  --sov-component-composer-padding-y: 14px;
  --sov-component-bridge-sheet-handle-height: 4px;
  --sov-component-bridge-sheet-handle-width: 36px;
  --sov-component-annotation-pair-tint: 6%;
  --sov-component-highlight-underline-width: 2px;
  --sov-component-highlight-tint: 10%;
  --sov-component-tool-reveal-tint: 5%;
  --sov-component-citation-chip-index-size: 14px;
  --sov-component-citation-chip-tint: 8%;
  --sov-component-pull-quote-tint: 5%;
  --sov-component-pull-quote-border-width: 3px;
  --sov-component-passage-padding-y: 22px;
  --sov-component-passage-max-width: 520px;
  --sov-component-passage-tint: 5%;
  --sov-component-chat-bubble-radius-kaos: 4px 18px 18px 18px;
  --sov-component-chat-bubble-radius-user: 18px 18px 4px 18px;
  --sov-component-chat-bubble-max-width: 72%;
  --sov-component-hero-tile-lift: translateY(-3px);
  --sov-component-hero-tile-ratio-compact: 3/4;
  --sov-component-hero-tile-ratio-hero: 5/8;
  --sov-component-unified-history-sessions-eyebrow: SESSIONS;
  --sov-component-unified-history-pinned-fallback-eyebrow: PINNED · THIS THREAD;
  --sov-component-unified-history-session-preview-chars: 100;
  --sov-component-nav-rail-group-item-gap: 2px;
  --sov-component-nav-rail-active-pip-width: 3px;
  --sov-component-nav-rail-active-tint: 10%;
  --sov-persona-hairline: color-mix(in oklab, var(--sov-persona-accent) 35%, transparent);
  --sov-wake-dormant-fade: 0.55;
  --sov-wake-quiescent-dim: 0.95;
  --sov-wake-quiescent-scale: 0.999;
  --sov-wake-quiescent-blur: 0.5px;
  --sov-wake-presence-threshold: 0.70;
  --sov-wake-tier-dormant-shadow-strength: 0.25;
  --sov-wake-tier-dormant-blur: 3px;
  --sov-wake-tier-dormant-opacity: 0.55;
  --sov-wake-tier-dormant-scale: 0.992;
  --sov-wake-tier-cold-shadow-strength: 0.55;
  --sov-wake-tier-cold-blur: 1.5px;
  --sov-wake-tier-cold-opacity: 0.78;
  --sov-wake-tier-cold-scale: 0.996;
  --sov-wake-tier-warm-shadow-strength: 0.85;
  --sov-wake-tier-warm-blur: 0px;
  --sov-wake-tier-warm-opacity: 0.92;
  --sov-wake-tier-warm-scale: 0.998;
  --sov-wake-tier-instant-shadow-strength: 1.0;
  --sov-wake-tier-instant-blur: 0px;
  --sov-wake-tier-instant-opacity: 1.0;
  --sov-wake-tier-instant-scale: 1.0;
  --sov-motion-keyframe-thinking-dot: sov-thinking-dot;
  --sov-motion-keyframe-breathe-ambient: sov-breathe-ambient;
  --sov-motion-keyframe-word-fade: sov-word-fade;
  --sov-motion-keyframe-gold-shimmer: sov-gold-shimmer;
  --sov-motion-keyframe-breathe: sov-breathe;
  --sov-motion-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --sov-motion-ease-out: cubic-bezier(0.16, 1, 0.30, 1);
  --sov-motion-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --sov-motion-duration-thinking-dot: 1200ms;
  --sov-motion-duration-ambient-breathe: 22000ms;
  --sov-motion-duration-wordmark-shimmer: 22000ms;
  --sov-motion-duration-breath: 4200ms;
  --sov-motion-duration-slow: 400ms;
  --sov-motion-duration-base: 240ms;
  --sov-motion-duration-quick: 180ms;
  --sov-motion-duration-instant: 120ms;
  --sov-hairline-on-raised: inset 0 0 0 1px rgba(255,255,255,0.08);
  --sov-hairline-neutral: inset 0 0 0 1px rgba(255,255,255,0.06);
  --sov-shadow-transport: 0 18px 48px -12px rgba(0,0,0,0.5);
  --sov-shadow-bridge: 0 -14px 48px -12px rgba(0,0,0,0.3);
  --sov-shadow-sheet: 0 24px 64px -16px rgba(0,0,0,0.6);
  --sov-shadow-card: 0 12px 32px -16px rgba(0,0,0,0.4);
  --sov-shadow-tile: 0 12px 32px -16px rgba(0,0,0,0.5);
  --sov-glass-saturate: 180%;
  --sov-glass-blur-ambient: 12px;
  --sov-glass-blur-deep: 28px;
  --sov-glass-blur: 16px;
  --sov-glass-mix-strong: 82%;
  --sov-glass-mix: 72%;
  --sov-layout-breakpoint-wide: 1440px;
  --sov-layout-breakpoint-desktop: 1280px;
  --sov-layout-breakpoint-tablet: 1024px;
  --sov-layout-breakpoint-mobile: 768px;
  --sov-layout-transport-width: 560px;
  --sov-layout-sheet-width: 480px;
  --sov-layout-bridge-sheet-width: 440px;
  --sov-layout-body-max: 640px;
  --sov-layout-stream-max: 720px;
  --sov-layout-pretext-prose-max: 820px;
  --sov-layout-column-max: 980px;
  --sov-layout-right-rail-width: 360px;
  --sov-layout-rail-width: 240px;
  --sov-radius-pill: 999px;
  --sov-radius-sheet: 24px;
  --sov-radius-xl: 20px;
  --sov-radius-lg: 16px;
  --sov-radius-md: 12px;
  --sov-radius-sm: 8px;
  --sov-radius-xs: 4px;
  --sov-space-8: 64px;
  --sov-space-7: 48px;
  --sov-space-6: 32px;
  --sov-space-5: 24px;
  --sov-space-4: 16px;
  --sov-space-3: 12px;
  --sov-space-2: 8px;
  --sov-space-1: 4px;
  --sov-typography-rung-caption-tracking: 0.14em;
  --sov-typography-rung-caption-weight: 400;
  --sov-typography-rung-caption-line: 1.30;
  --sov-typography-rung-caption-size: 10px;
  --sov-typography-rung-tile-tracking: 0;
  --sov-typography-rung-tile-weight: 500;
  --sov-typography-rung-tile-line: 1.35;
  --sov-typography-rung-tile-size: 14px;
  --sov-typography-rung-field-tracking: 0;
  --sov-typography-rung-field-weight: 400;
  --sov-typography-rung-field-line: 1.50;
  --sov-typography-rung-field-size: 16px;
  --sov-typography-rung-section-tracking: 0.14em;
  --sov-typography-rung-section-weight: 600;
  --sov-typography-rung-section-line: 1.20;
  --sov-typography-rung-section-size: 22px;
  --sov-typography-rung-display-tracking: -0.02em;
  --sov-typography-rung-display-weight: 500;
  --sov-typography-rung-display-line: 1.06;
  --sov-typography-rung-display-size: 36px;
  --sov-typography-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --sov-typography-font-serif: 'Newsreader', 'Noto Serif', Georgia, 'Times New Roman', serif;
  --sov-typography-font-sans: 'Inter', 'Noto Sans', system-ui, -apple-system, sans-serif;
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-surface-sunken: oklch(0.13 0.004 260);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-surface-raised: oklch(0.24 0.008 260);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-subtle: oklch(0.74 0.006 260);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-muted: oklch(0.58 0.008 260);
  /* origin: step-09 — primary surface accent · dark canonical */
  --sov-color-accent: oklch(0.72 0.10 60);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-veil: oklch(0.22 0.01 260);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-whisper: oklch(0.62 0.015 260);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-ink: oklch(0.95 0.004 80);
  /* origin: step-09 — surface tier · dark canonical */
  --sov-color-bg: oklch(0.17 0.005 260);
  --sov-alpha-ambient-where: 6%;
  --sov-alpha-ambient-gold: 8%;
  --sov-alpha-pied-halo: 28%;
  --sov-alpha-where-light-halo: 32%;
  --sov-alpha-gold-hairline: 35%;
  --sov-alpha-gold-halo: 30%;
  --mk-accent-ember: oklch(0.72 0.10 60);
  --mk-ink-neutral-13: oklch(0.13 0.004 260);
  --mk-ink-neutral-17: oklch(0.17 0.005 260);
  --mk-ink-neutral-22: oklch(0.22 0.010 260);
  --mk-ink-neutral-24: oklch(0.24 0.008 260);
  --mk-ink-neutral-62: oklch(0.62 0.015 260);
  --mk-ink-neutral-58: oklch(0.58 0.008 260);
  --mk-ink-neutral-74: oklch(0.74 0.006 260);
  --mk-ink-neutral-95: oklch(0.95 0.004 80);
  /* origin: step-library-v0.2 — Rumi · the leaping spark · dark canonical */
  --mk-glow-spark: oklch(0.85 0.19 105);
  /* origin: step-33 — Rumi · moon */
  --mk-glow-moon-stays-bright: oklch(0.82 0.03 260);
  /* origin: step-33 — Rumi · earth-gold */
  --mk-glow-ruin-and-treasure: oklch(0.58 0.16 45);
  /* origin: step-33 — Rumi · tide */
  --mk-glow-silently-drawn: oklch(0.62 0.12 250);
  /* origin: step-33 — Rumi · dawn */
  --mk-glow-morning-breeze: oklch(0.78 0.10 95);
  /* origin: step-33 — Rumi · open field */
  --mk-glow-out-beyond-ideas: oklch(0.76 0.08 100);
  /* origin: step-33 — Rumi · bridge rose */
  --mk-glow-love-is-the-bridge: oklch(0.64 0.17 320);
  /* origin: step-33 — Rumi · sea-air */
  --mk-glow-not-a-drop: oklch(0.68 0.10 210);
  /* origin: step-33 — Rumi · hushed cyan */
  --mk-glow-silence-of-god: oklch(0.72 0.06 230);
  /* origin: step-33 — Rumi · fire */
  --mk-glow-set-life-on-fire: oklch(0.58 0.24 25);
  /* origin: step-09 — Rumi · insight · reflection */
  --mk-glow-where-light-enters: oklch(0.72 0.18 40);
  /* origin: step-33 — Rumi · rose-beauty */
  --mk-glow-beauty-we-love: oklch(0.68 0.16 340);
  /* origin: step-33 — Rumi · warm call */
  --mk-glow-what-you-seek: oklch(0.70 0.18 60);
  /* origin: step-33 — Hopkins · wild water */
  --mk-glow-inversnaid: oklch(0.54 0.16 180);
  /* origin: step-33 — Hopkins · refuge teal */
  --mk-glow-heaven-haven: oklch(0.74 0.10 190);
  /* origin: step-33 — Hopkins · low-key rose */
  --mk-glow-no-worst-there-is-none: oklch(0.44 0.10 320);
  /* origin: step-33 — Hopkins · night violet */
  --mk-glow-the-starlight-night: oklch(0.56 0.14 260);
  /* origin: step-33 — Hopkins · actively speaking */
  --mk-glow-as-kingfishers-catch-fire: oklch(0.72 0.20 205);
  /* origin: step-33 — Hopkins · weight of water */
  --mk-glow-the-wreck-of-the-deutschland: oklch(0.50 0.20 260);
  /* origin: step-33 — Hopkins · seasonal softness */
  --mk-glow-spring-and-fall: oklch(0.72 0.14 135);
  /* origin: step-33 — Hopkins · lamp in dark */
  --mk-glow-the-lantern-out-of-doors: oklch(0.68 0.18 50);
  /* origin: step-33 — Hopkins · grief tempered */
  --mk-glow-carrion-comfort: oklch(0.48 0.08 315);
  /* origin: step-33 — Hopkins · charge */
  --mk-glow-gods-grandeur: oklch(0.64 0.16 245);
  /* origin: step-33 — Hopkins · tethered */
  --mk-glow-the-windhover: oklch(0.70 0.10 280);
  /* origin: step-33 — Hopkins · variety */
  --mk-glow-pied-beauty: oklch(0.76 0.12 140);
  /* origin: step-09 — gold family */
  --mk-glow-gold-ring: oklch(0.78 0.16 80);
  /* origin: step-09 — gold family */
  --mk-glow-gold-deep: oklch(0.70 0.16 78);
  /* origin: step-09 — gold family */
  --mk-glow-gold-soft: oklch(0.86 0.10 75);
  /* origin: step-09 — Malaika signature · dark canonical */
  --mk-glow-gold: oklch(0.82 0.14 80);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-surface-sunken: var(--sov-color-surface-sunken);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-surface-raised: var(--sov-color-surface-raised);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-subtle: var(--sov-color-subtle);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-muted: var(--sov-color-muted);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-accent: var(--sov-color-accent);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-veil: var(--sov-color-veil);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-whisper: var(--sov-color-whisper);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-ink: var(--sov-color-ink);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-bg: var(--sov-color-bg);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-font-mono: var(--sov-typography-font-mono);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-font-serif: var(--sov-typography-font-serif);
  /* origin: step-09 — migration bridge · sovereign.css → tokens.json */
  --sov-font-sans: var(--sov-typography-font-sans);
  --sov-component-mobile-bottom-sheet-radius: var(--sov-radius-xl);
  --sov-component-home-surface-featured-gap: var(--sov-space-4);
  --sov-component-home-surface-shelf-grid-gap: var(--sov-space-3);
  --sov-component-pill-row-padding-y: var(--sov-space-1);
  --sov-component-pill-row-gap: var(--sov-space-2);
  --sov-component-code-artifact-label-font: var(--sov-typography-font-mono);
  --sov-component-code-artifact-radius: var(--sov-radius-md);
  --sov-component-focus-pill-offset: var(--sov-space-5);
  --sov-component-toast-padding-x: var(--sov-space-4);
  --sov-component-toast-padding-y: var(--sov-space-3);
  --sov-component-toast-anchor-offset: var(--sov-space-4);
  --sov-component-toast-radius: var(--sov-radius-md);
  --sov-component-record-list-item-row-gap: var(--sov-space-3);
  --sov-component-transport-dock-primary-bg: var(--sov-color-accent);
  --sov-component-transport-dock-radius: var(--sov-radius-xl);
  --sov-component-transport-dock-width: var(--sov-layout-transport-width);
  --sov-component-composer-blur: var(--sov-glass-blur);
  --sov-component-composer-icon-button-size: var(--sov-space-7);
  --sov-component-composer-radius: var(--sov-radius-lg);
  --sov-component-bridge-sheet-radius-top: var(--sov-radius-xl);
  --sov-component-sheet-mix: var(--sov-glass-mix-strong);
  --sov-component-sheet-blur: var(--sov-glass-blur-deep);
  --sov-component-sheet-radius: var(--sov-radius-sheet);
  --sov-component-annotation-pair-kaos-indent: var(--sov-space-4);
  --sov-component-tool-reveal-label-color: var(--mk-glow-where-light-enters);
  --sov-component-passage-padding-x: var(--sov-space-5);
  --sov-component-chat-bubble-padding-x: var(--sov-space-4);
  --sov-component-chat-bubble-padding-y: var(--sov-space-3);
  --sov-component-hero-tile-radius-compact: var(--sov-radius-md);
  --sov-component-hero-tile-radius-hero: var(--sov-radius-lg);
  --sov-component-unified-history-list-row-gap: var(--sov-space-1);
  --sov-component-right-rail-drawer-breakpoint: var(--sov-layout-breakpoint-desktop);
  --sov-component-right-rail-search-radius: var(--sov-radius-pill);
  --sov-component-right-rail-width: var(--sov-layout-right-rail-width);
  --sov-component-nav-rail-eyebrow-padding-bottom: var(--sov-space-1);
  --sov-component-nav-rail-eyebrow-padding-top: var(--sov-space-2);
  --sov-component-nav-rail-group-section-gap: var(--sov-space-1);
  --sov-component-nav-rail-row-padding-x: var(--sov-space-3);
  --sov-component-nav-rail-row-padding-y: var(--sov-space-2);
  --sov-component-nav-rail-row-radius: var(--sov-radius-md);
  --sov-component-nav-rail-width: var(--sov-layout-rail-width);
  --sov-persona-presence: var(--mk-glow-gold-soft);
  --sov-persona-accent: var(--mk-glow-gold);
  --sov-wake-cost-inference: var(--sov-motion-duration-breath);
  --sov-wake-cost-network: var(--sov-motion-duration-slow);
  --sov-wake-cost-render: var(--sov-motion-duration-instant);
  --sov-wake-tier-transition: var(--sov-motion-duration-base);
  --sov-presence-error: var(--mk-glow-the-windhover);
  --sov-presence-listening: var(--mk-glow-where-light-enters);
  --sov-presence-speaking: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-presence-thinking: var(--mk-glow-pied-beauty);
  --sov-presence-idle: var(--mk-glow-gold);
  --sov-hairline-pied: inset 0 0 0 1px color-mix(in oklab, var(--mk-glow-pied-beauty) 28%, transparent);
  --sov-hairline-where-light: inset 0 0 0 1px color-mix(in oklab, var(--mk-glow-where-light-enters) 32%, transparent);
  --sov-hairline-gold: inset 0 0 0 1px color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
  --sov-shadow-glow-gold: 0 0 24px var(--sov-color-accent);
  --sov-ambient-pole-b: var(--mk-glow-where-light-enters);
  --sov-ambient-pole-a: var(--mk-glow-gold);
  --sov-color-glow-windhover: var(--mk-glow-the-windhover);
  --sov-color-glow-kingfishers: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-color-glow-pied: var(--mk-glow-pied-beauty);
  --sov-color-glow-where-light: var(--mk-glow-where-light-enters);
  --sov-color-glow-gold-deep: var(--mk-glow-gold-deep);
  --sov-color-glow-gold-soft: var(--mk-glow-gold-soft);
  --sov-color-glow-gold: var(--mk-glow-gold);
  --sov-color-accent-ink: var(--sov-color-accent);
}

/*!************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../tokens/dist/tokens-light.css ***!
  \************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/**
 * Do not edit directly
 */

[data-sovereign][data-sovereign-theme='light'] {
  /* origin: step-web-light — softened transport shadow for light */
  --sov-shadow-transport: 0 18px 48px -12px rgba(0,0,0,0.08);
  /* origin: step-web-light — softened bridge shadow for light */
  --sov-shadow-bridge: 0 -14px 48px -12px rgba(0,0,0,0.08);
  /* origin: step-web-light — softened sheet shadow for light */
  --sov-shadow-sheet: 0 24px 64px -16px rgba(0,0,0,0.12);
  /* origin: step-web-light — lift-card · web app */
  --sov-shadow-card: 0 10px 30px rgba(0,0,0,0.06);
  /* origin: step-web-light — lift-subtle · web app */
  --sov-shadow-tile: 0 6px 22px rgba(0,0,0,0.05);
  /* origin: step-web-light — #c9963c — brand mark gold · web app */
  --mk-web-mark-gold: oklch(0.7055 0.1216 78.45);
  /* origin: step-web-light — #c76040 — rare structural accent · web app */
  --mk-web-ember: oklch(0.6078 0.1396 37.88);
  /* origin: step-web-light — #2e9bd6 — bright jade variant · web app */
  --mk-web-jade-bright: oklch(0.6560 0.1291 237.81);
  /* origin: step-web-light — #2a7db1 — single brand accent · cool blue · web app */
  --mk-web-jade: oklch(0.5646 0.1120 240.83);
  /* origin: step-web-light — #e0d8c9 — hairlines and dividers · web app */
  --mk-web-divider: oklch(0.8845 0.0221 83.26);
  /* origin: step-web-light — #8a7e6d — tertiary copy, labels · web app */
  --mk-web-ink-faint: oklch(0.5991 0.0290 76.63);
  /* origin: step-web-light — #5a5348 — secondary copy · web app */
  --mk-web-ink-soft: oklch(0.4456 0.0197 79.21);
  /* origin: step-web-light — #2e2a24 — deep warm charcoal · body text · web app */
  --mk-web-ink: oklch(0.2872 0.0121 78.10);
  /* origin: step-web-light — #ffffff — pure white card surface · web app */
  --mk-web-card-surface: oklch(1 0 0);
  /* origin: step-web-light — #ece5d8 — deep parchment variant · web app */
  --mk-web-parchment-deep: oklch(0.9239 0.0190 83.06);
  /* origin: step-web-light — #f4eee4 — warm parchment variant · web app */
  --mk-web-parchment-warm: oklch(0.9511 0.0148 80.71);
  /* origin: step-web-light — #fbf8f2 — warm parchment ground · web app */
  --mk-web-parchment: oklch(0.9798 0.0086 84.57);
  /* origin: step-library-v0.2 — Rumi · the leaping spark · light override */
  --mk-glow-spark: oklch(0.72 0.21 105);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-moon-stays-bright: oklch(0.70 0.04 260);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-ruin-and-treasure: oklch(0.48 0.18 45);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-silently-drawn: oklch(0.48 0.14 250);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-morning-breeze: oklch(0.64 0.12 95);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-out-beyond-ideas: oklch(0.62 0.10 100);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-love-is-the-bridge: oklch(0.50 0.19 320);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-not-a-drop: oklch(0.54 0.12 210);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-silence-of-god: oklch(0.58 0.08 230);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-set-life-on-fire: oklch(0.48 0.26 25);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-beauty-we-love: oklch(0.54 0.18 340);
  /* origin: step-33 — Rumi · light override */
  --mk-glow-what-you-seek: oklch(0.56 0.20 60);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-no-worst-there-is-none: oklch(0.35 0.12 320);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-the-wreck-of-the-deutschland: oklch(0.40 0.22 260);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-spring-and-fall: oklch(0.58 0.16 135);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-the-lantern-out-of-doors: oklch(0.55 0.20 50);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-carrion-comfort: oklch(0.38 0.10 315);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-gods-grandeur: oklch(0.50 0.18 245);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-inversnaid: oklch(0.42 0.18 180);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-heaven-haven: oklch(0.60 0.12 190);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-the-starlight-night: oklch(0.44 0.16 260);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-the-windhover: oklch(0.56 0.12 280);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-pied-beauty: oklch(0.62 0.14 140);
  /* origin: step-web-light — where-light→ember in light mode · #c76040 web app warm accent */
  --mk-glow-where-light-enters: oklch(0.6078 0.1396 37.88);
  /* origin: step-33 — Hopkins · light override */
  --mk-glow-as-kingfishers-catch-fire: oklch(0.60 0.22 205);
  /* origin: step-web-light — gold-ring→jade at ring strength in light mode */
  --mk-glow-gold-ring: oklch(0.5646 0.1120 240.83);
  /* origin: step-web-light — gold-deep→deep jade for emphasis in light mode */
  --mk-glow-gold-deep: oklch(0.45 0.13 240);
  /* origin: step-web-light — gold-soft→jade-bright · #2e9bd6 web app */
  --mk-glow-gold-soft: oklch(0.6560 0.1291 237.81);
  /* origin: step-web-light — gold→jade in light mode · #2a7db1 web app brand accent */
  --mk-glow-gold: oklch(0.5646 0.1120 240.83);
  /* origin: step-web-light — jade glow replaces gold in light accent · web app */
  --sov-shadow-glow-gold: 0 0 24px var(--mk-web-jade);
  /* origin: step-web-light — stronger divider hairline for raised light surfaces */
  --sov-hairline-on-raised: inset 0 0 0 1px color-mix(in oklab, var(--mk-web-divider) 80%, transparent);
  /* origin: step-web-light — divider-tinted hairline for light surfaces */
  --sov-hairline-neutral: inset 0 0 0 1px color-mix(in oklab, var(--mk-web-divider) 60%, transparent);
  /* origin: step-web-light — #ece5d8 deep parchment · web app */
  --sov-color-surface-sunken: var(--mk-web-parchment-deep);
  /* origin: step-web-light — #ffffff pure white card · web app */
  --sov-color-surface-raised: var(--mk-web-card-surface);
  /* origin: step-web-light — #5a5348 secondary copy — subtle is the most prominent muted text (dark L=0.74) · web app */
  --sov-color-subtle: var(--mk-web-ink-soft);
  /* origin: step-web-light — #8a7e6d tertiary ink · web app */
  --sov-color-muted: var(--mk-web-ink-faint);
  /* origin: step-web-light — #2a7db1 jade — single brand accent · web app */
  --sov-color-accent: var(--mk-web-jade);
  /* origin: step-web-light — #f4eee4 warm parchment veil · web app */
  --sov-color-veil: var(--mk-web-parchment-warm);
  /* origin: step-web-light — #8a7e6d tertiary ink — whisper text · web app */
  --sov-color-whisper: var(--mk-web-ink-faint);
  /* origin: step-web-light — #2e2a24 deep charcoal · web app */
  --sov-color-ink: var(--mk-web-ink);
  /* origin: step-web-light — #fbf8f2 parchment ground · web app */
  --sov-color-bg: var(--mk-web-parchment);
}

/*!****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../packages/kaos-sovereign/styles/sovereign.css ***!
  \****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * Sovereign KaOS — token layer.
 *
 * EVERYTHING in this file is scoped under [data-sovereign] so it cannot
 * leak into existing apps or overwrite design-system tokens. Reuses the
 * cross-channel --glass-blur-* tokens declared in
 *   packages/design-system/styles/globals.css
 * and --motion-ease-expo. No Tailwind directives here — this is raw CSS
 * layered on top of the app's existing styles.
 *
 * Surfaces: no borders anywhere. Elevation via shadow + blur only.
 * Palette: quiet deep neutral that breathes between dark and light.
 * Dark is the canonical canvas (family reading at night, ambient amber
 * glow). Light is an opt-in via data-sovereign-theme='light'.
 *
 * ─── PROVENANCE INDEX ───────────────────────────────────────────────────
 * Every block in this file is sourced from a design-team PR package or
 * marked PROVISIONAL until one ships. CHARTER.md Rule 5 forbids inventing
 * values; PROVISIONAL blocks are tracked in `sovereign-design/requests/`
 * and must be replaced by an authored PR before "kaos-sovereign" ships.
 *
 * SANCTIONED:
 *   --mk-glow-* / --mk-hairline-* (palette + dark overrides) … step-01
 *   --sov-bg / --sov-ink / --sov-veil / --sov-whisper / --sov-accent /
 *     --sov-presence / --sov-presence-halo / --sov-radius-bloom /
 *     --sov-composer-* / --sov-mic-* … step-01
 *   --sov-chat-*                                          … step-05
 *   --sov-interaction-*                                   … step-06
 *   --sov-tile-* / --sov-book-* / --sov-spark-* /
 *     --sov-settings-* / --sov-bookcast-* / --sov-sheet-* … step-08
 *   --sov-word-reveal-* / --sov-caret-* / @keyframes
 *     sov-word-in / sov-caret                             … step-04
 *   --sov-font-sans / --sov-font-serif / --sov-font-mono  … step-09 §2
 *   --sov-text-*-line / --sov-text-*-weight (unitless)    … step-09 §1
 *   --sov-muted / --sov-subtle / --sov-surface-* /
 *     --sov-accent-ink                                    … step-09 §3
 *   --sov-glass-mix / --sov-glass-mix-strong /
 *     --sov-glass-blur / --sov-glass-blur-deep /
 *     --sov-glass-blur-ambient + .sov-glass utilities     … step-09 §4
 *   --sov-ambient-a / --sov-ambient-b + .sov-canvas::before
 *     + @keyframes sov-breathe-ambient                    … step-09 §5
 *   --sov-breath / --sov-wordmark-shimmer / --sov-wordmark-malaika-* /
 *     --sov-ease-spring + @keyframes sov-breathe /
 *     sov-gold-shimmer / sov-word-fade                  … step-09 §6
 *   Dark canonical (default), light as opt-in            … step-09 §7
 *   --sov-tiles-grid-columns / --sov-columns-break           … OPEN-07 (Charter Rule 2)
 *   --sov-tiles-grid-track-comfortable / --sov-tiles-grid-track-compact … OPEN-07
 *   --sov-text-body-* / --sov-text-*-tracking             … step-33
 *   --sov-z-* (z-index tier)                              … step-33
 *   Design-bundle bridge aliases (--mk-*, --fs-*, --z-*)  … step-33
 *   --sov-dial-pad-* (phone surface geometry)              … step-34
 *   Legacy canvas bridges (generic → canonical)           … step-35
 *   Pretext freeze veil + pinned-object chrome            … step-36
 *   Phone ringing-state halo + call-control token bridges   … step-37
 *   Reminder chip row (Malaika's gentle nudge surface)      … step-38
 *
 * READING-SURFACE TIER OVERRIDE NOTE:
 *   `styles/reading/sovereign-reading.css` loads AFTER this file and
 *   intentionally overrides the `.sov-adapter-text__*` inline-mark
 *   classes (bold, italic, inline-code, link) with reading-surface
 *   tokens (`--sov-read-*`).  No reconciliation is needed — the
 *   cascade priority is deliberate per the reading-surface tier's
 *   Charter Rule 5b handoff.
 *
 * PROVISIONAL — still tracked in OPEN-NN.md:
 *   --sov-rail-w / --sov-canvas-max / --sov-section-h /
 *     --sov-prompt-h / --sov-bloom / --sov-gutter                … OPEN-02.D
 *   --sov-radius-{field,tile,sheet,pill}                         … master sanctioned, no per-step PR
 *   sov-mic-pulse / sov-mic-spin keyframes                         … OPEN-01.A6
 *
 * Every block stays in place; spec values are applied verbatim from the
 * authored PR. Replacement only happens via a new PR package.
 * ────────────────────────────────────────────────────────────────────── */

/* No @import. Per step-09 §2, the consuming app registers Inter +
   Newsreader via next/font (packages/design-system/lib/fonts.ts). The
   --sov-font-* tokens declare the stack only; they do not load fonts. */

/* ─── Global scrollbar suppression — all sovereign surfaces, all devices ───
   scrollbar-width: none  → Firefox / all modern engines
   ::-webkit-scrollbar   → Chrome / Safari / Edge / WebKit
   Scroll behaviour is preserved; only the visual track is hidden. */
[data-sovereign] *,
[data-sovereign] *::before,
[data-sovereign] *::after {
  scrollbar-width: none;
}
[data-sovereign] *::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

[data-sovereign] {
  /* Font stacks live in tokens.json (typography.font.*) and reach this
   * scope via the bridge aliases (--sov-font-sans etc.) generated in
   * dist/tokens.css. Migrated in Piece 4 of the tokens audit. The
   * comments below preserve the historical step-09 §2 prose context. */
  /* ---------- Font stacks · step-09 §2 ----------
     Inter + Newsreader canonical; Noto* serves SSR fallback. No @import. */

  /* ---------- Palette (dark — canonical · step-09 §7) ----------
     Surface tier + Hopkins/Rumi glow palette live in tokens/tokens.json
     (color.*, palette.glow.*) and reach this scope via dist/tokens.css
     under [data-sovereign]. Legacy --sov-* names are bridged to
     --sov-color-*; --mk-glow-* emit from palette.glow.*. Migrated
     2026-07-05 source-of-truth consolidation. */
  --sov-accent-ink: var(--sov-accent);
  --sov-shadow-surface: 0 14px 36px -18px
    color-mix(in oklab, var(--sov-bg) 80%, transparent);

  /* step-09 §5 — ambient wash; references the glow palette so it
     re-tints automatically when the palette flips per theme. */
  --sov-ambient-a: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  --sov-ambient-b: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 6%,
    transparent
  );

  /* ═══════════════════════════════════════════════════════════════════════
   * PALETTE TIER — Hopkins/Rumi open family of glows
   * Raw oklch values live in tokens/tokens.json (palette.glow.* dark,
   * palette-light.glow.* light). Semantic aliases below assign roles.
   * ═══════════════════════════════════════════════════════════════════════ */

  --mk-glow-gold-halo: color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  --mk-glow-gold-hairline: color-mix(
    in oklab,
    var(--mk-glow-gold) 35%,
    transparent
  );

  /* Hairlines — role-keyed, 6 most-used glows */
  --mk-hairline-gold: color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
  --mk-hairline-pied: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 28%,
    transparent
  );
  --mk-hairline-windhover: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 25%,
    transparent
  );
  --mk-hairline-kingfishers: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 30%,
    transparent
  );
  --mk-hairline-gods-grandeur: color-mix(
    in oklab,
    var(--mk-glow-gods-grandeur) 30%,
    transparent
  );
  --mk-hairline-where-light: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 32%,
    transparent
  );
  --mk-hairline-bridge: color-mix(
    in oklab,
    var(--mk-glow-love-is-the-bridge) 30%,
    transparent
  );

  /* ═══════════════════════════════════════════════════════════════════════
   * SEMANTIC TIER — sovereign roles that reference the palette.
   * Components consume these. Existing --sov-* tokens above are untouched.
   * ═══════════════════════════════════════════════════════════════════════ */

  /* Malaika presence — gold-only. Never use gold for a person. */
  --sov-presence: var(--mk-glow-gold);
  --sov-presence-halo: var(--mk-glow-gold-halo);
  --sov-presence-ring: var(--mk-glow-gold-ring);
  --sov-status-ok: var(--mk-glow-gold);
  --sov-status-warn: var(--mk-glow-pied-beauty);
  --sov-status-error: var(--mk-glow-the-windhover);
  --sov-status-progress: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-status-pending: var(--sov-whisper);

  /* Composer — gold authority. Steps 2+ wire these into SovereignPrompt. */
  --sov-composer-border: var(--mk-glow-gold-hairline);
  --sov-composer-halo: var(--mk-glow-gold-halo);

  /* Mic states — match pretext-voice-surface.contract.md exactly:
     idle uses --sov-presence (gold); recording/transcribing use
     kingfishers / where-light; error uses windhover (never red). */
  --sov-mic-recording: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-mic-transcribing: var(--mk-glow-where-light-enters);
  --sov-mic-error: var(--mk-glow-the-windhover);

  /* Folio roles — forward-bound for Step 6 (reader surface) */
  --sov-annotation: var(--mk-glow-where-light-enters); /* Malaika footnote */
  --sov-bookmark: var(--mk-glow-pied-beauty); /* chapter marks    */
  --sov-listening: var(--mk-glow-as-kingfishers-catch-fire); /* listen mode      */

  /* ═══════════════════════════════════════════════════════════════════════
   * CHAT SURFACE — Step 5
   * Tokens consumed by apps/app/.../sovereign/chat/page.tsx and any future
   * chat primitives. All values reference the palette tier above; zero new
   * raw oklch.
   * ═══════════════════════════════════════════════════════════════════════ */

  /* Malaika's bubble — glass + gold hairline. Same surface language as
     the composer: she _is_ the composer. */
  --sov-chat-bubble-hers-bg: color-mix(in oklab, var(--sov-bg) 72%, transparent);
  --sov-chat-bubble-hers-border: var(--mk-glow-gold-hairline);
  --sov-chat-bubble-hers-shadow: 0 1px 0 rgba(255, 255, 255, 0.6);

  /* Your bubble — neutral, quiet, no hairline. */
  --sov-chat-bubble-yours-bg: color-mix(
    in oklab,
    var(--sov-ink) 88%,
    transparent
  );
  --sov-chat-bubble-yours-color: var(--sov-bg);

  /* Citation chip — inline gold-hairline chip that opens a passage sheet. */
  --sov-chat-citation-border: var(--mk-glow-gold-hairline);
  --sov-chat-citation-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 6%,
    transparent
  );
  --sov-chat-citation-color: var(--mk-glow-gold);

  /* Tool-call surface — step-19 voice pass:
     • Was: where-light-enters (hue 40, red-orange) — read as warning, not
       as "she is actively doing something."
     • Now: gods-grandeur (hue 245, "charge · voltage"). Hopkins'
       "The world is charged with the grandeur of God / It will flame out,
       like shining from shook foil" maps directly onto a tool-call
       firing — a brief blue flame of capacity engaging. Cool, technical,
       clearly operational rather than alarming. Distinct from the info
       callout (kingfishers cyan-teal) and from the warn (pied-beauty
       green). */
  --sov-chat-tool-bg: color-mix(
    in oklab,
    var(--mk-glow-gods-grandeur) 5%,
    var(--sov-veil)
  );
  --sov-chat-tool-border: var(--mk-hairline-gods-grandeur);
  --sov-chat-tool-dot: var(--mk-glow-gods-grandeur);
  --sov-chat-tool-label: var(--mk-glow-gods-grandeur);

  /* MCP data panels — passage vs memory/annotation. */
  --sov-chat-panel-passage-dot: var(--mk-glow-gold);
  --sov-chat-panel-passage-border: var(--mk-glow-gold-hairline);
  --sov-chat-panel-memory-dot: var(--mk-glow-where-light-enters);
  --sov-chat-panel-memory-border: var(--mk-hairline-where-light);

  /* Full-screen chat room — sanctioned by canvas-chat-deep
     (single-column conversation by default; rail mode is opt-in for
     users who prefer a traditional split layout with a live artifact
     column). The room is the composer expanded, not a second surface. */
  --sov-chat-room-z: 80;
  --sov-chat-room-backdrop: color-mix(in oklab, var(--sov-bg) 84%, transparent);
  --sov-chat-room-thread-max: 580px;
  --sov-chat-room-inset: clamp(16px, 4vw, 56px);
  --sov-chat-room-top: clamp(20px, 5vh, 56px);
  --sov-chat-room-bottom: clamp(18px, 4vh, 42px);
  --sov-chat-room-gap: var(--sov-gutter);
  --sov-chat-room-title-max: 540px;
  --sov-chat-room-thread-gap: calc(var(--sov-gutter) * 1.15);
  --sov-chat-room-composer-max: 640px;
  --sov-chat-room-close-size: 36px;
  --sov-chat-room-chip-pad: 0 12px;
  --sov-chat-room-chip-h: 28px;
  --sov-chat-room-actions-gap: 10px;
  --sov-chat-room-empty-min: 38dvh;
  --sov-chat-room-freeze-blur: 1.2px;
  --sov-chat-room-freeze-opacity: 0.34;
  /* Rail mode (opt-in). Width + gap describe the second column. */
  --sov-chat-room-rail-w: 248px;
  --sov-chat-room-rail-gap: clamp(20px, 4vw, 48px);
  --sov-chat-room-rail-pad: 18px 20px;
  --sov-chat-room-rail-radius: 16px;
  --sov-chat-room-rail-row-h: 32px;
  --sov-chat-room-rail-shell-max: 940px;
  --sov-chat-room-rail-bg: color-mix(in oklab, var(--sov-bg) 92%, transparent);
  --sov-chat-room-rail-border: color-mix(
    in oklab,
    var(--sov-ink) 8%,
    transparent
  );
  --sov-chat-room-rail-empty-ink: var(--sov-whisper);

  /* ═══════════════════════════════════════════════════════════════════════
   * CONTENT INTERACTION — Step 6
   * Unified vocabulary for every moment user and Malaika meet on a piece
   * of content — reader, chat, spark. Same tokens, any surface.
   * ═══════════════════════════════════════════════════════════════════════ */

  /* Highlights.
     Malaika's highlight is gold — she surfaces a passage to you.
     Yours is pied-beauty — variety + accumulation. */
  --sov-interaction-highlight-malaika: var(--mk-glow-gold);
  --sov-interaction-highlight-malaika-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 10%,
    transparent
  );
  --sov-interaction-highlight-malaika-rule: var(--mk-glow-gold);

  --sov-interaction-highlight-user: var(--mk-glow-pied-beauty);
  --sov-interaction-highlight-user-bg: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 10%,
    transparent
  );
  --sov-interaction-highlight-user-rule: var(--mk-glow-pied-beauty);

  /* Annotations.
     Malaika's footnote is where-light-enters — editorial / observing (†).
     Yours is pied-beauty — personal memory (◦). */
  --sov-interaction-annotation-malaika: var(--mk-glow-where-light-enters);
  --sov-interaction-annotation-malaika-bg: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 6%,
    var(--sov-veil)
  );
  --sov-interaction-annotation-malaika-border: var(--mk-hairline-where-light);

  --sov-interaction-annotation-user: var(--mk-glow-pied-beauty);
  --sov-interaction-annotation-user-bg: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 6%,
    var(--sov-veil)
  );
  --sov-interaction-annotation-user-border: var(--mk-hairline-pied);

  /* Pull-quote — intentional architecture. Gold left rule, 5% wash. */
  --sov-interaction-pull-quote-border: var(--mk-glow-gold);
  --sov-interaction-pull-quote-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 5%,
    var(--sov-veil)
  );
  --sov-interaction-pull-quote-border-w: 3px;

  /* Cross-reference chip — inline, never a tooltip. Tap → SovereignSheet. */
  --sov-interaction-cross-ref-border: var(--mk-glow-gold-hairline);
  --sov-interaction-cross-ref-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 7%,
    transparent
  );
  --sov-interaction-cross-ref-color: var(--mk-glow-gold);

  /* Bookmark gutter — 8px dots, pied-beauty, never labelled. */
  --sov-interaction-bookmark: var(--mk-glow-pied-beauty);
  --sov-interaction-bookmark-size: 8px;

  /* Ask-Malaika bridge — the pinned-passage card is the composer focused. */
  --sov-interaction-ask-border: var(--mk-glow-gold-hairline);
  --sov-interaction-ask-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 7%,
    var(--sov-veil)
  );
  --sov-interaction-ask-action: var(--mk-glow-gold);

  /* ═══════════════════════════════════════════════════════════════════════
   * SURFACE TOKENS — Step 8
   * Home, library, spark, settings, bookcast, sheet. Every remaining
   * sovereign surface in the monorepo now speaks the palette tier.
   * ═══════════════════════════════════════════════════════════════════════ */

  /* Home · activity tiles.
     Shimmer is Malaika's where-light insight, not a loading state. */
  --sov-tile-shimmer-glow: var(--mk-glow-where-light-enters);
  --sov-tile-shimmer-bg: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 6%,
    var(--sov-veil)
  );
  --sov-tile-shimmer-border: var(--mk-hairline-where-light);
  --sov-tile-activity-dot: var(--mk-glow-gold);
  --sov-tile-activity-halo: var(--mk-glow-gold-halo);
  /* Kind-row shelf tile — meta strip below the cover. Sunken surface tier
     reads as a distinct band in both dark and light (tokens-light.css). */
  --sov-tile-meta-bg: var(--sov-surface-sunken);
  /* Cover-less tile wash floor — must be a real token (--sov-surface is not). */
  --sov-tile-cover-floor: var(--sov-surface-sunken);
  --sov-passage-shadow: inset 0 0 0 1px var(--mk-hairline-gold), 0 12px 32px
    -16px color-mix(in oklab, var(--sov-bg) 82%, transparent);
  --sov-pullquote-hairline: color-mix(in oklab, var(--sov-ink) 3%, transparent);
  --sov-nav-hairline: color-mix(in oklab, var(--sov-ink) 4%, transparent);
  --sov-hero-gradient-gold: linear-gradient(
    135deg,
    var(--mk-glow-gold),
    var(--mk-glow-where-light-enters),
    var(--mk-glow-the-starlight-night)
  );
  --sov-hero-gradient-bridge: linear-gradient(
    135deg,
    var(--mk-glow-as-kingfishers-catch-fire),
    var(--mk-glow-the-starlight-night),
    var(--mk-glow-love-is-the-bridge)
  );
  --sov-hero-gradient-pied: linear-gradient(
    135deg,
    var(--mk-glow-pied-beauty),
    var(--mk-glow-where-light-enters),
    var(--mk-glow-heaven-haven)
  );
  --sov-hero-scrim: linear-gradient(
    180deg,
    transparent 40%,
    color-mix(in oklab, var(--sov-bg) 72%, transparent) 100%
  );
  --sov-hero-shadow: 0 12px 32px -16px
    color-mix(in oklab, var(--sov-bg) 86%, transparent);
  --sov-hero-shadow-hover: 0 20px 48px -16px
    color-mix(in oklab, var(--sov-bg) 86%, transparent), 0 0 40px
    color-mix(in oklab, var(--mk-glow-gold) 10%, transparent);
  --sov-hero-text-meta: color-mix(in oklab, var(--sov-ink) 60%, transparent);
  --sov-hero-text-title: color-mix(in oklab, var(--sov-ink) 95%, transparent);
  --sov-hero-text-sub: color-mix(in oklab, var(--sov-ink) 78%, transparent);

  /* Library · book covers. The scrim is ink-based so it stays neutral
     over any Hopkins gradient cover. Last-read marker is where-light
     because it's a memory annotation, not a primary action. */
  --sov-book-cover-scrim: linear-gradient(
    180deg,
    transparent 60%,
    color-mix(in oklab, var(--sov-ink) 30%, transparent)
  );
  --sov-book-last-read: var(--mk-glow-where-light-enters);

  /* Spark · working state.
     Progress is gold because Malaika is working _for you_. The
     "begin" button stays neutral ink-on-bg. */
  --sov-spark-progress: var(--mk-glow-gold);
  --sov-spark-progress-bg: color-mix(
    in oklab,
    var(--mk-glow-gold) 10%,
    transparent
  );
  --sov-spark-action-bg: var(--sov-ink);
  --sov-spark-action-color: var(--sov-bg);
  --sov-spark-sheet-progress: var(--mk-glow-gold);

  /* Settings · chips. Neutral by design — settings are not gold-
     significant. These tokens document current behaviour so the chip
     helper can adopt them on the next settings touch. */
  --sov-settings-chip-active-bg: var(--sov-ink);
  --sov-settings-chip-active-color: var(--sov-bg);
  --sov-settings-chip-idle-bg: color-mix(
    in oklab,
    var(--sov-veil) 90%,
    transparent
  );
  --sov-settings-chip-idle-color: var(--sov-ink);

  /* Bookcast · listening surface. Kingfishers throughout — same as
     composer voice-active and reader's listen badge. */
  --sov-bookcast-listen-dot: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-bookcast-listen-border: var(--mk-hairline-kingfishers);
  --sov-bookcast-listen-progress: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-bookcast-scrubber-bg: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 12%,
    var(--sov-veil)
  );

  /* SovereignSheet — glass surface used across spark, reader, content-
     interaction. Gold border because the sheet is always Malaika's. */
  --sov-sheet-bg: color-mix(in oklab, var(--sov-bg) 78%, transparent);
  --sov-sheet-border: var(--mk-glow-gold-hairline);
  --sov-sheet-handle: color-mix(in oklab, var(--sov-ink) 18%, transparent);
  --sov-sheet-shadow: 0 -14px 48px -12px rgba(0, 0, 0, 0.08);
  --sov-bridge-shadow: inset 0 0 0 1px var(--mk-hairline-gold), 0 -14px 48px
    -12px color-mix(in oklab, var(--sov-bg) 80%, transparent);
  --sov-bridge-handle: color-mix(in oklab, var(--sov-ink) 12%, transparent);
  --sov-bridge-divider: color-mix(in oklab, var(--sov-ink) 5%, transparent);

  /* ---------- Radii · PROVISIONAL · OPEN-01 (radii not yet authored) ---------- */
  --sov-radius-field: 28px;
  --sov-radius-tile: 10px;
  --sov-radius-sheet: 24px;
  --sov-radius-pill: 999px;

  /* ---------- Spacing + layout · PROVISIONAL · OPEN-02.D ----------
     Pinned numerals — reserve API not yet shipped by pretext.
     Canvas widths: tokens `layout.column-max` + `layout.pretext-prose-max`
     (dist/tokens.css) — this file aliases them for pretext-only surfaces. */

  /* ── Rail width — dynamic, responsive to viewport.
     Above 1200px: rails are 300px (capped by clamp max).
       Center = 100vw - 600, capped at --sov-content-max (768px).
       Full layout activates at 1368px viewport.
     Between 1200px and 1000px: center freezes at 600px, rails contract:
       rail = (100vw - 600) / 2, clamped to [200px, 300px].
    Below 1000px: rails hit 200px minimum.
      Center = 100vw - 400, continues shrinking.
    Below 800px: rails enter compact state (48px icons, viewport-driven
      compact, same visual system as scroll-driven).
    At 480px and below: rails hidden entirely (phone/very narrow layout).
    This is a single custom property — every consumer (rails, scroll,
     composer, layout tokens) reads the same value automatically. */
  --sov-rail-w: clamp(200px, (100vw - 600px) / 2, 300px);
  /* ── rail-width symmetry — left and right rails share one token as of 2026-05-11.
     --sov-rail-r-w removed 2026-05-10. Use --sov-rail-w for both sides. */
  --sov-rail-pad: var(--sov-space-3);
  /* Canvas background grid — 28px, the second perfect number.
   *   28 = 1+2+4+7+14. Lunar cycle. Mathematically rare, poetically
   *   weighted. All SVG grid-snap arithmetic references this single token.
   *   Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-43/PR.md §Grid */
  --sov-canvas-grid: 28px;

  /* Sole pretext column — must match --sov-layout-column-max from tokens. */
  --sov-canvas-max: var(--sov-layout-column-max, 980px);
  /* Prose / descriptor inside that canvas — must match --sov-layout-pretext-prose-max. */
  --sov-content-max: var(--sov-layout-pretext-prose-max, 768px);
  /* Folio reading measure — per-column cap for the spread view and the
     scroll view's prose column. Classical optimum: ~65–70 characters at
     the body serif size (≈ 34em at 19px ≈ 40rem). Consumed by the
     spread grid clamp, repaginate() in the spread view, and the inner
     folio renderer. Sanctioned under Charter Rule 5b. */
  --sov-folio-measure-max: 40rem;
  --sov-section-h: 64px;
  --sov-top-rail-h: 58px;
  --sov-bloom: 28px;
  --sov-gutter: 24px;
  --sov-dock-lift: 12px;
  /* Top row chrome (a03 / a05): mix with --sov-bg, not transparent — oklch+transparent muddies to “nothing”. */
  --sov-chrome-top-t: color-mix(
    in oklab,
    var(--sov-surface-raised) 40%,
    var(--sov-bg)
  );
  --sov-chrome-top-b: color-mix(in oklab, var(--sov-veil) 82%, var(--sov-bg));
  --sov-space-00: 2px;
  --sov-space-0: 3px;
  --sov-space-1: 4px;
  --sov-space-2: 8px;
  --sov-space-3: 12px;
  --sov-space-4: 16px;
  --sov-space-5: 24px;
  --sov-space-6: 32px;
  --sov-space-7: 48px;
  --sov-space-8: 64px;

  /* Tile-grid columns · OPEN-07 (Sovereign Design Authority, mode 5b).
     Chartered column count for sovereign tile shelves. The `columns`
     prop on SovereignTilesGrid maps 3 → this token; 2 and 4 pass through
     as literal `2` / `4`. Tune once here; every page follows. */
  --sov-tiles-grid-columns: 3;

  /* Responsive column breakpoint for tile grids. Desktop renders the
     chartered column count; below this width all grids collapse to 2
     columns. Charter Rule 2 — token-first, no magic numbers. */
  --sov-columns-break: 680px;

  /* Tile-grid tracks · OPEN-07 (Sovereign Design Authority, mode 5b).
     Canonical auto-fit minmax for sovereign tile shelves; tune once here. */
  --sov-tiles-grid-track-comfortable: minmax(220px, 1fr);
  --sov-tiles-grid-track-compact: minmax(180px, 1fr);

  /* Companion base widths (raw px) for flex-wrap layouts. Same sanctioned
     values as the minmax tracks above; tune them together. Charter Rule 5b. */
  --sov-tiles-grid-track-comfortable-base: 220px;
  --sov-tiles-grid-track-compact-base: 180px;

  /* Composer / SovereignPrompt — derived from space scale (after --sov-space-*). */
  --sov-prompt-h: calc(var(--sov-space-8) + var(--sov-space-4));
  /* Live composer footprint — the FULL rendered height (border-box) of
     SovereignPrompt, published via ResizeObserver to the nearest
     [data-sovereign] host. Covers every state (idle cigar-tube pill,
     typing dock, chips row, intent-pills row, multi-line). Falls back to
     the static idle baseline + wrap allowance before the composer mounts
     or when it is suppressed. The shell's bottom reservation consumes
     this exclusively — one token, one consumer, every page. */
  --sov-prompt-h-live: calc(
    var(--sov-prompt-h) +
    var(--sov-composer-wrap-pad-b)
  );
  --sov-prompt-pad-y: var(--sov-space-3);
  --sov-prompt-pad-x: var(--sov-space-3);
  --sov-prompt-pad-x-tight: var(--sov-space-2);
  --sov-prompt-stack-gap: var(--sov-space-3);
  --sov-prompt-chips-below-gap: var(--sov-space-4);
  --sov-prompt-chips-row-gap: var(--sov-space-2);
  --sov-composer-wrap-pad-b: max(
    calc(var(--sov-space-5) + var(--sov-space-3)),
    env(safe-area-inset-bottom, 0px)
  );

  /* ---------- Nav-rail canonical (malaika-home parity) ----------
     Uses existing spacing tokens; only unique values get new tokens.
     Sanctioned: step-16 self-authored mode 5b. */
  --sov-nav-brand-wordmark-size: 30px;
  --sov-nav-item-font-size: 11.5px;
  --sov-nav-item-weight: 500;
  --sov-nav-item-weight-active: 700;
  --sov-nav-item-tracking: 0.14em;
  --sov-nav-item-tracking-active: 0.17em;
  --sov-nav-group-gap: var(--sov-space-4);
  /* Right-chrome identity — avatar + two-line label (shell UserCard). */
  --sov-user-card-avatar-size: calc(var(--sov-space-5) + var(--sov-space-4));
  --sov-user-card-gap: var(--sov-space-3);
  /* Collapsed-rail chrome glyphs — logo, comms pill, collapse toggle. */
  --sov-rail-compact-glyph-size: var(--sov-user-card-avatar-size);

  /* ---------- Utility icon button ---------- */
  --sov-icon-btn-size: 36px;
  --sov-icon-btn-radius: var(--sov-radius-pill);
  --sov-icon-btn-icon-size: 16px;
  --sov-icon-btn-stroke: 1.6;

  /* ---------- Top-rail section tabs ---------- */
  --sov-top-rail-radius: var(--sov-radius-sheet);
  --sov-tab-font-size: 11px;
  --sov-tab-weight: 600;
  --sov-tab-weight-active: 700;
  --sov-tab-tracking: 0.14em;
  --sov-tab-indicator-w: 14px;
  --sov-tab-indicator-h: 2px;

  /* ---------- Right-rail (user, search, aside, focus) ---------- */
  --sov-user-avatar-size: 38px;
  --sov-user-name-size: 11px;
  --sov-user-name-weight: 600;
  --sov-user-name-tracking: 0.16em;
  --sov-search-pill-h: 42px;
  --sov-search-pill-pad-x: var(--sov-space-3);
  --sov-focus-btn-font-size: 10px;
  --sov-focus-btn-icon-size: 14px;
  --sov-rail-btn-h: 40px;
  --sov-rail-btn-font-size: 12px;

  /* ---------- Step-12 sanctioned tokens · self-authored mode 5b ----------
     Sanctioned in sovereign-design/kaOS Design System (self-authored)/
     pr/step-12/PR.md §3 (--sov-transport-h) and §5 (--sov-bp-side-rail).

     --sov-bp-side-rail: first viewport width where Reader can render
       (rail 240) + (gutter 24) + (cushion 24) + (body 640) + (cushion
       24) + (BridgeSheet 440) ≈ 1392 with breathing room rounded down
       to 1280 — the canonical "side-rail or collapse" threshold.

     --sov-transport-h: Bookcast TransportDock height. 4 (breath) + 24
       (scrub) + 8 (gap) + 40 (control row) + 8 (breath) + 4 (base pad)
       = 88. The shell reserves this when a surface passes
       suppressComposer={true}. */
  --sov-bp-side-rail: 1280px;
  --sov-transport-h: 88px;

  /* ---------- Motion · step-16 malaika-home parity ----------
     Step-04 sanctioned the word-reveal + caret tokens (below).
     Step-16 adds entrance animation durations and stagger timings
     from malaika-home.html for delight and breathing. */
  --sov-ease-expo: var(--motion-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
  --sov-ease: var(--sov-ease-expo);
  --sov-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --sov-ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --sov-stagger: 80ms;
  --sov-hush: 220ms;
  --sov-bloom-dur: 520ms;
  /* malaika-home durations */
  --sov-d-instant: 80ms;
  --sov-d-fast: 160ms;
  --sov-d-base: 280ms;
  --sov-d-slow: 520ms;
  --sov-d-breath: 4600ms;
  /* Nav entrance stagger delays (60ms base, 60ms increments) */
  --sov-nav-stagger-base: 60ms;
  --sov-nav-stagger-step: 60ms;
  --sov-nav-in-dur: 520ms;
  /* Canonical breath cadence — every presence dot, ember, shimmer
     pulses at 4.2s (see CHARTER.md). Single source of truth.
     Aliases pretext --breathe-slow (OPEN-02.F). */
  --sov-breath: 4.2s;
  --sov-wordmark-shimmer: 22s;
  /* The kaOS wordmark animates on its own cadence (16s per the
     canonical source/components/kaos-wordmark.html). The longer
     22s --sov-wordmark-shimmer drives ambient surfaces. */
  --sov-wordmark-cycle: 16s;
  /* Primary kaOS mark — hopkins multicolor lives in tokens/tokens.json
     (wordmark.hopkins-* → --sov-wordmark-hopkins-* via dist/tokens.css) */
  --sov-wordmark-malaika-weight: 900;
  --sov-wordmark-malaika-tracking: -0.04em;
  --sov-wordmark-malaika-gradient: linear-gradient(
    135deg,
    var(--sov-wordmark-hopkins-a),
    var(--sov-wordmark-hopkins-b),
    var(--sov-wordmark-hopkins-c),
    var(--sov-wordmark-hopkins-d),
    var(--sov-wordmark-hopkins-a)
  );

  /* Word-fade timing — Malaika's streaming reveal.
     Pretext6 exposes these through --word-fade-in-* aliases. */
  --sov-word-reveal-dur: 360ms;
  --sov-word-reveal-stagger: 55ms;
  --sov-word-reveal-lead: 300ms;

  /* Gold caret — streaming cursor during TTS or typed streams. */
  --sov-caret-color: var(--mk-glow-gold);
  --sov-caret-dur: 0.9s;

  /* ---------- Glass · step-09 §4 ----------
     Mix = % of --sov-bg in the translucent surface. Blur tiers are
     named after expression, not pixel size.

     --sov-glass-mix-strong is the SINGLE knob for "how see-through is
     sovereign deep glass" — fed into the .sov-glass-strong utility,
     which paints the auth overlay, the user popover, and the rails
     when the Projects canvas pans behind them.

     SOURCE OF TRUTH lives in tokens/tokens.json → glass.mix-strong,
     built by Style Dictionary into tokens/dist/tokens.css and shipped
     via @repo/sovereign-tokens/css (imported AFTER this file in
     apps/sovereign/app/layout.tsx). Do NOT re-declare the strong-mix
     value here — the tokens-package value would win on cascade and
     any local override would be silently clobbered.

     The other glass tokens (mix, blur, blur-deep, blur-ambient) are
     also mirrored from tokens.json; kept here for backstop while we
     migrate the whole glass token block to the tokens package. */
  --sov-glass-mix: 72%;
  --sov-glass-blur: 16px;
  --sov-glass-blur-deep: 28px;
  --sov-glass-blur-ambient: 12px;

  /* ---------- Typography tokens · step-09 §1 ----------
     Sizes (step-01) + line/weight (step-09 §1). Lines are unitless
     ratios so any consumer applies them directly via line-height.
     These tokens are the single source of truth for both CSS and
     pretext font strings — see lib/typography-map.ts. */
  --sov-text-display-size: 40px;
  --sov-text-display-line: 1.06;
  --sov-text-display-weight: 500;

  --sov-text-section-size: 18px;
  --sov-text-section-line: 1.2;
  --sov-text-section-weight: 600;

  --sov-text-field-size: 16px;
  --sov-text-field-line: 1.5;
  --sov-text-field-weight: 400;

  --sov-text-tile-size: 15px;
  --sov-text-tile-line: 1.35;
  --sov-text-tile-weight: 500;

  --sov-text-caption-size: 13px;
  --sov-text-caption-line: 1.3;
  --sov-text-caption-weight: 400;

  --sov-text-body-size: 16px;
  --sov-text-body-line: 1.65;
  --sov-text-body-weight: 400;

  /* Sub-rung sizes — surfaces two rungs below caption for rail eyebrows,
     keyboard chips, and dense data labels where 13px (caption) is too large.
     These are the canonical size tokens for the right-rail surfaces:
       • eyebrow  → 9.5px  · session/activity section eyebrow labels
       • chip     → 11px   · kbd badges, toolkit entries, session action buttons
       • micro    → 10px   · FastSearch input, project rail badges, item counts
     Authored: sovereign-design/kaOS Design System (self-authored)/
     pr/step-37/PR.md §1 (right-rail token purification).
     Sanctioned under Charter Rule 5b (Sovereign Design Authority). */
  --sov-text-eyebrow-size: 9.5px;
  --sov-text-chip-size: 11px;
  --sov-text-micro-size: 10px;

  /* Tracking for every rung · step-33 */
  --sov-text-display-tracking: -0.02em;
  --sov-text-section-tracking: -0.01em;
  --sov-text-field-tracking: 0;
  --sov-text-tile-tracking: 0;
  --sov-text-caption-tracking: 0.14em;
  --sov-text-body-tracking: 0;

  /* §17.2c rail mode toggle · step-17/PR.md §2c
     Must live in this file so Vars resolve in the shipped CSS bundle.
     Type quartet matches .sov-reminder-disclosure__trigger (rail-button
     rung): --sov-rail-btn-font-size + 0.08em tracking like "+ NEW SESSION". */
  --sov-rail-toggle-h: calc(var(--sov-search-pill-h) - var(--sov-space-1) * 2);
  --sov-rail-toggle-pad-x: var(--sov-space-3);
  --sov-rail-toggle-tracking: 0.08em;
  --sov-rail-toggle-font-size: var(--sov-rail-btn-font-size);
  --sov-rail-toggle-gap: var(--sov-space-1);

  /* §17.2b kind colorways · step-17/PR.md §2b (same values as tokens/colors.css) */
  --sov-activity-kind-conductor: var(--mk-glow-gold);
  --sov-activity-kind-vision: var(--mk-glow-the-lantern-out-of-doors);
  --sov-activity-kind-audio: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-activity-kind-code: var(--mk-glow-where-light-enters);
  --sov-activity-kind-reasoning: var(--mk-glow-the-windhover);
  --sov-activity-kind-gui-action: var(--mk-glow-pied-beauty);

  /* §17.2c activity stream · step-17/PR.md §2c */
  --sov-activity-section-gap: var(--sov-space-5); /* 24px · chapter-level break between sections */
  --sov-activity-item-gap: var(--sov-space-1); /* 4px · tight list within a section */
  --sov-activity-item-pad-y: var(--sov-space-1); /* 4px · compact item tile */
  --sov-activity-item-pad-x: var(--sov-space-3); /* 12px · on-scale horizontal */
  --sov-activity-item-radius: var(--sov-radius-sm);
  --sov-activity-glow-fade-ms: 1800ms;
  --sov-activity-stale-ms: 30000ms;

  /* ═══ @repo/sovereign-ui semantic aliases · Step 12 / manifest.json tokens ═══
     Color + typography font stacks live in tokens/tokens.json →
     @repo/sovereign-tokens/css (imported before this file). Do not
     re-bridge --sov-color-* ↔ --sov-* or --sov-typography-font-* ↔
     --sov-font-* here — that creates circular custom properties and
     invalidates backgrounds, ink, and font-family across the shell. */

  /* Hairlines + elevation (sovereign-ui naming) */
  --sov-hairline-gold: var(--mk-hairline-gold);
  --sov-hairline-where-light: var(--mk-hairline-where-light);
  --sov-hairline-pied: var(--mk-hairline-pied);
  --sov-hairline-neutral: var(--sov-nav-hairline);
  --sov-shadow-tile: 0 20px 48px -20px
    color-mix(in oklab, var(--sov-bg) 78%, transparent);
  --sov-shadow-card: var(--sov-shadow-surface);
  --sov-shadow-sheet: var(--sov-sheet-shadow);
  --sov-shadow-bridge: var(--sov-bridge-shadow);
  --sov-glass-saturate: 1.4;

  /* Typography rungs (maps to step-09 §1 text rungs) */
  --sov-typography-rung-caption-size: var(--sov-text-caption-size);
  --sov-typography-rung-caption-tracking: 0.14em;
  --sov-typography-rung-display-size: var(--sov-text-display-size);
  --sov-typography-rung-display-weight: var(--sov-text-display-weight);
  --sov-typography-rung-display-line: var(--sov-text-display-line);
  --sov-typography-rung-display-tracking: -0.02em;
  --sov-typography-rung-field-size: var(--sov-text-field-size);
  --sov-typography-rung-field-line: var(--sov-text-field-line);

  /* Layout */
  --sov-layout-rail-width: var(--sov-rail-w);
  --sov-layout-right-rail-width: var(--sov-rail-w); /* symmetrised 2026-05-10 */
  --sov-layout-sheet-width: min(100vw - 32px, 520px);
  --sov-layout-bridge-sheet-width: min(100vw - 32px, 440px);
  --sov-layout-stream-max: 640px;

  /* Composer containment — constrained to center column between rails. */
  --sov-composer-offset-left: var(--sov-rail-w);
  --sov-composer-offset-right: var(--sov-rail-w);

  /* Radii (supplement OPEN radii)
     --sov-radius-xs added 2026-05-11 for dense-rail badges and action buttons
     where sm (8px) is too large. Authored: pr/step-37/PR.md §1. */
  --sov-radius-xs: 4px;
  --sov-radius-sm: 8px;
  --sov-radius-md: 12px;
  --sov-radius-lg: var(--sov-radius-tile);

  /* Motion (bridge malaika-home d-* to sovereign-ui names) */
  --sov-motion-duration-base: var(--sov-d-base);
  --sov-motion-duration-quick: var(--sov-d-fast);
  --sov-motion-duration-thinking-dot: 0.6s;
  --sov-motion-duration-breath: var(--sov-breath);
  --sov-motion-duration-ambient-breathe: 8s;
  --sov-motion-duration-wordmark-shimmer: var(--sov-wordmark-shimmer);
  --sov-motion-ease-out: var(--sov-ease-smooth);
  --sov-motion-ease-spring: var(--sov-ease-spring);

  /* Presence dot */
  --sov-presence-idle: var(--mk-glow-gold);
  --sov-presence-thinking: var(--mk-glow-where-light-enters);
  --sov-presence-speaking: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-presence-listening: var(--mk-glow-pied-beauty);
  --sov-presence-error: var(--mk-glow-the-windhover);

  /* Pretext empty canvas ambient (maps to existing ambient poles) */
  --sov-ambient-pole-a: var(--mk-glow-gold);
  --sov-ambient-pole-b: var(--mk-glow-where-light-enters);
  --sov-alpha-ambient-gold: 12%;
  --sov-alpha-ambient-where: 10%;

  /* —— Component scale tokens (@repo/sovereign-ui) —— */
  --sov-component-hero-tile-radius-hero: var(--sov-radius-tile);
  --sov-component-hero-tile-radius-compact: 16px;
  --sov-component-hero-tile-lift: translateY(-2px) scale(1.01);
  --sov-component-nav-rail-width: var(--sov-rail-w);
  /* ── nav-rail-row padding tokens removed 2026-05-11 (rail shell handles inset);
     --sov-component-nav-rail-row-row-radius kept for .nr-row border-radius. */
  --sov-component-nav-rail-row-radius: calc(
    (var(--sov-space-2) + var(--sov-space-3)) /
    2
  );
  /* Left active rail — full-height accent (reference: kaOS primary nav). */
  --sov-component-nav-rail-active-pip-width: var(--sov-space-1);
  --sov-component-passage-padding-y: 20px;
  --sov-component-passage-padding-x: 24px;
  --sov-component-passage-tint: 8%;
  --sov-component-passage-max-width: 720px;
  --sov-component-highlight-tint: 12%;
  --sov-component-highlight-underline-width: 2px;
  --sov-component-citation-chip-tint: 12%;
  --sov-component-citation-chip-index-size: 18px;
  --sov-component-annotation-pair-tint: 8%;
  --sov-component-annotation-pair-kaos-indent: 12px;
  --sov-component-tool-reveal-tint: 6%;
  --sov-component-tool-reveal-label-color: var(--sov-muted);
  --sov-component-code-artifact-tint: 78%;
  --sov-component-code-artifact-label-size: 10.5px;
  --sov-component-code-artifact-radius: 10px;
  --sov-component-code-artifact-label-font: var(--sov-font-mono);
  --sov-component-sheet-radius: var(--sov-radius-sheet);
  --sov-component-sheet-mix: 78%;
  --sov-component-sheet-blur: var(--sov-glass-blur-deep);
  --sov-component-bridge-sheet-radius-top: var(--sov-radius-sheet);
  --sov-component-bridge-sheet-handle-width: 36px;
  --sov-component-bridge-sheet-handle-height: 4px;
  --sov-component-focus-pill-offset: 20px;
  --sov-component-focus-pill-size: 48px;
  --sov-component-toast-anchor-offset: 20px;
  --sov-component-toast-padding-y: 12px;
  --sov-component-toast-padding-x: 16px;
  --sov-component-toast-radius: var(--sov-radius-md);
  --sov-component-pull-quote-tint: 6%;
  --sov-component-pull-quote-border-width: 3px;
  --sov-component-mobile-bottom-nav-height: 64px;
  --sov-component-chat-bubble-max-width: 88%;
  --sov-component-chat-bubble-padding-y: 12px;
  --sov-component-chat-bubble-padding-x: 16px;
  --sov-component-chat-bubble-radius-kaos: 4px 18px 18px 18px;
  --sov-component-chat-bubble-radius-user: 18px 4px 18px 18px;

  /* §17 Activity stream tokens (kind colorways + rail-toggle + geometry)
     live in the canonical tokens/colors.css — see lines ~1028-1061 there.
     This block was a copy authored in the same step and was removed
     2026-05-16 per the neuromorphic autonomy redesign (Charter Rule 5b:
     one source of truth per token; tokens live in tokens/). */

  /* ═══════════════════════════════════════════════════════════════════════
   * STEP-33 COMPREHENSIVE TOKEN BRIDGE · self-authored mode 5b
   *
   * Sanctioned: sovereign-design/kaOS Design System (self-authored)/
   *             pr/step-33/PR.md
   *
   * Closes 136 charter-debt records (79 unique tokens, 754 refs) by
   * bridging design-bundle naming into the canonical sovereign namespace.
   * Every bridge is a one-direction alias → canonical always wins.
   * ═══════════════════════════════════════════════════════════════════════ */

  /* ── Typography rung bridges (design-bundle --fs-* / --lh-* / --tracking-*) ── */
  --sov-typography-rung-section-size: var(--sov-text-section-size);
  --sov-typography-rung-section-line: var(--sov-text-section-line);
  --sov-typography-rung-section-weight: var(--sov-text-section-weight);
  --sov-typography-rung-section-tracking: var(--sov-text-section-tracking);
  --sov-typography-rung-tile-size: var(--sov-text-tile-size);
  --sov-typography-rung-tile-line: var(--sov-text-tile-line);
  --sov-typography-rung-tile-weight: var(--sov-text-tile-weight);
  --sov-typography-rung-tile-tracking: var(--sov-text-tile-tracking);
  --sov-typography-rung-caption-weight: var(--sov-text-caption-weight);
  --sov-typography-rung-body-size: var(--sov-text-body-size);
  --sov-typography-rung-body-line: var(--sov-text-body-line);
  --sov-typography-rung-body-weight: var(--sov-text-body-weight);
  --sov-typography-rung-body-tracking: var(--sov-text-body-tracking);

  /* ── z-index tier · canonical stack order for sovereign surfaces ── */
  --sov-z-body: 0;
  --sov-z-canvas: 10;
  --sov-z-tooltip: 20;
  --sov-z-popover: 30;
  --sov-z-flyout: 40;
  --sov-z-sheet: 50;
  --sov-z-folio-sheet: 50;
  --sov-z-listen-overlay: 50;
  --sov-z-canvas-veil: 55;
  --sov-z-drawer: 60;
  --sov-z-pretext-canvas: 60;
  --sov-z-dialog: 70;
  --sov-z-pretext-pinned: 80;
  --sov-z-toast: 90;
  --sov-z-pretext-rail: 100;
  --sov-z-composer: 110;
  --sov-z-pretext-composer: 120;
  --sov-z-toolbar: 999;

  /* ── Missing canonical --sov-* bridges ── */
  --sov-bg-elevated: var(--sov-surface-raised);
  --sov-col-max: var(--sov-canvas-max);
  --sov-col-reading: var(--sov-content-max);
  --sov-ease-out: var(--sov-ease-smooth);
  --sov-hairline: var(--sov-nav-hairline);
  --sov-hairline-on-raised: var(--sov-nav-hairline);
  --sov-header-h: var(--sov-section-h);
  --sov-motion-base: var(--sov-d-base);
  --sov-motion-fast: var(--sov-d-fast);
  /* ── rail-width symmetry — removed 2026-05-10.
     --sov-rail-w is canonical for both left and right rails. */
  --sov-surface-strong: var(--sov-surface-raised);
  --you-glow: var(--mk-glow-pied-beauty);
  --p-glow: var(--mk-glow-where-light-enters);

  /* ── Design-bundle --mk-* legacy namespace bridges ── */
  --mk-hairline: var(--sov-nav-hairline);
  --mk-subtle: var(--sov-subtle);
  --mk-surface: var(--sov-surface-raised);
  --mk-surface-raised: var(--sov-surface-raised);
  --mk-surface-sunken: var(--sov-surface-sunken);
  --mk-font-mono: var(--sov-font-mono);
  --mk-ease-expo: var(--sov-ease-expo);
  --mk-ease-out: var(--sov-ease-smooth);
  --mk-ease-spring: var(--sov-ease-spring);
  --mk-dur-base: var(--sov-d-base);
  --mk-dur-fast: var(--sov-d-fast);
  --mk-dur-slow: var(--sov-d-slow);
  --mk-dur-breathe: var(--sov-breath);
  --mk-dur-word: var(--sov-word-reveal-dur);
  --mk-blur-card: var(--sov-glass-blur);
  --mk-blur-folio: var(--sov-glass-blur-deep);
  --mk-composer-bg: var(--sov-bg);
  --mk-composer-blur: var(--sov-glass-blur);
  --mk-glass-blur-showcase: var(--sov-glass-blur-deep);
  --mk-ink-warm: var(--sov-accent);
  --mk-radius-card: var(--sov-radius-tile);
  --mk-radius-card-lg: var(--sov-radius-tile);
  --mk-radius-card-sm: var(--sov-radius-sm);
  --mk-radius-composer: var(--sov-radius-field);

  /* ── Design-bundle glow shorthand bridges ── */
  --mk-glow-bridge: var(--mk-glow-love-is-the-bridge);
  --mk-glow-kingfishers: var(--mk-glow-as-kingfishers-catch-fire);
  --mk-glow-peregrine: var(--mk-glow-the-windhover);
  --mk-glow-pied: var(--mk-glow-pied-beauty);
  --mk-glow-pied-h: var(--mk-hairline-pied);
  --mk-glow-where-light: var(--mk-glow-where-light-enters);
  --mk-glow-where-light-h: var(--mk-hairline-where-light);
  --mk-glow-windhover: var(--mk-glow-the-windhover);
  --mk-hairline-love-is-the-bridge: var(--mk-hairline-bridge);
  --mk-hairline-peregrine: var(--mk-hairline-windhover);
  --mk-hairline-starlight: color-mix(
    in oklab,
    var(--mk-glow-the-starlight-night) 28%,
    transparent
  );

  /* ── Gradient aliases (design-bundle shorthand) ── */
  --mk-gradient-as-kingfishers-catch-fire: linear-gradient(
    135deg,
    var(--mk-glow-as-kingfishers-catch-fire),
    var(--mk-glow-the-starlight-night)
  );
  --mk-gradient-hopkins: linear-gradient(
    135deg,
    var(--mk-glow-pied-beauty),
    var(--mk-glow-the-windhover),
    var(--mk-glow-gold),
    var(--mk-glow-where-light-enters)
  );
  --mk-gradient-pied-beauty: linear-gradient(
    135deg,
    var(--mk-glow-pied-beauty),
    var(--mk-glow-where-light-enters),
    var(--mk-glow-heaven-haven)
  );
  --mk-gradient-where-light-enters: linear-gradient(
    135deg,
    var(--mk-glow-where-light-enters),
    var(--mk-glow-gold)
  );

  /* ── z-index design-bundle bridges (--z-* → --sov-z-*) ── */
  --z-composer: var(--sov-z-composer);
  --z-dialog: var(--sov-z-dialog);
  --z-drawer: var(--sov-z-drawer);
  --z-flyout: var(--sov-z-flyout);
  --z-folio-sheet: var(--sov-z-sheet);
  --z-listen-overlay: var(--sov-z-sheet);
  --z-popover: var(--sov-z-popover);
  --z-sheet: var(--sov-z-sheet);
  --z-toast: var(--sov-z-toast);
  --z-tooltip: var(--sov-z-tooltip);
  --z-voice-modal: var(--sov-z-dialog);

  /* ── Phone surface · dial-pad + call-control · step-34 ──
     Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-34/PR.md
     All geometry aliases existing space-scale / radius / pretext tokens.
     Call-control colors reuse the palette tier under semantic metaphor. */
  --sov-dial-pad-cell-min: 64px;
  --sov-dial-pad-cell-radius: var(--sov-radius-md);
  --sov-dial-pad-gutter: var(--sov-space-3);
  --sov-dial-pad-display-h: 56px;

  /* ── Phone surface · ringing-state · step-37 §A2 ──
     Ringing-state halo borrowed from the Pretext pinned-object
     vocabulary — a where-light-enters glow + gold hairline ring
     pulsing on the sovereign breath cadence. Gold is reserved
     for Malaika's presence; where-light-enters signals "something
     found, something worth attending to."
     The incoming variant swaps where-light-enters for bridge rose —
     an incoming call is a connection offered, not an insight found.
     Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-37/PR.md */
  --sov-phone-ringing-halo: 0 0 0 1px var(--mk-hairline-gold), 0 0 32px 0
    var(--mk-glow-where-light-enters);
  --sov-phone-ringing-cadence: var(--sov-breath);
  --sov-phone-ringing-fade: 0.5;
  --sov-phone-ringing-halo-incoming: 0 0 0 1px var(--mk-hairline-bridge), 0 0
    32px 0 var(--mk-glow-love-is-the-bridge);
  --sov-phone-ringing-halo-outgoing: 0 0 0 1px var(--mk-hairline-gold), 0 0 32px
    0 var(--mk-glow-where-light-enters);

  /* Call-control color assignments — reuse the palette tier.
     No new color tokens invented. Every glow already exists. */
  --sov-phone-call-mute-glow: var(--mk-glow-pied-beauty);
  --sov-phone-call-hold-glow: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-phone-call-transfer-glow: var(--mk-glow-where-light-enters);
  --sov-phone-call-hangup-glow: var(--mk-glow-love-is-the-bridge);
  --sov-phone-call-speaker-glow: var(--mk-glow-the-windhover);
  --sov-phone-call-keypad-glow: var(--mk-glow-gold);

  /* ── Typography design-bundle bridges (--fs-* / --lh-* / --tracking-*) ── */
  --fs-display: var(--sov-text-display-size);
  --fs-h1: var(--sov-text-section-size);
  --fs-h2: var(--sov-text-field-size);
  --fs-h3: var(--sov-text-tile-size);
  --fs-body: var(--sov-text-body-size);
  --fs-lede: var(--sov-text-body-size);
  --fs-ui: var(--sov-text-caption-size);
  --fs-kbd: var(--sov-text-caption-size);
  --fs-label: var(--sov-text-caption-size);
  --lh-tight: 1.1;
  --lh-snug: 1.35;
  --lh-reading: 1.65;
  --tracking-caps: 0.14em;
  --tracking-display: -0.02em;

  /* ── Legacy Canvas Bridge · step-35 ──
     Bridges generic token names from early claude-design-bundle canvases
     (pre-Step-09) into the canonical sovereign namespace.
     Every bridge is a one-direction alias → canonical always wins.
     Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-35/PR.md */

  /* Color & surface — generic → canonical */
  --background: var(--sov-bg);
  --foreground: var(--sov-ink);
  --charcoal: var(--sov-bg);
  --jet: var(--sov-bg);
  --warm-white: var(--sov-ink);
  --muted: var(--sov-muted);
  --subtle: var(--sov-subtle);
  --surface-1: var(--sov-bg);
  --surface-2: var(--sov-surface-raised);
  --surface-3: var(--sov-surface-sunken);

  /* Gold family — generic → canonical */
  --gold: var(--mk-glow-gold);
  --gold-bright: var(--mk-glow-gold);
  --gold-deep: var(--mk-glow-gold-deep);
  --gold-muted: var(--mk-glow-gold-soft);
  --gold-solid: var(--mk-glow-gold);

  /* Radius — generic → canonical */
  --radius-sm: var(--sov-radius-sm);
  --radius-md: var(--sov-radius-md);
  --radius-lg: var(--sov-radius-lg);
  --radius-xl: var(--sov-radius-tile);
  --radius-2xl: var(--sov-radius-sheet);
  --radius-pill: var(--sov-radius-pill);

  /* Duration — generic → canonical */
  --d-base: var(--sov-d-base);
  --d-fast: var(--sov-d-fast);
  --d-slow: var(--sov-d-slow);
  --d-breath: var(--sov-breath);

  /* Easing — generic → canonical */
  --ease-expo: var(--sov-ease-expo);
  --ease-smooth: var(--sov-ease-smooth);
  --ease-spring: var(--sov-ease-spring);

  /* Layout — generic → canonical */
  --content-max: var(--sov-content-max);
  --rail-l-w: var(--sov-rail-w);
  --rail-r-w: var(--sov-rail-w);
  --rail-pad: var(--sov-rail-pad);
  --top-rail-h: var(--sov-top-rail-h);
  --dock-bg: var(--sov-bg);
  --dock-lift: var(--sov-dock-lift);

  /* Glass — generic → canonical */
  --glass-bg: var(--sov-glass-mix);
  --glass-blur: var(--sov-glass-blur);
  --glass-blur-deep: var(--sov-glass-blur-deep);
  --glass-sat: var(--sov-glass-saturate);

  /* mk-* shorthand variants → canonical */
  --mk-glow-holy-gold: var(--mk-glow-gold);
  --mk-hairline-kingfs: var(--mk-hairline-kingfishers);
  --mk-hairline-windhvr: var(--mk-hairline-windhover);
  --mk-hairline-rumi: var(--mk-hairline-where-light);

  /* mk-* generic surface tokens → canonical */
  --mk-bg: var(--sov-bg);
  --mk-fg: var(--sov-ink);
  --mk-muted: var(--sov-muted);

  /* mk-* font aliases → canonical */
  --mk-font-sans: var(--sov-font-sans);
  --mk-font-serif: var(--sov-font-serif);

  /* Do not set --font-sans here. next/font publishes --font-sans on
   * html/body; bridging it to --sov-font-sans on the same [data-sovereign]
   * node creates a circular custom-property loop with tokens.css and
   * invalidates every --sov-font-* / --sov-typography-font-* stack. */

  /* Additional design-bundle bridges */
  --mk-glass-blur-tile: var(--sov-glass-blur);
  --mk-radius-btn: var(--sov-radius-pill);
  --sov-anim-fast: var(--sov-d-fast);
  --sov-easing-standard: var(--sov-ease-smooth);

  /* Full-name hairline aliases */
  --mk-hairline-as-kingfishers-catch-fire: var(--mk-hairline-kingfishers);
  --mk-hairline-pied-beauty: var(--mk-hairline-pied);
  --mk-hairline-the-windhover: var(--mk-hairline-windhover);

  /* Missing canonical definitions (used without fallback in component code) */
  --sov-rule: color-mix(in oklab, var(--sov-ink) 8%, transparent);
  --sov-typography-rung-caption-line: var(--sov-text-caption-line);

  /* Step 12 canvas bridge */
  --sov-surface-stronger: var(--sov-surface-raised);

  /* ── Pretext Forge Canvas · Freeze Veil · step-36 §A2 ──
     When the pretext canvas covers the viewport, the body beneath
     receives this dim-and-blur treatment. Uses --sov-veil via color-mix
     so it re-tints automatically in light mode.
     Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-36/PR.md */
  --sov-pretext-freeze-veil: color-mix(
    in oklab,
    var(--sov-veil) 88%,
    transparent
  );
  --sov-pretext-freeze-blur: 8px;
  --sov-pretext-freeze-fade-ms: var(--sov-d-base);

  /* ── Pretext Forge Canvas · Pinned-Object Chrome · step-36 §A3 ──
     Pinned content blocks (book chunks, documents, dataset rows)
     receive a where-light-enters halo + accent pip so they read as
     "fixed here on purpose." Gold is deliberately not used — it is
     reserved for Malaika's presence.
     Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-36/PR.md */
  --sov-pretext-pinned-halo: 0 0 0 1px var(--mk-hairline-where-light), 0 8px
    32px -8px var(--mk-glow-where-light-enters);
  --sov-pretext-pinned-radius: var(--sov-radius-md);
  --sov-pretext-pinned-pip-size: 8px;
  --sov-pretext-pinned-pip-color: var(--sov-accent);

  /* ── Canvas Connections · TRON-mode stroke + glow family · step-43 §Connections ──
   *   One family for every surface that draws node connectors:
   *   Projects (SVG) and Library Constellation (Canvas2D).
   *   Every value is a palette promotion from --mk-glow-gold at named opacities.
   *   No new palette colors; all derive from the already-sanctioned gold seed.
   *   Established (magi / authored) — 42% gold + near/far glow.
   *   Subject (shared tags) — quieter solid sibling of preview stroke.
   *   Semantic (embedding) — faintest web; also used by Projects cosine lines.
   *   Preview — dashed “about to connect” on Projects only.
   *   Hover — 65% gold with wider bloom.
   *   *-glow-blur tokens are Canvas2D companions (SVG uses drop-shadow filters).
   *   Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-43/PR.md §Connections */
  --sov-canvas-connection-stroke: color-mix(
    in oklab,
    var(--mk-glow-gold) 42%,
    transparent
  );
  --sov-canvas-connection-stroke-width: 7px;
  --sov-canvas-connection-glow-near: drop-shadow(
    0 0 3px color-mix(in oklab, var(--mk-glow-gold) 25%, transparent)
  );
  --sov-canvas-connection-glow-far: drop-shadow(
    0 0 8px color-mix(in oklab, var(--mk-glow-gold) 12%, transparent)
  );
  --sov-canvas-connection-glow-blur: 3px;
  --sov-canvas-connection-preview-stroke: color-mix(
    in oklab,
    var(--mk-glow-gold) 32%,
    transparent
  );
  --sov-canvas-connection-preview-stroke-width: 7px;
  --sov-canvas-connection-preview-dash: 8px 7px;
  --sov-canvas-connection-preview-glow: drop-shadow(
    0 0 4px color-mix(in oklab, var(--mk-glow-gold) 28%, transparent)
  );
  --sov-canvas-connection-hover-stroke: color-mix(
    in oklab,
    var(--mk-glow-gold) 65%,
    transparent
  );
  --sov-canvas-connection-hover-glow: drop-shadow(
    0 0 6px color-mix(in oklab, var(--mk-glow-gold) 35%, transparent)
  );
  --sov-canvas-connection-hover-glow-blur: 6px;
  --sov-canvas-connection-preview-flow: sov-canvas-connection-flow 800ms linear
    infinite;
  /* Subject = shared-tag web (constellation). Same gold ladder, quieter than established. */
  --sov-canvas-connection-subject-stroke: var(
    --sov-canvas-connection-preview-stroke
  );
  --sov-canvas-connection-subject-stroke-width: 1.1px;
  /* Semantic = embedding web (Projects cosine + constellation when ready).
   * Lifted from the original near-invisible 0.8px / 18% / ×0.45 so the
   * cosine web actually reads on the project canvas. */
  --sov-canvas-connection-semantic-stroke: color-mix(
    in oklab,
    var(--mk-glow-gold) 38%,
    transparent
  );
  --sov-canvas-connection-semantic-stroke-width: 2.5px;
  /* Coread = read-together web (constellation "Read together" lens — pairs
   * the reader opened within the same window of days, from the local
   * reading history). Same gold ladder: sits between established (42%)
   * and subject (28%) because it is lived fact, quieter than authored. */
  --sov-canvas-connection-coread-stroke: color-mix(
    in oklab,
    var(--mk-glow-gold) 34%,
    transparent
  );
  --sov-canvas-connection-coread-stroke-width: 3px;

  /* Substrate edges — beholding (warm amber) + aesthetic (deeper amber).
   * Track 2: the felt-trace layer. Where the gold arithmetic edges are
   * cool/neutral, the substrate edges glow warmer — a visible distinction
   * between "computed" and "felt". */
  --sov-canvas-connection-beholding-stroke: color-mix(
    in oklab,
    #f59e0b 45%,
    transparent
  );
  --sov-canvas-connection-beholding-stroke-width: 3.5px;
  --sov-canvas-connection-aesthetic-stroke: color-mix(
    in oklab,
    #f59e0b 58%,
    transparent
  );
  --sov-canvas-connection-aesthetic-stroke-width: 4px;

  /* Annotation accent — the ring drawn around nodes that have highlights.
   * A warm gold-amber, brighter than the edge strokes, so it reads as
   * "there is something here worth reading" even at zoom-out. */
  --sov-canvas-annotation-glow: #fbbf24;

  /* -----------------------------------------------------------------------
   * REVENUE — council verdict, campaign status, metric delta, sparkline,
   * budget burndown, pre-flight check.
   * Authored: sovereign-design/kaOS Design System (revenue)/PR.md §Tokens.
   * Sanctioned under Charter Rule 5a.
   * Zero new palette colors — every token binds to an existing --mk-glow-*
   * seed in this file. Two-tier discipline preserved.
   * -------------------------------------------------------------------- */
  --sov-verdict-pass-glow: var(--mk-glow-where-light-enters);
  --sov-verdict-pass-hairline: var(--mk-hairline-light);
  --sov-verdict-pass-ink: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 90%,
    var(--mk-fg)
  );

  --sov-verdict-concern-glow: var(--mk-glow-the-windhover);
  --sov-verdict-concern-hairline: var(--mk-hairline-windhover);
  --sov-verdict-concern-ink: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 88%,
    var(--mk-fg)
  );

  --sov-verdict-block-glow: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-verdict-block-hairline: var(--mk-hairline-fire);
  --sov-verdict-block-ink: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 90%,
    var(--mk-fg)
  );

  --sov-status-ready-glow: var(--mk-glow-where-light-enters);
  --sov-status-ready-hairline: var(--mk-hairline-light);

  --sov-status-live-glow: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-status-live-hairline: var(--mk-hairline-fire);

  --sov-status-paused-glow: var(--mk-glow-pied-beauty);
  --sov-status-paused-hairline: var(--mk-hairline-pied);

  --sov-status-completed-glow: var(--mk-glow-gold);
  --sov-status-completed-hairline: var(--mk-hairline-gold);

  --sov-status-killed-glow: var(--mk-glow-the-starlight-night);
  --sov-status-killed-hairline: var(--mk-hairline-starlight);

  --sov-delta-up-ink: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 90%,
    var(--mk-fg)
  );
  --sov-delta-down-ink: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 88%,
    var(--mk-fg)
  );
  --sov-delta-flat-ink: var(--sov-whisper);

  --sov-spark-line-anchor: color-mix(
    in oklab,
    var(--mk-glow-gold) 80%,
    transparent
  );
  --sov-spark-line-live: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 80%,
    transparent
  );
  --sov-spark-fill-anchor: color-mix(
    in oklab,
    var(--mk-glow-gold) 14%,
    transparent
  );
  --sov-spark-fill-live: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 14%,
    transparent
  );
  --sov-spark-axis: color-mix(in oklab, var(--mk-fg) 8%, transparent);

  /* SovereignChart — multi-series palette + grid. Sanctioned under
     sovereign-design/kaOS Design System (business)/PR-sovereign-chart.md.
     Series 1-3 reuse existing Hopkins glows so the chart never introduces
     off-palette ink; anchor/live come from the spark tokens above. */
  --sov-chart-series-1: color-mix(in oklab, var(--mk-glow-gods-grandeur) 80%, transparent);
  --sov-chart-series-2: color-mix(in oklab, var(--mk-glow-pied-beauty) 80%, transparent);
  --sov-chart-series-3: color-mix(in oklab, var(--mk-glow-where-light-enters) 80%, transparent);
  --sov-chart-fill-series-1: color-mix(in oklab, var(--mk-glow-gods-grandeur) 12%, transparent);
  --sov-chart-fill-series-2: color-mix(in oklab, var(--mk-glow-pied-beauty) 12%, transparent);
  --sov-chart-fill-series-3: color-mix(in oklab, var(--mk-glow-where-light-enters) 12%, transparent);
  --sov-chart-grid: color-mix(in oklab, var(--mk-fg) 7%, transparent);

  --sov-burndown-track: color-mix(in oklab, var(--mk-fg) 7%, transparent);
  --sov-burndown-spent: color-mix(
    in oklab,
    var(--mk-glow-gold) 60%,
    transparent
  );
  --sov-burndown-projected: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 50%,
    transparent
  );
  --sov-burndown-target-tick: color-mix(in oklab, var(--mk-fg) 36%, transparent);

  --sov-preflight-ok-glow: var(--mk-glow-where-light-enters);
  --sov-preflight-warn-glow: var(--mk-glow-the-windhover);
  --sov-preflight-error-glow: var(--mk-glow-as-kingfishers-catch-fire);
}

/* ---------- Palette (light opt-in · step-09 §3 + §7 + step-33) ----------
   Light surface tier (color-light.*) and deepened glow palette
   (palette-light.glow.*) live in tokens/tokens.json and reach this
   scope via dist/tokens-light.css under
   [data-sovereign][data-sovereign-theme='light']. Legacy --sov-* names
   bridge to --sov-color-*; --mk-glow-* override from palette-light.
   Migrated 2026-07-05 source-of-truth consolidation. */

/* ---------- Base root ----------
 * Applies to the [data-sovereign] shell itself.
 *
 * NOTE: isolation:isolate is intentionally NOT set here. Adding it creates
 * a z:auto stacking context that traps internal elements (sov-a05__composer-wrap
 * etc.) below the body-level portals at z-60, hiding the chat input.
 *
 * Instead, when pretext/voice overlays are active, the OverlayChromePortal
 * stamps [data-overlay-active] on this element. CSS rules under that attribute
 * hide the shell's own chrome (left-chrome, tabs, right-chrome) to prevent
 * duplication with the portal's chrome. The composer-wrap is given z-65 so
 * it remains visible above the z-60 portals even without isolation.
 */
[data-sovereign] {
  background: var(--sov-bg);
  color: var(--sov-ink);
  font-family: var(--sov-font-sans);
  font-feature-settings: "ss01", "cv01";
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  width: 100%;
  max-width: none;
  margin: 0;
  position: relative;
}

/* ---------- Chat surface scope · Cycle V.3 Todo #10 ----------
   The chat surface is conversation, not long-form reading. Pin the
   whole `[data-sovereign-chat]` subtree to `--sov-font-sans` so the
   typography stays in chat register even when a child component
   would otherwise switch to serif (e.g. SovereignPassage's body
   under `.sov-t-body`, which uses --sov-font-serif by default for
   reading surfaces). One attribute on the chat root, every
   descriptor / bubble / passage inside speaks sans.

   The body element itself doesn't need the font-family — line 1290
   already sets it on `[data-sovereign]`. This descendant override
   exists so any nested rule that *escapes* sans (passage, prose
   block, future "reading mode" surface that lives inside chat) is
   still pulled back into the chat voice. The selector is one
   level higher than the descendants because we want the inheritance
   to win over per-component font-family declarations.

   Pattern matches the `[data-sovereign-theme="light"]` opt-in: a
   data attribute on a substrate node selects an alternative
   register. */
[data-sovereign] [data-sovereign-chat],
[data-sovereign] [data-sovereign-chat] * {
  font-family: var(--sov-font-sans);
}

/* Ambient wash · step-09 §5 — .sov-canvas = SovereignCanvas column;
   [data-sovereign].sov-surface (same-node) = app root. The class
   `.sov-surface` is *also* worn by every SovereignTile (descendant of
   [data-sovereign]); a descendant-scoped rule here would leak app-root
   sizing onto every tile and stretch them to one full viewport. The
   same-node selector binds these rules to the provider root only.
   Sanctioned recipe (PR.md §5).

   Authored: sovereign-design/kaOS Design System (self-authored)/pr/step-20/PR.md
             §SR-1 surface-scope regression fix.
             Sanctioned under Charter Rule 5b (Sovereign Design Authority). */
.sov-canvas,
[data-sovereign].sov-surface {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100dvh;
  width: 100vw;
  overflow: hidden;
  max-width: none;
  margin: 0;
  border-radius: 0;
  box-shadow: none;
  /* background: [data-sovereign] block above */
}
/* Ambient wash pseudo · same-node scope.
   Tiles also wear `.sov-surface` (descendant of [data-sovereign]); a
   descendant `.sov-surface::before` would paint a 10vmax radial-gradient
   wash behind every card. Bind to the provider root only.
   See sovereign-design/kaOS Design System (self-authored)/pr/step-20/PR.md
   §SR-1. */
.sov-canvas::before,
[data-sovereign].sov-surface::before {
  content: "";
  position: absolute;
  inset: -10vmax;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
      60vmax 50vmax at 18% 12%,
      var(--sov-ambient-a),
      transparent 62%
    ),
    radial-gradient(
      55vmax 40vmax at 82% 88%,
      var(--sov-ambient-b),
      transparent 64%
    );
  filter: blur(24px);
  animation: sov-breathe-ambient var(--sov-wordmark-shimmer) ease-in-out
    infinite alternate;
}
@keyframes sov-breathe-ambient {
  0% {
    opacity: 0.55;
  }
  100% {
    opacity: 1;
  }
}

/* ── Compact rails — hide the ambient wash ::before so the narrow
 *   48px rail strips don't wear a visible gradient bleed-through.
 *   The ambient wash is a large (50-60vmax) radial gradient at z:0;
 *   at full rail width it reads as a warm ambient glow behind the
 *   transparent rails. At 48px the sliver still catches gradient
 *   colour and looks like a mismatched leak. Suppress it. */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact]).sov-surface::before {
  content: none;
}

/* Per-word reveal — Malaika's spoken-like streaming.
   Used by SovereignField when wordFade is true. Blur lift is subtle
   (2px → 0) so the word appears to settle rather than flash. */
@keyframes sov-word-in {
  from {
    opacity: 0;
    filter: blur(2px);
  }
  to {
    opacity: 1;
    filter: blur(0);
  }
}

/* Gold streaming caret. */
@keyframes sov-caret {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* Breath — the canonical sovereign heartbeat (step-09 §6). Dots,
   embers, shimmer tiles all pulse on this rhythm at --sov-breath. */
@keyframes sov-breathe {
  0%,
  100% {
    opacity: 0.45;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1.1);
  }
}

/* Gold wordmark shimmer — the animated kaOS gradient. 22s cycle; reduced
   motion collapses to static. */
@keyframes sov-gold-shimmer {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}

/* Per-word fade reveal used by SovereignPassage. */
@keyframes sov-word-fade {
  from {
    opacity: 0;
    filter: blur(3px);
  }
  to {
    opacity: 1;
    filter: blur(0);
  }
}

/* Step-16 keyframes — malaika-home.html entrance animations. */
@keyframes sov-fade-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes sov-nav-in {
  from {
    opacity: 0;
    transform: translateX(-4px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
@keyframes sov-soft-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Pretext pinned-object entrance · step-36 §A3
   Subtle scale-from-94% — the pinned object "settles into place."
   Suppressed under prefers-reduced-motion per A3-3 decision.
   Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-36/PR.md */
@keyframes sov-pretext-pinned-in {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Tab indicator breathing (gold bar under active tab) */
@keyframes sov-tab-breathe {
  0%,
  100% {
    opacity: 0.42;
    transform: scaleX(0.7);
  }
  50% {
    opacity: 0.9;
    transform: scaleX(1);
  }
}

/* Phone ringing-state halo · step-37 §A2
   Pulses a where-light-enters glow on the sovereign breath cadence.
   Gold hairline ring stays constant — the glow breathes in/out.
   The consumer sets box-shadow: var(--sov-phone-ringing-halo) on the
   idle frame and this animation on the ringing state, overriding
   box-shadow at 50% to pulse the glow radius + opacity.
   Reduced-motion: static halo = animation: none with the
   var(--sov-phone-ringing-halo) visible at full opacity.
   Sanctioned: sovereign-design/kaOS Design System (self-authored)/pr/step-37/PR.md */
@keyframes sov-phone-ring {
  0%,
  100% {
    box-shadow: 0 0 0 1px var(--mk-hairline-gold), 0 0 32px 0
      var(--mk-glow-where-light-enters);
    opacity: 1;
  }
  50% {
    box-shadow: 0 0 0 1px var(--mk-hairline-gold), 0 0 64px 12px
      var(--mk-glow-where-light-enters);
    opacity: calc(1 - var(--sov-phone-ringing-fade, 0.5));
  }
}

@keyframes sov-phone-ring-incoming {
  0%,
  100% {
    box-shadow: 0 0 0 1px var(--mk-hairline-bridge), 0 0 32px 0
      var(--mk-glow-love-is-the-bridge);
    opacity: 1;
  }
  50% {
    box-shadow: 0 0 0 1px var(--mk-hairline-bridge), 0 0 64px 12px
      var(--mk-glow-love-is-the-bridge);
    opacity: calc(1 - var(--sov-phone-ringing-fade, 0.5));
  }
}

@keyframes sov-phone-ring-outgoing {
  0%,
  100% {
    box-shadow: 0 0 0 1px var(--mk-hairline-gold), 0 0 32px 0
      var(--mk-glow-where-light-enters);
    opacity: 1;
  }
  50% {
    box-shadow: 0 0 0 1px var(--mk-hairline-gold), 0 0 64px 12px
      var(--mk-glow-where-light-enters);
    opacity: calc(1 - var(--sov-phone-ringing-fade, 0.5));
  }
}

/* Step-10 keyframes (sanctioned via pr/step-10/primitives.html lines 61-77).
   sov-breathe-pulse  — HeroTile shimmer state (kaOS-is-finding wash).
   sov-tool-in        — SovereignToolReveal entrance.
   sov-thinking-dot   — three-dot bounce inside SovereignThinkingState.
   sov-mic-pulse/spin — sovereign voice composer states, centralized here
                        so prompt components never inject ad hoc CSS. */
@keyframes sov-breathe-pulse {
  0%,
  100% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
}
@keyframes sov-tool-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes sov-thinking-dot {
  0%,
  80%,
  100% {
    transform: scale(0.6);
    opacity: 0.3;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}
@keyframes sov-mic-pulse {
  0% {
    transform: scale(0.92);
    opacity: 0.75;
  }
  70% {
    transform: scale(1.18);
    opacity: 0;
  }
  100% {
    transform: scale(1.18);
    opacity: 0;
  }
}
@keyframes sov-mic-spin {
  to {
    transform: rotate(360deg);
  }
}

/* Composer mic — token-driven utility classes. Sovereign chrome
   applies these so prompt components never inject inline animation
   styles. The recording ring pulses on the canonical breath cadence
   (--sov-breath); the spinner runs at a fixed UX rate. Both are
   gated by the global prefers-reduced-motion block above. */
[data-sovereign] .sov-mic-pulse-ring {
  animation: sov-mic-pulse var(--sov-breath) var(--sov-ease) infinite;
}
[data-sovereign] .sov-mic-spinner {
  animation: sov-mic-spin 0.9s linear infinite;
}

/* Per-word reveal utility — Malaika's streaming reply fade. The
   consumer sets `--sov-word-i` per span (the word's index relative
   to the stream-onset) and this class drives the cadence-aware
   stagger from the canonical triplet. Ad-hoc inline animations are
   forbidden; sovereign field surfaces use this class only. */
[data-sovereign] .sov-word-reveal {
  display: inline;
  opacity: 0;
  animation: sov-word-in var(--sov-word-reveal-dur) var(--sov-ease-expo) both;
  animation-delay: calc(
    var(--sov-word-reveal-lead) +
    var(--sov-word-i, 0) *
    var(--sov-word-reveal-stagger)
  );
}

/* ── Deleted (step-40): dead .sov-nav-rail component from @repo/kaos-sovereign — the
 *    canonical SovereignNavRail lives in @repo/sovereign-ui and uses .nr / .nr-scroll /
 *    .nr-row classes in its own CSS block below. The old .sov-icon-btn helper was
 *    only consumed by this dead rail and is also removed. */

/* ---------- SovereignTopRail ----------
   Step-16: malaika-home.html parity. Horizontal section tabs at top of
   main content area. Glass pill with uppercase tabs. */
[data-sovereign] .sov-top-rail-wrap {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 18px 28px 14px;
  pointer-events: none;
}
[data-sovereign] .sov-top-rail {
  pointer-events: auto;
  height: var(--sov-top-rail-h);
  border-radius: var(--sov-top-rail-radius);
  padding: 0 var(--sov-space-2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sov-space-1);
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix-strong),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
  box-shadow: var(--sov-shadow-surface);
}
[data-sovereign] .sov-top-rail__tab {
  padding: var(--sov-space-2) var(--sov-space-4);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-tab-font-size);
  font-weight: var(--sov-tab-weight);
  letter-spacing: var(--sov-tab-tracking);
  text-transform: uppercase;
  color: var(--sov-muted);
  border-radius: var(--sov-radius-pill);
  white-space: nowrap;
  border: 0;
  background: transparent;
  cursor: pointer;
  transition: color var(--sov-d-base) var(--sov-ease-expo);
}
[data-sovereign] .sov-top-rail__tab:hover {
  color: var(--sov-subtle);
}
[data-sovereign] .sov-top-rail__tab[aria-selected="true"] {
  color: var(--sov-ink);
  font-weight: var(--sov-tab-weight-active);
}
[data-sovereign] .sov-top-rail__tab[aria-selected="true"]::after {
  content: "";
  display: block;
  width: var(--sov-tab-indicator-w);
  height: var(--sov-tab-indicator-h);
  margin: 6px auto 0;
  border-radius: 2px;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 10px color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
  opacity: 0.7;
  animation: sov-tab-breathe var(--sov-d-breath) var(--sov-ease-smooth) infinite;
}

/* ---------- SovereignRightRail ----------
   Step-16: malaika-home.html parity. User cluster, search pill, aside
   groups, focus music button. */
[data-sovereign] .sov-right-rail {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--sov-rail-w);
  padding: var(--sov-rail-pad) var(--sov-rail-pad) var(--sov-gutter);
  display: flex;
  flex-direction: column;
  background: transparent;
}
[data-sovereign] .sov-user-cluster {
  display: flex;
  align-items: center;
  gap: var(--sov-space-3);
  padding: 0 var(--sov-space-2) var(--sov-space-6);
  opacity: 0;
  animation: sov-fade-rise var(--sov-d-slow) var(--sov-ease-expo) forwards;
  animation-delay: 80ms;
}
[data-sovereign] .sov-user-avatar {
  width: var(--sov-user-avatar-size);
  height: var(--sov-user-avatar-size);
  flex-shrink: 0;
  border-radius: var(--sov-radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(
    135deg,
    var(--mk-glow-gold-soft) 0%,
    var(--mk-glow-gold-deep) 100%
  );
  color: var(--sov-bg);
  font-family: var(--sov-font-sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold-deep) 20%, transparent), 0 0 18px
    color-mix(in oklab, var(--mk-glow-gold-deep) 14%, transparent), 0 0 32px
    color-mix(in oklab, var(--mk-glow-gold-deep) 8%, transparent), inset 0 1px 0
    rgba(255, 255, 255, 0.18);
  cursor: pointer;
  transition: transform var(--sov-d-fast) var(--sov-ease-spring), box-shadow
    var(--sov-d-base) var(--sov-ease-expo);
}
[data-sovereign] .sov-user-avatar:hover {
  box-shadow: 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 28%, transparent), 0 0 24px
    color-mix(in oklab, var(--mk-glow-gold) 20%, transparent), 0 0 44px
    color-mix(in oklab, var(--mk-glow-gold-deep) 12%, transparent), inset 0 1px
    0 rgba(255, 255, 255, 0.22);
}
[data-sovereign] .sov-user-avatar:active {
  transform: scale(0.94);
}
[data-sovereign] .sov-user-info {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
[data-sovereign] .sov-user-name {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-user-name-size);
  font-weight: var(--sov-user-name-weight);
  letter-spacing: var(--sov-user-name-tracking);
  text-transform: uppercase;
  color: var(--sov-subtle);
}
[data-sovereign] .sov-user-email {
  font-family: var(--sov-font-sans);
  font-size: 10px;
  color: var(--sov-muted);
  margin-top: 2px;
}

/* Single-line body input — the canonical token-driven field surface. */
[data-sovereign] .sov-input {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--sov-ink);
  padding: var(--sov-space-3) var(--sov-space-4);
  border-radius: var(--sov-radius-md);
  border: 0;
  outline: 0;
  background: var(--sov-surface-raised);
  box-shadow:
    inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
  transition:
    box-shadow var(--sov-d-fast) var(--sov-ease-smooth),
    background-color var(--sov-d-fast) var(--sov-ease-smooth);
}
[data-sovereign] .sov-input::placeholder {
  color: var(--sov-whisper);
  opacity: 0.6;
}
[data-sovereign] .sov-input:focus,
[data-sovereign] .sov-input:focus-visible {
  background: var(--sov-surface-raised);
  box-shadow:
    inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 56%, transparent),
    0 0 0 3px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
}
[data-sovereign] .sov-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
/* The sheet context tightens the input — same shape, less vertical air. */
[data-sovereign] .sov-glass-strong .sov-input,
[data-sovereign] .sov-sheet .sov-input {
  padding: var(--sov-space-2) var(--sov-space-3);
  font-size: var(--sov-text-tile-size);
  line-height: var(--sov-text-tile-line);
}

/* Search pill */
[data-sovereign] .sov-search-pill {
  display: flex;
  align-items: center;
  gap: var(--sov-space-3);
  padding: var(--sov-space-3) var(--sov-space-3);
  box-sizing: border-box;
  height: var(--sov-search-pill-h);
  border-radius: var(--sov-radius-pill);
  background: var(--sov-surface-raised);
  color: var(--sov-muted);
  font-family: var(--sov-font-sans);
  font-size: 13px;
  cursor: pointer;
  border: 0;
  width: 100%;
  text-align: left;
  transition: background var(--sov-d-base) var(--sov-ease-expo), color
    var(--sov-d-base) var(--sov-ease-expo), box-shadow var(--sov-d-base)
    var(--sov-ease-expo);
  opacity: 0;
  animation: sov-fade-rise var(--sov-d-slow) var(--sov-ease-expo) forwards;
  animation-delay: 160ms;
}
[data-sovereign] .sov-search-pill:hover {
  background: var(--sov-veil);
  color: var(--sov-subtle);
}
[data-sovereign] .sov-search-pill__icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
[data-sovereign] .sov-search-pill__label {
  flex: 1 1;
  min-width: 0;
}
[data-sovereign] .sov-search-pill__shortcut {
  font-family: var(--sov-font-mono);
  font-size: 10px;
  padding: 2px 5px;
  background: var(--sov-bg);
  border-radius: 4px;
  color: var(--sov-whisper);
}

/* Right-rail footer — no background, absorbs --sov-gutter at bottom.
   Content left/right-padded by parent .sov-a03__rside (--sov-rail-pad);
   no redundant inset here so focus button aligns with project rail above. */
[data-sovereign] .sov-right-rail__bottom {
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: var(--sov-space-3) 0 var(--sov-gutter);
  background: transparent;
  opacity: 0;
  animation: sov-fade-rise var(--sov-d-slow) var(--sov-ease-expo) forwards;
  animation-delay: 520ms;
}
[data-sovereign] .sov-focus-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) var(--sov-space-3) var(--sov-space-2)
    var(--sov-space-3);
  border-radius: var(--sov-radius-pill);
  background: var(--sov-surface-raised);
  color: var(--sov-subtle);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-focus-btn-font-size);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 0;
  cursor: pointer;
  transition: background var(--sov-d-base) var(--sov-ease-expo), color
    var(--sov-d-base) var(--sov-ease-expo), box-shadow var(--sov-d-base)
    var(--sov-ease-expo);
}
[data-sovereign] .sov-focus-btn:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
[data-sovereign] .sov-focus-btn svg {
  width: var(--sov-focus-btn-icon-size);
  height: var(--sov-focus-btn-icon-size);
  stroke-width: 1.6;
  color: var(--mk-glow-gold);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-top-rail__tab[aria-selected="true"]::after {
    animation: none;
    opacity: 0.7;
  }
  [data-sovereign] .sov-user-cluster,
  [data-sovereign] .sov-search-pill,
  [data-sovereign] .sov-right-rail__bottom {
    opacity: 1;
    animation: none;
  }
  /* Phone ringing — static halo at full opacity, no pulse */
  [data-sovereign] .sov-phone-ring {
    animation: none;
    opacity: 1;
    box-shadow: var(--sov-phone-ringing-halo);
  }
}

/* ---------- SovereignRail ----------
   Quiet vertical menu for both left- and right-rail variants. Items are
   bordered in pied hairline only via background mix, never with a real
   border — elevation is shadow + blur. */
[data-sovereign] .sov-rail {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-inline: 4px;
  width: 100%;
  min-width: 0;
}
[data-sovereign] .sov-rail__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--sov-radius-pill);
  background: transparent;
  color: var(--sov-whisper);
  text-decoration: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background var(--sov-hush) var(--sov-ease), color var(--sov-hush)
    var(--sov-ease);
}
[data-sovereign] .sov-rail__item:hover {
  background: color-mix(in oklab, var(--sov-veil) 70%, transparent);
  color: var(--sov-subtle);
}
[data-sovereign] .sov-rail__item[data-active="true"] {
  background: color-mix(in oklab, var(--sov-veil) 90%, transparent);
  color: var(--sov-ink);
}
[data-sovereign] .sov-rail__item-body {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
[data-sovereign] .sov-rail__icon {
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-rail__labels {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
[data-sovereign] .sov-rail__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: var(--sov-radius-pill);
  color: var(--sov-ink);
  min-width: 0;
}
[data-sovereign] .sov-rail__mark {
  position: relative;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
[data-sovereign] .sov-rail__mark-glow {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 210deg, var(--sov-accent), transparent 60%);
  filter: blur(6px);
  opacity: 0.7;
  animation: sov-breathe 6s var(--sov-ease) infinite;
}
[data-sovereign] .sov-rail__mark-core {
  position: relative;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--sov-ink);
  opacity: 0.85;
}

/* ---------- SovereignCanvas ----------
   Centered content column (NOT the app root — that is .sov-surface on
   SovereignProvider). Must be a *descendant* of [data-sovereign] so the
   provider root must not use class sov-canvas or it would pick up this
   padding when any ancestor had [data-sovereign]. Holds scroll + max width. */
[data-sovereign] .sov-canvas {
  flex: 1 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding-block: 32px;
  padding-inline: clamp(8px, 2vw, 24px);
}
[data-sovereign] .sov-canvas__inner {
  margin-inline: auto;
  width: 100%;
  max-width: var(--sov-canvas-max);
  padding-bottom: calc(var(--sov-prompt-h) + 2 * var(--sov-bloom));
  display: flex;
  flex-direction: column;
  gap: 24px;
}
[data-sovereign] .sov-canvas__inner[data-compact="true"] {
  padding-bottom: calc(var(--sov-prompt-h) + 16px);
}

/* Full-screen chat room. These classes intentionally hold every visual
   value for the modal so app code only declares structure and state. */
[data-sovereign] .sov-chat-room {
  position: fixed;
  inset: 0;
  z-index: var(--sov-chat-room-z);
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  background: var(--sov-chat-room-backdrop);
  backdrop-filter: blur(var(--sov-glass-blur-ambient)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-ambient)) saturate(150%);
  color: var(--sov-ink);
  isolation: isolate;
}

[data-sovereign] .sov-chat-room__body {
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--sov-chat-room-top) var(--sov-chat-room-inset)
    calc(var(--sov-prompt-h) + var(--sov-chat-room-bottom) * 2);
}

[data-sovereign] .sov-chat-room__column {
  width: min(100%, var(--sov-chat-room-thread-max));
  margin-inline: auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-chat-room-thread-gap);
}

[data-sovereign] .sov-chat-room__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sov-gutter);
}

[data-sovereign] .sov-chat-room__title {
  max-width: var(--sov-chat-room-title-max);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 8px);
}

[data-sovereign] .sov-chat-room__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-2, 8px);
}

[data-sovereign] .sov-chat-room__close {
  width: var(--sov-chat-room-close-size);
  height: var(--sov-chat-room-close-size);
  border-radius: var(--sov-radius-pill);
  border: 0;
  color: var(--sov-whisper);
  background: color-mix(in oklab, var(--sov-veil) 78%, transparent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
}

[data-sovereign] .sov-chat-room__close:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--sov-composer-border);
}

[data-sovereign] .sov-chat-room__actions {
  display: flex;
  align-items: center;
  gap: var(--sov-chat-room-actions-gap);
  flex-shrink: 0;
}

[data-sovereign] .sov-chat-room__chip {
  height: var(--sov-chat-room-chip-h);
  padding: var(--sov-chat-room-chip-pad);
  border-radius: var(--sov-radius-pill);
  border: 0;
  background: color-mix(in oklab, var(--sov-veil) 78%, transparent);
  color: var(--sov-whisper);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  transition: color var(--sov-d-base) var(--sov-ease-expo), background
    var(--sov-d-base) var(--sov-ease-expo);
}

[data-sovereign] .sov-chat-room__chip:hover {
  color: var(--sov-subtle);
  background: var(--sov-surface-raised);
}

[data-sovereign] .sov-chat-room__chip[aria-pressed="true"] {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
}

[data-sovereign] .sov-chat-room__thread {
  display: flex;
  flex-direction: column;
  gap: var(--sov-chat-room-thread-gap);
}

[data-sovereign] .sov-chat-room__turn {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 8px);
}

[data-sovereign] .sov-chat-room__turn--user {
  align-items: flex-end;
}

[data-sovereign] .sov-chat-room__turn--assistant {
  align-items: flex-start;
}

[data-sovereign] .sov-chat-room__byline {
  display: flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
[data-sovereign] .sov-chat-room__byline--user {
  justify-content: flex-end;
}

[data-sovereign] .sov-chat-room__assistant {
  max-width: 100%;
  color: var(--sov-ink);
}

[data-sovereign] .sov-chat-room__placeholder {
  color: var(--sov-whisper);
  font-style: italic;
}

[data-sovereign] .sov-chat-room__empty {
  min-height: var(--sov-chat-room-empty-min);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--sov-gutter);
}

[data-sovereign] .sov-chat-room__streaming-caption {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-whisper);
  margin-top: calc(var(--sov-gutter) * 0.5);
}

[data-sovereign] .sov-chat-room__footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--sov-chat-room-bottom);
  z-index: calc(var(--sov-chat-room-z) + 1);
  pointer-events: none;
  padding-inline: var(--sov-chat-room-inset);
}

[data-sovereign] .sov-chat-room__composer {
  width: min(100%, var(--sov-chat-room-composer-max));
  margin-inline: auto;
  pointer-events: auto;
}

[data-sovereign] .sov-chat-room__tail {
  height: var(--sov-gutter);
}

[data-sovereign] .sov-chat-room__frozen {
  opacity: var(--sov-chat-room-freeze-opacity);
  filter: blur(var(--sov-chat-room-freeze-blur));
  transition: opacity var(--sov-hush) var(--sov-ease), filter var(--sov-hush)
    var(--sov-ease);
}

@media (max-width: 900px) {
  [data-sovereign] .sov-chat-room__shell {
    grid-template-columns: minmax(0, 1fr);
  }

  [data-sovereign] .sov-chat-room__side {
    position: static;
    padding-left: 0;
    box-shadow: none;
  }
}

/* Mobile · no-tab-bar composer (canvas-mobile.html). Composer hugs the
   bottom safe-area; thread pads enough to clear the floating dock. */
@media (max-width: 720px) {
  [data-sovereign] .sov-chat-room__body {
    padding: clamp(16px, 5vw, 28px) clamp(14px, 5vw, 24px)
      calc(var(--sov-prompt-h) + env(safe-area-inset-bottom, 0px) + 28px);
  }
  [data-sovereign] .sov-chat-room__footer {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
    padding-inline: 12px;
  }
  [data-sovereign] .sov-chat-room__composer {
    max-width: 100%;
  }
}

/* ---------- Primitives ---------- */

/* Glass utilities · step-09 §4 — global selectors.
   The classes depend on [data-sovereign] custom properties being in
   scope; they apply wherever the markup uses them but the tokens
   resolve only inside the sovereign root. */
.sov-glass {
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
}
/* Deep sovereign glass — the canonical recipe.
 *
 * One declaration block, three entry points:
 *   - .sov-glass-strong                — utility class for components
 *                                        that apply it directly (auth
 *                                        overlay, user popover).
 *   - [data-sov-projects-active]       — entire rails (header + body +
 *     .sov-shell__rail--left/right       footer all share one painted
 *                                        glass surface) when the
 *                                        Projects canvas pans behind
 *                                        them. (restored 2026-05-16
 *                                        per Architect — full rail
 *                                        as one panel reads cleaner
 *                                        than body-only.)
 *   - [data-sov-folio-spread-active]   — same rail glass when folio
 *                                        reads edge-to-edge on the
 *                                        canvas pan layer (wide only).
 *   - [data-sov-constellation-active]  — same rail glass: the library
 *                                        constellation pans an infinite
 *                                        Canvas2D graph behind the rails,
 *                                        the same floating-chrome case as
 *                                        Projects, so it shares this one
 *                                        painted route (unified 2026-07-11).
 *
 * Fed by --sov-glass-mix-strong (sourced from tokens/tokens.json →
 * tokens/dist/tokens.css, shipped via @repo/sovereign-tokens/css) and
 * --sov-glass-blur-deep. To tune the see-through of every sovereign
 * deep-glass surface at once, change `glass.mix-strong` in
 * tokens/tokens.json and run `pnpm --filter @repo/sovereign-tokens
 * build`. Do not redeclare background/backdrop-filter on these
 * surfaces elsewhere — that creates drift. Add a new strong-glass
 * surface by appending its selector to this list (CSS-state surfaces)
 * or applying the utility class via JSX (component-owned surfaces). */
.sov-glass-strong,
[data-sovereign] .sov-user-panel,
[data-sovereign][data-sov-projects-active] .sov-shell__rail--left,
[data-sovereign][data-sov-projects-active] .sov-shell__rail--right,
[data-sovereign][data-sov-folio-spread-active] .sov-shell__rail--left,
[data-sovereign][data-sov-folio-spread-active] .sov-shell__rail--right,
[data-sovereign][data-sov-constellation-active] .sov-shell__rail--left,
[data-sovereign][data-sov-constellation-active] .sov-shell__rail--right {
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix-strong),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(180%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(180%);
}

/* Light-theme user panel — parchment glass from web-light tokens,
 * not the dark canonical --sov-bg glass-mix-strong recipe above. */
[data-sovereign][data-sovereign-theme="light"] .sov-user-panel {
  background: color-mix(
    in oklab,
    var(--sov-color-bg, var(--mk-web-parchment)) 82%,
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(140%);
}

[data-sovereign][data-sovereign-theme="light"] .sov-user-panel__body {
  color: var(--sov-color-ink, var(--mk-web-ink));
}

[data-sovereign] .sov-surface {
  background: var(--sov-surface-raised, var(--sov-veil));
  border-radius: var(--sov-radius-tile);
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--sov-ink) 4%, transparent),
    var(--sov-shadow-tile);
}

/* Typography classes — single source of truth for sizes.
   The sovereign voice is serif for prose + display, sans for labels. */
[data-sovereign] .sov-t-display {
  font-family: var(--sov-font-serif);
  font-weight: var(--sov-text-display-weight);
  font-size: var(--sov-text-display-size);
  line-height: var(--sov-text-display-line);
  letter-spacing: -0.02em;
}
[data-sovereign] .sov-t-display em {
  /* Malaika's gold-italic accent on names + emphasis. Used for the
     greeting ("Good morning, <em>Name</em>.") and pull-quotes. */
  font-style: italic;
  font-weight: 500;
  background-image: linear-gradient(
    90deg,
    var(--mk-glow-gold-soft) 0%,
    var(--mk-glow-gold) 50%,
    var(--mk-glow-gold-deep) 100%
  );
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: sov-gold-shimmer var(--sov-wordmark-shimmer) var(--sov-ease)
    infinite;
}
[data-sovereign] .sov-t-section {
  font-family: var(--sov-font-sans);
  font-weight: var(--sov-text-section-weight);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-section-line);
  letter-spacing: -0.005em;
  color: var(--mk-glow-gold);
  text-transform: uppercase;
}
/* Section info icon — "i in a circle" beside section headings.
   Hover brightens to gold, matching the section-heading color. */
[data-sovereign] .sov-section-info:hover {
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-t-field {
  /* Body prose — sans-serif, the sovereign interface voice.
     Serif is the reading voice (book pages, chronicle, spark text).
     Sans-serif is the navigation / metadata / section-intro voice —
     every surface that isn't a reading surface. */
  font-family: var(--sov-font-sans);
  font-weight: var(--sov-text-field-weight);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--sov-subtle, var(--sov-ink));
}
/* Opt-in italic modifier for prose that wants the reading voice:
   pull-quotes, sub-greetings, tile bodies, footnotes, and so on. */
[data-sovereign] .sov-t-field--italic {
  font-style: italic;
  font-family: var(--sov-font-serif);
}
[data-sovereign] .sov-t-tile {
  font-family: var(--sov-font-sans);
  font-weight: var(--sov-text-tile-weight);
  font-size: var(--sov-text-tile-size);
  line-height: var(--sov-text-tile-line);
  letter-spacing: -0.005em;
}
[data-sovereign] .sov-t-caption {
  /* Caption · 13px metadata, timestamps, inline hints. step-09 §1. */
  font-family: var(--sov-font-sans);
  font-weight: var(--sov-text-caption-weight);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-muted, var(--sov-whisper));
}

[data-sovereign] .sov-ink-whisper {
  color: var(--sov-whisper);
}

/* When the prompt has focus, the whole canvas hushes — content recedes so
   thought has room. Toggled by SovereignShell via [data-sov-hushed='true']. */
[data-sovereign] .sov-hushable {
  transition: opacity var(--sov-hush) var(--sov-ease), filter var(--sov-hush)
    var(--sov-ease);
}
[data-sovereign][data-sov-hushed="true"] .sov-hushable {
  opacity: 0.58;
  filter: blur(0.6px);
  transition: opacity var(--sov-hush) var(--sov-ease), filter var(--sov-hush)
    var(--sov-ease);
}

/* ═══════════════════════════════════════════════════════════════════════
 * DESCRIPTOR ADAPTERS — sovereign-aligned vocabulary for the
 * SovereignRenderer pipeline. Every visual value lives here so the
 * adapter TSX only declares structure + state.
 * Sourced from canvas-chat-deep.html + step-10/primitives.html.
 * ═══════════════════════════════════════════════════════════════════════ */

[data-sovereign] {
  --sov-adapter-gap: var(--sov-space-3, 12px);
  --sov-adapter-gap-tight: var(--sov-space-2, 8px);
  --sov-adapter-radius: 12px;
  --sov-adapter-radius-tight: 8px;
  --sov-adapter-radius-pill: var(--sov-radius-pill, 999px);

  /* Inline surface — sunken-tinted glass used by code, patch, and the
     orphan tool-result fallback. */
  --sov-adapter-surface: var(--sov-surface-sunken);
  --sov-adapter-surface-raised: color-mix(
    in oklab,
    var(--sov-surface-raised) 92%,
    transparent
  );
  --sov-adapter-hairline: color-mix(in oklab, var(--sov-ink) 6%, transparent);
  --sov-adapter-hairline-soft: color-mix(
    in oklab,
    var(--sov-ink) 4%,
    transparent
  );

  /* Patch line tones — gain/loss are warm-cool semantic, not raw red/green. */
  --sov-adapter-patch-add: var(--mk-glow-pied-beauty);
  --sov-adapter-patch-add-bg: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 10%,
    transparent
  );
  --sov-adapter-patch-del: var(--mk-glow-the-windhover);
  --sov-adapter-patch-del-bg: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 10%,
    transparent
  );
  --sov-adapter-patch-meta: var(--sov-whisper);

  /* Callout tones — step-19 voice pass:
     • info   → as-kingfishers-catch-fire (cyan-teal, hue 205). The Hopkins
       poem about each thing speaking itself fits INFO exactly: Malaika is
       noting something the reader should carry forward. The previous
       where-light-enters family was hue 40 (red-orange) and read as a
       warning to the reader — wrong register for "soft, observational".
     • warn   → pied-beauty (variety green, hue 140).
     • sacred → gold (hue 80). */
  --sov-adapter-callout-info: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-adapter-callout-info-bg: color-mix(
    in oklab,
    var(--mk-glow-as-kingfishers-catch-fire) 7%,
    var(--sov-veil)
  );
  --sov-adapter-callout-info-border: var(--mk-hairline-kingfishers);

  --sov-adapter-callout-warn: var(--mk-glow-pied-beauty);
  --sov-adapter-callout-warn-bg: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 8%,
    var(--sov-veil)
  );
  --sov-adapter-callout-warn-border: var(--mk-hairline-pied);

  --sov-adapter-callout-sacred: var(--mk-glow-gold);
  --sov-adapter-callout-sacred-bg: linear-gradient(
    135deg,
    color-mix(in oklab, var(--mk-glow-gold) 12%, transparent),
    color-mix(in oklab, var(--mk-glow-gold) 3%, transparent)
  );
  --sov-adapter-callout-sacred-border: var(--mk-hairline-gold);

  /* Error tones — windhover stand-in for "wrong/refused" (never raw red). */
  --sov-adapter-error: var(--mk-glow-the-windhover);
  --sov-adapter-error-bg: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 8%,
    transparent
  );
  --sov-adapter-error-border: color-mix(
    in oklab,
    var(--mk-glow-the-windhover) 35%,
    transparent
  );

  /* Spinner / pending dot. */
  --sov-adapter-spinner-bg: var(--sov-whisper);
  --sov-adapter-spinner-ok: var(--mk-glow-pied-beauty);
  --sov-adapter-spinner-fail: var(--mk-glow-the-windhover);

  /* Renderer flow gap — the base rhythm between two adjacent
     adapter children inside `.sov-renderer`. The flex `gap`
     idiom means there is exactly ONE source of vertical rhythm
     and adapters MUST NOT carry block margins of their own. */
  --sov-renderer-gap: var(--sov-space-2, 8px);
  /* Section-break rhythm — used as padding-top on the second-or-later
     heading / rule child to give chapter breaks extra room without
     compounding with the flex `gap` (margin-on-flex-item adds, it
     doesn't collapse). The visible gap before a heading becomes
     `gap + (loose - gap) = loose`; the gap after a heading stays
     at the base `gap`. Asymmetric rhythm by construction. */
  --sov-renderer-gap-loose: var(--sov-space-5);
  /* Block-adapter rhythm — the canonical breath that every "this is
     its own object" adapter inside `.sov-renderer` rides:
     callout, pullquote, voice clip, code, patch, table, tool-call,
     thinking, raw-html, mermaid, and list (ul/ol).
     One token, one rung — so lists and callouts and code blocks all
     share the same vertical music and the renderer reads as one
     cohesive flow. Sits between the chapter break (--sov-space-7 on H2)
     and the sub-section break (--sov-renderer-gap-loose on H1/H3/rule)
     so blocks visibly inhabit their own register without overshadowing
     a real section opener. Used via the
     `calc(--sov-block-breath - --sov-renderer-gap)` idiom so the flex
     `gap` is not double-counted. step-19 voice pass · unified. */
  --sov-block-breath: var(--sov-space-6);
}

/* SovereignRenderer flow container. The renderer is the single
   source of vertical rhythm. Children inherit it via flex `gap`;
   section breaks ride asymmetric `padding-top` (see below) so a
   heading's pre-space is wider than its post-space. */
[data-sovereign] .sov-renderer {
  display: flex;
  flex-direction: column;
  gap: var(--sov-renderer-gap);
}

/* Section-break asymmetry — heading / rule children of the renderer
   get extra space ABOVE them (so a new section feels like a chapter
   break) without giving up the tight pull-down between the heading
   and the first body line that follows. Padding (not margin) lives
   inside the flex box so the flex `gap` is not added twice. */
[data-sovereign] .sov-renderer > .sov-adapter-heading--1:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-heading--2:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-heading--3:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-rule:not(:first-child) {
  padding-top: calc(var(--sov-renderer-gap-loose) - var(--sov-renderer-gap));
}

/* ---------- Text adapter · prose paragraph ---------- */
/* step-19 voice pass: Malaika's prose body rides on the sans family
 * (Noto Sans via `apps/sovereign/fonts.ts`), not serif. Serif remains
 * the voice of distinct typographic registers — pullquote, thinking,
 * voice-clip transcript, citation, heading — but the *speaking* voice
 * of a reply is sans. The four voice variants below all inherit this;
 * `--diagnostic` overrides to mono further down, which is correct. */
[data-sovereign] .sov-adapter-text {
  margin: 0;
  white-space: normal;
  font-family: var(--sov-font-sans);
  font-weight: var(--sov-text-field-weight);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-text--narrative {
  color: var(--sov-ink);
  /* Narrative is the default voice — same sans family as every other
   * base-rung paragraph in the system. Family deliberately inherits — the
   * sans is the floor of the whole surface, and narrative reads as the
   * unmarked voice that everything else can shift away from. Leading
   * binds to a canonical token. */
  line-height: var(--sov-text-body-line);
}
[data-sovereign] .sov-adapter-text--instructive {
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-text--intimate {
  color: var(--sov-ink);
  font-style: italic;
}
[data-sovereign] .sov-adapter-text--diagnostic {
  color: var(--sov-whisper);
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-caption-size);
  /* leading lifted from caption-rung (1.3) to body-rung (1.65) so the
   * dense mono telemetry rows have room to breathe across multi-line
   * notes. Font/size/colour stay on the caption-whisper rung — only
   * the leading loosens. Token-bound; no new variable introduced. */
  line-height: var(--sov-text-body-line);
}

/* Model-fluent justification policy (descriptor.meta.justification).
   The adapter emits `data-justification` on the paragraph; the visual
   binding lives here so surfaces can override or extend (greedy /
   Knuth–Plass) without re-authoring the adapter. */
[data-sovereign] .sov-adapter-text[data-justification] {
  text-align: justify;
  text-justify: inter-word;
}

/* ---------- Text adapter · inline marks (step-18) ---------- */
/* Authored under Charter Rule 5b (Sovereign Design Authority).
 * Bold / italic / inline-code / link bound to the canonical token
 * shelf so headings, lists, and pullquotes can carry rich rhythm
 * without escaping the design system. No invented values. */
[data-sovereign] .sov-adapter-text__bold {
  font-weight: var(--sov-text-section-weight);
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-text__italic {
  font-style: italic;
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-text__inline-code {
  font-family: var(--sov-font-mono);
  font-size: 0.92em;
  padding: 0.05em 0.35em;
  border-radius: var(--sov-adapter-radius-tight);
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline-soft);
  /* step-19 voice pass: inline code sits a step quieter than the prose
     so the technical mark reads as a different register, not a louder
     mono shout. --sov-subtle is the canonical "between ink and whisper"
     rung in the dark and light palettes. */
  color: var(--sov-subtle);
  white-space: pre-wrap;
}
[data-sovereign] .sov-adapter-text__link {
  color: var(--sov-ink);
  text-decoration: underline;
  -webkit-text-decoration-color: var(--mk-glow-gold-halo, currentColor);
          text-decoration-color: var(--mk-glow-gold-halo, currentColor);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: -webkit-text-decoration-color var(--sov-anim-fast)
    var(--sov-easing-standard, ease-out);
  transition: text-decoration-color var(--sov-anim-fast)
    var(--sov-easing-standard, ease-out);
  transition: text-decoration-color var(--sov-anim-fast)
    var(--sov-easing-standard, ease-out), -webkit-text-decoration-color var(--sov-anim-fast)
    var(--sov-easing-standard, ease-out);
}
[data-sovereign] .sov-adapter-text__link:hover {
  -webkit-text-decoration-color: var(--mk-glow-gold);
          text-decoration-color: var(--mk-glow-gold);
}
[data-sovereign] .sov-adapter-text__sub {
  font-size: 0.78em;
  vertical-align: sub;
  line-height: 0;
}
[data-sovereign] .sov-adapter-text__sup {
  font-size: 0.78em;
  vertical-align: super;
  line-height: 0;
}

/* ---------- Heading adapter (step-18) ---------- */
/* Three rungs bound to the canonical typography tokens.
 * Empty body renders an <hr/> via .sov-adapter-rule. */
[data-sovereign] .sov-adapter-heading {
  margin: 0;
  color: var(--sov-ink);
  font-family: var(--sov-font-serif);
}
/* Heading + rule margins removed (step-19): rhythm is owned by
   `.sov-renderer` (flex gap + asymmetric padding-top on section
   breaks). Authoring a heading outside the renderer must therefore
   wrap it in a container with explicit spacing. */
[data-sovereign] .sov-adapter-heading--1 {
  font-size: var(--sov-text-display-size);
  font-weight: var(--sov-text-display-weight);
  line-height: var(--sov-text-display-line);
  letter-spacing: var(--sov-text-display-tracking, 0);
}
[data-sovereign] .sov-adapter-heading--2 {
  font-size: var(--sov-text-section-size);
  font-weight: var(--sov-text-section-weight);
  line-height: var(--sov-text-section-line);
}
[data-sovereign] .sov-adapter-heading--3 {
  font-size: var(--sov-text-field-size);
  font-weight: var(--sov-text-section-weight);
  line-height: var(--sov-text-field-line);
  color: var(--sov-whisper);
  letter-spacing: 0.02em;
}
/* ───────────────────────────────────────────────────────────────────
 * Section-break trio · H2 → adjacent intro text → bottom hairline
 *
 * In Malaika's prose, an H2 is a section opener, not a louder paragraph.
 * The visual treatment matches `.sov-review__sample-title` /
 * `.sov-review__sample-intro` on the design-test surface so review and
 * live chat read as the same conversation about rhythm.
 *
 *   <h2 class="sov-adapter-heading--2">SECTION TITLE</h2>      ← gold eyebrow
 *   <p  class="sov-adapter-text">          intro sentence...</p> ← whisper caption
 *   ── hairline ──                                                 ← border-bottom
 *   <next body content>
 *
 * The hairline that closes the head trio lives on the LAST element
 * of the title+intro pair (the intro paragraph if present, otherwise
 * the heading itself). Above the trio: section-7 of breath, so a new
 * section feels like an arrival. step-19 voice pass.
 * ─────────────────────────────────────────────────────────────────── */

/* H2 = section eyebrow.
   Overrides `.sov-t-section` (the typography rung the HeadingAdapter
   also applies) and `.sov-adapter-heading` (serif ink). The greater
   selector specificity wins over both. */
[data-sovereign] .sov-renderer > .sov-adapter-heading--2 {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 500;
  line-height: var(--sov-text-caption-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mk-glow-gold);
}

/* Adjacent prose paragraph after an H2 reads as the section intro —
   whisper caption clamped to 56ch so the line measure stays narrow.
   `font-style: normal` overrides the --intimate italic variant when
   Malaika happens to author an intimate paragraph here. */
[data-sovereign] .sov-renderer > .sov-adapter-heading--2 + .sov-adapter-text {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-caption-weight);
  font-style: normal;
  line-height: var(--sov-text-caption-line);
  letter-spacing: 0;
  color: var(--sov-whisper);
  max-width: 56ch;
}

/* The hairline that closes the section-head trio. Lives under the
   intro paragraph when one exists; otherwise directly under the H2.
   Uses :has() so we don't add a wrapper element. Matches
   `.sov-review__sample-head { padding-bottom: space-2; border-bottom }`. */
[data-sovereign] .sov-renderer > .sov-adapter-heading--2 + .sov-adapter-text,
[data-sovereign]
  .sov-renderer
  > .sov-adapter-heading--2:not(:has(+ .sov-adapter-text)) {
  padding-bottom: var(--sov-space-2);
  border-bottom: 1px solid var(--sov-adapter-hairline);
}

/* Breathing room above a new section. The earlier asymmetric rhythm
   rule gives non-first h2 a padding-top of space-2 (gap-loose - gap);
   here we widen that to total space-7 above (gap + this padding-top),
   matching `.sov-review__column { gap: space-7 }` between samples. */
[data-sovereign] .sov-renderer > .sov-adapter-heading--2:not(:first-child) {
  padding-top: calc(var(--sov-space-7) - var(--sov-renderer-gap));
}

/* ───────────────────────────────────────────────────────────────────
 * H3 = subsection signpost
 *
 * One rung quieter than the H2 section-break: all-caps Noto Sans, no
 * gold, no hairline. Reads as a small label that announces the next
 * paragraph rather than closing the one above it.
 *
 * Asymmetric breath above (handled by the existing rhythm rule that
 * now includes `.sov-adapter-heading--3:not(:first-child)`): gap-loose
 * above, gap below — a 2:1 ratio that gives a clean separation
 * without the budget of an h2 section-break.
 * ─────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-renderer > .sov-adapter-heading--3 {
  font-family: var(--sov-font-sans);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

[data-sovereign] .sov-adapter-rule {
  border: 0;
  height: 1px;
  background: var(--sov-adapter-hairline);
}

/* ---------- Pullquote adapter (step-18) ---------- */
/* Plain blockquote (no [!tone] callout). The canonical hairline rule
 * sits on the left edge; body uses the section rung; attribution uses
 * the caption rung. */
/* Pullquote outer margin removed (step-19): rhythm is owned by the
   parent `.sov-renderer`. The internal padding remains because it is
   the quote's own breathing room, not flow rhythm. */
[data-sovereign] .sov-adapter-pullquote {
  /* step-19 voice pass refinement: the gold left bar is the lockmark of
     the pullquote — it carries the warmth on its own. The earlier
     three-side halo (negative-x box-shadow into --mk-glow-gold-halo) was
     reading as a glow around the whole figure rather than a directional
     mark, so it has been removed. Padding bumped one rung on top, bottom,
     and left so the body and attribution have room to breathe past the
     gold bar; right side stays one rung tighter because nothing crowds
     that edge. */
  padding: var(--sov-space-5) var(--sov-space-4) var(--sov-space-5)
    var(--sov-space-5);
  border-left: 2px solid var(--mk-glow-gold);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1, 6px);
  /* Pullquote carries its own internal padding; the renderer's flex gap
     would double the breathing above and below. */
  margin-block: calc(-1 * var(--sov-renderer-gap, 12px));
}
[data-sovereign] .sov-adapter-pullquote__body {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-size: var(--sov-text-section-size);
  /* step-19 voice pass refinement: italic 18px serif at caption-leading
     (1.3) was reading as too tight against the longer pullquote bodies.
     Promoted to the body rung (1.65) — the same chapter-prose leading
     used elsewhere — so each line has air without feeling airy. */
  line-height: var(--sov-text-body-line);
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-pullquote__attribution {
  /* step-19 voice pass: attribution row is a flex band with caps text
     on the left and a small copy affordance at far right. Uppercase +
     tracking matches the caption-rung treatment used elsewhere when
     a row sits as a label rather than as prose. */
  color: var(--sov-whisper);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-adapter-pullquote__attribution-text {
  /* Anchors the caption text to the left and absorbs the free space so
     the copy button stays pinned to the far right. step-19 voice pass
     refinement: dropped one rung from caption (13px) to micro (10px) so
     the all-caps attribution sits as a quiet sub-mark under the quote
     rather than competing with it. Letter-spacing and uppercase carry
     the labelling weight; size doesn't need to. */
  min-width: 0;
  flex: 1 1;
  font-size: var(--sov-text-micro-size);
}
[data-sovereign] .sov-adapter-pullquote__copy {
  /* step-19 voice pass refinement: copy affordance now speaks the same
     icon-button voice as the patch chevron and section disclosures —
     dimmed gold at rest, bright gold when reached. No --mk-glow-gold-dim
     token exists in the system (Grep confirmed), so the documented
     fallback is a 60% mix of --mk-glow-gold into transparent. Hover,
     focus-visible, and active all promote to full strength. */
  background: none;
  border: 0;
  padding: 4px;
  cursor: pointer;
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--sov-adapter-radius-tight, 4px);
  transition: color 0.15s var(--sov-ease), background-color 0.15s ease;
}
[data-sovereign] .sov-adapter-pullquote__copy:hover,
[data-sovereign] .sov-adapter-pullquote__copy:focus-visible,
[data-sovereign] .sov-adapter-pullquote__copy:active {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, transparent);
}
[data-sovereign] .sov-adapter-pullquote__copy:focus-visible {
  outline: 2px solid var(--mk-glow-gold);
  outline-offset: 1px;
}

/* ---------- Code adapter ---------- */
[data-sovereign] .sov-adapter-code {
  margin: 0;
  border-radius: var(--sov-adapter-radius-tight);
  background: var(--sov-adapter-surface);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  overflow: hidden;
}
[data-sovereign] .sov-adapter-code__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-whisper);
  /* step-19 voice pass: header sits a notch darker than the artifact
     body so the lang label and copy affordance read as a distinct
     "captain's strip" above the code. The mix is into ink, which works
     in both dark and light palettes. */
  background: color-mix(
    in oklab,
    var(--sov-adapter-surface) 86%,
    var(--sov-ink) 14%
  );
  box-shadow: inset 0 -1px 0 var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-code__actions {
  display: inline-flex;
  gap: 8px;
}
[data-sovereign] .sov-adapter-code__action {
  background: none;
  border: none;
  padding: 0;
  color: var(--sov-ink);
  cursor: pointer;
  font: inherit;
}
/* step-19 voice pass: dedicated icon-button affordance for copy (and
   any future icon action). Dimmed gold at rest, full gold on hover /
   focus / active — quiet sibling to the pullquote copy button. Sized
   to read as an actual button, not a glyph hiding among caption text. */
[data-sovereign] .sov-adapter-code__action--icon {
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--sov-adapter-radius-tight, 4px);
  transition: color 0.15s ease, background-color 0.15s ease;
}
[data-sovereign] .sov-adapter-code__action--icon:hover,
[data-sovereign] .sov-adapter-code__action--icon:focus-visible,
[data-sovereign] .sov-adapter-code__action--icon:active {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-adapter-code__action--icon:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 14%, transparent);
}
[data-sovereign] .sov-adapter-code__action--icon:focus-visible {
  outline: 2px solid var(--mk-glow-gold);
  outline-offset: 1px;
}
[data-sovereign] .sov-adapter-code__action--icon svg {
  width: 18px;
  height: 18px;
}
[data-sovereign] .sov-adapter-code__body {
  margin: 0;
  padding: 12px 14px;
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: dense mono content rides on the caption rung
     so code, patch, table, and tool-result share one type scale. */
  font-size: var(--sov-text-caption-size);
  line-height: 1.55;
  overflow-x: auto;
  color: var(--sov-ink);
}

/* ---------- Patch adapter ---------- */
/* step-19 voice pass · patch surface — the most consequential thing
   Malaika can emit (she wants to write to your codebase). The whole
   figure is now a <details> drawer; the header is a conversational
   sentence with the full path as a quiet mono pill alongside, and a
   gold chevron that rotates on open. Gold (not muted) on the chevron
   because patches sit at a different rank in the chat than tool calls
   do — tool calls are procedural, patches are proposed changes to
   your files. */
[data-sovereign] .sov-adapter-patch {
  margin: 0;
  border-radius: var(--sov-adapter-radius-tight);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
}
[data-sovereign] .sov-adapter-patch__header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  list-style: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  color: var(--sov-ink);
  box-shadow: inset 0 -1px 0 var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-patch__header::-webkit-details-marker {
  display: none;
}
[data-sovereign] .sov-adapter-patch__header:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border), inset 0 -1px 0
    var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-patch__heading {
  /* The patch heading is a conversational announcement, not a label —
   * sans, caption rung (matches the BASH/code-header register so every
   * block-adapter "this is its row-top" eyebrow sits at the same size),
   * gold + slightly wider tracking (0.12em vs the code header's 0.08em)
   * to mark this as a higher-consequence section than a code fence
   * without making the header visually heavier. */
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-caption-weight);
  line-height: var(--sov-text-caption-line);
  color: var(--mk-glow-gold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
[data-sovereign] .sov-adapter-patch__path {
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
  padding: 1px 6px;
  border-radius: var(--sov-adapter-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 70%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
[data-sovereign] .sov-adapter-patch__chevron {
  margin-left: auto;
  color: var(--mk-glow-gold);
  font-size: var(--sov-text-section-size);
  line-height: 1;
  transform: rotate(0deg);
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign]
  .sov-adapter-patch[open]
  > .sov-adapter-patch__header
  .sov-adapter-patch__chevron {
  transform: rotate(90deg);
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-adapter-patch__chevron {
    transition: none;
  }
}
[data-sovereign] .sov-adapter-patch__body {
  margin: 0;
  padding: 10px 12px;
  background: var(--sov-adapter-surface);
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: caption rung, shared with code/table/tool-result. */
  font-size: var(--sov-text-caption-size);
  line-height: 1.5;
  overflow-x: auto;
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-patch__line {
  display: block;
  color: var(--sov-ink);
}
[data-sovereign] .sov-adapter-patch__line--add {
  color: var(--sov-adapter-patch-add);
  background: var(--sov-adapter-patch-add-bg);
}
[data-sovereign] .sov-adapter-patch__line--del {
  color: var(--sov-adapter-patch-del);
  background: var(--sov-adapter-patch-del-bg);
}
[data-sovereign] .sov-adapter-patch__line--meta {
  color: var(--sov-adapter-patch-meta);
}

/* ---------- Mermaid adapter ---------- *
 * Sovereign-themed mermaid diagrams. The SVG is rendered server-side
 * by `apps/sovereign/lib/sovereign-mermaid-renderer.ts` with hardcoded
 * resolved hex/oklch values that mirror the tokens used here; the
 * client only frames the result. Token discipline: every colour and
 * spacing on this surface flows through `var(--sov-…)`.
 */
[data-sovereign] .sov-adapter-mermaid {
  /* Full-width by default — fills the chat-bubble body horizontally
   * (the bubble itself owns the outer max-width). No internal padding
   * on the figure; the header gets its own pad-y/x rung and the SVG
   * gets generous breathing room independently. */
  margin: 0;
  width: 100%;
  padding: 0;
  border-radius: var(--sov-adapter-radius-tight, 10px);
  background: color-mix(in oklab, var(--sov-color-bg) 96%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    var(
      --sov-adapter-hairline,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  overflow: hidden;
}
/* Success-state header — same rung + chrome as the code adapter's
 * header, with the diagram-kind eyebrow on the left and the copy
 * affordance on the right. Hairline-soft bottom rule separates header
 * from canvas in the same idiom code/patch headers use. */
[data-sovereign] .sov-adapter-mermaid__header--ready {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin: 0;
  box-shadow: inset 0 -1px 0 var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-mermaid__actions {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* SVG canvas — fills the figure's available width with generous
 * breathing room on all four sides. Mermaid emits an inline
 * `style="max-width: <intrinsic>px"` that we strip server-side (see
 * `stripSvgRootInlineStyle` in mermaid-renderer.server.ts), so the SVG
 * honours `width: 100%` here. The `!important` is a defensive fallback
 * in case a future mermaid-cli release writes the same inline style
 * through a different code path.
 *
 * Padding: 22px y / 26px x — bigger than the prior 14/18 because
 * diagrams need air around the rendered viewBox more than other
 * adapters do. Mermaid's own diagramPadding handles the inside-the-
 * viewBox margin; this is the outside-the-viewBox frame.
 *
 * overflow-y: visible — the only place we relax the figure's
 * containing `overflow: hidden`. Some diagram kinds (deep gantt charts,
 * tall ER stacks) have a viewBox that doesn't fully contain text
 * descenders on the last row; visible-y lets that 1-2px breathe instead
 * of being clipped at the figure's bottom edge. */
[data-sovereign] .sov-adapter-mermaid__svg {
  display: block;
  width: 100%;
  padding: 22px 26px;
  overflow-x: auto;
  overflow-y: visible;
}
[data-sovereign] .sov-adapter-mermaid__svg svg {
  display: block;
  width: 100% !important;
  max-width: 100% !important;
  height: auto;
  /* The viewBox has authority — let it size the rendered SVG and don't
   * crop its own internal overflow. Combined with overflow-y: visible
   * on the parent, this ensures descenders in the last row of an ER
   * diagram or the bottom of a gantt timeline never disappear. */
  overflow: visible;
}
[data-sovereign] .sov-adapter-mermaid__caption {
  color: var(--sov-whisper);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  /* Caption rung (13px / 1.5) — was micro (10px) which read as cramped
   * dev-noise. Same caption family the rail, telemetry, and tool-result
   * captions use. Generous line-height because the text is uppercase. */
  font-size: var(--sov-text-caption-size);
  line-height: 1.5;
  margin-bottom: 6px;
}
[data-sovereign] .sov-adapter-mermaid--pending {
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
}
[data-sovereign] .sov-adapter-mermaid--pending .sov-adapter-mermaid__caption {
  margin: 0;
}

/* Error state — collapsed disclosure that mirrors the patch adapter
 * chrome (gold uppercase heading, hairline-soft bottom rule on the
 * summary, gold chevron that rotates 90° on open). The diagram source
 * is the consolation prize when the SVG can't be produced; collapsing
 * it by default keeps the failure quiet and on-tone.
 *
 * Token discipline: every colour comes from --sov-adapter-error-* (the
 * shared windhover-tinted palette used by .sov-adapter-parse-error and
 * .sov-renderer__error) or the patch adapter's gold + hairline tokens.
 * No new tokens. */
[data-sovereign] details.sov-adapter-mermaid {
  margin: 0;
  padding: 0;
  border-radius: var(--sov-adapter-radius-tight, 10px);
  overflow: hidden;
  background: var(--sov-adapter-error-bg);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-error-border);
}
[data-sovereign] .sov-adapter-mermaid__header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  cursor: pointer;
  list-style: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  color: var(--sov-ink);
}
[data-sovereign]
  details.sov-adapter-mermaid[open]
  > .sov-adapter-mermaid__header {
  box-shadow: inset 0 -1px 0 var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-mermaid__header::-webkit-details-marker {
  display: none;
}
[data-sovereign] .sov-adapter-mermaid__header:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border), inset 0 -1px 0
    var(--sov-adapter-hairline-soft);
}
[data-sovereign] .sov-adapter-mermaid__heading {
  /* Conversational announcement in the patch idiom — same caption-rung
   * size as the BASH/code-header register so every block-adapter
   * "this is its row-top" eyebrow sits at one canonical size. Gold +
   * slightly wider tracking (0.12em vs the code header's 0.08em) marks
   * this as a higher-consequence section than a code fence without
   * making the header visually heavier. */
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-caption-weight);
  line-height: var(--sov-text-caption-line);
  color: var(--mk-glow-gold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
[data-sovereign] .sov-adapter-mermaid__chevron {
  margin-left: auto;
  color: var(--mk-glow-gold);
  font-size: var(--sov-text-section-size);
  line-height: 1;
  transform: rotate(0deg);
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign]
  details.sov-adapter-mermaid[open]
  > .sov-adapter-mermaid__header
  .sov-adapter-mermaid__chevron {
  transform: rotate(90deg);
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-adapter-mermaid__chevron {
    transition: none;
  }
}
[data-sovereign] .sov-adapter-mermaid__error-body {
  padding: 10px 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
[data-sovereign] .sov-adapter-mermaid__reason {
  margin: 0;
  color: var(--sov-adapter-error);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
}
[data-sovereign] .sov-adapter-mermaid__source {
  margin: 0;
  padding: 10px 12px;
  background: var(--sov-adapter-surface);
  border-radius: var(--sov-adapter-radius-tight, 10px);
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-caption-size);
  line-height: 1.5;
  color: var(--sov-ink);
  overflow-x: auto;
  white-space: pre;
}
[data-sovereign] .sov-adapter-mermaid__source code {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  background: none;
}

/* Each line in a CA-5 terminal block. The colourised children
 * (.sov-code-artifact__ok / __skip / __err) already paint themselves,
 * so the row is just a flex container that preserves whitespace. */
[data-sovereign] .sov-code-artifact__term-line {
  display: block;
  white-space: pre;
}

/* ---------- Table adapter ----------
 * Spec-sheet dress (2026-05-15): gold-hairline perimeter cousin of the
 * user bubble, a slightly tinted header band that reads as a label row,
 * and very subtle zebra rhythm on body rows. All values from existing
 * ink / muted / hairline-gold / eyebrow-size tokens — no new tokens. */
[data-sovereign] .sov-adapter-table {
  border-radius: var(--sov-adapter-radius-tight);
  overflow: auto;
  box-shadow: inset 0 0 0 1px var(--sov-hairline-gold);
}
[data-sovereign] .sov-adapter-table table {
  width: 100%;
  border-collapse: collapse;
  /* step-19 typography pass: caption rung, same as code/patch family. */
  font-size: var(--sov-text-caption-size);
  font-family: var(--sov-font-sans);
}
/* Header band: subtle ink-tinted strip behind the column labels so the
 * top row reads as a label register, not data. */
[data-sovereign] .sov-adapter-table thead tr {
  background: color-mix(in oklab, var(--sov-ink) 4%, transparent);
}
[data-sovereign] .sov-adapter-table th {
  text-align: left;
  padding: 8px 10px;
  /* Eyebrow voice — same register as CALL/RESULT in tool calls and the
   * eyebrow rungs in the typography spec. */
  font-size: var(--sov-text-eyebrow-size);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--sov-muted);
  font-weight: 500;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  box-shadow: inset 0 -1px 0 var(--sov-adapter-hairline);
}
[data-sovereign] .sov-adapter-table th[data-sortable="true"] {
  cursor: pointer;
}
[data-sovereign] .sov-adapter-table td {
  padding: 6px 10px;
  color: var(--sov-ink);
  box-shadow: inset 0 1px 0 var(--sov-adapter-hairline-soft);
}
/* Zebra rhythm: even body rows pick up a near-imperceptible ink wash to
 * help the eye track wide spec-sheet rows without raising contrast. */
[data-sovereign] .sov-adapter-table tbody tr:nth-child(even) {
  background: color-mix(in oklab, var(--sov-ink) 2%, transparent);
}
[data-sovereign] .sov-adapter-table__footer {
  padding: 6px 10px;
  color: var(--sov-whisper);
}

/* ---------- List adapter ---------- */
[data-sovereign] .sov-adapter-list {
  margin: 0;
  padding-left: 22px;
  display: flex;
  flex-direction: column;
  /* step-19 voice pass · list rhythm: inter-item gap nudged from 6px to
     space-2 (8px) so each line stands cleanly apart from its neighbours.
     Same selector catches both `<ol class="sov-adapter-list">` and
     `<ul class="sov-adapter-list">` — the ListAdapter applies the same
     class to either tag. The flex `gap` lives on the parent (not as a
     margin on each <li>) so nested lists inherit the rhythm from their
     own column without compounding. */
  gap: var(--sov-space-2);
  color: var(--sov-ink);
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
}
[data-sovereign] .sov-adapter-list__item {
  line-height: 1.6;
}

/* ───────────────────────────────────────────────────────────────────
 * Block-adapter rhythm · the unified family
 *
 * Every "this is its own object" adapter inside `.sov-renderer` rides
 * the same canonical breath token, `--sov-block-breath`. One rung,
 * one source of truth — lists, callouts, code, pullquotes, voice
 * clips, tool calls, patches, tables, thinking drawers, raw-html and
 * mermaid all share the same vertical music so the renderer reads as
 * one cohesive flow rather than a panel of strangers each picking
 * their own spacing.
 *
 * Pattern is the same as the heading / rule rules above near line
 * 2623: asymmetric `padding-top` on every renderer child after the
 * first, computed as `calc(--sov-block-breath - --sov-renderer-gap)`
 * so the *visible* gap above a block equals the token (the flex
 * `gap` is not double-counted). No `margin-*` — we let the next
 * child's `padding-top` do the work, the way headings already do.
 *
 * Lists are the one exception that ALSO ride `padding-bottom`.
 * They are internally stacked (every <li> is its own paragraph), so
 * the space *after* a list block has to live on the list itself —
 * relying on the next sibling's `padding-top` doesn't work when the
 * next sibling is a plain text adapter (no top-pad). The bottom
 * padding compounds with the next padded block's top correctly,
 * because the flex `gap` is between item boxes, not at their content
 * edges — so list→callout still reads at one `--sov-block-breath`
 * worth of visible space, not two.
 *
 * step-19 voice pass · unified block rhythm.
 * ─────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-renderer > .sov-adapter-callout:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-voice:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-code:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-patch:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-table:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-tool:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-tool-row:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-thinking-status:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-reasoning-glimpse:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-raw-html:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-mermaid:not(:first-child),
[data-sovereign] .sov-renderer > .sov-adapter-list:not(:first-child) {
  padding-top: calc(var(--sov-block-breath) - var(--sov-renderer-gap));
}
[data-sovereign] .sov-renderer > .sov-adapter-list:not(:last-child) {
  padding-bottom: calc(var(--sov-block-breath) - var(--sov-renderer-gap));
}

/* ---------- Callout adapter ---------- */
[data-sovereign] .sov-adapter-callout {
  padding: 12px 14px;
  border-radius: var(--sov-adapter-radius);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
[data-sovereign] .sov-adapter-callout--info {
  background: var(--sov-adapter-callout-info-bg);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-callout-info-border);
}
[data-sovereign] .sov-adapter-callout--warn {
  background: var(--sov-adapter-callout-warn-bg);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-callout-warn-border);
}
[data-sovereign] .sov-adapter-callout--sacred {
  background: var(--sov-adapter-callout-sacred-bg);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-callout-sacred-border);
}
[data-sovereign] .sov-adapter-callout__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-adapter-callout--info .sov-adapter-callout__label {
  color: var(--sov-adapter-callout-info);
}
[data-sovereign] .sov-adapter-callout--warn .sov-adapter-callout__label {
  color: var(--sov-adapter-callout-warn);
}
[data-sovereign] .sov-adapter-callout--sacred .sov-adapter-callout__label {
  color: var(--sov-adapter-callout-sacred);
}
[data-sovereign] .sov-adapter-callout__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ---------- Citation chip · primitive class ----------
   Inline gold pill used by SovereignCitationChip and CitationAdapter.
   Sacred sources opt into the 𓂀 lockmark via the modifier. */
[data-sovereign] .sov-chip-citation {
  display: inline-flex;
  align-items: center;
  /* step-19 voice pass · citation chip — opened up in two passes:
     2/8/4 → 4/11/6 → 5/12/6. The first pass gave the sacred chip
     room around 𓂀; the second extends the same breath to the
     neutral (hairline) variant, whose longer labels (URLs, titles)
     read more cramped at smaller padding. "Hairline" refers to the
     1px inset border, not the interior breathing. Still inline-
     baseline with surrounding prose. */
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--sov-adapter-radius-pill);
  background: var(--sov-chat-citation-bg);
  box-shadow: inset 0 0 0 1px var(--sov-chat-citation-border);
  font-family: var(--sov-font-sans);
  /* step-19 typography pass: chip rung, shared with telemetry / tool-name. */
  font-size: var(--sov-text-chip-size);
  font-weight: 500;
  color: var(--sov-chat-citation-color);
  cursor: pointer;
  vertical-align: baseline;
  border: 0;
  text-decoration: none;
}
[data-sovereign] .sov-chip-citation--neutral {
  color: var(--sov-ink);
  background: color-mix(in oklab, var(--sov-veil) 92%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
}
[data-sovereign] .sov-chip-citation > span[aria-hidden] {
  /* step-19 voice pass · citation chip — sacred 𓂀 lockmark.
     Sits one rung above the label (`field` vs `chip`) so the glyph
     reads at a glance without dominating the row — earlier the section
     rung pushed the line-box to 18px and the lockmark visibly towered
     over the file name. The field rung (16px) is the right register:
     bigger than the label, smaller than a heading, equal to the body
     it cites. line-height:1 keeps the Egyptian Hieroglyph block's tall
     intrinsic line-box from stretching the chip's inline rhythm; the
     chip's flex centering still keeps both the glyph and the label
     optically aligned. Selector intentionally targets the bare
     aria-hidden span (not the .sov-chip-citation__counter class) so it
     scopes only to the glyph emitter in CitationAdapter. */
  font-size: var(--sov-text-field-size);
  line-height: 1;
}
[data-sovereign] .sov-chip-citation__counter {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  color: var(--sov-bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* step-19 typography pass: tied to the micro rung so the digit
     inside the pip rescales with the canonical type shelf rather
     than carrying an invented pixel value. */
  font-size: calc(var(--sov-text-micro-size) - 2px);
  font-weight: 700;
  line-height: 1;
}

/* ── SovereignChip — pill chip (label + interactive filter pill) ── */

[data-sovereign] .sov-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--sov-space-1) var(--sov-space-3);
  border-radius: var(--sov-radius-pill);
  border: 1px solid var(--sov-hairline-quiet, var(--sov-veil));
  background: transparent;
  color: var(--sov-ink);
  font-family: inherit;
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-section-weight);
  line-height: var(--sov-text-caption-line);
  cursor: default;
  transition: background var(--sov-d-fast) var(--sov-ease-smooth), color
    var(--sov-d-fast) var(--sov-ease-smooth), border-color var(--sov-d-fast)
    var(--sov-ease-smooth);
}

/* Interactive: filter-pill variant — <button> as="button". */
[data-sovereign] .sov-chip:is(button) {
  cursor: pointer;
}

/* Pressed / active state — gold-on-raised. */
[data-sovereign] .sov-chip[data-pressed="true"] {
  background: var(--sov-surface-raised);
  color: var(--sov-accent-ink);
}

/* Tone variants — anchor gold tone. */
[data-sovereign] .sov-chip[data-tone="anchor"] {
  background: color-mix(in oklab, var(--sov-accent) 14%, transparent);
  color: var(--sov-accent-ink);
  border-color: color-mix(in oklab, var(--sov-accent) 30%, transparent);
}

/* ── Section nav — "see all →" link beside section headings ── */

[data-sovereign] .sov-section-nav {
  text-decoration: none;
  color: var(--sov-muted);
  font-size: var(--sov-text-caption-size);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  transition: color var(--sov-d-fast) var(--sov-ease-smooth);
}

[data-sovereign] .sov-section-nav:hover {
  color: var(--sov-ink);
}

/* ── Filter row — horizontally scrollable pill set ──
   Sanctioned under Charter Rule 5b (Sovereign Design Authority).
   Follows the same overflow pattern as .sov-a03-page-tabs:
   nowrap flex with hidden scrollbar, children pinned with
   flex-shrink: 0 so they don't collapse. */
[data-sovereign] .sov-filter-row {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--sov-space-2);
  overflow-x: auto;
  overflow-y: visible;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
}
[data-sovereign] .sov-filter-row::-webkit-scrollbar {
  display: none;
}
[data-sovereign] .sov-filter-row > * {
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── Filter pill — gold-edged interactive pill button ──
   Sanctioned under Charter Rule 5b. Active state uses mk-glow-gold
   border + tint; inactive uses a quiet hairline. Uppercase with
   letter-spacing for cockpit-grade legibility. All values are token-
   derived — zero hardcoded colors or sizes. */
[data-sovereign] .sov-filter-pill {
  padding: var(--sov-space-1) var(--sov-space-3);
  border: 1px solid var(--sov-hairline-quiet, var(--sov-veil));
  border-radius: var(--sov-radius-pill);
  background: transparent;
  color: var(--sov-muted);
  cursor: pointer;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background var(--sov-d-fast) var(--sov-ease-smooth), color
    var(--sov-d-fast) var(--sov-ease-smooth), border-color var(--sov-d-fast)
    var(--sov-ease-smooth);
}
[data-sovereign] .sov-filter-pill[aria-pressed="true"],
[data-sovereign] .sov-filter-pill[aria-current="true"] {
  border-color: color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  color: var(--mk-glow-gold);
}

/* ---------- Citation adapter ----------
   The footnote sheet that opens when the user taps a citation chip. */
[data-sovereign] .sov-adapter-citation {
  display: inline-block;
  vertical-align: baseline;
}
[data-sovereign] .sov-adapter-citation__sheet {
  display: block;
  margin-top: 6px;
  padding: 10px 12px;
  border-radius: var(--sov-adapter-radius-tight);
  background: color-mix(in oklab, var(--sov-veil) 90%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
}
[data-sovereign] .sov-adapter-citation__meta {
  display: flex;
  gap: 6px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-whisper);
  margin-bottom: 6px;
}
[data-sovereign] .sov-adapter-citation__quote {
  margin: 0;
  padding-left: 10px;
  border-left: 2px solid var(--mk-hairline-gold);
  color: var(--sov-ink);
  font-style: italic;
  font-family: var(--sov-font-serif);
  line-height: 1.5;
}
[data-sovereign] .sov-adapter-citation__source {
  margin-top: 6px;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-adapter-citation__source a {
  color: var(--sov-ink);
  text-decoration: underline;
  -webkit-text-decoration-color: var(--mk-hairline-gold);
          text-decoration-color: var(--mk-hairline-gold);
  text-underline-offset: 2px;
}

/* ---------- Voice-clip adapter ---------- */
[data-sovereign] .sov-adapter-voice {
  /* step-19 voice pass refinement: head + foot bumped one rung
     (10px → var(--sov-space-5) = 24px) so the label has breath above
     and the spoken passage has breath below. Matches the loose-tier
     vertical padding the pullquote adopted in the same pass — both
     spoken/quoted blocks share the same head/foot proportions.
     Horizontal padding stays at 12px; only head and foot move. */
  margin: 0;
  padding: var(--sov-space-5) 12px;
  border-radius: var(--sov-adapter-radius);
  background: color-mix(in oklab, var(--sov-veil) 86%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
[data-sovereign] .sov-adapter-voice__label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-whisper);
}
/* voice-clip label — gold speaker SVG paired with the eyebrow
   "Spoken aloud" tells the user this artifact is audible
   (something Malaika speaks, has spoken, or will speak). The
   text stays whisper so the gold icon remains the lone accent. */
[data-sovereign] .sov-adapter-voice__label-icon {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-adapter-voice__audio {
  width: 100%;
}
/* step-19 voice pass · pending state —
   a gentle gold pulse paired with quiet italic copy. Reuses the
   shared sov-breathe-pulse keyframe so the rhythm matches other
   ambient breathing across the surface. */
[data-sovereign] .sov-adapter-voice__pending {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--sov-whisper);
  font-style: italic;
}
[data-sovereign] .sov-adapter-voice__pending-pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 6px color-mix(in oklab, var(--mk-glow-gold) 55%, transparent);
  animation: sov-breathe-pulse 2.4s ease-in-out infinite;
  flex: 0 0 auto;
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-adapter-voice__pending-pulse {
    animation: none;
    opacity: 0.8;
  }
}
/* voice-clip quote — body line-height token (1.65) so the spoken
   passage rhythm matches Malaika's prose elsewhere; padding-top
   stacks on top of the figure's 6px flex gap to give the spoken
   passage visible breath above (≈18px total) instead of crushing
   it against the pending/play row. */
[data-sovereign] .sov-adapter-voice__quote {
  margin: 0;
  padding-top: var(--sov-space-3);
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-body-line);
  color: var(--sov-ink);
  font-style: italic;
}

/* ---------- Tool-call / tool-result adapters ----------
   Authored: sovereign-design step-10/primitives.html § SovereignToolReveal.
   where-light-enters surface (Malaika's editorial / observing voice). */
[data-sovereign] .sov-adapter-tool {
  border-radius: var(--sov-adapter-radius);
  overflow: hidden;
  background: var(--sov-chat-tool-bg);
  box-shadow: inset 0 0 0 1px var(--sov-chat-tool-border);
  animation: sov-tool-in 280ms ease both;
}
[data-sovereign] .sov-adapter-tool__summary {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--sov-chat-tool-label);
  text-align: left;
  list-style: none;
  font: inherit;
}
[data-sovereign] .sov-adapter-tool__summary::-webkit-details-marker {
  display: none;
}
[data-sovereign] .sov-adapter-tool__summary:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border);
}
[data-sovereign] .sov-adapter-tool__name {
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: chip rung. */
  font-size: var(--sov-text-chip-size);
  color: var(--sov-chat-tool-label);
  flex: 1 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* step-19 voice pass · tool trace-id —
   small monospace pill with a #-prefix and a tooltip explaining its
   job. Reads as metadata, not chrome. Sits as a sibling of __name in
   the summary row (not nested inside it), so `margin-left: auto`
   floats it to the right edge — the chevron stays as the absolute
   right element. The summary's `gap: 10px` handles spacing on either
   side. */
[data-sovereign] .sov-adapter-tool__call-id {
  display: inline-flex;
  align-items: baseline;
  margin-left: auto;
  padding: 1px 6px;
  border-radius: var(--sov-adapter-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 70%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: micro rung. */
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
  cursor: help;
  white-space: nowrap;
}
[data-sovereign] .sov-adapter-tool__chevron {
  display: inline-flex;
  align-items: center;
  color: var(--sov-muted);
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign] .sov-adapter-tool[open] .sov-adapter-tool__chevron {
  transform: rotate(90deg);
}
[data-sovereign] .sov-adapter-tool__body {
  padding: 0 14px 14px;
  display: flex;
  flex-direction: column;
  /* step-19 voice pass · tool body — looser gap so the new CALL /
     RESULT sections have visible breath between them. */
  gap: var(--sov-space-4);
}
/* step-19 voice pass · tool body sections —
   each section (CALL / RESULT) is itself a <details> dropdown. The
   closed row carries a one-word eyebrow label and an optional badge
   (the technical tool name on the call side, success/failure on the
   result side); the JSON or hydrated descriptor lives below, one
   click away. Section labels use the gods-grandeur tool palette so
   they tie back to the surface, not pull attention away from it. */
[data-sovereign] .sov-adapter-tool__section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-adapter-tool__section-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  cursor: pointer;
  list-style: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
[data-sovereign] .sov-adapter-tool__section-head::-webkit-details-marker {
  display: none;
}
[data-sovereign] .sov-adapter-tool__section-head:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border);
  border-radius: var(--sov-adapter-radius-tight);
}
[data-sovereign] .sov-adapter-tool__section-label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 500;
  line-height: var(--sov-text-caption-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-chat-tool-label);
}
[data-sovereign] .sov-adapter-tool__section-name {
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
  padding: 1px 6px;
  border-radius: var(--sov-adapter-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 70%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
}
[data-sovereign] .sov-adapter-tool__section-status {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-micro-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-adapter-tool__section-status[data-tone="ok"] {
  color: var(--sov-adapter-spinner-ok);
}
[data-sovereign] .sov-adapter-tool__section-status[data-tone="fail"] {
  color: var(--sov-adapter-spinner-fail);
}
[data-sovereign] .sov-adapter-tool__section-chevron {
  margin-left: auto;
  color: var(--sov-whisper);
  font-size: var(--sov-text-body-size);
  line-height: 1;
  transform: rotate(0deg);
  transition: transform 180ms ease, color 180ms ease;
}
[data-sovereign]
  .sov-adapter-tool__section[open]
  > .sov-adapter-tool__section-head
  .sov-adapter-tool__section-chevron {
  transform: rotate(90deg);
  color: var(--sov-chat-tool-label);
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-adapter-tool__section-chevron {
    transition: none;
  }
}
[data-sovereign] .sov-adapter-tool__args {
  margin: 0;
  padding: 8px 10px;
  border-radius: var(--sov-adapter-radius-tight);
  background: var(--sov-surface-sunken);
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: micro rung. Inline tool-arg blocks read denser
     than the body so the parent prose stays the focal voice. */
  font-size: var(--sov-text-micro-size);
  line-height: 1.6;
  color: var(--sov-subtle);
  overflow-x: auto;
}
[data-sovereign] .sov-adapter-tool__pending {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  /* step-19 typography pass: chip rung; sibling to tool-name. */
  font-size: var(--sov-text-chip-size);
}
[data-sovereign] .sov-adapter-tool__spinner {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sov-chat-tool-dot);
  animation: sov-breathe var(--sov-breath) ease-in-out infinite;
}
[data-sovereign] .sov-adapter-tool__spinner[data-state="ok"] {
  background: var(--sov-adapter-spinner-ok);
  animation: none;
}
[data-sovereign] .sov-adapter-tool__spinner[data-state="fail"] {
  background: var(--sov-adapter-spinner-fail);
  animation: none;
}
[data-sovereign] .sov-adapter-tool-result {
  padding: 8px 10px;
  border-radius: var(--sov-adapter-radius-tight);
  background: color-mix(in oklab, var(--sov-veil) 84%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  color: var(--sov-ink);
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: caption rung, shared with code/patch/table. */
  font-size: var(--sov-text-caption-size);
}
[data-sovereign] .sov-adapter-tool-result--fail,
[data-sovereign] .sov-adapter-tool-result[data-tone="fail"] {
  color: var(--sov-adapter-error);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-error-border);
}
[data-sovereign] .sov-adapter-tool__args[data-tone="fail"] {
  color: var(--sov-adapter-error);
}
[data-sovereign] .sov-adapter-tool-result__label {
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-whisper);
  margin-bottom: 4px;
}
[data-sovereign] .sov-adapter-tool-result__body {
  margin: 0;
  overflow-x: auto;
}

/* ---------- Thinking adapter ----------
   One-line status whisper (visible) + dim reasoning glimpse (chain-of-thought
   between tool calls). No box, no details toggle — personal and light. */
[data-sovereign] .sov-adapter-thinking-status {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 2px 0;
  min-height: 0;
  animation: sov-tool-in 280ms ease both;
}
[data-sovereign] .sov-adapter-thinking-status__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  flex-shrink: 0;
  align-self: center;
  background: var(--sov-presence-thinking);
  box-shadow: 0 0 5px var(--sov-presence-thinking);
  animation: sov-breathe var(--sov-breath) ease-in-out infinite;
}
[data-sovereign] .sov-adapter-thinking-status__text {
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-caption-size);
  font-style: italic;
  font-weight: 400;
  line-height: 1.45;
  color: var(--sov-whisper);
  animation: sov-thinking-text-in 360ms ease both;
}
@keyframes sov-thinking-text-in {
  from {
    opacity: 0.35;
    transform: translateY(1px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
[data-sovereign] .sov-adapter-reasoning-glimpse {
  margin: 0;
  padding: 0 0 0 11px;
  border-left: 1px solid color-mix(in oklab, var(--sov-presence-thinking) 22%, transparent);
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-micro-size);
  font-style: italic;
  font-weight: 400;
  line-height: 1.45;
  color: var(--sov-muted);
  opacity: 0.78;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  animation: sov-tool-in 280ms ease both;
}

/* ---------- Compact tool-call rows · 2026-07-12 ----------
   Quiet Cursor-IDE-style display: colored dot, plain-English label,
   collapsed by default. Detail body is dim and small. */
[data-sovereign] .sov-adapter-tool-row {
  border-radius: var(--sov-adapter-radius);
  overflow: hidden;
  background: var(--sov-chat-tool-bg);
  box-shadow: inset 0 0 0 1px var(--sov-chat-tool-border);
  animation: sov-tool-in 280ms ease both;
}
[data-sovereign] .sov-adapter-tool-row__summary {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--sov-chat-tool-label);
  text-align: left;
  list-style: none;
  font: inherit;
}
[data-sovereign] .sov-adapter-tool-row__summary::-webkit-details-marker {
  display: none;
}
[data-sovereign] .sov-adapter-tool-row__summary:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border);
}
[data-sovereign] .sov-adapter-tool-row__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
}
[data-sovereign] .sov-adapter-tool-row__dot--pending {
  background: var(--sov-status-pending);
  box-shadow: 0 0 6px var(--sov-status-pending);
}
[data-sovereign] .sov-adapter-tool-row__dot--ok {
  background: var(--sov-status-ok);
  box-shadow: 0 0 6px var(--sov-status-ok);
}
[data-sovereign] .sov-adapter-tool-row__dot--error {
  background: var(--sov-status-error);
  box-shadow: 0 0 6px var(--sov-status-error);
}
[data-sovereign] .sov-adapter-tool-row__label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 500;
  line-height: var(--sov-text-caption-line);
  color: var(--sov-chat-tool-label);
  flex: 1 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
[data-sovereign] .sov-adapter-tool-row__spinner {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sov-chat-tool-dot);
  animation: sov-breathe var(--sov-breath) ease-in-out infinite;
}
[data-sovereign] .sov-adapter-tool-row__call-id {
  display: inline-flex;
  align-items: baseline;
  margin-left: auto;
  padding: 1px 6px;
  border-radius: var(--sov-adapter-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 70%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
  cursor: help;
  white-space: nowrap;
}
[data-sovereign] .sov-adapter-tool-row__chevron {
  display: inline-flex;
  align-items: center;
  color: var(--sov-muted);
  font-size: var(--sov-text-chip-size);
  line-height: 1;
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign] .sov-adapter-tool-row[open] .sov-adapter-tool-row__chevron {
  transform: rotate(90deg);
}
[data-sovereign] .sov-adapter-tool-row__body {
  padding: 0 12px 10px;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-adapter-tool-row__details {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  padding: 0 0 0 9px;
  border-left: 2px solid color-mix(in oklab, var(--sov-chat-tool-dot) 24%, transparent);
}
[data-sovereign] .sov-adapter-tool-row__field {
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  line-height: 1.45;
  color: var(--sov-muted);
}
[data-sovereign] .sov-adapter-tool-row__field-key {
  font-style: normal;
  color: var(--sov-whisper);
  margin-right: 4px;
}
[data-sovereign] .sov-adapter-tool-row__pending-text {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
  padding-left: 9px;
  border-left: 2px solid color-mix(in oklab, var(--sov-whisper) 16%, transparent);
}
[data-sovereign] .sov-adapter-tool-row__hydrated {
  padding-left: 9px;
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
}
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-text,
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-text--narrative,
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-text--instructive,
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-text--diagnostic {
  font-size: var(--sov-text-micro-size);
  line-height: 1.5;
  color: var(--sov-muted);
}
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-code,
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-code-artifact {
  background: color-mix(in oklab, var(--sov-surface-sunken) 80%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--sov-ink) 4%, transparent);
}
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-adapter-code__body,
[data-sovereign] .sov-adapter-tool-row__hydrated .sov-code-artifact__pre {
  font-size: var(--sov-text-micro-size);
  line-height: 1.5;
  color: var(--sov-muted);
}
[data-sovereign] .sov-adapter-tool-row__raw-result {
  padding-left: 9px;
}
[data-sovereign] .sov-adapter-tool-row__result-pre {
  margin: 0;
  padding: 6px 8px;
  border-radius: var(--sov-adapter-radius-tight);
  background: color-mix(in oklab, var(--sov-surface-sunken) 80%, transparent);
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  line-height: 1.45;
  color: var(--sov-muted);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 12rem;
  overflow-y: auto;
}
[data-sovereign] .sov-adapter-file-changes {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  padding: 0 0 0 9px;
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  line-height: 1.45;
}
[data-sovereign] .sov-adapter-file-changes__file {
  color: var(--sov-muted);
  flex: 1 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-sovereign] .sov-adapter-file-changes__stats {
  display: inline-flex;
  gap: 6px;
  flex-shrink: 0;
}
[data-sovereign] .sov-adapter-file-changes__add {
  color: var(--sov-status-ok);
  font-weight: 500;
}
[data-sovereign] .sov-adapter-file-changes__del {
  color: var(--sov-status-error);
  font-weight: 500;
}

/* ---------- Legacy thinking adapter (details toggle) — retired 2026-07-12.
   Kept as empty selectors so stale markup does not inherit tool-call chrome. */
[data-sovereign] .sov-adapter-thinking {
  display: contents;
}
[data-sovereign] .sov-adapter-thinking__summary,
[data-sovereign] .sov-adapter-thinking__body {
  display: none;
}

/* ---------- Telemetry adapter ---------- */
[data-sovereign] .sov-adapter-telemetry {
  display: inline-flex;
  align-items: baseline;
  /* step-19 voice pass · telemetry chip — opened up to give the
     hairline some breath. 2/8 → 5/12 mirrors the citation chip's
     final comfort pass; "hairline" refers to the 1px inset border,
     not the interior breathing. Gap stays at 6px between value and
     metric label. Still inline-baseline with surrounding prose. */
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--sov-adapter-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 92%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
  color: var(--sov-whisper);
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: chip rung. */
  font-size: var(--sov-text-chip-size);
}
[data-sovereign] .sov-adapter-telemetry__value {
  color: var(--sov-ink);
}

/* ---------- Raw-html adapter ----------
 * Wrapper carries the surface + hairline so the iframe sits inside a
 * padded artifact box (same idiom as .sov-adapter-code: hairline-bounded
 * surface, modest inner pad). The iframe itself is bare: full bubble
 * width, block-level so width: 100% is honored against its replaced-
 * inline default, no border (the wrapper's hairline is the only edge).
 * min-height keeps an empty sandbox from collapsing to nothing. */
[data-sovereign] .sov-adapter-raw-html {
  margin: 0;
  width: 100%;
  display: block;
  padding: var(--sov-space-3) var(--sov-space-4);
  border-radius: var(--sov-adapter-radius-tight);
  background: var(--sov-adapter-surface);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-hairline);
}
[data-sovereign] .sov-adapter-raw-html__frame {
  width: 100%;
  min-height: 120px;
  display: block;
  border: 0;
  background: transparent;
}
[data-sovereign] .sov-adapter-raw-html-blocked {
  padding: 10px 12px;
  border-radius: var(--sov-adapter-radius-tight);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  color: var(--mk-glow-gold);
}

/* ---------- Parse-error / renderer-error ---------- */
[data-sovereign] .sov-adapter-parse-error,
[data-sovereign] .sov-renderer__error {
  padding: 6px 10px;
  border-radius: var(--sov-adapter-radius-tight);
  background: var(--sov-adapter-error-bg);
  box-shadow: inset 0 0 0 1px var(--sov-adapter-error-border);
  color: var(--sov-adapter-error);
  font-family: var(--sov-font-mono);
}

/* ---------- Thinking-state primitive ----------
   Authored: sovereign-design/kaOS Design System (3)/source/components/
             sovereign-thinking-state.html. Glass surface (--sov-glass-mix),
             gold hairline ring, 12/16 padding, 12px radius. Compact tightens
             padding to 8/12 and hides the mono sub caption. The dots run on
             sov-thinking-dot 1.2s with a 160ms stagger. */
[data-sovereign] .sov-thinking-state {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix),
    transparent
  );
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  width: -moz-fit-content;
  width: fit-content;
}
[data-sovereign] .sov-thinking-state[data-compact="true"] {
  padding: 8px 12px;
}
[data-sovereign] .sov-thinking-state__label {
  font-family: var(--sov-font-sans);
  /* step-19 typography pass: caption rung — same as thinking adapter body. */
  font-size: var(--sov-text-caption-size);
  color: var(--sov-subtle);
}
[data-sovereign] .sov-thinking-state__sub {
  font-family: var(--sov-font-mono);
  /* step-19 typography pass: micro rung. */
  font-size: var(--sov-text-micro-size);
  color: var(--sov-muted);
}
[data-sovereign] .sov-thinking-dots {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  height: 20px;
}
[data-sovereign] .sov-thinking-dots__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  display: inline-block;
  animation: sov-thinking-dot 1.2s ease-in-out infinite;
}
[data-sovereign] .sov-thinking-dots__dot[data-i="1"] {
  animation-delay: 0.16s;
}
[data-sovereign] .sov-thinking-dots__dot[data-i="2"] {
  animation-delay: 0.32s;
}
[data-sovereign][data-sovereign-motion="off"] .sov-thinking-dots__dot {
  animation: none;
  opacity: 0.6;
}

/* ---------- Citation chip primitive ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html
             § Citation. Inline gold pill with a numbered counter circle.
             100px radius (full pill), gold-mix 8% bg, gold hairline ring,
             11/500 sans label in gold. Counter is a 14px gold disc with
             the bg punching through (8/700 sans). */
[data-sovereign] .sov-citation-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 6px;
  border-radius: 100px;
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  font-family: var(--sov-font-sans);
  /* step-19 typography pass: chip rung; sibling to .sov-chip-citation. */
  font-size: var(--sov-text-chip-size);
  font-weight: 500;
  color: var(--mk-glow-gold);
  vertical-align: middle;
  text-decoration: none;
  border: 0;
}
[data-sovereign] .sov-citation-chip[data-interactive="true"] {
  cursor: pointer;
}
[data-sovereign] .sov-citation-chip__counter {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  color: var(--sov-bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* step-19 typography pass: tied to the micro rung; mirrors
     .sov-chip-citation__counter so both citation primitives scale together. */
  font-size: calc(var(--sov-text-micro-size) - 2px);
  font-weight: 700;
  line-height: 1;
}

/* ---------- Sovereign Prompt (composer) ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html
             § Composer (4 states) + reference modal: chip row + pill bar
             (+ / field / mic), near-black fill, gold hairline.
             States hook off `[data-state]`; `data-layout="reference"`. */
[data-sovereign] .sov-prompt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sov-prompt-stack-gap);
  width: 100%;
  min-width: 0;
  max-width: var(--sov-content-max);
  margin-inline: auto;
  padding-inline: 0;
  box-sizing: border-box;
}
[data-sovereign] .sov-prompt[data-chips="true"] {
  gap: var(--sov-prompt-chips-below-gap);
}
[data-sovereign] .sov-prompt__chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sov-prompt-chips-row-gap);
  width: 100%;
  max-width: min(100%, 52rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
[data-sovereign] .sov-prompt__chips-item {
  margin: 0;
  padding: 0;
  list-style: none;
}
[data-sovereign] .sov-prompt__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-2);
  max-width: 100%;
  padding: var(--sov-space-2) calc(var(--sov-space-3) + var(--sov-space-1));
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--sov-font-sans);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: color-mix(in oklab, var(--sov-ink) 78%, var(--sov-subtle));
  background: color-mix(in oklab, var(--sov-ink) 10%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
  transition: background var(--sov-hush) var(--sov-ease), box-shadow
    var(--sov-hush) var(--sov-ease);
}
[data-sovereign] .sov-prompt__chip:hover {
  background: color-mix(in oklab, var(--sov-ink) 14%, transparent);
}
[data-sovereign] .sov-prompt__chip:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px var(--mk-glow-gold), inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
}
[data-sovereign] .sov-prompt__chip-dot {
  flex: 0 0 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 6px -1px
    color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
}
/* Intent-specific dot colors on the mode context chip */
[data-sovereign]
  .sov-prompt__chip--mode[data-intent="code"]
  .sov-prompt__chip-dot {
  background: var(--mk-glow-the-lantern-out-of-doors);
  box-shadow: 0 0 6px -1px
    color-mix(
      in oklab,
      var(--mk-glow-the-lantern-out-of-doors) 60%,
      transparent
    );
}
[data-sovereign]
  .sov-prompt__chip--mode[data-intent="research"]
  .sov-prompt__chip-dot {
  background: var(--mk-glow-gods-grandeur);
  box-shadow: 0 0 6px -1px
    color-mix(in oklab, var(--mk-glow-gods-grandeur) 60%, transparent);
}
[data-sovereign]
  .sov-prompt__chip--mode[data-intent="publish"]
  .sov-prompt__chip-dot {
  background: var(--mk-glow-pied-beauty);
  box-shadow: 0 0 6px -1px
    color-mix(in oklab, var(--mk-glow-pied-beauty) 60%, transparent);
}
[data-sovereign]
  .sov-prompt__chip--mode[data-intent="translate"]
  .sov-prompt__chip-dot {
  background: var(--mk-glow-heaven-haven);
  box-shadow: 0 0 6px -1px
    color-mix(in oklab, var(--mk-glow-heaven-haven) 60%, transparent);
}
[data-sovereign]
  .sov-prompt__chip--mode[data-intent="design"]
  .sov-prompt__chip-dot {
  background: var(--mk-glow-the-starlight-night);
  box-shadow: 0 0 6px -1px
    color-mix(in oklab, var(--mk-glow-the-starlight-night) 60%, transparent);
}
/* Attachment chip — slightly dimmer, no dot */
[data-sovereign] .sov-prompt__chip--attachment {
  color: var(--sov-color-whisper);
  gap: var(--sov-space-1);
}
[data-sovereign] .sov-prompt__chip--attachment:hover {
  color: var(--sov-color-ink);
}
/* File chip — same pill shape, image icon, truncatable label */
[data-sovereign] .sov-prompt__chip--file {
  color: var(--sov-color-whisper);
  gap: var(--sov-space-1);
  max-width: 220px;
}
[data-sovereign] .sov-prompt__chip--file:hover {
  color: var(--sov-color-ink);
}
[data-sovereign] .sov-prompt__chip-label {
  min-width: 0;
  text-align: left;
}
[data-sovereign] .sov-prompt__chip--file .sov-prompt__chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-sovereign] .sov-prompt__model-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sov-space-2) var(--sov-space-3);
  width: 100%;
  /* Animated show/hide — always in layout, collapses height when absent.
     The negative margin-bottom cancels the parent .sov-prompt's flex gap
     so the collapsed row takes zero effective space. */
  max-height: 0px;
  margin-top: 0px;
  margin-bottom: calc(-1 * var(--sov-prompt-stack-gap));
  overflow: hidden;
  opacity: 0;
  transition: max-height 280ms var(--sov-ease-expo), margin-top 280ms
    var(--sov-ease-expo), margin-bottom 280ms var(--sov-ease-expo), opacity
    220ms ease;
}
[data-sovereign] .sov-prompt__model-row--visible {
  max-height: 48px;
  margin-top: var(--sov-space-2);
  margin-bottom: 0px;
  opacity: 1;
}
[data-sovereign] .sov-prompt__intent-pills {
  display: flex;
  gap: var(--sov-space-1);
  background: color-mix(in oklab, var(--sov-color-veil) 60%, transparent);
  border-radius: var(--sov-radius-sm);
  padding: var(--sov-space-1);
  flex: 0 0 auto;
}
[data-sovereign] .sov-prompt__intent-pill {
  all: unset;
  padding: var(--sov-space-1) var(--sov-space-3);
  border-radius: var(--sov-radius-sm);
  font-size: var(--sov-text-caption-size);
  font-family: var(--sov-typography-font-mono, monospace);
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  color: var(--sov-color-whisper, var(--sov-color-muted));
  transition: background 150ms ease, color 150ms ease;
}
[data-sovereign] .sov-prompt__intent-pill:hover {
  color: var(--sov-color-ink);
}
[data-sovereign] .sov-prompt__intent-pill--active {
  background: color-mix(in oklab, var(--sov-color-veil) 80%, transparent);
  color: var(--sov-color-ink);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--code {
  color: var(--mk-glow-the-lantern-out-of-doors);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--research {
  color: var(--mk-glow-gods-grandeur);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--publish {
  color: var(--mk-glow-pied-beauty);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--translate {
  color: var(--mk-glow-heaven-haven);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--design {
  color: var(--mk-glow-the-starlight-night);
}

/* Project / consilience mode pill colours. Brainstorm is subdued
 * (quiet solo work); With Malaika uses the gold glow token. */
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--brainstorm {
  color: var(--sov-ink);
}
[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--malaika {
  color: var(--mk-glow-gold);
}
/* sov-prompt__local-model, sov-model-picker, sov-prompt__local-model-select removed (Cycle V.3 — model dropdown deleted; only 6 action pills remain) */
[data-sovereign] .sov-prompt__dock {
  display: flex;
  align-items: center;
  gap: var(--sov-space-3);
  width: 100%;
  box-sizing: border-box;
  min-height: var(--sov-prompt-h);
  padding: var(--sov-prompt-pad-y) var(--sov-prompt-pad-x)
    var(--sov-prompt-pad-y) var(--sov-prompt-pad-x-tight);
  border-radius: var(--sov-component-composer-radius, var(--sov-radius-lg));
  background: var(--sov-color-surface-sunken);
  box-shadow: inset 0 0 0 1px
    var(--mk-hairline-gold, var(--sov-composer-border));
  transition: box-shadow var(--sov-hush) var(--sov-ease), min-height
    var(--sov-d-base) var(--sov-ease-expo), border-radius var(--sov-d-base)
    var(--sov-ease-expo), padding var(--sov-d-base) var(--sov-ease-expo);
}

/* Cigar-tube idle state: pill-shaped, collapsed to content height.
   On focus/typing/voice, expands upward to full composer height. */
[data-sovereign]
  .sov-prompt:not([data-focused]):not([data-state="typing"]):not(
    [data-state="voice"]
  ):not([data-state="awaiting"])
  .sov-prompt__dock {
  min-height: 0;
  height: calc(
    var(--sov-component-composer-icon-button-size, 40px) +
    var(--sov-prompt-pad-y) *
    2
  );
  border-radius: var(--sov-radius-pill);
  padding-top: 0;
  padding-bottom: 0;
  overflow: hidden;
  cursor: text;
}

[data-sovereign] .sov-prompt[data-layout="reference"] .sov-prompt__dock {
  max-width: min(100%, 52rem);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
[data-sovereign] .sov-prompt[data-focused="true"] .sov-prompt__dock,
[data-sovereign] .sov-prompt[data-state="typing"] .sov-prompt__dock {
  background: var(--sov-color-surface-raised);
  box-shadow: inset 0 0 0 1px
    var(--mk-hairline-gold, var(--sov-composer-border)),
    0 0 32px -8px color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
}
[data-sovereign] .sov-prompt[data-state="voice"] .sov-prompt__dock {
  background: var(--sov-color-surface-raised);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 35%, transparent),
    0 0 32px -8px color-mix(in oklab, var(--mk-glow-gold) 14%, transparent);
}
[data-sovereign] .sov-prompt[data-state="awaiting"] .sov-prompt__dock {
  background: var(--sov-color-surface-raised);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 35%, transparent),
    0 0 32px -8px color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
}
[data-intent="code"] .sov-prompt .sov-prompt__dock {
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mk-glow-the-lantern-out-of-doors) 50%, transparent), 0 0
    0 1px color-mix(in oklab, var(--mk-glow-the-lantern-out-of-doors) 20%, transparent), 0 18px 40px -24px
    color-mix(in oklab, var(--mk-glow-the-lantern-out-of-doors) 18%, transparent);
}
[data-intent="terminal"] .sov-prompt .sov-prompt__dock {
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mk-glow-heaven-haven) 40%, transparent), 0 0
    0 1px color-mix(in oklab, var(--mk-glow-heaven-haven) 16%, transparent), 0 18px 40px -24px
    color-mix(in oklab, var(--mk-glow-heaven-haven) 14%, transparent);
}
[data-sovereign] .sov-prompt__icon-btn {
  flex: 0 0 auto;
  width: var(
    --sov-component-composer-icon-button-size,
    calc(var(--sov-space-5) + var(--sov-space-4))
  );
  height: var(
    --sov-component-composer-icon-button-size,
    calc(var(--sov-space-5) + var(--sov-space-4))
  );
  border-radius: 50%;
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--sov-color-surface-raised);
  color: var(--sov-color-accent);
  cursor: pointer;
  position: relative;
  transform: scale(1);
  transition: background var(--sov-hush) var(--sov-ease), color var(--sov-hush)
    var(--sov-ease), box-shadow var(--sov-hush) var(--sov-ease), transform
    var(--sov-hush) var(--sov-ease);
}
[data-sovereign] .sov-prompt__icon-btn:hover {
  color: var(--sov-color-glow-gold);
}
/* Pin icon buttons to the bottom when the dock expands with multi-line content.
   The cigar-tube idle state (data-state=idle) keeps align-items: center on the
   dock, so the buttons stay centered in the collapsed pill. */
[data-sovereign] .sov-prompt[data-focused="true"] .sov-prompt__icon-btn,
[data-sovereign] .sov-prompt[data-state="typing"] .sov-prompt__icon-btn,
[data-sovereign] .sov-prompt[data-state="voice"] .sov-prompt__icon-btn,
[data-sovereign] .sov-prompt[data-state="awaiting"] .sov-prompt__icon-btn {
  align-self: flex-end;
}
[data-sovereign] .sov-prompt__icon-btn:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
[data-sovereign] .sov-prompt__icon-btn:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 2px
    color-mix(in oklab, var(--mk-glow-gold) 55%, transparent);
}
[data-sovereign] .sov-prompt__textarea {
  flex: 1 1 auto;
  min-width: 0;
  resize: none;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--sov-ink);
  padding: 0 var(--sov-space-2) var(--sov-space-2) var(--sov-space-1);
  font-family: inherit;
}
[data-sovereign] .sov-prompt__textarea::placeholder {
  color: color-mix(in oklab, var(--sov-ink) 28%, transparent);
  letter-spacing: 0.01em;
}
[data-sovereign] .sov-prompt__send {
  /* extends .sov-prompt__icon-btn — send: filled gold CTA when typing */
  background: var(--mk-glow-gold);
  color: var(--sov-bg);
}
[data-sovereign] .sov-prompt__send:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 92%, var(--sov-color-surface-raised));
  color: var(--sov-bg);
}
[data-sovereign] .sov-prompt__send[disabled] {
  background: color-mix(in oklab, var(--mk-glow-gold) 28%, var(--sov-bg));
  color: color-mix(in oklab, var(--sov-ink) 50%, var(--sov-bg));
  cursor: default;
  transform: scale(0.98);
  pointer-events: none;
}
[data-sovereign] .sov-prompt__send:focus-visible {
  box-shadow: 0 0 0 2px
    color-mix(in oklab, var(--mk-glow-gold) 70%, transparent);
}
[data-sovereign] .sov-prompt__interrupt {
  /* streaming: filled amber pause button — prominent, interruptible */
  background: color-mix(in oklab, var(--mk-glow-gold) 18%, var(--sov-veil));
  color: var(--mk-glow-gold);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 42%, transparent), 0 0 16px -6px
    color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  animation: sov-interrupt-breathe 1.8s ease-in-out infinite;
}
[data-sovereign] .sov-prompt__interrupt:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 28%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 65%, transparent), 0 0 20px -4px
    color-mix(in oklab, var(--mk-glow-gold) 45%, transparent);
}
@keyframes sov-interrupt-breathe {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.72;
  }
}
[data-sovereign] .sov-prompt__mic {
  /* Idle mic: dark-theme gold, not accent blue */
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-prompt__mic[data-state="recording"] {
  background: var(--mk-glow-gold);
  box-shadow: 0 0 20px -4px var(--mk-glow-gold);
  color: var(--sov-bg);
  transform: scale(1.04);
}
[data-sovereign] .sov-prompt__mic[data-state="transcribing"] {
  background: color-mix(in oklab, var(--mk-glow-gold) 72%, var(--mk-glow-where-light-enters));
  box-shadow: 0 0 14px -4px var(--mk-glow-gold);
  color: var(--sov-bg);
}
[data-sovereign] .sov-prompt__mic[data-state="requesting"] {
  background: var(--sov-color-surface-raised);
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-prompt__mic-pulse {
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid
    color-mix(in oklab, var(--mk-glow-gold) 45%, transparent);
  pointer-events: none;
}
[data-sovereign] .sov-prompt__mic-spinner {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
}
[data-sovereign] .sov-prompt__voice-status {
  margin-top: var(--sov-space-2);
  padding-inline: var(--sov-space-2);
  color: var(--sov-whisper);
}

/* Voice-surface: keep the attach (+) affordance visible but quiet. */
[data-sovereign] .sov-prompt__add[data-voice-dimmed="true"] {
  opacity: 0.38;
  color: var(--mk-glow-gold);
}

/* Waveform strip above the dock chips on the voice surface. */
[data-sovereign] .sov-prompt__voice-waveform {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  margin-bottom: var(--sov-space-2, 8px);
}

/* ---------- Tool reveal primitive ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html
             § ToolCall (lines 264–330). Where-light surface, 12px radius,
             1px hairline ring, 280ms entrance bloom. The chevron rotates
             90° on open, the input/output stay mono. Usable independently
             of the descriptor pipeline. */
[data-sovereign] .sov-tool-reveal {
  border-radius: 12px;
  background: var(--sov-chat-tool-bg);
  box-shadow: inset 0 0 0 1px var(--sov-chat-tool-border);
  overflow: hidden;
  max-width: 400px;
  animation: sov-tool-in 280ms ease both;
}
[data-sovereign] .sov-tool-reveal__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--sov-chat-tool-label);
  text-align: left;
  font: inherit;
}
[data-sovereign] .sov-tool-reveal__trigger:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--sov-composer-border);
}
[data-sovereign] .sov-tool-reveal__icon {
  flex-shrink: 0;
}
[data-sovereign] .sov-tool-reveal__name {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-chat-tool-label);
  flex: 1 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
[data-sovereign] .sov-tool-reveal__chevron {
  display: inline-flex;
  align-items: center;
  color: var(--sov-muted);
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign] .sov-tool-reveal[data-open="true"] .sov-tool-reveal__chevron {
  transform: rotate(90deg);
}
[data-sovereign] .sov-tool-reveal__body {
  padding: 0 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
[data-sovereign] .sov-tool-reveal__input {
  font-family: var(--sov-font-mono);
  font-size: 10.5px;
  color: var(--sov-muted);
  line-height: 1.6;
}
[data-sovereign] .sov-tool-reveal__arrow {
  color: var(--sov-chat-tool-dot);
  margin-right: 6px;
}
[data-sovereign] .sov-tool-reveal__output {
  font-family: var(--sov-font-mono);
  font-size: 10.5px;
  color: var(--sov-subtle);
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--sov-surface-sunken);
  line-height: 1.6;
}

/* ---------- Reminder disclosure (right-rail dropdown) ----------
   Pattern: sov-tool-reveal structure. Tokens: Malaika gold presence.
   Compact header with breathing notification dot + chevron; body
   reveals the reminder content on click. No red — gold only. */
[data-sovereign] .sov-reminder-disclosure {
  border-radius: var(--sov-radius-md);
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(160%);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  overflow: hidden;
}
[data-sovereign] .sov-reminder-disclosure__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px var(--sov-rail-pad);
  background: none;
  border: 0;
  cursor: pointer;
  /* Color rung matches .sov-project-rail__new-btn exactly: --sov-subtle
     (oklch 0.74). Previously this was --sov-ink with the label child
     trying to dim it via the phantom var(--sov-faint). That phantom
     token is undeclared anywhere in the system (documented in
     sovereign-design/.../atelier-notes/2026-05-15-revenue-ad-card-dreamteam-block.md
     and pr/step-revenue-02/PR.md addendum -j) so the var() unset and
     the label inherited the trigger's --sov-ink — reading near-white
     against the muted new-btn. Setting --sov-subtle here lets the label
     inherit the correct rung; the override on the label was removed in
     the same pass, retiring one reference to the phantom. */
  color: var(--sov-subtle);
  text-align: left;
  font-family: var(--sov-font-sans);
  /* Text tokens aligned to the canonical rail-button set used by
     .sov-project-rail__new-btn ("+ NEW SESSION", "+ NEW PROJECT").
     Same size (12px via --sov-rail-btn-font-size), same weight (600),
     same letter-spacing (0.08em). The label fully inherits these from
     the button — no overrides on the child. This is the canonical
     "rail button" text rung — any new rail-tier button should adopt
     the same quartet (size, weight, tracking, color). */
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-reminder-disclosure__trigger:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 5%, transparent);
}
[data-sovereign] .sov-reminder-disclosure__trigger:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}
[data-sovereign] .sov-reminder-disclosure__dot {
  flex-shrink: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 6px var(--mk-glow-gold-halo);
  animation: sov-thinking-dot 2.4s ease-in-out infinite;
}
[data-sovereign] .sov-live-dot {
  display: inline-block;
  flex-shrink: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 6px var(--mk-glow-gold-halo);
  animation: sov-thinking-dot 2.4s ease-in-out infinite;
  vertical-align: middle;
  margin-left: 6px;
  position: relative;
  top: -1px;
}
[data-sovereign] .sov-reminder-disclosure__label {
  flex: 1 1;
  min-width: 0;
  /* Text color inherits from .sov-reminder-disclosure__trigger (--sov-subtle).
     The previous `color: var(--sov-faint)` was a phantom-token reference —
     removed in the same pass that set the trigger's color rung. See the
     comment block on .sov-reminder-disclosure__trigger above. */
}
[data-sovereign] .sov-reminder-disclosure__chevron {
  display: inline-flex;
  align-items: center;
  color: var(--mk-glow-gold);
  transition: transform 180ms var(--sov-ease);
  flex-shrink: 0;
  opacity: 0.7;
}
[data-sovereign]
  .sov-reminder-disclosure[data-open="true"]
  .sov-reminder-disclosure__chevron {
  transform: rotate(180deg);
  opacity: 1;
}
[data-sovereign] .sov-reminder-disclosure__body {
  padding: var(--sov-space-2) var(--sov-rail-pad) var(--sov-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

/* ---------- Library summary section (right-rail glass card) ----------
   Section sibling to sov-reminder-disclosure. Glass background, softer
   hairline, dim aesthetic. Built from existing tokens — nothing invented.
   Stats render inline as label · value pairs, breathing toward faint. */
[data-sovereign] .sov-reminder-summary {
  border-radius: var(--sov-radius-md);
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(140%);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
  overflow: hidden;
  padding: var(--sov-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-reminder-summary__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
[data-sovereign] .sov-reminder-summary__head-label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--sov-faint);
}
[data-sovereign] .sov-reminder-summary__head-line {
  flex: 1 1;
  height: 1px;
  background: color-mix(in oklab, var(--mk-glow-gold) 20%, transparent);
  opacity: 0.6;
}
[data-sovereign] .sov-reminder-summary__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}
[data-sovereign] .sov-reminder-summary__kpi {
  font-family: var(--sov-font-mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--sov-whisper);
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
[data-sovereign] .sov-reminder-summary__kpi-value {
  color: var(--sov-ink);
  font-weight: 600;
  font-size: 13px;
}
[data-sovereign] .sov-reminder-summary__kpi-label {
  color: var(--sov-muted);
  font-size: 10px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ---------- Chat surface + bubble primitive ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html
             § BubbleMalaika / BubbleUser  (step-10 baseline).

   Amended:  Sovereign Design Authority · 2026-05-15 · speaker asymmetry pass.

   Two speakers, two voices, one rule set. The architect's reply is a
   gold-hairline glass card — same gold signature his composer wears, so
   the surface speaks with one authority. Malaika's reply is unframed
   prose — she IS the canvas; she does not appear inside a card that
   interrupts the column. Spacing between turns belongs to the stack
   (.sov-chat), not the primitive.

   All visual values consume tokens that already live in this file:
     · --sov-component-chat-bubble-{max-width,padding-y,padding-x,radius-user}
     · --sov-hairline-gold              (= --mk-hairline-gold)
     · --sov-composer-halo              (= --mk-glow-gold-halo)
     · --sov-veil, --sov-glass-blur, --sov-ink, --sov-whisper, --sov-font-serif
     · --sov-space-5 (stack vertical breathing), --sov-space-6 (turn gap)
   No new values authored. Surface no longer needs inline style literals. */

[data-sovereign] .sov-chat {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-6);
  padding: var(--sov-space-5) 0;
}

[data-sovereign] .sov-chat-bubble {
  display: flex;
  width: 100%;
}
[data-sovereign] .sov-chat-bubble--user {
  justify-content: flex-end;
}
[data-sovereign] .sov-chat-bubble--malaika {
  justify-content: flex-start;
}

/* Body — shared typography rung; chrome is variant-scoped below. */
[data-sovereign] .sov-chat-bubble__body {
  max-width: var(--sov-component-chat-bubble-max-width);
  padding: var(--sov-component-chat-bubble-padding-y)
    var(--sov-component-chat-bubble-padding-x);
  font-family: var(--sov-font-serif);
  font-size: 16px;
  line-height: 1.65;
  color: var(--sov-ink);
}

/* USER — persona-hairline glass card. Carries the same gold signature the
   composer wears when typing — and when the user has selected a persona
   (or their profile has one set), the hairline shifts to that persona's
   accent. The substrate default --sov-persona-hairline is a 35% gold mix,
   so the bubble looks identical to the original gold-hairline card when
   no persona override is in scope. 18/4/18/18 mortice (top-right tightens —
   the architect's voice docks against the composer corner). */
[data-sovereign] .sov-chat-bubble--user .sov-chat-bubble__body {
  border-radius: var(--sov-component-chat-bubble-radius-user);
  background: color-mix(in oklab, var(--sov-veil) 78%, transparent);
  box-shadow: 0 0 0 1px var(--sov-persona-hairline, var(--sov-hairline-gold)),
    0 12px 32px -12px var(--sov-composer-halo);
  backdrop-filter: blur(var(--sov-glass-blur));
  -webkit-backdrop-filter: blur(var(--sov-glass-blur));
}

/* MALAIKA — unframed prose. No background, no padding, no border, no
   shadow, no blur, no radius. Reads like a page, not a card. The
   SovereignRenderer flow container (.sov-renderer) handles paragraph
   rhythm inside; the stack (.sov-chat) handles turn-to-turn breathing. */
[data-sovereign] .sov-chat-bubble--malaika .sov-chat-bubble__body {
  max-width: 100%;
  padding: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-radius: 0;
}

/* Whisper variant — historical non-streaming Malaika turns. */
[data-sovereign] .sov-chat-bubble__whisper {
  color: var(--sov-whisper);
}

/* ---------- Data panel primitive ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html
             § DataPanel (MCP / memory / artifact). Veil background, gold or
             glow-tinted hairline, monospaced meta on the right, serif body
             pulled in 13px from the glow dot. The panel is the artifact
             body: it should never feel like a chat bubble. */
[data-sovereign] .sov-data-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border-radius: 14px;
  max-width: 92%;
  background: var(--sov-veil);
  box-shadow: inset 0 0 0 1px var(--sov-data-panel-border, var(--sov-rule));
  --sov-data-panel-glow: var(--mk-glow-gold);
  --sov-data-panel-border: var(--mk-glow-gold-hairline);
}
[data-sovereign] .sov-data-panel[data-tone="kingfishers"] {
  --sov-data-panel-glow: var(--mk-glow-as-kingfishers-catch-fire);
  --sov-data-panel-border: var(--mk-hairline-as-kingfishers-catch-fire);
}
[data-sovereign] .sov-data-panel[data-tone="where-light"] {
  --sov-data-panel-glow: var(--mk-glow-where-light-enters);
  --sov-data-panel-border: var(--mk-hairline-where-light);
}
[data-sovereign] .sov-data-panel[data-tone="windhover"] {
  --sov-data-panel-glow: var(--mk-glow-the-windhover);
  --sov-data-panel-border: var(--mk-hairline-the-windhover);
}
[data-sovereign] .sov-data-panel[data-tone="pied"] {
  --sov-data-panel-glow: var(--mk-glow-pied-beauty);
  --sov-data-panel-border: var(--mk-hairline-pied-beauty);
}
[data-sovereign] .sov-data-panel__head {
  display: flex;
  align-items: center;
  gap: 8px;
}
[data-sovereign] .sov-data-panel__glow {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--sov-data-panel-glow);
  box-shadow: 0 0 8px var(--sov-data-panel-glow);
  flex-shrink: 0;
}
[data-sovereign] .sov-data-panel__title {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  font-weight: 600;
  color: var(--sov-ink);
}
[data-sovereign] .sov-data-panel__meta {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-whisper);
  margin-left: auto;
}
[data-sovereign] .sov-data-panel__body {
  margin: 0;
  padding-left: 13px;
  font-family: var(--sov-font-serif);
  font-size: 14px;
  line-height: 1.55;
  color: var(--sov-subtle);
}

/* ---------- §03 screen a03 · full-viewport app layout (3-col + bottom bar) ----------
   Node: main#a03.ab — rail + top strip + main + right; composer is one full-
   width row (not a nested “section” with side margins). */
[data-sovereign] .sov-a03,
[data-sovereign] .sov-a05 {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 100dvh;
  align-self: stretch;
  background: var(--sov-bg);
  color: var(--sov-ink);
  width: 100%;
  max-width: none;
  margin: 0;
}
[data-sovereign] .sov-a03__frame,
[data-sovereign] .sov-a05__frame {
  /* Air between top chrome (wordmark / tabs / user) and the three main columns. */
  --sov-below-chrome-pad: var(--sov-space-6);
  display: grid;
  box-sizing: border-box;
  grid-template-columns: var(--sov-layout-rail-width, 270px) minmax(0, 1fr) var(
      --sov-layout-right-rail-width,
      270px
    );
  /* Row 1: top chrome · Row 2: scroll · Row 3: composer (center column only) */
  grid-template-rows: auto minmax(0, 1fr) auto;
  flex: 1 1 auto;
  /* Lock to viewport so row 3 stays on-screen; only .sov-a03__scroll scrolls */
  height: 100dvh;
  max-height: 100dvh;
  min-height: 0;
  overflow: hidden;
  max-width: none;
  margin: 0;
  width: 100%;
}
/* Left: row 1 = wordmark · rows 2–3 = nav (aligns with scroll + rside). Mobile stacks in .sov-a03__left-col. */
[data-sovereign] .sov-a03__left-col,
[data-sovereign] .sov-a05__left-col {
  display: contents;
}
[data-sovereign] .sov-a03__left-chrome,
[data-sovereign] .sov-a05__left-chrome {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
  position: relative;
  z-index: 65;
  align-self: start;
}
[data-sovereign] .sov-a03__left,
[data-sovereign] .sov-a05__left {
  grid-column: 1;
  grid-row: 2 / 4;
  min-width: 0;
  position: relative;
  align-self: stretch;
  padding-top: var(--sov-below-chrome-pad);
  box-sizing: border-box;
}
[data-sovereign] .sov-a03__tabs,
[data-sovereign] .sov-a05__tabs {
  grid-column: 2;
  grid-row: 1;
  position: relative;
  z-index: 65;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sov-space-3) var(--sov-space-4) var(--sov-space-2);
  min-width: 0;
  box-sizing: border-box;
  /* Flat top strip: canvas only (no glass fill, no hairline). */
  background: transparent;
  border: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
[data-sovereign] .sov-a03__right-chrome,
[data-sovereign] .sov-a05__right-chrome {
  grid-column: 3;
  grid-row: 1;
  position: relative;
  z-index: 65;
  display: flex;
  flex-direction: column;
  /* Identity: left edge aligns to chrome inset (same as nav rail / working-ng rail pad). */
  align-items: flex-start;
  justify-content: center;
  gap: 0;
  padding: var(--sov-space-4) var(--sov-rail-pad) var(--sov-space-3);
  min-width: 0;
  width: 100%;
  box-sizing: border-box;
  /* Identity only — no panel fill or hairline; canvas shows through. */
  background: transparent;
  box-shadow: none;
  border: 0;
}
/* ── User card slot — the wrapper the app mounts the card into. It is a
 *   flex child of the flex .sov-shell__rail-header, so it must carry
 *   min-width:0; otherwise its default min-width:auto lets it grow to the
 *   full email width, overflowing the header's inline padding and shoving
 *   the email to the screen edge (killing the ellipsis and the right gap). ── */
[data-sovereign] .sov-user-card-slot {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
}

/* ── User card — clean identity strip. No glow — the rail header
 *   owns the ambient halo so it radiates behind the entire chrome band
 *   rather than only around the user card. ── */
[data-sovereign] .sov-user-card {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sov-user-card-gap);
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  box-sizing: border-box;
  text-decoration: none;
  color: inherit;
  border-radius: var(--sov-radius-sm);
  padding: 4px var(--sov-user-card-meta-pad-right, 12px) 4px 0;
}
[data-sovereign] .sov-user-card__avatar {
  flex: 0 0 auto;
  width: var(--sov-user-card-avatar-size);
  height: var(--sov-user-card-avatar-size);
  border-radius: var(--sov-radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-tile-size);
  font-weight: var(--sov-text-section-weight);
  line-height: 1;
  color: var(--sov-color-bg);
  background: var(--sov-color-glow-gold);
  overflow: hidden;
}
[data-sovereign] .sov-user-card__avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
[data-sovereign] .sov-user-card__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sov-space-1);
  min-width: 0;
  overflow: hidden;
  flex: 1 1;
  text-align: start;
}
[data-sovereign] .sov-user-card__name {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-tile-size);
  font-weight: 500;
  line-height: var(--sov-text-tile-line);
  color: var(--sov-color-ink);
  /* No text-transform — the name slot holds the user's email, which must
     render verbatim (lowercase). Capitalize mangled it to "Architect@Kaosintelligence.Com". */
  text-transform: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
[data-sovereign] .sov-user-card__org {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-nav-item-font-size);
  font-weight: 600;
  letter-spacing: var(--sov-nav-item-tracking);
  line-height: 1.25;
  text-transform: uppercase;
  color: var(--sov-color-whisper);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* ── User card main button — overflow hidden keeps content trimmed.
 *   The glow effect lives on .sov-shell__rail-header, not here. ── */

[data-sovereign] .sov-user-card__main {
  display: flex;
  align-items: center;
  gap: var(--sov-user-card-gap);
  min-width: 0;
  text-decoration: none;
  color: inherit;
  flex: 1 1;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  font: inherit;
  text-align: start;
  overflow: hidden;
  border-radius: var(--sov-radius-sm);
}

[data-sovereign] .sov-user-card__lock {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--sov-radius-sm);
  border: none;
  background: transparent;
  color: var(--sov-color-whisper);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 150ms var(--sov-ease-out), background 150ms
    var(--sov-ease-out);
}

[data-sovereign] .sov-user-card__lock:hover {
  color: var(--sov-color-ink);
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
}

/* ── Chrome rail toggle section · § 2026-05-09 ──
 *
 * The rail-collapse toggle has moved from .sov-chrome-rail-toggle
 * (a chevron in the right-chrome) to .sov-a03-focus (the ♫ FOCUS
 * pill in the right-rail bottom). The toggle classes remain in the
 * CSS for backward compatibility with any remaining references.
 *
 * Sanctioned: Charter Rule 5b.
 * Tokens: --mk-hairline-gold, --mk-glow-gold, --sov-radius-pill,
 *   --sov-d-base, --sov-ease-expo.
 */
[data-sovereign] .sov-chrome-rail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: var(--sov-space-2);
  min-width: 0;
}
/* Rail-collapse rules REMOVED — replaced by unified [data-sov-chrome] system. */
[data-sovereign] .sov-a03__scroll,
[data-sovereign] .sov-a05__scroll {
  grid-column: 2;
  grid-row: 2;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  padding: var(--sov-below-chrome-pad) 28px 24px;
  box-sizing: border-box;
}
/* §03 home — malaika-home.html .canvas: --content-max 820, centered. */
[data-sovereign] .sov-a03__scroll,
[data-sovereign] .sov-a05__scroll {
  max-width: var(--sov-content-max);
  width: 100%;
  justify-self: center;
}
/* Span main + composer rows (col 3 has no composer) — same vertical band as .sov-a03__left. */
[data-sovereign] .sov-a03__rside,
[data-sovereign] .sov-a05__rside {
  grid-column: 3;
  grid-row: 2 / 4;
  align-self: stretch;
  min-height: 0;
  overflow: hidden;
  padding: var(--sov-below-chrome-pad) var(--sov-rail-pad) 0 var(--sov-rail-pad);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  box-sizing: border-box;
}
[data-sovereign] .sov-a03__composer-wrap,
[data-sovereign] .sov-a05__composer-wrap {
  grid-column: 2;
  grid-row: 3;
  box-sizing: border-box;
  min-width: 0;
  padding: var(--sov-space-2) var(--sov-gutter) var(--sov-composer-wrap-pad-b);
  display: flex;
  justify-content: center;
  align-items: flex-end;
  width: 100%;
  /* Grid items support z-index without position:relative. z-65 keeps
     the input bar above pretext/voice portals (z-60) when
     [data-overlay-active] is set and no ancestor creates a stacking
     context that would trap it. */
  z-index: 65;
}
[data-sovereign] .sov-a03-page-tabs {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  justify-content: center;
  gap: 4px 20px;
  overflow-x: auto;
  overflow-y: visible;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
  /* Glassmorphic bar — same background tokens as the right-rail settings
   * flyout (.sov-user-panel): --sov-glass-mix over --sov-bg with the deep
   * blur. The light-theme override below swaps to parchment warmth so the
   * glass registers on the near-white canvas, mirroring the flyout exactly. */
  padding: var(--sov-space-1) var(--sov-space-4);
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--sov-bg) var(--sov-glass-mix), transparent);
  backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(160%);
}
[data-sovereign][data-sovereign-theme="light"] .sov-a03-page-tabs {
  background: color-mix(
    in oklab,
    var(--sov-color-bg, var(--mk-web-parchment)) 82%,
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-deep)) saturate(140%);
}
[data-sovereign] .sov-a03-page-tabs::-webkit-scrollbar {
  display: none;
}
[data-sovereign] .sov-a03-page-tabs__tab {
  position: relative;
  flex-shrink: 0;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px 2px 10px;
  color: var(--sov-whisper);
  letter-spacing: 0.14em;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 240ms var(--sov-ease-spring);
}
[data-sovereign] .sov-a03-page-tabs__tab:hover {
  color: var(--sov-subtle);
}
[data-sovereign] .sov-a03-page-tabs__tab[data-active="true"] {
  color: var(--sov-ink);
}
[data-sovereign] .sov-a03-page-tabs__tab[data-active="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2px;
  height: 2px;
  border-radius: 1px;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 12px color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
  transition: transform 240ms var(--sov-ease-spring), opacity 240ms
    var(--sov-ease-spring);
}

/* ── Focus ring — the sanctioned gold hairline ring from the token
 *    substrate. Only visible on keyboard focus, not mouse click. */
[data-sovereign] .sov-a03-page-tabs__tab:focus-visible {
  outline: 2px solid var(--mk-glow-gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Reduced motion — freeze transitions so the gold underline
 *    doesn't animate. The active color and underline still appear;
 *    the motion is the only thing removed. */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-a03-page-tabs__tab {
    transition: none;
  }
  [data-sovereign] .sov-a03-page-tabs__tab[data-active="true"]::after {
    transition: none;
  }
}

[data-sovereign] .sov-a03-fast-search {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  min-height: var(--sov-search-pill-h);
  box-sizing: border-box;
  padding: var(--sov-space-2) var(--sov-search-pill-pad-x);
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 88%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
}
[data-sovereign] .sov-a03-fast-search__input {
  flex: 1 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--sov-whisper);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: var(--sov-text-micro-size);
  font-weight: 600;
  line-height: 1;
  padding: 0;
}
[data-sovereign] .sov-a03-fast-search__input::placeholder {
  color: var(--sov-whisper);
  opacity: 0.85;
}
[data-sovereign] .sov-a03-fast-search__kbd {
  flex-shrink: 0;
  border: 0;
  background: color-mix(in oklab, var(--sov-ink) 12%, transparent);
  color: var(--mk-glow-gold);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: var(--sov-text-chip-size);
  cursor: pointer;
}
[data-sovereign][data-sovereign-theme="light"] .sov-a03-fast-search__kbd {
  color: var(--mk-glow-as-kingfishers-catch-fire);
}
/* .sov-a03-focus REMOVED — replaced by unified Hide/Show toggle in right rail footer. */
[data-sovereign] [data-kaos-component="kaos-nav-rail"].sov-nav-rail--embed {
  position: relative;
  inset: auto;
  width: 100%;
  height: 100%;
  z-index: auto;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* a01 / SovereignNavRail — aside.nr · nr-eyebrow · nr-row (no rail card fill when embed). */
[data-sovereign] .nr {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  width: 100%;
  box-sizing: border-box;
}
[data-sovereign] .nr--fixed {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sov-component-nav-rail-width);
  z-index: 20;
  /* Global nav: flat canvas (token); no glass card behind the list. */
  background: var(--sov-color-bg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}
[data-sovereign] .nr-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sov-component-nav-rail-group-section-gap, var(--sov-space-1));
  padding: var(--sov-space-04, var(--sov-space-4)) 0;
  -webkit-overflow-scrolling: touch;
}
/* Glass pill utility button — shared tokens for footer actions.
 * Matches .sov-rail-hide-toggle tokens exactly.
 * Idle: dim muted color with subtle gold hairline. Hover: full gold glow + 6% wash. */
[data-sovereign] .nr-utils__pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sov-space-2);
  min-height: calc(var(--sov-space-5) + var(--sov-space-3));
  padding: var(--sov-space-2) var(--sov-rail-pad);
  border-radius: var(--sov-radius-pill);
  border: 0;
  background: transparent;
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-tile-size);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--sov-d-fast) var(--sov-ease-expo), background
    var(--sov-d-fast) var(--sov-ease-expo), box-shadow var(--sov-d-fast)
    var(--sov-ease-expo);
}
/* Hover — full gold glow + 6% gold wash background */
[data-sovereign] .nr-utils__pill:hover {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
}
/* Icon inside a utility pill — same gold as text, inline with label */
[data-sovereign] .nr-utils__pill-icon {
  flex-shrink: 0;
  color: currentColor;
}
[data-sovereign] .nr-group {
  display: flex;
  flex-direction: column;
  gap: var(--sov-component-nav-rail-group-item-gap, var(--sov-space-1));
  min-width: 0;
}
[data-sovereign] .nr-group + .nr-group {
  padding-top: var(--sov-space-3);
  position: relative;
}
[data-sovereign] .nr-group + .nr-group::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: var(--sov-space-2);
  width: var(--sov-space-6);
  height: 1px;
  background: var(--mk-hairline-gold);
  opacity: 0.7;
}
[data-sovereign] .nr-eyebrow {
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-space-1) * 2.375);
  font-weight: 600;
  letter-spacing: var(--sov-nav-item-tracking);
  line-height: var(--sov-text-caption-line);
  text-transform: uppercase;
  color: var(--sov-color-whisper);
  padding: var(--sov-component-nav-rail-eyebrow-padding-top, var(--sov-space-3))
    var(--sov-space-2)
    var(--sov-component-nav-rail-eyebrow-padding-bottom, var(--sov-space-2));
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  background: transparent;
  box-shadow: none;
  border: 0;
}
[data-sovereign] .nr-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  width: 100%;
  box-sizing: border-box;
  min-height: var(--sov-search-pill-h);
  padding: var(--sov-space-2) var(--sov-space-2);
  border: 0;
  border-radius: var(--sov-component-nav-rail-row-radius);
  cursor: pointer;
  text-align: left;
  text-decoration: none;
  font-family: var(--sov-typography-font-sans);
  background: transparent;
  color: var(--sov-color-muted);
  transition: background var(--sov-motion-duration-quick)
    var(--sov-motion-ease-out), color var(--sov-motion-duration-quick)
    var(--sov-motion-ease-out), transform var(--sov-motion-duration-quick)
    var(--sov-motion-ease-out);
}

/* ── Compact — label hidden, icon gold-tinted. Icon stays in place —
 *   the row keeps its open-state width, height, padding, and gap.
 *   Idle paths get dimmed gold; the active path gets full gold + border. ── */

/* ── Icon base — define before any compact/hover/active overrides ── */
[data-sovereign] .nr-row__icon {
  flex-shrink: 0;
  color: currentColor;
  transition: filter var(--sov-motion-duration-quick) var(--sov-motion-ease-out),
    width var(--sov-rail-transition),
    height var(--sov-rail-transition);
}

[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .nr-row {
  color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .nr-row[data-kaos-state="active"] {
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold);
  color: var(--mk-glow-gold);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .nr-row__label {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sov-rail-transition);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .nr-row
  .nr-row__icon {
  width: 20px;
  height: 20px;
}

/* ── Hover-to-peek — restore open state color and labels when hovering compact rail.
 *   No sizing changes needed — the row never changed size. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .nr-row,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .nr-row {
  box-shadow: none;
  color: var(--sov-color-muted);
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .nr-row[data-kaos-state="active"],
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .nr-row[data-kaos-state="active"] {
  color: var(--sov-color-glow-gold);
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .nr-row
  .nr-row__icon,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .nr-row
  .nr-row__icon {
  width: 16px;
  height: 16px;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .nr-row__label,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .nr-row__label {
  opacity: 1;
  pointer-events: auto;
}
/* ── Hover: gold treatment matching .nr-utils__btn —
 *    gold label + 6% gold wash background + scale press.
 *    Sanctioned step-41. Hover-only on idle rows. */
[data-sovereign] .nr-row:hover[data-kaos-state="idle"] {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
/* Icon glow on hover — same drop-shadow as utility cluster */
[data-sovereign] .nr-row:hover[data-kaos-state="idle"] .nr-row__icon {
  filter: drop-shadow(
    0 0 5px color-mix(in oklab, var(--mk-glow-gold) 45%, transparent)
  );
}
[data-sovereign] .nr-row:active[data-kaos-state="idle"] {
  transform: scale(0.98);
}
[data-sovereign] .nr-row[data-kaos-state="active"] {
  color: var(--sov-color-glow-gold);
  background: transparent;
  box-shadow: none;
}
[data-sovereign] .nr-row__label {
  font-size: var(--sov-text-tile-size);
  font-weight: 400;
  line-height: var(--sov-text-tile-line);
  text-transform: uppercase;
  font-feature-settings: "ss01", "cv01";
  letter-spacing: 0.06em;
}
[data-sovereign] .nr-row[data-kaos-state="active"] .nr-row__label {
  font-weight: 500;
}

/* ── Focus ring — sanctioned gold hairline ring from the token
 *    substrate. Only visible on keyboard focus, not mouse click.
 *    Matches the .sov-a03-page-tabs__tab:focus-visible pattern
 *    shipped in step-39. */
[data-sovereign] .nr-row:focus-visible {
  outline: 2px solid var(--mk-glow-gold);
  outline-offset: 2px;
  border-radius: var(--sov-component-nav-rail-row-radius);
}

/* ── Reduced motion — disable transitions and scale press on nav rows.
 *    Matches .nr-utils__btn reduced-motion block shipped in step-40. */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .nr-row {
    transition: none;
  }
  [data-sovereign] .nr-row__icon {
    transition: none;
  }
  [data-sovereign] .nr-row:active[data-kaos-state="idle"] {
    transform: none;
  }
}

/* Wordmark row — flat; canvas only (no glass, no hairline, no ambient ::before). */
[data-sovereign] [data-kaos-subcomponent="kaos-nav-rail-header"] {
  position: relative;
  overflow: visible;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sov-space-5) var(--sov-rail-pad) var(--sov-space-2);
  box-sizing: border-box;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
[data-sovereign] [data-kaos-subcomponent="kaos-nav-rail-header"]::before {
  content: none;
}
[data-sovereign] [data-kaos-subcomponent="kaos-nav-rail-header"] > * {
  position: relative;
  z-index: 1;
}
[data-sovereign] .nr-header__brand {
  display: flex;
  align-items: center;
  min-width: 0;
}
[data-sovereign] .nr-header__brand [data-kaos-wordmark-mode="mark"],
[data-sovereign] .nr-header__brand .sov-kaos-text-logo {
  flex: 0 0 auto;
  max-width: 180px;
  overflow: hidden;
}
/* malaika-home.html .kaos-logo text — Hopkins fill is inline on the SVG;
   typography uses sanctioned wordmark tokens. */
[data-sovereign] .sov-kaos-text-logo__text {
  font-family: var(--sov-typography-font-sans);
  font-weight: var(--sov-wordmark-malaika-weight);
  font-size: var(--sov-nav-brand-wordmark-size);
  letter-spacing: var(--sov-wordmark-malaika-tracking);
}
/* ── Rail header brand logos — watermark (expanded) + icon (compact) ──
 *   sov-kaos-logo-icon defaults to display:none, shown only in compact mode.
 *   sov-kaos-text-logo defaults to block, hidden via opacity in compact mode.
 *   Theme switching: watermarks swap between light/dark variants.
 *   Both images default to block; the wrong one is hidden per theme. */
[data-sovereign] .sov-kaos-logo-icon {
  display: none;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact]) .sov-kaos-logo-icon {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: auto;
  height: 100%;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact]) .sov-kaos-logo-icon img {
  display: block;
  width: var(--sov-rail-compact-glyph-size);
  height: var(--sov-rail-compact-glyph-size);
  object-fit: contain;
}
/* Base: both watermark images are block. */
[data-sovereign] .sov-watermark-light,
[data-sovereign] .sov-watermark-dark {
  display: block;
  max-width: 100%;
}
/* Light theme: show dark watermark, hide white. */
[data-sovereign][data-sovereign-theme="light"] .sov-watermark-light {
  display: block !important;
}
[data-sovereign][data-sovereign-theme="light"] .sov-watermark-dark {
  display: none !important;
}
/* Dark theme: show white watermark, hide dark. */
[data-sovereign][data-sovereign-theme="dark"] .sov-watermark-light {
  display: none !important;
}
[data-sovereign][data-sovereign-theme="dark"] .sov-watermark-dark {
  display: block !important;
}
/* Compact icons — only shown in compact mode. Theme picks which variant.
 *   The parent .sov-kaos-logo-icon is display:none by default and
 *   display:flex in compact mode (above). Inside compact mode the <img>
 *   gets display:block; the theme rules below hide the wrong variant. */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])[data-sovereign-theme="light"] .sov-logo-icon-light {
  display: block !important;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])[data-sovereign-theme="light"] .sov-logo-icon-dark {
  display: none !important;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])[data-sovereign-theme="dark"] .sov-logo-icon-light {
  display: none !important;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])[data-sovereign-theme="dark"] .sov-logo-icon-dark {
  display: block !important;
}
/* Hover — hide PNG icon, show text watermark logo. */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact]):not([data-sov-rail-locked]):not([data-sov-viewport-compact]) .sov-shell__rail--left:hover .sov-kaos-logo-icon {
  display: none;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact]):not([data-sov-rail-locked]):not([data-sov-viewport-compact]) .sov-shell__rail--left:hover .nr-header__brand .sov-kaos-text-logo {
  display: flex;
  align-items: center;
  opacity: 1;
  pointer-events: auto;
  max-width: 100%;
  width: auto;
  flex: 0 0 auto;
}
/* Right-rail "On this page" — same token spine as left SovereignNavRail. */
[data-sovereign] .sov-a03-onpage {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0 var(--sov-space-3);
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
[data-sovereign] .sov-a03-onpage__heading {
  flex-shrink: 0;
  margin: 0 0 var(--sov-space-2) 0;
  padding: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  font-weight: 600;
  letter-spacing: var(--sov-typography-rung-caption-tracking);
  text-transform: uppercase;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-a03-onpage__eyebrow {
  display: block;
  margin: 0 0 var(--sov-space-1) 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-nav-item-font-size);
  font-weight: var(--sov-nav-item-weight);
  letter-spacing: var(--sov-nav-item-tracking);
  text-transform: uppercase;
  color: var(--sov-muted);
}
[data-sovereign] .sov-a03-onpage__line {
  display: block;
  margin: 0;
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  font-weight: var(--sov-text-field-weight);
  color: var(--sov-subtle);
}
[data-sovereign] .sov-a03-onpage__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}
[data-sovereign] .sov-a03-onpage__item {
  display: block;
  padding-bottom: var(--sov-space-1);
  border-bottom: 1px solid color-mix(in oklab, var(--sov-ink) 6%, transparent);
}
[data-sovereign] .sov-a03-onpage__item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

/* ---------- SovereignRestingField — Malaika's wandering background ----------
   Token-driven ambient layer for any sovereign surface that wants her
   resting presence behind it. Edge-to-edge under chrome: both the
   ambient glass washes and the ghost words are `position: fixed` so
   they fill the viewport behind every chrome layer (top tabs z=10,
   nav rail z=20, composer z=60). The root `.sov-resting` stays
   `position: relative` with no `contain` / `isolate` / `transform`
   so the fixed descendants escape to the viewport containing block
   instead of being trapped by an ancestor. Component lives at
   packages/kaos-sovereign/components/sovereign-resting-field.tsx; the
   words come from Malaika's local-model SSE
   (/api/sovereign/resting/stream) with a curated lexicon fallback in
   lib/resting-lexicon.ts. Only mount it where you actually want her
   wandering presence — it's intended to coexist with chrome, not
   compete with primary content. */
[data-sovereign] .sov-resting {
  position: relative;
  width: 100%;
  min-height: 0;
  margin: 0;
  pointer-events: none;
}
[data-sovereign] .sov-resting-glass {
  display: none;
}

[data-sovereign] .sov-resting-ghosts {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
[data-sovereign] .sov-resting-ghost {
  position: absolute;
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-weight: 200;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  white-space: nowrap;
  font-size: clamp(3.5rem, 11vw, 11rem);
  line-height: 1;
  color: color-mix(in oklab, var(--sov-color-glow-gold-soft) 50%, transparent);
  opacity: 0;
  filter: blur(calc(var(--sov-glass-blur-deep) * 0.7));
  text-shadow: 0 0 var(--sov-space-6)
    color-mix(in oklab, var(--sov-color-glow-gold) 18%, transparent), 0 0
    var(--sov-space-4)
    color-mix(in oklab, var(--sov-color-glow-where-light) 12%, transparent);
  pointer-events: none;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
  will-change: opacity, transform, filter;
  animation: sov-resting-ghost-drift
    calc(var(--sov-motion-duration-ambient-breathe) * 4) ease-in-out infinite;
}
[data-sovereign] .sov-resting-ghost--one {
  top: 18%;
  left: 6%;
  color: color-mix(in oklab, var(--sov-color-glow-gold) 46%, transparent);
  animation-duration: calc(var(--sov-motion-duration-ambient-breathe) * 3.6);
  animation-delay: calc(var(--sov-motion-duration-ambient-breathe) * -0.2);
}
[data-sovereign] .sov-resting-ghost--two {
  top: 56%;
  left: 18%;
  color: color-mix(in oklab, var(--sov-color-glow-where-light) 40%, transparent);
  animation-duration: calc(var(--sov-motion-duration-ambient-breathe) * 4.4);
  animation-delay: calc(var(--sov-motion-duration-ambient-breathe) * -1.6);
}
[data-sovereign] .sov-resting-ghost--three {
  top: 32%;
  right: 8%;
  color: color-mix(in oklab, var(--sov-color-glow-pied) 38%, transparent);
  animation-duration: calc(var(--sov-motion-duration-ambient-breathe) * 4);
  animation-delay: calc(var(--sov-motion-duration-ambient-breathe) * -2.8);
}
[data-sovereign] .sov-resting-ghost--four {
  top: 70%;
  right: 22%;
  color: color-mix(in oklab, var(--sov-color-glow-windhover) 36%, transparent);
  animation-duration: calc(var(--sov-motion-duration-ambient-breathe) * 4.8);
  animation-delay: calc(var(--sov-motion-duration-ambient-breathe) * -3.6);
}

@keyframes sov-resting-glass-breathe {
  0%,
  100% {
    opacity: 0.34;
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    opacity: 0.6;
    transform: translate3d(var(--sov-space-3), calc(var(--sov-space-2) * -1), 0)
      scale(1.04);
  }
}
@keyframes sov-resting-glass-drift {
  0%,
  100% {
    opacity: 0.22;
    transform: translate3d(calc(var(--sov-space-5) * -1), 0, 0);
  }
  50% {
    opacity: 0.42;
    transform: translate3d(var(--sov-space-5), calc(var(--sov-space-1) * -1), 0);
  }
}
@keyframes sov-resting-ghost-drift {
  0%,
  100% {
    opacity: 0;
    transform: translate3d(calc(var(--sov-space-7) * -1), var(--sov-space-3), 0)
      scale(0.9);
    letter-spacing: 0.22em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 1.2));
  }
  28%,
  62% {
    opacity: 0.24;
    transform: translate3d(0, 0, 0) scale(1);
    letter-spacing: 0.04em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 0.55));
  }
  85% {
    opacity: 0.08;
    transform: translate3d(var(--sov-space-6), calc(var(--sov-space-3) * -1), 0)
      scale(1.06);
    letter-spacing: 0.16em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 0.95));
  }
}
/* Light-mode ghost words — higher opacity + less blur for the near-white canvas.
   Colors are handled by colors-light.css token overrides; this block only
   adjusts visibility and legibility. */
@keyframes sov-resting-ghost-drift-light {
  0%,
  100% {
    opacity: 0.04;
    transform: translate3d(calc(var(--sov-space-7) * -1), var(--sov-space-3), 0)
      scale(0.9);
    letter-spacing: 0.22em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 0.7));
  }
  28%,
  62% {
    opacity: 0.28;
    transform: translate3d(0, 0, 0) scale(1);
    letter-spacing: 0.04em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 0.35));
  }
  85% {
    opacity: 0.12;
    transform: translate3d(var(--sov-space-6), calc(var(--sov-space-3) * -1), 0)
      scale(1.06);
    letter-spacing: 0.16em;
    filter: blur(calc(var(--sov-glass-blur-deep) * 0.55));
  }
}
[data-sovereign][data-sovereign-theme="light"] .sov-resting-ghost {
  animation-name: sov-resting-ghost-drift-light;
}
[data-sovereign] .sov-a05-typing {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-1);
  padding: var(--sov-space-2) var(--sov-space-3);
  border-radius: var(--sov-radius-pill);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 10%, transparent);
  width: -moz-fit-content;
  width: fit-content;
}
[data-sovereign] .sov-a05-typing span {
  width: var(--sov-space-1);
  height: var(--sov-space-1);
  border-radius: 50%;
  background: var(--mk-glow-gold);
  opacity: 0.85;
  animation: sov-a05-dot calc(var(--sov-motion-duration-thinking-dot) * 2)
    ease-in-out infinite;
}
[data-sovereign] .sov-a05-typing span:nth-child(2) {
  animation-delay: calc(var(--sov-motion-duration-thinking-dot) / 3);
}
[data-sovereign] .sov-a05-typing span:nth-child(3) {
  animation-delay: calc(var(--sov-motion-duration-thinking-dot) / 1.5);
}
@keyframes sov-a05-dot {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 1;
  }
}
/* ── Studio section nav — disclosure dropdowns in the right rail ──
 * Mirrors the .sov-reminder-disclosure pattern: glass card, gold
 * hairline, rail-button text quartet, chevron that rotates on open.
 * Each dropdown reveals nested sub-section links. */

[data-sovereign] .sov-studio-disclosure {
  border-radius: var(--sov-radius-md);
  background: color-mix(in oklab, var(--sov-bg) var(--sov-glass-mix), transparent);
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(160%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(160%);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  overflow: hidden;
  transition: box-shadow var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-studio-disclosure[data-active="true"] {
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}
[data-sovereign] .sov-studio-disclosure__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) var(--sov-rail-pad);
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--sov-subtle);
  text-align: left;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background var(--sov-d-fast) var(--sov-ease-expo),
    color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-studio-disclosure__trigger:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 5%, transparent);
  color: var(--sov-color-glow-gold);
}
[data-sovereign] .sov-studio-disclosure[data-active="true"] .sov-studio-disclosure__trigger {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-studio-disclosure__trigger:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}
[data-sovereign] .sov-studio-disclosure__label {
  flex: 1 1;
  min-width: 0;
}
[data-sovereign] .sov-studio-disclosure__chevron {
  display: inline-flex;
  align-items: center;
  color: var(--mk-glow-gold);
  opacity: 0.7;
  flex-shrink: 0;
  transition: transform 180ms var(--sov-ease);
}
[data-sovereign] .sov-studio-disclosure[data-open="true"] .sov-studio-disclosure__chevron {
  transform: rotate(180deg);
  opacity: 1;
}
[data-sovereign] .sov-studio-disclosure__body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  padding: 0 var(--sov-rail-pad) var(--sov-space-3);
}
[data-sovereign] .sov-studio-disclosure__sub {
  display: block;
  width: 100%;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 400;
  line-height: var(--sov-text-caption-line);
  letter-spacing: 0.04em;
  color: var(--sov-whisper);
  padding: var(--sov-space-1) 0 var(--sov-space-1) var(--sov-space-3);
  border-radius: var(--sov-radius-sm);
  transition: color var(--sov-d-fast) var(--sov-ease-expo),
    background var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-studio-disclosure__sub:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
[data-sovereign] .sov-studio-disclosure__sub:focus-visible {
  outline: 2px solid var(--mk-glow-gold);
  outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-studio-disclosure,
  [data-sovereign] .sov-studio-disclosure__trigger,
  [data-sovereign] .sov-studio-disclosure__chevron,
  [data-sovereign] .sov-studio-disclosure__sub { transition: none; }
}

/* ── Sub-classes inside the right-rail body content (used by SovereignA05RailSessions etc.) ── */

[data-sovereign] .sov-a05-rail__eyebrow {
  margin: 0;
  font-family: var(--sov-font-sans);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
  letter-spacing: 0.12em;
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  text-transform: uppercase;
}
[data-sovereign] .sov-a05-rail__pinned {
  border-radius: var(--sov-radius-sm);
  padding: var(--sov-space-2) 0 var(--sov-space-3);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 10%, transparent);
  background: color-mix(in oklab, var(--sov-veil) 35%, transparent);
}
[data-sovereign] .sov-a05-rail__pinned-title {
  margin: 0 0 var(--sov-space-2);
  color: var(--mk-glow-gold);
  letter-spacing: 0.1em;
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  text-transform: uppercase;
}
[data-sovereign] .sov-a05-rail__pinned-code {
  margin: 0;
  font-family: var(--sov-font-mono, ui-monospace, monospace);
  font-size: var(--sov-text-chip-size);
  line-height: 1.45;
  color: var(--sov-subtle);
  white-space: pre-wrap;
  word-break: break-word;
}
[data-sovereign] .sov-a05-rail__sessions {
  list-style: none;
  margin: 0;
  /* `padding-block` (top + bottom only) gives the first and last rows
     breathing room from the scroll viewport's clip edge. Required
     because `.sov-a05-rail__session-button` paints decoration *outside*
     its own box on hover/focus:
       · transform: translateY(-1px)                  → 1px up
       · outline: 2px solid + outline-offset: 2px     → 4px ring outside
       · box-shadow ..., 0 0 18px -8px var(--mk-glow-gold) → soft halo
     Without padding, those land at scrollTop:0 / scrollBottom:0 and
     get sheared by `overflow-y: auto`. 4px clears the outline ring
     comfortably and reveals enough halo to read as a glow. Horizontal
     padding stays 0 because the parent (.sov-shell__rail-body) owns
     canonical L/R rail padding. */
  padding-block: var(--sov-space-1);
  padding-inline: 0;
  display: flex;
  flex-direction: column;
  /* Stack gap stepped one notch up the spacing scale (--sov-space-1 → -2)
     under sovereign-design/.../pr/step-43/PR.md addendum 4. Gives the
     rows visible breathing room between glass tiles. */
  gap: var(--sov-space-2);
  /* Internal scroll containment per sovereign-design/.../pr/step-43/PR.md
     addendum 5. The list owns its scroll viewport — eyebrows above stay
     pinned, rows scroll inside the panel, the outer body never scrolls.
     Charter rule: scroll containment is a component-level concern. The
     global invisible-scrollbar rule (line ~71) keeps the visual surface
     clean; overscroll-behavior:contain prevents the scroll chain from
     bubbling to ancestors (sanctioned at lines 2185, 6069, 6393, 12142). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
[data-sovereign] .sov-a05-rail__session {
  margin: 0;
}
[data-sovereign] .sov-a05-rail__session:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
[data-sovereign] .sov-a05-rail__session-row {
  position: relative;
  display: block;
}
/* §27 family rail surface ──────────────────
   Originally sanctioned: sovereign-design/kaOS Design System (self-authored)/
   pr/step-27/PR.md §2. Reuses every existing rail token; adds the layout
   container + button reset for the family-id picker / session list.

   2026-05-15 delight pass — sovereign-design/kaOS Design System
   (self-authored)/pr/step-43/PR.md.
   Closes four polish gaps on the chat-history rail rows:
     1. horizontal padding (--sov-space-3) so titles breathe
     2. translateY(-1px) on hover — direct analogy to .sov-a06-node and
        .sov-call-card__action
     3. focus-visible split with an outline-offset gold ring for keyboard
        clarity
     4. actions cluster slides in from translateX(--sov-space-1) → 0 as
        opacity rises, so the reveal feels intentional
   Reduced-motion branch authored at the foot of this section.
   Zero new tokens. Zero new values. */
[data-sovereign] .sov-a05-rail__family {
  display: flex;
  flex-direction: column;
}
[data-sovereign] .sov-a05-rail__session-button {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  outline: none;
  /* Glass tile — same family as .sov-activity-item */
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-0);
  width: 100%;
  /* Vertical padding nudged from --sov-space-2 (8px) to a calc-paired
     8 + 2 = 10px lift. Direct analogy: line 4023 in this file.
     Horizontal stays at --sov-space-3 (12px) from step-43. */
  padding: calc(var(--sov-space-2) + var(--sov-space-00)) var(--sov-space-3);
  border-radius: var(--sov-radius-sm);
  background: color-mix(in oklab, var(--sov-veil) 45%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
  color: var(--sov-subtle);
  transition: background var(--sov-d-base) var(--sov-ease-spring), box-shadow
    var(--sov-d-base) var(--sov-ease-spring), color var(--sov-d-base)
    var(--sov-ease-spring), transform var(--sov-d-base) var(--sov-ease-spring);
}
[data-sovereign] .sov-a05-rail__session-button:hover,
[data-sovereign] .sov-a05-rail__session-button:focus-visible {
  /* Canonical button-hover recipe used across the system:
     8% gold over transparent + inset --mk-glow-gold-ring (solid OKLCH).
     Direct analogy: .sov-user-panel__item:hover (line 11993) — the
     dropdown menu pattern. The outer halo at -8px y-offset is the
     rail-tier flourish that lifts this row out of a plain menu item
     and into the chat-history surface. */
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring), 0 0 18px -8px
    color-mix(in oklab, var(--mk-glow-gold) 16%, transparent);
  color: var(--sov-ink);
  outline: none;
  transform: translateY(-1px);
}
/* Keyboard focus adds a clear outer ring on top of the canonical hover
   treatment above. Direct analogy: .sov-rail-mode-toggle__chip:focus-visible
   (line 6035). The inset --mk-glow-gold-ring inherits from the hover rule. */
[data-sovereign] .sov-a05-rail__session-button:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
}
[data-sovereign]
  .sov-a05-rail__session[data-active="true"]
  .sov-a05-rail__session-button {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 38%, transparent), 0 0 22px -8px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-a05-rail__session-title {
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  font-weight: 500;
  color: color-mix(in oklab, var(--sov-ink) 82%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
[data-sovereign]
  .sov-a05-rail__session[data-active="true"]
  .sov-a05-rail__session-title {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-a05-rail__session-preview {
  /* Stepped up one rung from chip (11px) to caption (13px). Hierarchy
     against the title is now carried by weight + colour + opacity
     rather than size — title is weight 500 / 82% ink, preview is
     weight 400 / --sov-whisper / 0.55 opacity. */
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.55;
}

/* ─── cycle-042 · OPEN working-set rows ───────────────────────────────
   Loaded stylesheet is sovereign.css (rail.css is a mirror only).
   OPEN buttons are TWO COLUMNS inside the glass tile when a presence
   light is showing (working / unread):
     · left  — presence gutter (top-aligned; omitted entirely when idle)
     · right — title + preview stack (same as Session History rows)
   Idle open rows match Session History layout — no empty gutter. */
[data-sovereign] .sov-a05-rail__session-row--open {
  display: flex;
  align-items: stretch;
  gap: var(--sov-space-1);
}
[data-sovereign] .sov-a05-rail__session-button--open {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: var(--sov-space-1);
}
[data-sovereign] .sov-a05-rail__session-presence-col {
  flex: 0 0 10px;
  width: 10px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* Tiny top pad so the light sits just below the title cap-line. */
  padding-top: 5px;
  line-height: 0;
  align-self: stretch;
}
[data-sovereign] .sov-a05-rail__session-copy {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-0);
  text-align: left;
}
[data-sovereign] .sov-a05-rail__session-presence {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  pointer-events: none;
}
[data-sovereign] .sov-a05-rail__session-presence--working {
  filter: drop-shadow(
      0 0 4px color-mix(in oklab, var(--mk-glow-pied-beauty) 70%, transparent)
    )
    drop-shadow(
      0 0 8px color-mix(in oklab, var(--mk-glow-pied-beauty) 35%, transparent)
    );
}
[data-sovereign] .sov-a05-rail__session-presence--unread {
  opacity: 0.85;
}
[data-sovereign] .sov-a05-rail__session-actions--open {
  position: static;
  top: auto;
  right: auto;
  transform: none;
  opacity: 1;
  pointer-events: auto;
  flex-direction: row;
  align-self: center;
  flex: none;
  gap: var(--sov-space-00);
  margin-right: var(--sov-space-1);
}
[data-sovereign]
  .sov-a05-rail__session-actions--open
  .sov-a05-rail__session-action {
  flex: none;
  min-height: 22px;
  min-width: 22px;
  padding: 0 var(--sov-space-1);
}
[data-sovereign]
  .sov-a05-rail__session-action--close
  svg,
[data-sovereign]
  .sov-a05-rail__session-action--delete
  svg {
  display: block;
}
[data-sovereign] .sov-a05-rail__eyebrow-row {
  display: flex;
  align-items: baseline;
  gap: var(--sov-space-00);
  /* Lift above the session list so section-info tooltips are not
     painted under the glass tiles that follow in the DOM. */
  position: relative;
  z-index: var(--sov-z-flyout);
}
[data-sovereign] .sov-a05-rail__eyebrow-row .sov-a05-rail__eyebrow {
  margin: 0;
}
[data-sovereign] .sov-a05-rail__eyebrow-row .sov-section-info {
  align-self: flex-start;
  transform: translateY(-0.15em) scale(0.78);
  transform-origin: left center;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-a05-rail__eyebrow-row .sov-section-info__tooltip {
  z-index: var(--sov-z-dialog);
  background: color-mix(in oklab, var(--sov-veil) 88%, #0a0a0a);
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--sov-ink) 16%, transparent),
    0 12px 32px -10px color-mix(in oklab, #000 70%, transparent);
}
[data-sovereign] .sov-a05-rail__load-more {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  margin: var(--sov-space-1) 0 0;
  padding: var(--sov-space-1) 0;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
  font-size: calc(var(--sov-text-caption-size) - 1px);
  line-height: var(--sov-text-caption-line);
  letter-spacing: 0.04em;
  color: var(--sov-whisper);
  background: transparent;
  opacity: 0.55;
  transition: opacity var(--sov-d-base) var(--sov-ease-spring), color
    var(--sov-d-base) var(--sov-ease-spring);
  outline: none;
}
[data-sovereign] .sov-a05-rail__load-more:hover,
[data-sovereign] .sov-a05-rail__load-more:focus-visible {
  opacity: 0.9;
  color: var(--sov-subtle);
}
[data-sovereign] .sov-a05-rail__load-more:disabled {
  cursor: wait;
  opacity: 0.4;
}
[data-sovereign] .sov-a05-rail__session-title {
  display: flex;
  align-items: center;
  gap: var(--sov-space-1);
  min-width: 0;
}
[data-sovereign] .sov-a05-rail__session-title-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

[data-sovereign] .sov-a05-rail__session-actions {
  /* Top-right corner of the row, side-by-side. translateX(--sov-space-1)
     is the resting offset that the cluster slides in from on hover/focus.
     Reduced-motion fallback below pins X to 0. */
  position: absolute;
  top: var(--sov-space-1);
  right: var(--sov-space-1);
  transform: translateX(var(--sov-space-1));
  display: flex;
  flex-direction: row;
  gap: var(--sov-space-00);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sov-d-base) var(--sov-ease-spring), transform
    var(--sov-d-base) var(--sov-ease-spring);
}
[data-sovereign] .sov-a05-rail__session:hover .sov-a05-rail__session-actions,
[data-sovereign]
  .sov-a05-rail__session:focus-within
  .sov-a05-rail__session-actions {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}
[data-sovereign] .sov-a05-rail__session-action {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  margin: 0;
  font: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Square chip — 24px (--sov-space-5) is the codebase minimum tap-target. */
  width: var(--sov-space-5);
  height: var(--sov-space-5);
  padding: 0;
  border-radius: var(--sov-radius-sm);
  /* Solid glass fill so the cluster reads as filled chips against the
     gold-washed hovered row (not the 45% veil tile we used when the
     actions sat centred and stacked). Hairline strengthened to match. */
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 14%, transparent);
  color: var(--sov-subtle);
  font-size: var(--sov-text-chip-size);
  line-height: 1;
  transition: background var(--sov-d-base) var(--sov-ease-spring), box-shadow
    var(--sov-d-base) var(--sov-ease-spring), color var(--sov-d-base)
    var(--sov-ease-spring);
  outline: none;
}
[data-sovereign] .sov-a05-rail__session-action:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-a05-rail__session-action--active {
  color: var(--mk-glow-gold);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
}
[data-sovereign] .sov-a05-rail__session-action--delete:hover {
  background: color-mix(
    in oklab,
    var(--mk-glow-set-life-on-fire) 10%,
    var(--sov-veil)
  );
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-set-life-on-fire) 28%, transparent);
  color: var(--mk-glow-set-life-on-fire);
}
/* Reduced-motion fallback for the §27 delight pass.
   Authored under sovereign-design/.../pr/step-43/PR.md.
   Pattern matches the existing reduced-motion blocks at lines ~2027,
   ~3061, ~3517, ~3688, ~5083, ~5370, ~6043, ~6162. */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-a05-rail__session-button {
    transition: background var(--sov-d-base) var(--sov-ease-spring), box-shadow
      var(--sov-d-base) var(--sov-ease-spring), color var(--sov-d-base)
      var(--sov-ease-spring);
  }
  [data-sovereign] .sov-a05-rail__session-button:hover,
  [data-sovereign] .sov-a05-rail__session-button:focus-visible {
    transform: none;
  }
  [data-sovereign] .sov-a05-rail__session-actions {
    transform: none;
    transition: opacity var(--sov-d-base) var(--sov-ease-spring);
  }
  [data-sovereign] .sov-a05-rail__session:hover .sov-a05-rail__session-actions,
  [data-sovereign]
    .sov-a05-rail__session:focus-within
    .sov-a05-rail__session-actions {
    transform: none;
  }
}

/* ─── §50 Folio TOC · self-authored mode 5b ─────────────────────────────
   Sanctioned in sovereign-design/kaOS Design System (self-authored)/
   pr/step-50/PR.md. Target matches the Claude Design Agency folio TOC.
   Mono chapter numbers, natural-case sans titles, hairline separators,
   section headers (FRONT MATTER / BACK MATTER), single global progress
   bar at bottom. All tokens are var(--sov-*) or var(--mk-*). */

/* ── Root container ── */
[data-sovereign] .sov-folio-toc {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sov-space-2) 0 var(--sov-space-3);
}

/* ── Header ── */
[data-sovereign] .sov-folio-toc__header {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-0);
  padding: 0 var(--sov-space-3);
}

[data-sovereign] .sov-folio-toc__summary {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
}

/* ── Empty / loading ── */
[data-sovereign] .sov-folio-toc__empty {
  margin: 0;
  padding: 0 var(--sov-space-3);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
}

/* ── List ── */
[data-sovereign] .sov-folio-toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* ── Section title (FRONT MATTER / BACK MATTER — once per section, not per row) ── */
[data-sovereign] .sov-folio-toc__section-title {
  margin: 0;
  padding: var(--sov-space-3) var(--sov-space-3) var(--sov-space-1);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  letter-spacing: var(--sov-text-caption-tracking, 0.12em);
  text-transform: uppercase;
  color: var(--sov-whisper);
}

/* ── Row ── */
[data-sovereign] .sov-folio-toc__row {
  margin: 0;
  padding: 0;
}

/* ── Button: hairline-separated row, no glass tile ── */
[data-sovereign] .sov-folio-toc__button {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  outline: none;
  display: flex;
  align-items: baseline;
  gap: var(--sov-space-2);
  width: 100%;
  padding: calc(var(--sov-space-2) + var(--sov-space-00)) var(--sov-space-3);
  background: transparent;
  color: var(--sov-subtle);
  box-shadow: 0 1px 0
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  transition: background var(--sov-d-base) var(--sov-ease-spring), box-shadow
    var(--sov-d-base) var(--sov-ease-spring), color var(--sov-d-base)
    var(--sov-ease-spring);
}

/* Hairline at the very top of first row */
[data-sovereign] .sov-folio-toc__row:first-child .sov-folio-toc__button {
  box-shadow: 0 1px 0
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    ), inset 0 1px 0
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
}

/* Hover — full-width gold surface wash, no transform, no tile effect */
[data-sovereign] .sov-folio-toc__button:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  box-shadow: 0 1px 0 var(--mk-glow-gold-hairline), inset 0 1px 0
    var(--mk-glow-gold-hairline);
  color: var(--sov-ink);
}

[data-sovereign] .sov-folio-toc__button:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: -2px;
}

/* Active — gold glow, subtle surface */
[data-sovereign]
  .sov-folio-toc__row[data-active="true"]
  .sov-folio-toc__button {
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, var(--sov-veil));
  box-shadow: 0 1px 0 color-mix(in oklab, var(--mk-glow-gold) 35%, transparent),
    inset 0 1px 0 color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
  color: var(--mk-glow-gold);
}

/* ── Chapter number: monospace, caption-sized, muted ── */
[data-sovereign] .sov-folio-toc__num {
  flex: none;
  font-family: var(--mk-font-mono);
  font-size: var(--sov-text-caption-size);
  font-weight: 400;
  line-height: var(--sov-text-caption-line);
  color: var(--sov-muted);
  min-width: 2.2ch;
  text-align: right;
  transition: color var(--sov-d-base) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-toc__row[data-active="true"] .sov-folio-toc__num {
  color: var(--mk-glow-gold);
}

/* ── Body: title + subtitle column ── */
[data-sovereign] .sov-folio-toc__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* ── Title: caption-sized sans, natural case ── */
[data-sovereign] .sov-folio-toc__title {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  font-weight: 500;
  color: color-mix(in oklab, var(--sov-ink) 82%, transparent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color var(--sov-d-base) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-toc__row[data-active="true"] .sov-folio-toc__title {
  color: var(--mk-glow-gold);
}

/* ── Subtitle ── */
[data-sovereign] .sov-folio-toc__subtitle {
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size) - 1px);
  line-height: var(--sov-text-caption-line);
  font-weight: 400;
  color: var(--sov-whisper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Progress bar (single, at the bottom of the TOC) ── */
[data-sovereign] .sov-folio-toc__progress {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  padding: 0 var(--sov-space-3);
}

[data-sovereign] .sov-folio-toc__progress-label {
  display: flex;
  justify-content: space-between;
  font-family: var(--mk-font-mono);
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-muted);
}

[data-sovereign] .sov-folio-toc__progress-track {
  width: 100%;
  height: 3px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--sov-ink) 6%, transparent);
  overflow: hidden;
}

[data-sovereign] .sov-folio-toc__progress-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--mk-glow-gold-hairline);
  transition: width var(--sov-d-base) var(--sov-ease-smooth);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-folio-toc__button {
    transition: background var(--sov-d-base) var(--sov-ease-spring), box-shadow
      var(--sov-d-base) var(--sov-ease-spring), color var(--sov-d-base)
      var(--sov-ease-spring);
  }
  [data-sovereign] .sov-folio-toc__progress-fill {
    transition: none;
  }
}
/* ── Folio export rail ──
   Sanctioned under Charter Rule 5b. Matches the Reader settings section
   layout (eyebrow + row of stepper buttons) using sanctioned tokens. */

[data-sovereign] .sov-folio-export {
  padding: var(--sov-space-2) var(--sov-space-3) var(--sov-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  /* Gold hairline at top separating from the section above */
  border-top: 1px solid
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  margin-top: var(--sov-space-1);
  padding-top: calc(var(--sov-space-2) + var(--sov-space-1));
}

[data-sovereign] .sov-folio-export__label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-eyebrow-size, 10px);
  font-weight: 600;
  letter-spacing: var(--sov-text-caption-tracking, 0.12em);
  text-transform: uppercase;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-folio-export__buttons {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

[data-sovereign] .sov-folio-export__btn {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 1px solid transparent;
  margin: 0;
  font: inherit;
  cursor: pointer;
  padding: calc(var(--sov-space-1) + 1px) var(--sov-space-2);
  border-radius: var(--sov-radius-pill, 6px);
  background: transparent;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  font-weight: 500;
  color: var(--sov-subtle);
  transition: background var(--sov-d-fast, 200ms) var(--sov-ease-spring), color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring), border-color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

[data-sovereign] .sov-folio-export__btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

[data-sovereign] .sov-folio-export__btn:not(:disabled):hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  border-color: color-mix(in oklab, var(--mk-glow-gold) 24%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-export__btn[data-active="true"] {
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, var(--sov-veil));
  border-color: color-mix(in oklab, var(--mk-glow-gold) 38%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-export__spinner {
  display: inline-block;
  width: 10px;
  height: 10px;
  border: 1.5px solid var(--sov-subtle);
  border-top-color: var(--mk-glow-gold);
  border-radius: 50%;
  animation: sov-export-spin 0.6s linear infinite;
}

@keyframes sov-export-spin {
  to {
    transform: rotate(360deg);
  }
}

[data-sovereign] .sov-folio-export__error {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  line-height: var(--sov-text-caption-line, 1.5);
  color: var(--sov-whisper);
}

[data-sovereign] .sov-folio-export__success {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  line-height: var(--sov-text-caption-line, 1.5);
  color: var(--sov-subtle);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-folio-export__spinner {
    animation: none;
  }
}

/* ── Folio rail — edit, selection, highlights (2026-07-12) ──
   Token-only controls under Book settings. No floating chrome. */

[data-sovereign] .sov-folio-rail-actions {
  padding: var(--sov-space-2) var(--sov-space-3) var(--sov-space-2);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  border-top: 1px solid
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  margin-top: var(--sov-space-1);
  padding-top: calc(var(--sov-space-2) + var(--sov-space-1));
}

[data-sovereign] .sov-folio-rail-actions__button {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 1px solid transparent;
  margin: 0;
  font: inherit;
  cursor: pointer;
  width: 100%;
  padding: calc(var(--sov-space-2) + 1px) var(--sov-space-3);
  border-radius: var(--sov-radius-pill, 6px);
  background: transparent;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size, 12px);
  font-weight: 600;
  letter-spacing: var(--sov-text-caption-tracking, 0.12em);
  text-transform: uppercase;
  color: var(--sov-subtle);
  text-align: center;
  transition: background var(--sov-d-fast, 200ms) var(--sov-ease-spring), color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring), border-color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-rail-actions__button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

[data-sovereign] .sov-folio-rail-actions__button:not(:disabled):hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  border-color: color-mix(in oklab, var(--mk-glow-gold) 24%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-rail-actions__button--quiet {
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: none;
}

[data-sovereign] .sov-folio-rail-selection {
  padding: var(--sov-space-2) var(--sov-space-3) var(--sov-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  border-top: 1px solid
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
}

[data-sovereign] .sov-folio-rail-selection__preview {
  margin: 0;
  font-family: var(--sov-font-serif, var(--sov-font-sans));
  font-size: var(--sov-text-caption-size, 12px);
  line-height: var(--sov-text-caption-line, 1.5);
  color: var(--sov-subtle);
}

[data-sovereign] .sov-folio-rail-selection__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sov-space-1);
}

[data-sovereign] .sov-folio-rail-highlights {
  padding: 0 0 var(--sov-space-2);
  border-top: 1px solid
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  margin-top: var(--sov-space-1);
  padding-top: var(--sov-space-2);
}

[data-sovereign] .sov-folio-spread-canvas-wrap {
  width: 100%;
  height: 100%;
  margin-inline: auto;
}

[data-sovereign] .sov-folio-spread-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: text;
}

[data-sovereign] .sov-folio-inner-article {
  max-width: var(--sov-folio-measure-max, 42rem);
  margin-inline: auto;
  padding-inline: var(--sov-space-4);
  padding-block: var(--sov-space-4) var(--sov-space-8);
}

[data-sovereign] .sov-prompt__chip--folio-context {
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, var(--sov-veil));
  border: 1px solid color-mix(in oklab, var(--mk-glow-gold) 28%, transparent);
  color: var(--sov-ink);
}

[data-sovereign] .sov-prompt__chip--folio-context:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 16%, var(--sov-veil));
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-prompt__intent-pill--folio-edit-together {
  text-transform: uppercase;
  letter-spacing: var(--sov-text-caption-tracking, 0.12em);
  font-weight: 600;
}

[data-sovereign]
  .sov-prompt__intent-pill--active.sov-prompt__intent-pill--folio-edit-together {
  color: var(--mk-glow-gold);
}

/* ── Folio annotator + editor ──
   The highlighting / capture / edit organs of the folio surface
   (2026-07-12). Token-only; matches the export-rail idiom. */

[data-sovereign] mark.sov-folio-highlight {
  background: color-mix(in oklab, var(--mk-glow-gold) 22%, transparent);
  color: inherit;
  border-bottom: 1px solid
    color-mix(in oklab, var(--mk-glow-gold) 55%, transparent);
  border-radius: 2px;
  padding: 0 1px;
  cursor: pointer;
  transition: background var(--sov-d-fast, 200ms) var(--sov-ease-spring);
}

[data-sovereign] mark.sov-folio-highlight:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 34%, transparent);
}

[data-sovereign] .sov-folio-annotator-popover {
  position: fixed;
  transform: translate(-50%, calc(-100% - var(--sov-space-2)));
  z-index: 120;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: var(--sov-space-1);
  border-radius: var(--sov-radius-pill, 999px);
  background: var(--sov-glass-mix, var(--sov-surface-2));
  -webkit-backdrop-filter: blur(var(--sov-glass-blur, 20px));
  backdrop-filter: blur(var(--sov-glass-blur, 20px));
  border: 1px solid
    color-mix(in oklab, var(--mk-glow-gold) 24%, transparent);
  box-shadow: var(--sov-shadow-2, 0 8px 24px rgba(0, 0, 0, 0.35));
}

[data-sovereign] .sov-folio-annotator-btn {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 1px solid transparent;
  margin: 0;
  cursor: pointer;
  padding: calc(var(--sov-space-1) + 1px) var(--sov-space-2);
  border-radius: var(--sov-radius-pill, 6px);
  background: transparent;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  font-weight: 500;
  color: var(--sov-subtle);
  white-space: nowrap;
  transition: background var(--sov-d-fast, 200ms) var(--sov-ease-spring), color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-annotator-btn:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-annotator-btn--danger:hover {
  background: color-mix(in oklab, var(--sov-danger, #c0564e) 12%, transparent);
  color: var(--sov-danger, #c0564e);
}

[data-sovereign] .sov-folio-annotator-captures {
  position: fixed;
  bottom: calc(5rem + 3.25rem);
  right: 2rem;
  z-index: 100;
  padding: var(--sov-space-1) var(--sov-space-3);
  border-radius: var(--sov-radius-pill, 999px);
  background: var(--sov-glass-mix, var(--sov-surface-2));
  -webkit-backdrop-filter: blur(var(--sov-glass-blur, 20px));
  backdrop-filter: blur(var(--sov-glass-blur, 20px));
  border: 1px solid
    color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-edit-toggle {
  position: fixed;
  bottom: 5rem;
  right: calc(2rem + 11.5rem);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) var(--sov-space-4);
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid var(--sov-hairline, color-mix(in oklab, var(--sov-ink) 14%, transparent));
  background: var(--sov-surface-2, rgba(255, 255, 255, 0.06));
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  color: var(--sov-text);
  font-family: var(--sov-font-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color var(--sov-d-fast, 200ms) var(--sov-ease-spring),
    color var(--sov-d-fast, 200ms) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-edit-toggle:hover {
  border-color: color-mix(in oklab, var(--mk-glow-gold) 45%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-editor {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  min-height: 60vh;
}

[data-sovereign] .sov-folio-editor-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sov-space-2);
  flex-wrap: wrap;
}

[data-sovereign] .sov-folio-editor-label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-eyebrow-size, 10px);
  font-weight: 600;
  letter-spacing: var(--sov-text-caption-tracking, 0.12em);
  text-transform: uppercase;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-folio-editor-actions {
  display: flex;
  gap: var(--sov-space-1);
}

[data-sovereign] .sov-folio-editor-btn {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 1px solid transparent;
  margin: 0;
  cursor: pointer;
  padding: calc(var(--sov-space-1) + 1px) var(--sov-space-3);
  border-radius: var(--sov-radius-pill, 6px);
  background: transparent;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  font-weight: 500;
  color: var(--sov-subtle);
  transition: background var(--sov-d-fast, 200ms) var(--sov-ease-spring), color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring), border-color
    var(--sov-d-fast, 200ms) var(--sov-ease-spring);
}

[data-sovereign] .sov-folio-editor-btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

[data-sovereign] .sov-folio-editor-btn:not(:disabled):hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
  border-color: color-mix(in oklab, var(--mk-glow-gold) 24%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-editor-btn--primary {
  border-color: color-mix(in oklab, var(--mk-glow-gold) 38%, transparent);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-folio-editor-textarea {
  width: 100%;
  min-height: 60vh;
  resize: vertical;
  box-sizing: border-box;
  padding: var(--sov-space-3);
  border-radius: var(--sov-radius-2, 10px);
  border: 1px solid
    var(
      --sov-hairline-quiet,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
  background: color-mix(in oklab, var(--sov-veil, transparent) 60%, transparent);
  color: var(--sov-text);
  font-family: var(--sov-font-mono, ui-monospace, monospace);
  font-size: calc(var(--sov-text-caption-size, 12px) + 1px);
  line-height: 1.7;
}

[data-sovereign] .sov-folio-editor-textarea:focus-visible {
  outline: none;
  border-color: color-mix(in oklab, var(--mk-glow-gold) 38%, transparent);
}

[data-sovereign] .sov-folio-editor-status {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: calc(var(--sov-text-caption-size, 12px) - 1px);
  line-height: var(--sov-text-caption-line, 1.5);
  color: var(--sov-whisper);
}

/* Spread mode swaps the whole canvas grid for the editor — give it a
   readable measure and breathing room inside the spread frame. */
[data-sovereign] .sov-folio-editor-spread-wrap {
  display: block;
  overflow-y: auto;
  padding: var(--sov-space-4);
}

[data-sovereign] .sov-folio-editor-spread-wrap .sov-folio-editor {
  max-width: calc(var(--sov-folio-measure-max, 40rem) * 2);
  margin: 0 auto;
}

/* ---------- §17 Sovereign activity stream · self-authored mode 5b ----------
   Sanctioned in sovereign-design/kaOS Design System (self-authored)/
   pr/step-17/PR.md §2-§3.

   Three primitives styled here:
     .sov-rail-mode-toggle      — top toggle (sessions ↔ activity)
     .sov-activity-stream       — container + per-kind sections
     .sov-activity-item         — single line in the stream

   Token-only. No hardcoded color/radius/shadow/font/motion that isn't a
   var(--sov-*) or var(--mk-glow-*). All motion has a reduced-motion
   branch. */

/* §17.3 — rail mode toggle (chip pair) */
[data-sovereign] .sov-rail-mode-toggle {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sov-rail-toggle-gap);
  padding: var(--sov-space-1);
  width: 100%;
  box-sizing: border-box;
  min-height: var(--sov-search-pill-h);
  background: var(--sov-glass-mix);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur));
  backdrop-filter: blur(var(--sov-glass-blur));
  border-radius: var(--sov-radius-pill);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  font-family: inherit;
}
[data-sovereign] .sov-rail-mode-toggle__chip {
  flex: 1 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  border: 0;
  box-sizing: border-box;
  height: var(--sov-rail-toggle-h);
  padding-block: 0;
  padding-inline: var(--sov-rail-toggle-pad-x);
  border-radius: var(--sov-radius-pill);
  color: var(--sov-subtle);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-toggle-font-size);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--sov-rail-toggle-tracking);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--sov-d-base) var(--sov-ease-spring), background
    var(--sov-d-base) var(--sov-ease-spring), box-shadow var(--sov-d-base)
    var(--sov-ease-spring);
}
[data-sovereign] .sov-rail-mode-toggle__chip[aria-selected="true"] {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
}
[data-sovereign] .sov-rail-mode-toggle__chip:hover:not([aria-selected="true"]) {
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
[data-sovereign] .sov-rail-mode-toggle__chip:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
}

/* §17.4 — constellation lens chips.
   Multi-select pill row for the relationship lenses (Alongside / Named /
   Echoes / Read together). Same pill recipe the chat-room chips and the
   rail mode toggle use — veil rest state, gold 12% mix when pressed,
   --sov-radius-pill geometry — expressed as its own class because these
   are independent toggles (aria-pressed), not a segmented pair.
   Rendered in two places off one lens state: the right-rail constellation
   panel and the in-canvas bottom-right row. (Mirrored in
   styles/systems/rail.css; this file is the loaded stylesheet.) */
[data-sovereign] .sov-constellation-lenses {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sov-space-1) var(--sov-space-2);
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}
[data-sovereign] .sov-constellation-lenses__chip {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-1);
  height: var(--sov-chat-room-chip-h);
  padding: var(--sov-chat-room-chip-pad);
  border: 0;
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--sov-veil) 78%, transparent);
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 600;
  letter-spacing: var(--sov-rail-toggle-tracking);
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition:
    color var(--sov-d-base) var(--sov-ease-expo),
    background var(--sov-d-base) var(--sov-ease-expo),
    box-shadow var(--sov-d-base) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-lenses__chip:hover {
  color: var(--sov-subtle);
  background: var(--sov-surface-raised);
}
[data-sovereign] .sov-constellation-lenses__chip[aria-pressed="true"] {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
}
[data-sovereign] .sov-constellation-lenses__chip:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
}
/* A lens with nothing to show — still pressable (state is honest either
   way) but visually quiet so the eye reads where the field actually is. */
[data-sovereign] .sov-constellation-lenses__chip[data-empty="true"] {
  opacity: 0.45;
}
/* Count suffix inside a chip — quieter than the label. */
[data-sovereign] .sov-constellation-lenses__count {
  opacity: 0.72;
  font-weight: 500;
}

/* ── Constellation right-rail inspector ─────────────────────────────────
 * Vertical rhythm: chapter gap between sections (--sov-activity-section-gap),
 * tight gaps inside each section. Kind chips (find works) and lens chips
 * (show connections) are deliberately different recipes so two jobs never
 * read as one filter row. Stats under the title use charted spark tokens. */
[data-sovereign] .sov-constellation-rail {
  gap: var(--sov-activity-section-gap);
}
[data-sovereign] .sov-constellation-rail__header {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__title {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-whisper);
  line-height: 1.2;
}
[data-sovereign] .sov-constellation-rail__stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: var(--sov-space-2);
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__stat {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
  padding: var(--sov-space-2) var(--sov-space-3);
  border-radius: var(--sov-radius-tile);
  background: color-mix(in oklab, var(--sov-veil) 55%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 8%, transparent);
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__stat[data-trace="anchor"] {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-spark-line-anchor) 18%, transparent);
}
[data-sovereign] .sov-constellation-rail__stat[data-trace="live"] {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-spark-line-live) 18%, transparent);
}
[data-sovereign] .sov-constellation-rail__stat-value {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-tile-title-size, 15px);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--sov-fg-baseline);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
[data-sovereign] .sov-constellation-rail__stat[data-trace="anchor"]
  .sov-constellation-rail__stat-value {
  color: var(--sov-spark-line-anchor);
}
[data-sovereign] .sov-constellation-rail__stat[data-trace="live"]
  .sov-constellation-rail__stat-value {
  color: var(--sov-spark-line-live);
}
[data-sovereign] .sov-constellation-rail__stat-label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--sov-whisper);
  line-height: 1.2;
}
[data-sovereign] .sov-constellation-rail__section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__section-head {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
}
[data-sovereign] .sov-constellation-rail__section-label {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-subtle);
  line-height: 1.2;
}
[data-sovereign] .sov-constellation-rail__section-hint {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--sov-whisper);
  line-height: 1.35;
  text-wrap: pretty;
}
[data-sovereign] .sov-constellation-rail__section-body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__search {
  width: 100%;
  box-sizing: border-box;
  background: color-mix(in oklab, var(--sov-fg-baseline) 5%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 12%, transparent);
  border-radius: var(--sov-radius-tile);
  padding: var(--sov-space-2) var(--sov-space-3);
  color: var(--sov-fg-baseline);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size, 13px);
  line-height: 1.3;
  outline: none;
  transition:
    border-color var(--sov-d-base) var(--sov-ease-expo),
    background var(--sov-d-base) var(--sov-ease-expo),
    box-shadow var(--sov-d-base) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-rail__search::placeholder {
  color: var(--sov-whisper);
  opacity: 1;
}
[data-sovereign] .sov-constellation-rail__search:hover {
  border-color: color-mix(in oklab, var(--sov-fg-baseline) 20%, transparent);
}
[data-sovereign] .sov-constellation-rail__search:focus-visible {
  border-color: var(--mk-hairline-gold);
  box-shadow: 0 0 0 2px var(--mk-glow-gold-halo);
}
[data-sovereign] .sov-constellation-rail__reset {
  align-self: flex-start;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--sov-subtle);
  transition: color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-rail__reset:hover {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-constellation-rail__reading-body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  padding: var(--sov-space-3);
  border-radius: var(--sov-radius-tile);
  background: color-mix(in oklab, var(--sov-veil) 42%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 8%, transparent);
  min-height: calc(var(--sov-space-8, 48px) + var(--sov-space-4));
}
[data-sovereign] .sov-constellation-rail__empty {
  margin: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 400;
  color: var(--sov-whisper);
  line-height: 1.45;
  text-wrap: pretty;
}

/* Kind filters — quieter single-select chips (not the gold lens recipe). */
[data-sovereign] .sov-constellation-kinds {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sov-space-1) var(--sov-space-2);
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}
[data-sovereign] .sov-constellation-kinds__chip {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-1);
  height: var(--sov-chat-room-chip-h);
  padding: var(--sov-chat-room-chip-pad);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 12%, transparent);
  border-radius: var(--sov-radius-pill);
  background: transparent;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 600;
  letter-spacing: var(--sov-rail-toggle-tracking);
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition:
    color var(--sov-d-base) var(--sov-ease-expo),
    background var(--sov-d-base) var(--sov-ease-expo),
    border-color var(--sov-d-base) var(--sov-ease-expo),
    transform var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-kinds__chip:hover {
  color: var(--sov-subtle);
  background: color-mix(in oklab, var(--sov-fg-baseline) 6%, transparent);
  border-color: color-mix(in oklab, var(--sov-fg-baseline) 20%, transparent);
}
[data-sovereign] .sov-constellation-kinds__chip[aria-pressed="true"] {
  color: var(--sov-fg-baseline);
  background: color-mix(in oklab, var(--sov-fg-baseline) 10%, transparent);
  border-color: color-mix(in oklab, var(--sov-fg-baseline) 28%, transparent);
}
[data-sovereign] .sov-constellation-kinds__chip:active {
  transform: translateY(1px);
}
[data-sovereign] .sov-constellation-kinds__chip:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
}
[data-sovereign] .sov-constellation-kinds__count {
  opacity: 0.65;
  font-weight: 500;
}

/* Lens chips — light press delight (state feedback, not decoration). */
[data-sovereign] .sov-constellation-lenses__chip:active {
  transform: translateY(1px);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-constellation-kinds__chip,
  [data-sovereign] .sov-constellation-lenses__chip {
    transition: none;
  }
  [data-sovereign] .sov-constellation-kinds__chip:active,
  [data-sovereign] .sov-constellation-lenses__chip:active {
    transform: none;
  }
}

/* Constellation rail — selection & detail blocks.
 * Vertical rhythm: section-body gap inside, hairline divider before each
 * click-down disclosure so the eye reads title → action row → context →
 * deeper list as one thought, not four. */
[data-sovereign] .sov-constellation-rail__selection {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__row {
  display: flex;
  gap: var(--sov-space-3);
  align-items: flex-start;
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__row--cover-only {
  flex-direction: column;
  gap: var(--sov-space-1);
  flex-shrink: 0;
}
[data-sovereign] .sov-constellation-rail__copy {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  min-width: 0;
  flex: 1 1 auto;
}
[data-sovereign] .sov-constellation-rail__cover {
  border-radius: var(--sov-radius-tile);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--sov-fg-baseline) 6%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 12%, transparent);
  overflow: hidden;
}
[data-sovereign] .sov-constellation-rail__cover--with-image {
  background: transparent;
  border: 0;
}
[data-sovereign] .sov-constellation-rail__cover-glyph {
  font-family: var(--sov-font-sans);
  line-height: 1;
}
[data-sovereign] .sov-constellation-rail__title-row {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sov-space-1) var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__action {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  background: color-mix(in oklab, var(--sov-fg-baseline) 6%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-fg-baseline) 14%, transparent);
  border-radius: var(--sov-radius-pill, 999px);
  padding: var(--sov-space-00) var(--sov-space-2);
  cursor: pointer;
  font-family: inherit;
  color: var(--sov-fg-baseline);
  line-height: 1.2;
  transition:
    background var(--sov-d-fast) var(--sov-ease-expo),
    border-color var(--sov-d-fast) var(--sov-ease-expo),
    color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-rail__action:hover {
  background: color-mix(in oklab, var(--sov-fg-baseline) 10%, transparent);
  border-color: color-mix(in oklab, var(--sov-fg-baseline) 22%, transparent);
}
[data-sovereign] .sov-constellation-rail__action[aria-pressed="true"] {
  color: var(--mk-glow-gold);
  border-color: color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, transparent);
}
[data-sovereign] .sov-constellation-rail__action:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
}
[data-sovereign] .sov-constellation-rail__action:active {
  transform: translateY(1px);
}
[data-sovereign] .sov-constellation-rail__disclosure {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  border-top: 1px solid
    color-mix(in oklab, var(--sov-fg-baseline) 10%, transparent);
  padding-top: var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__disclosure-trigger {
  display: flex;
  align-items: center;
  gap: var(--sov-space-1);
  width: 100%;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--sov-subtle);
  text-align: left;
  line-height: 1.3;
  transition: color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-rail__disclosure-trigger:hover {
  color: var(--sov-fg-baseline);
}
[data-sovereign] .sov-constellation-rail__disclosure-trigger:focus-visible {
  outline: 2px solid var(--mk-glow-gold-halo);
  outline-offset: 2px;
  border-radius: var(--sov-radius-tile);
}
[data-sovereign] .sov-constellation-rail__disclosure-chevron {
  margin-left: auto;
  flex-shrink: 0;
  opacity: 0.7;
  transition: transform var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-constellation-rail__disclosure[data-open="true"]
  .sov-constellation-rail__disclosure-chevron {
  transform: rotate(180deg);
  opacity: 1;
}
[data-sovereign] .sov-constellation-rail__neighbours {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-constellation-rail__neighbour {
  display: flex;
  gap: var(--sov-space-2);
  align-items: flex-start;
  min-width: 0;
}
[data-sovereign] .sov-constellation-rail__neighbour-copy {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
  min-width: 0;
  flex: 1 1 auto;
}
[data-sovereign] .sov-constellation-rail__edge-list {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
}
[data-sovereign] .sov-constellation-rail__metadata {
  margin: 0;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 400;
  line-height: 1.4;
  text-wrap: pretty;
}
[data-sovereign] .sov-constellation-rail__subjects {
  margin: 0;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 400;
  line-height: 1.4;
  text-wrap: pretty;
  letter-spacing: 0.01em;
}
[data-sovereign] .sov-constellation-rail__stat-row {
  display: flex;
  align-items: baseline;
  gap: var(--sov-space-1);
  flex-wrap: wrap;
}
[data-sovereign] .sov-constellation-rail__stat-num {
  font-family: var(--sov-font-sans);
  font-weight: 600;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--sov-spark-line-anchor);
}
[data-sovereign] .sov-constellation-rail__stat-num[data-trace="live"] {
  color: var(--sov-spark-line-live);
}
[data-sovereign] .sov-constellation-rail__stat-word {
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-chip-size);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: lowercase;
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-constellation-rail__action,
  [data-sovereign] .sov-constellation-rail__disclosure-chevron,
  [data-sovereign] .sov-constellation-rail__disclosure-trigger {
    transition: none;
  }
  [data-sovereign] .sov-constellation-rail__action:active {
    transform: none;
  }
}

/* §17.3 — unified right-rail mode panel wrapper.
   One wrapper per mode pane (Sessions / Activity / Toolkit).
   Owns gap between its direct children; no child sets its own
   inter-sibling gap. Token: --sov-space-3 (12px). */
[data-sovereign] .sov-rail-panel {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  /* Vertical only. Horizontal rail padding is owned exclusively by
     .sov-shell__rail-body (canonical single source — see comment at
     the .sov-shell__rail-body rule). The panel inherits that inset
     from its parent and never adds its own L/R, so children align
     with siblings of the panel (mode toggle, + New Session button). */
  padding: var(--sov-space-2) 0 var(--sov-space-3);
  box-sizing: border-box;
  /* Panels claim the rail-body slot they're placed in. The flex:1 +
     min-height:0 chain lets a child list (e.g. .sov-a05-rail__sessions)
     constrain to the panel's height and own its own scroll viewport
     without leaking to the rail body or the page. Authored under
     sovereign-design/.../pr/step-43/PR.md addendum 5. */
  flex: 1 1 auto;
  min-height: 0;
}
/* Projects rail panel inherits the canonical zero-L/R padding from
   .sov-rail-panel above; the rail-body's own padding-inline supplies
   the entire horizontal inset, same as sessions, activity, and every
   other rail panel. (The earlier projects-only padding-left override
   was removed 2026-05-16 — drift against the canonical system.) */

/* §17.3 — activity stream container + per-kind section */
[data-sovereign] .sov-activity-stream {
  display: flex;
  flex-direction: column;
  gap: var(--sov-activity-section-gap);
}
[data-sovereign] .sov-activity-section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-activity-item-gap);
}
[data-sovereign] .sov-activity-section__items {
  display: flex;
  flex-direction: column;
  gap: var(--sov-activity-item-gap);
  max-height: 480px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
[data-sovereign] .sov-activity-section__head {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
  margin: 0;
  padding-bottom: var(--sov-space-2);
  font-size: var(--sov-text-eyebrow-size);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-activity-section__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--sov-radius-pill);
  background: var(--sov-activity-kind, var(--sov-whisper));
  box-shadow: 0 0 8px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 40%,
      transparent
    );
  opacity: 0.55;
}
[data-sovereign]
  .sov-activity-section[data-active="true"]
  .sov-activity-section__dot {
  opacity: 1;
  animation: sov-activity-section-breathe var(--sov-breath) ease-in-out infinite;
}
[data-sovereign] .sov-activity-section__name {
  color: var(--sov-activity-kind, var(--sov-whisper));
  opacity: 0.95;
}
[data-sovereign] .sov-activity-section__count {
  color: var(--sov-whisper);
  font-weight: 500;
  letter-spacing: 0.12em;
}

/* §17.2b — action slot (e.g. thinking toggle) trailing the count */
[data-sovereign] .sov-activity-section__action {
  margin-left: auto;
  display: flex;
  align-items: center;
}

/* Thinking toggle pill */
[data-sovereign] .sov-think-toggle {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sov-space-2);
  height: calc(var(--sov-space-3) + 2px);
  border-radius: 999px;
  font-family: var(--sov-typography-font-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 35%,
      transparent
    );
  background: transparent;
  color: color-mix(
    in oklab,
    var(--sov-activity-kind, var(--sov-whisper)) 55%,
    transparent
  );
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}

[data-sovereign] .sov-think-toggle--on {
  background: color-mix(
    in oklab,
    var(--sov-activity-kind, var(--sov-whisper)) 12%,
    transparent
  );
  color: var(--sov-activity-kind, var(--sov-whisper));
  border-color: color-mix(
    in oklab,
    var(--sov-activity-kind, var(--sov-whisper)) 55%,
    transparent
  );
}

[data-sovereign] .sov-think-toggle:hover {
  background: color-mix(
    in oklab,
    var(--sov-activity-kind, var(--sov-whisper)) 18%,
    transparent
  );
  color: var(--sov-activity-kind, var(--sov-whisper));
  border-color: color-mix(
    in oklab,
    var(--sov-activity-kind, var(--sov-whisper)) 70%,
    transparent
  );
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-think-toggle {
    transition: none;
  }
}

/* Coder ship button — sibling chip to .sov-think-toggle, tuned for the
 * coder cycle row. Idle reads as a quiet positive affordance; pending
 * dims and disables; success collapses to a calm "shipped" mark;
 * error opens an amber tint with a "retry" label. Authored under
 * Charter Rule 5b for neuromorphic-autonomy-redesign §B4. */
[data-sovereign] .sov-coder-ship-btn {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sov-space-3);
  height: calc(var(--sov-space-3) + 4px);
  border-radius: 999px;
  font-family: var(--sov-typography-font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid color-mix(in oklab, var(--sov-whisper) 45%, transparent);
  background: color-mix(in oklab, var(--sov-whisper) 12%, transparent);
  color: var(--sov-whisper);
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}

[data-sovereign] .sov-coder-ship-btn:hover:not(:disabled) {
  background: color-mix(in oklab, var(--sov-whisper) 22%, transparent);
  border-color: color-mix(in oklab, var(--sov-whisper) 70%, transparent);
}

[data-sovereign] .sov-coder-ship-btn:disabled {
  cursor: not-allowed;
}

[data-sovereign] .sov-coder-ship-btn--pending {
  opacity: 0.7;
  color: var(--sov-subtle);
  border-color: color-mix(in oklab, var(--sov-subtle) 35%, transparent);
  background: transparent;
}

[data-sovereign] .sov-coder-ship-btn--success {
  background: transparent;
  border-color: color-mix(in oklab, var(--sov-subtle) 25%, transparent);
  color: var(--sov-subtle);
}

[data-sovereign] .sov-coder-ship-btn--error {
  background: color-mix(
    in oklab,
    var(--sov-attention, #c98a30) 15%,
    transparent
  );
  border-color: color-mix(
    in oklab,
    var(--sov-attention, #c98a30) 55%,
    transparent
  );
  color: var(--sov-attention, #c98a30);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-coder-ship-btn {
    transition: none;
  }
}

/* §17.3 — activity item (single line tile) */
[data-sovereign] .sov-activity-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  grid-gap: var(--sov-space-2);
  gap: var(--sov-space-2);
  padding: var(--sov-activity-item-pad-y) var(--sov-activity-item-pad-x);
  border-radius: var(--sov-activity-item-radius);
  background: color-mix(in oklab, var(--sov-veil) 35%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
  font-size: var(--sov-text-chip-size);
  line-height: var(--sov-text-tile-line);
  color: var(--sov-subtle);
  text-decoration: none;
  transition: box-shadow var(--sov-activity-glow-fade-ms) var(--sov-ease-spring),
    color var(--sov-activity-glow-fade-ms) var(--sov-ease-spring), opacity
    var(--sov-activity-glow-fade-ms) var(--sov-ease-spring);
}
[data-sovereign] .sov-activity-item--link {
  cursor: pointer;
}
[data-sovereign] .sov-activity-item--link:hover {
  box-shadow: inset 0 0 0 1px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 28%,
      transparent
    ), 0 0 14px -6px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 35%,
      transparent
    );
  color: var(--sov-color-ink);
}
[data-sovereign] .sov-activity-item[data-state="starting"],
[data-sovereign] .sov-activity-item[data-state="running"] {
  box-shadow: inset 0 0 0 1px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 30%,
      transparent
    ), 0 0 24px -8px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 60%,
      transparent
    );
}
[data-sovereign] .sov-activity-item[data-state="queued"] {
  box-shadow: inset 0 0 0 1px
    color-mix(
      in oklab,
      var(--sov-activity-kind, var(--sov-whisper)) 18%,
      transparent
    );
}
[data-sovereign] .sov-activity-item[data-state="done"] {
  opacity: 0.85;
}
[data-sovereign] .sov-activity-item[data-state="stale"] {
  color: var(--sov-whisper);
  opacity: 0.7;
}
[data-sovereign] .sov-activity-item__pip {
  width: 5px;
  height: 5px;
  border-radius: var(--sov-radius-pill);
  background: var(--sov-activity-kind, var(--sov-whisper));
}
[data-sovereign]
  .sov-activity-item[data-state="starting"]
  .sov-activity-item__pip,
[data-sovereign]
  .sov-activity-item[data-state="running"]
  .sov-activity-item__pip {
  animation: sov-activity-thinking-dot 1.2s ease-in-out infinite;
}
[data-sovereign] .sov-activity-item__detail {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
[data-sovereign] .sov-activity-item__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
[data-sovereign] .sov-activity-item__subtitle {
  font-size: 10px;
  color: var(--sov-whisper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.7;
}
[data-sovereign] .sov-activity-item__badge {
  font-size: 9px;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  margin-left: 3px;
}
[data-sovereign] .sov-activity-item__badge--ok {
  color: var(--mk-glow-as-kingfishers-catch-fire);
}
[data-sovereign] .sov-activity-item__badge--fail {
  color: var(--mk-glow-set-life-on-fire);
}
[data-sovereign] .sov-activity-item__badge--timeout {
  color: var(--sov-whisper);
}
[data-sovereign] .sov-activity-item__elapsed {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  color: var(--sov-whisper);
  letter-spacing: 0.04em;
}

@keyframes sov-activity-section-breathe {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.55;
  }
}
@keyframes sov-activity-thinking-dot {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-rail-mode-toggle__chip,
  [data-sovereign] .sov-activity-item {
    transition: none !important;
  }
  [data-sovereign]
    .sov-activity-section[data-active="true"]
    .sov-activity-section__dot,
  [data-sovereign]
    .sov-activity-item[data-state="starting"]
    .sov-activity-item__pip,
  [data-sovereign]
    .sov-activity-item[data-state="running"]
    .sov-activity-item__pip {
    animation: none !important;
    opacity: 1;
  }
}

/* ---------- §reminder-row — Malaika's reminder chips ----------
   Authored: sovereign-design/kaOS Design System (self-authored)/pr/step-38/PR.md §1.
   Sanctioned under Charter Rule 5b (Sovereign Design Authority).
   Horizontal row of glass chips with gold accent pips — a soft surface
   for Malaika to leave items to review, attend to, or be asked about.
   Tokens: glass mix + blur from step-09 §4, gold from step-01 palette,
   spacing and radius from sanctioned scale, motion from step-09 §6.
*/

[data-sovereign] .sov-reminder-row {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-reminder-row__preface {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-section-weight);
  color: var(--sov-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

[data-sovereign] .sov-reminder-row__description {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-field-size);
  font-weight: var(--sov-text-field-weight);
  line-height: var(--sov-text-field-line);
  color: var(--sov-subtle);
  margin: 0;
}

[data-sovereign] .sov-reminder-row__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sov-space-2);
  align-items: center;
}

/* Each chip — soft glass, gold pip, quiet label. */
[data-sovereign] .sov-reminder-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) var(--sov-space-3);
  border-radius: var(--sov-radius-pill);
  border: 1px solid var(--mk-hairline-gold);
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur)) saturate(180%);
  transition: border-color var(--sov-hush) var(--sov-ease), background
    var(--sov-hush) var(--sov-ease);
  cursor: default;
  font-family: var(--sov-font-sans);
}

[data-sovereign] .sov-reminder-chip--link {
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

[data-sovereign] .sov-reminder-chip--link:hover {
  border-color: var(--mk-glow-gold);
  background: color-mix(
    in oklab,
    var(--sov-bg) var(--sov-glass-mix-strong),
    transparent
  );
}

/* Gold accent pip — a 3px circle on the left, using the ambient-breathe
   keyframe so it has a subtle living quality. */
[data-sovereign] .sov-reminder-chip__pip {
  display: block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  flex-shrink: 0;
}

[data-sovereign] .sov-reminder-chip__label {
  font-size: var(--sov-text-caption-size);
  font-weight: var(--sov-text-tile-weight);
  color: var(--sov-ink);
  white-space: nowrap;
  line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-reminder-chip {
    transition: none !important;
  }
}

/* ---------- §code-rail — FILES tree + terminal split ----------
   Rendered inside sov-a05-rail__content when mode === 'files'.
   All spacing uses the same tokens as the activity stream so the three
   rail tabs feel like one coherent surface.
*/

[data-sovereign] .sov-rail-code {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

[data-sovereign] .sov-rail-code__tree {
  overflow: auto;
  overscroll-behavior: contain;
}

[data-sovereign] .sov-rail-code__file-list {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--sov-space-3);
}

[data-sovereign] .sov-rail-code__file-item {
  display: flex;
  align-items: center;
  gap: var(--sov-space-1);
  width: 100%;
  padding: var(--sov-activity-item-pad-y) var(--sov-activity-item-pad-x);
  border: none;
  background: transparent;
  color: var(--sov-subtle);
  font-size: 11px;
  font-family: var(--sov-font-mono);
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  border-radius: var(--sov-activity-item-radius);
  transition: color 120ms ease, background 120ms ease;
}

[data-sovereign] .sov-rail-code__file-item:hover {
  color: var(--sov-ink);
  background: color-mix(in oklab, var(--sov-veil) 40%, transparent);
}

[data-sovereign] .sov-rail-code__file-item[data-active="true"] {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}

/* Folder arrow / file dot glyph */
[data-sovereign] .sov-rail-code__glyph {
  flex-shrink: 0;
  width: 10px;
  font-size: 9px;
  text-align: center;
  opacity: 0.4;
  font-family: inherit;
}

/* Drag-to-resize hairline between tree and terminal */
[data-sovereign] .sov-rail-code__divider {
  height: 1px;
  flex-shrink: 0;
  background: color-mix(in oklab, var(--sov-ink) 10%, transparent);
  cursor: row-resize;
  touch-action: none;
  transition: background 120ms ease;
}

[data-sovereign] .sov-rail-code__divider:hover {
  background: color-mix(in oklab, var(--mk-hairline-gold) 60%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-rail-code__file-item,
  [data-sovereign] .sov-rail-code__divider {
    transition: none;
  }
}

/* ---------- §voice · Visual breadcrumbs rail ----------
   Mounted alongside the presence surface (chat/voice/page.tsx). When
   the chat session has emitted any structured pretext descriptors
   (mermaid, table, code, citation, callout, patch, raw_html), this
   rail surfaces them so the family can glance at the diagram while
   still in voice mode. Collapsed default → thin gold pip; expanded →
   right-edge tray (~360px). Token-discipline only — no literal hex /
   px / rgba allowed below this header.

   Sanctioned 2026-04-26 under Charter Rule 5b. */

[data-sovereign] .sov-voice-visual-rail__pip {
  position: fixed;
  top: 50%;
  right: clamp(10px, 2vw, 20px);
  transform: translateY(-50%);
  z-index: 10001;
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-2, 6px);
  padding: 6px 10px 6px 8px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--mk-bg) 70%, transparent);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 18%, transparent);
  color: var(--mk-fg);
  cursor: pointer;
  opacity: 0.55;
  pointer-events: auto;
  transition: opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-voice-visual-rail__pip:hover,
[data-sovereign] .sov-voice-visual-rail__pip:focus-visible {
  opacity: 1;
  border-color: color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
  outline: none;
}
[data-sovereign] .sov-voice-visual-rail__pip-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--sov-radius-pill);
  background: var(--mk-glow-gold);
  box-shadow: 0 0 12px color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
}
[data-sovereign] .sov-voice-visual-rail__pip-count {
  color: var(--mk-fg);
  font-size: 11px;
  letter-spacing: 0.06em;
}
@keyframes sov-voice-visual-flash {
  0% {
    box-shadow: 0 0 0 0
      color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
  }
  60% {
    box-shadow: 0 0 0 10px
      color-mix(in oklab, var(--mk-glow-gold) 0%, transparent);
  }
  100% {
    box-shadow: 0 0 0 0 color-mix(in oklab, var(--mk-glow-gold) 0%, transparent);
  }
}
[data-sovereign] .sov-voice-visual-rail__pip[data-flash]:not([data-flash="0"]) {
  animation: sov-voice-visual-flash 1.4s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) 1;
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign]
    .sov-voice-visual-rail__pip[data-flash]:not([data-flash="0"]) {
    animation: none;
  }
}

[data-sovereign] .sov-voice-visual-rail {
  position: fixed;
  top: clamp(56px, 8vh, 96px);
  bottom: clamp(112px, 16vh, 200px);
  right: clamp(12px, 2vw, 24px);
  width: min(360px, 92vw);
  z-index: 10001;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3, 12px);
  padding: var(--sov-space-4, 16px);
  border-radius: var(--sov-adapter-radius, 14px);
  background: color-mix(in oklab, var(--mk-bg) 78%, transparent);
  -webkit-backdrop-filter: blur(var(--sov-glass-blur, 18px));
  backdrop-filter: blur(var(--sov-glass-blur, 18px));
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold), 0 12px 36px
    color-mix(in oklab, var(--mk-bg) 50%, transparent);
  pointer-events: auto;
  overflow: hidden;
}
[data-sovereign] .sov-voice-visual-rail__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sov-space-2, 6px);
  flex: 0 0 auto;
}
[data-sovereign] .sov-voice-visual-rail__title {
  margin: 0;
  color: var(--sov-whisper);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
[data-sovereign] .sov-voice-visual-rail__close {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  border: 0;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--sov-subtle);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--sov-radius-pill);
  transition: color 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-voice-visual-rail__close:hover,
[data-sovereign] .sov-voice-visual-rail__close:focus-visible {
  color: var(--mk-fg);
  background: color-mix(in oklab, var(--sov-veil) 50%, transparent);
  outline: none;
}
[data-sovereign] .sov-voice-visual-rail__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3, 12px);
  overflow-y: auto;
  flex: 1 1 auto;
}
[data-sovereign] .sov-voice-visual-rail__item {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 6px);
  padding: var(--sov-space-3, 12px);
  border-radius: var(--sov-adapter-radius-tight, 10px);
  background: color-mix(in oklab, var(--sov-color-bg) 92%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    var(
      --sov-adapter-hairline,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
}
[data-sovereign] .sov-voice-visual-rail__kind {
  margin: 0;
  color: var(--sov-whisper);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
[data-sovereign] .sov-voice-visual-rail__frame {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 6px);
}
[data-sovereign] .sov-voice-visual-rail__frame .sov-adapter-mermaid,
[data-sovereign] .sov-voice-visual-rail__frame .sov-code-artifact,
[data-sovereign] .sov-voice-visual-rail__frame .sov-adapter-table,
[data-sovereign] .sov-voice-visual-rail__frame .sov-adapter-code {
  margin: 0;
  font-size: 11.5px;
}
[data-sovereign] .sov-voice-visual-rail__frame .sov-adapter-mermaid__svg svg {
  max-height: 200px;
}

/* ─── Conductor idle status (inside activity conductor section) ──────
   Token purification · 2026-05-11 (step-37). Moves inline styles from
   ConductorIdleStatus component into canonical CSS classes so the rail
   carries zero layout-impacting inline styles. Authored: pr/step-37/PR.md §3.
   ──────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-conductor-status {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
}
[data-sovereign] .sov-conductor-status__line {
  opacity: 0.7;
}
[data-sovereign] .sov-conductor-status__line--primary {
  opacity: 0.9;
}
[data-sovereign] .sov-conductor-status__line--quiet {
  opacity: 0.45;
}
[data-sovereign] .sov-conductor-status__line--faded {
  opacity: 0.55;
}
[data-sovereign] .sov-conductor-status__line--tabular {
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
[data-sovereign] .sov-conductor-status__label {
  opacity: 0.75;
}

/* ─── Toolkit rail micro-classes (inline-style extraction) ─────────
   Token purification · 2026-05-11 (step-37). Moves inline layout
   styles from SovereignA05RailToolkit into CSS. Authored: pr/step-37/PR.md §4.
   ────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-toolkit-group__label {
  text-transform: uppercase;
  opacity: 0.7;
}
[data-sovereign] .sov-toolkit-group__entry {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
}
[data-sovereign] .sov-toolkit-group__entry-name {
  font-weight: 600;
}
[data-sovereign] .sov-toolkit-group__entry-desc {
  opacity: 0.6;
}
[data-sovereign] .sov-toolkit-group__entry-badge {
  opacity: 0.65;
  margin-left: 4px;
}

/* ─── Ops drain / spend inline-style extraction ───────────────────
   Token purification · 2026-05-11 (step-37). Moves inline layout
   styles from SovereignA05RailOps into CSS. Authored: pr/step-37/PR.md §5.
   ────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-ops-drain-row {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-00);
}
[data-sovereign] .sov-ops-spend-row {
  display: flex;
  justify-content: space-between;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
[data-sovereign] .sov-ops-spend-row__label {
  opacity: 0.65;
}
[data-sovereign] .sov-ops-drain-row__label {
  font-weight: 600;
}
[data-sovereign] .sov-ops-drain-row__sub {
  opacity: 0.6;
}
[data-sovereign] .sov-activity-section__earlier {
  opacity: 0.45;
}

/* ─── Reminder rail wrapper (inline-style extraction) ──────────────
   Removes the last inline flex-column from SovereignRightRailReminder.
   Kept separate from sov-rail-panel because this wraps the disclosure
   card rather than being the panel itself.
   ────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-reminder-rail {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

/* ─── Thinking trace timestamp + body (inline-style extraction) ────
   Purification · 2026-05-11. Moves inline display:block, opacity, and
   white-space styles from thinking trace `<span>` elements into CSS.
   ──────────────────────────────────────────────────────────────────── */
[data-sovereign] .sov-a05-rail__thinking-time {
  display: block;
  opacity: 0.6;
}
[data-sovereign] .sov-a05-rail__thinking-body {
  white-space: pre-wrap;
}

/* ---------- §17.x Sovereign visual breadcrumbs rail ----------
   Sanctioned under Charter Rule 5b (Sovereign Design Authority),
   2026-04-26 visual-language hardening pass.

   The visuals tab on the right rail (and the same panel mounted on
   the voice surface side rail) shows a ring buffer of the last
   structured pretext descriptors emitted in this session — diagrams,
   tables, code, citations. This complements the live activity stream
   with the *artefacts* of the conversation, not just the chips. */
[data-sovereign] .sov-a05-rail__visuals {
  display: flex;
  flex-direction: column;
  gap: var(--sov-activity-section-gap, var(--sov-space-3, 12px));
}
[data-sovereign] .sov-a05-rail__visual-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-activity-section-gap, var(--sov-space-3, 12px));
}
[data-sovereign] .sov-a05-rail__visual-item {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 6px);
  padding: var(--sov-space-3, 12px);
  border-radius: var(--sov-adapter-radius-tight, 10px);
  background: color-mix(in oklab, var(--sov-color-bg) 92%, var(--sov-veil));
  box-shadow: inset 0 0 0 1px
    var(
      --sov-adapter-hairline,
      color-mix(in oklab, var(--sov-ink) 6%, transparent)
    );
}
[data-sovereign] .sov-a05-rail__visual-frame {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2, 6px);
}
/* Scope-down inner adapter padding inside the breadcrumb tile so the
 * rail variant stays compact even when the same descriptor is shown
 * in-line in the chat bubble at full size. */
[data-sovereign] .sov-a05-rail__visual-frame .sov-adapter-mermaid,
[data-sovereign] .sov-a05-rail__visual-frame .sov-code-artifact,
[data-sovereign] .sov-a05-rail__visual-frame .sov-adapter-table,
[data-sovereign] .sov-a05-rail__visual-frame .sov-adapter-code {
  margin: 0;
  font-size: 11.5px;
}
[data-sovereign] .sov-a05-rail__visual-frame .sov-adapter-mermaid__svg svg {
  max-height: 220px;
}

/* ---------- §06 a06 · Pretext canvas (Jarvis) — main#a06.ab ----------
   Node: data-screen-label="06 Chat pretext" · float graph, not rail-bound. */
[data-sovereign] .sov-a06 {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 100dvh;
  align-self: stretch;
  background: var(--sov-bg);
  color: var(--sov-ink);
  width: 100%;
  max-width: none;
  margin: 0;
}
[data-sovereign] .sov-a06__frame {
  display: grid;
  box-sizing: border-box;
  grid-template-columns: var(--sov-layout-rail-width, 240px) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  flex: 1 1 auto;
  height: 100dvh;
  max-height: 100dvh;
  min-height: 0;
  overflow: hidden;
  max-width: none;
  margin: 0;
  width: 100%;
}
[data-sovereign] .sov-a06__left {
  grid-column: 1;
  grid-row: 1 / -1;
  min-width: 0;
  position: relative;
  align-self: stretch;
}
[data-sovereign] .sov-a06__head {
  grid-column: 2;
  grid-row: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: var(--sov-space-3) var(--sov-space-4) var(--sov-space-2);
  min-width: 0;
  position: relative;
  z-index: 65;
}
[data-sovereign] .sov-a06__tabs {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  min-width: 0;
}
[data-sovereign] .sov-a06__head-right {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  min-width: 200px;
}
[data-sovereign] .sov-a06__body {
  grid-column: 2;
  grid-row: 2;
  min-width: 0;
  min-height: min(62dvh, 640px);
  overflow: auto;
  position: relative;
  padding: 0;
  scroll-behavior: smooth;
}
[data-sovereign] .sov-a06__composer-wrap {
  grid-column: 2;
  grid-row: 3;
  box-sizing: border-box;
  min-width: 0;
  padding: 8px 28px max(12px, env(safe-area-inset-bottom, 0px));
  display: flex;
  justify-content: center;
  align-items: flex-end;
  width: 100%;
  position: relative;
  z-index: 65;
}
[data-sovereign] .sov-a06-canvas {
  position: relative;
  min-height: min(62dvh, 640px);
  width: 100%;
  isolation: isolate;
  background: var(--sov-bg);
}
[data-sovereign] .sov-a06-canvas::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0.16;
  pointer-events: none;
  background-image: linear-gradient(
      color-mix(in oklab, var(--sov-ink) 14%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      90deg,
      color-mix(in oklab, var(--sov-ink) 14%, transparent) 1px,
      transparent 1px
    );
  background-size: var(--sov-canvas-grid, 28px) var(--sov-canvas-grid, 28px);
}
[data-sovereign] .sov-a06-node {
  position: absolute;
  z-index: 1;
  /* Fixed maximum width — the pretext canvas uses fixed coordinates, so node
   * sizing must not respond to viewport width. The spatialData.size.width
   * (if set) overrides this via inline style. */
  max-width: 340px;
  padding: var(--sov-space-3) var(--sov-space-4) var(--sov-space-4);
  border-radius: var(--sov-radius-md);
  background: color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 12%, transparent);
  backdrop-filter: blur(var(--sov-glass-blur-ambient, 12px));
  -webkit-backdrop-filter: blur(var(--sov-glass-blur-ambient, 12px));
  cursor: -webkit-grab;
  cursor: grab;
  transition: box-shadow 0.2s var(--sov-ease-expo), transform 0.15s
    var(--sov-ease-expo), opacity 0.2s var(--sov-ease-expo), filter 0.2s
    var(--sov-ease-expo);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

/* While a node is being resized, kill every transition so the size tracks
 * the cursor 1:1 with no smoothing lag. The data-resizing attribute is set
 * by the resize handler for the duration of the drag. */
[data-sovereign] .sov-a06-node[data-resizing='true'] {
  transition: none;
}

/* Poem-glow top hairline — every node carries a whisper-thin trace of
 * its content-type glow along the top edge (never a wash; Charter
 * Rule: hairline at ~22%, gold reserved for Malaika-authored nodes).
 * The hairline colour is set per variant via --sov-node-glow below. */
[data-sovereign] .sov-a06-node::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--sov-space-3);
  right: var(--sov-space-3);
  height: 1px;
  border-radius: var(--sov-radius-pill);
  background: color-mix(
    in oklab,
    var(--sov-node-glow, var(--sov-ink)) 22%,
    transparent
  );
  pointer-events: none;
}
[data-sovereign] .sov-a06-node__surface {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: inherit;
}

/* Node exit dissolve — scale down + fade out + blur. Runs once; node
 * is removed from DOM after animation completes.
 * Authored under Charter Rule 5b — zero new palette tokens. */
[data-sovereign] .sov-a06-node--exiting {
  opacity: 0;
  filter: blur(4px);
  transform: scale(0.93);
  pointer-events: none;
  transition: opacity 0.18s var(--sov-ease-expo), filter 0.18s
    var(--sov-ease-expo), transform 0.18s var(--sov-ease-expo);
}

/* Node entry — scale up + fade in on first paint.
 * Applied via --entering, removed after animation completes. */
[data-sovereign] .sov-a06-node--entering {
  animation: sov-a06-node-enter 0.26s var(--sov-ease-expo) both;
}

@keyframes sov-a06-node-enter {
  from {
    opacity: 0;
    transform: scale(0.88);
    filter: blur(2px);
  }
  to {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
}

/* Breathing empty-state tile — gentle glow pulse on the canonical
 * breath cadence. Signals "this space is alive, waiting for you." */
[data-sovereign] .sov-a06-node--breathing {
  animation: sov-a06-node-breathe var(--sov-breath, 4.2s) ease-in-out infinite;
}

@keyframes sov-a06-node-breathe {
  0%,
  100% {
    box-shadow: inset 0 0 0 1px
      color-mix(in oklab, var(--sov-ink) 12%, transparent);
  }
  50% {
    box-shadow: inset 0 0 0 1px
      color-mix(in oklab, var(--mk-glow-gold) 18%, transparent), 0 0 24px
      color-mix(in oklab, var(--mk-glow-gold) 4%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-a06-node--exiting {
    transition: none;
    opacity: 0;
    filter: none;
    transform: none;
  }
  [data-sovereign] .sov-a06-node--entering,
  [data-sovereign] .sov-a06-node--breathing {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }
}

/* Hover / focus / pinned / selected rings all draw from the node's own
 * poem-glow (--sov-node-glow, set per content-type variant below;
 * neutral ink by default). Gold therefore appears ONLY on
 * Malaika-authored (--aaliyah) nodes — Charter: gold is hers. */
[data-sovereign] .sov-a06-node:hover {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 20%, transparent), 0 0 24px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 6%, transparent);
  transform: translateY(-1px);
}

[data-sovereign] .sov-a06-node:focus-visible {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 50%, transparent),
    0 0 28px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 12%, transparent);
  outline: none;
}
[data-sovereign] .sov-a06-node[data-pinned="true"] {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 55%, transparent),
    0 0 28px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 8%, transparent);
}
/* Selected node — persistent poem-glow ring (not dependent on focus).
 * Same glow variable as :focus-visible but with a distinct inner
 * shadow so selection reads as intentional, not accidental. */
[data-sovereign] .sov-a06-node[data-selected="true"] {
  box-shadow: inset 0 0 0 2px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 55%, transparent),
    0 0 32px
    color-mix(in oklab, var(--sov-node-glow, var(--sov-ink)) 14%, transparent);
}
/* Delete pill — visible only on selected nodes. Positioned top-right
 * inside the node. Error-ink hairline on glass, warming on hover —
 * token-first (--sov-error), no raw reds. */
[data-sovereign] .sov-a06-node__delete {
  position: absolute;
  top: var(--sov-space-2);
  right: var(--sov-space-2);
  z-index: 2;
  width: 24px;
  height: 24px;
  border-radius: var(--sov-radius-pill);
  border: 1px solid color-mix(in oklab, var(--sov-error) 24%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 85%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: color-mix(in oklab, var(--sov-error) 80%, transparent);
  font-family: var(--sov-font-sans);
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s var(--sov-ease), color 0.15s var(--sov-ease),
    border-color 0.15s var(--sov-ease);
}
[data-sovereign] .sov-a06-node__delete:hover {
  background: color-mix(in oklab, var(--sov-error) 14%, var(--sov-bg));
  border-color: color-mix(in oklab, var(--sov-error) 45%, transparent);
  color: var(--sov-error);
}
[data-sovereign] .sov-a06-node__pin {
  position: absolute;
  top: 11px;
  right: 11px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 10px color-mix(in oklab, var(--mk-glow-gold) 55%, transparent);
}

/* Resize handle — bottom-right corner grip. Only visible on hover or
 * when the node is selected. Drag diagonally to stretch/shrink the tile.
 * Authored under Charter Rule 5b — zero new palette tokens. */
[data-sovereign] .sov-a06-node__resize-handle {
  position: absolute;
  bottom: 0;
  right: 0;
  /* Visible hit area is generous (touch-friendly); the visible grip mark is
   * drawn smaller by the ::before pseudo-element. */
  width: 24px;
  height: 24px;
  cursor: nwse-resize;
  opacity: 0;
  transition: opacity 0.15s var(--sov-ease);
  pointer-events: none;
  z-index: 4;
  touch-action: none;
}

[data-sovereign] .sov-a06-node__resize-handle::before {
  content: "";
  position: absolute;
  bottom: 2px;
  right: 2px;
  width: 12px;
  height: 12px;
  border-right: 2px solid
    color-mix(in oklab, var(--sov-whisper) 50%, transparent);
  border-bottom: 2px solid
    color-mix(in oklab, var(--sov-whisper) 50%, transparent);
  border-radius: 0 0 2px 0;
}

[data-sovereign] .sov-a06-node:hover .sov-a06-node__resize-handle,
[data-sovereign] .sov-a06-node--selected .sov-a06-node__resize-handle,
[data-sovereign]
  .sov-a06-node[data-selected="true"]
  .sov-a06-node__resize-handle {
  opacity: 1;
  pointer-events: auto;
}
[data-sovereign] .sov-a06-node__eyebrow {
  margin: 0 0 10px;
  padding-right: 16px;
  letter-spacing: 0.1em;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
}
[data-sovereign] .sov-a06-node--kaos .sov-a06-node__eyebrow {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-a06-node__body {
  position: relative;
  /* Grow to fill the surface so an explicit node height stretches the body
   * rather than leaving dead space. */
  flex: 1 1 auto;
  min-height: 0;
  /* Fixed maximum height — node body must not respond to viewport height.
   * The pretext canvas is a fixed coordinate space. */
  max-height: 420px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--sov-whisper) 30%, transparent)
    transparent;
}

/* Fade-out mask at the bottom edge when content overflows —
 * signals "more below" without a hard cut-off. */
[data-sovereign] .sov-a06-node__body::after {
  content: "";
  position: -webkit-sticky;
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  display: block;
  height: 28px;
  pointer-events: none;
  background: linear-gradient(
    transparent,
    color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent) 90%
  );
  opacity: 0;
  transition: opacity 0.2s var(--sov-ease);
}

[data-sovereign] .sov-a06-node__body[data-overflowed="true"]::after {
  opacity: 1;
}

/* Expanded — removes max-height when the node is selected or being
 * edited so the user can "expand to read" by clicking the tile. */
[data-sovereign] .sov-a06-node__body--expanded {
  max-height: none !important;
  overflow-y: visible;
}

[data-sovereign] .sov-a06-node__body--expanded::after {
  opacity: 0 !important;
}
[data-sovereign] .sov-a06-node__display {
  margin: 0 0 12px;
  font-size: clamp(24px, 2.8vw, 34px);
  line-height: 1.2;
  font-family: var(--sov-font-serif);
  color: var(--sov-ink);
}
[data-sovereign] .sov-a06-node__display-q {
  font-weight: 500;
}
[data-sovereign] .sov-a06-node__quote {
  margin: 0;
  font-style: italic;
  line-height: 1.55;
  color: var(--sov-subtle);
  font-family: var(--sov-font-serif);
  font-size: 14px;
}
[data-sovereign] .sov-a06-node__serif {
  margin: 0;
  font-family: var(--sov-font-serif);
  line-height: 1.55;
  color: var(--sov-ink);
  font-size: 14px;
}
[data-sovereign] .sov-a06-node__code {
  margin: 0;
  font-family: var(--sov-font-mono, ui-monospace, monospace);
  font-size: 12px;
  line-height: 1.5;
  color: var(--sov-whisper);
  white-space: pre;
  overflow-x: auto;
}
[data-sovereign] .sov-a06-node--passage {
  --sov-node-glow: var(--mk-glow-where-light);
  top: 4%;
  left: 3%;
}
/* Sea-glass colour profiles — content-type-aware glass tints.
 * All derive from already-sanctioned --mk-glow-* palette tokens at
 * gentle opacities so the variation is felt, not shouted.
 * Authored under Charter Rule 5b — zero new palette tokens. */
[data-sovereign] .sov-a06-node--spark {
  --sov-node-glow: var(--mk-glow-where-light);
  background: color-mix(
    in oklab,
    var(--mk-glow-gold) 3%,
    color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent)
  );
}
[data-sovereign] .sov-a06-node--quote-glass {
  --sov-node-glow: var(--mk-glow-where-light);
  background: color-mix(
    in oklab,
    var(--mk-glow-where-light) 3%,
    color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent)
  );
}
[data-sovereign] .sov-a06-node--bookcast-glass {
  --sov-node-glow: var(--mk-glow-rose);
  background: color-mix(
    in oklab,
    var(--mk-glow-rose) 2%,
    color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent)
  );
}
[data-sovereign] .sov-a06-node--code {
  --sov-node-glow: var(--mk-glow-forest);
  top: 30%;
  left: 4%;
  max-width: min(92%, 380px);
  background: color-mix(
    in oklab,
    var(--mk-glow-forest) 3%,
    color-mix(in oklab, var(--sov-color-surface-raised) 78%, transparent)
  );
}
[data-sovereign] .sov-a06-node--kaos {
  --sov-node-glow: var(--mk-glow-rose);
  top: 15%;
  right: 5%;
  left: auto;
  max-width: min(92%, 300px);
}
[data-sovereign] .sov-a06-node--aaliyah {
  /* Malaika-authored — the only variant that wears the gold glow. */
  --sov-node-glow: var(--mk-glow-gold);
  top: 5%;
  right: 6%;
  left: auto;
  max-width: min(92%, 280px);
  background: color-mix(
    in oklab,
    var(--mk-glow-gold) 4%,
    color-mix(in oklab, var(--sov-color-surface-raised) 72%, transparent)
  );
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
}
[data-sovereign] .sov-a06-node--diagram {
  bottom: 7%;
  right: 5%;
  top: auto;
  left: auto;
  max-width: min(92%, 260px);
}
[data-sovereign] .sov-a06-diagram__svg {
  width: 100%;
  height: auto;
  display: block;
}
[data-sovereign] .sov-a06-diagram__n--left {
  fill: var(--mk-glow-the-windhover);
}
[data-sovereign] .sov-a06-diagram__n--mid {
  fill: var(--mk-glow-gold);
}
[data-sovereign] .sov-a06-diagram__n--right {
  fill: var(--mk-glow-spring-and-fall);
}
[data-sovereign] .sov-a06-diagram__labels {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 4px;
  gap: 4px;
  margin-top: 6px;
  text-align: center;
  color: var(--sov-whisper);
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-resting-ghost,
  [data-sovereign] .sov-a05-typing span {
    animation: none;
  }
  [data-sovereign] .sov-resting-ghost {
    opacity: 0.16;
    transform: none;
    letter-spacing: 0.06em;
  }
}

/* ── A06 + right rail layout · § 2026-05-09 ──────────────────────
 *
 * When a project canvas route renders inside the sov-surface, the
 * A06 layout and the project rail sit side-by-side in a flex wrapper.
 * The unified [data-sov-chrome] attribute drives rail visibility;
 * CSS hides the right rail when chrome is collapsed or minimal.
 */
[data-sovereign] .sov-a06-with-rail {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
[data-sovereign] .sov-a06-with-rail > main.sov-a06 {
  flex: 1 1;
  min-width: 0;
}
[data-sovereign] .sov-a06-right-rail {
  width: var(--sov-rail-w);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sov-space-2) var(--sov-space-2) var(--sov-space-2) 0;
  background: var(--sov-bg);
  border-left: 1px solid color-mix(in oklab, var(--sov-ink) 8%, transparent);
}
/* Sidebar toggle — hide the right-rail column in compact mode. */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-a06-right-rail {
  display: none;
}

@media (max-width: 1023px) {
  [data-sovereign] .sov-a03__frame,
  [data-sovereign] .sov-a05__frame {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto 1fr auto auto;
  }
  [data-sovereign] .sov-a03__left-col,
  [data-sovereign] .sov-a05__left-col {
    display: flex;
    flex-direction: column;
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    min-height: 0;
  }
  [data-sovereign] .sov-a03__left,
  [data-sovereign] .sov-a05__left {
    flex: 1 1 auto;
    min-height: 0;
  }
  [data-sovereign] .sov-a03__tabs,
  [data-sovereign] .sov-a05__tabs {
    grid-column: 1;
    grid-row: 2;
  }
  [data-sovereign] .sov-a03__right-chrome,
  [data-sovereign] .sov-a05__right-chrome {
    grid-column: 1;
    grid-row: 3;
  }
  [data-sovereign] .sov-a03__scroll,
  [data-sovereign] .sov-a05__scroll {
    grid-column: 1;
    grid-row: 4;
  }
  [data-sovereign] .sov-a03__rside,
  [data-sovereign] .sov-a05__rside {
    grid-column: 1;
    grid-row: 5;
  }
  [data-sovereign] .sov-a03__composer-wrap,
  [data-sovereign] .sov-a05__composer-wrap {
    grid-column: 1;
    grid-row: 6;
  }
  [data-sovereign] .sov-a06__frame {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto 1fr auto;
  }
  [data-sovereign] .sov-a06__left {
    grid-column: 1;
    grid-row: 1;
  }
  [data-sovereign] .sov-a06__head {
    grid-column: 1;
    grid-row: 2;
  }
  [data-sovereign] .sov-a06__body {
    grid-column: 1;
    grid-row: 3;
  }
  [data-sovereign] .sov-a06__composer-wrap {
    grid-column: 1;
    grid-row: 4;
  }
  /* The static §A06 showcase grid stacks nodes into a column below 1023px.
   * This MUST NOT apply to the live persisted pretext canvas, where nodes are
   * fixed absolute coordinates in the pretext positioning system. The showcase
   * uses .sov-a06-canvas--static; the live canvas uses .sov-canvas-pan-layer. */
  [data-sovereign] .sov-a06-canvas--static .sov-a06-node--passage,
  [data-sovereign] .sov-a06-canvas--static .sov-a06-node--code,
  [data-sovereign] .sov-a06-canvas--static .sov-a06-node--kaos,
  [data-sovereign] .sov-a06-canvas--static .sov-a06-node--aaliyah,
  [data-sovereign] .sov-a06-canvas--static .sov-a06-node--diagram {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    bottom: auto;
    max-width: 100%;
    margin-bottom: 16px;
  }
  [data-sovereign] .sov-a06-canvas--static {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-height: auto;
    padding: 8px 12px 16px;
  }
}

/* ---------- §07 a07 + SovereignCodeArtifact (SR-8 / six treatments) ----------
   section#a07 · data-screen-label="07 Code artifacts"
   [data-kaos-component="SovereignCodeArtifact"][data-kaos-variant=…] */
[data-sovereign] .sov-a07 {
  max-width: 1440px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: 0 0 48px;
  min-height: min(1100px, 100%);
}
[data-sovereign] .sov-a07__treatment {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
[data-sovereign] .sov-a07__label {
  margin: 0;
  color: var(--sov-whisper);
  font-family: var(--sov-font-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
[data-sovereign] .sov-a07__row {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 16px;
  gap: 16px;
}
[data-sovereign] .sov-a07__grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 28px 24px;
  gap: 28px 24px;
}
@media (min-width: 1024px) {
  [data-sovereign] .sov-a07__row--split {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
  [data-sovereign] .sov-a07__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  [data-sovereign] .sov-a07__span2 {
    grid-column: 1 / -1;
  }
}
/* biome-ignore lint/nursery/noDescendingSpecificity: base class follows higher-specificity descendant variant — intentional, rules cascade forward on the same DOM surface */
[data-sovereign] .sov-code-artifact {
  margin: 0;
  border-radius: var(--sov-component-code-artifact-radius, 10px);
  background: color-mix(
    in oklab,
    var(--sov-color-bg) var(--sov-component-code-artifact-tint),
    var(--sov-surface-raised, var(--sov-veil))
  );
  box-shadow: var(
    --sov-hairline-neutral,
    inset 0 0 0 1px rgba(255, 255, 255, 0.06)
  );
  overflow: hidden;
  max-width: 100%;
}
[data-sovereign] [data-kaos-component="SovereignCodeArtifact"] {
  font-family: var(--sov-typography-font-sans, var(--sov-font-sans));
}
[data-sovereign]
  [data-kaos-component="SovereignCodeArtifact"]
  .sov-code-artifact--phrase {
  font-family: var(--sov-typography-font-mono, var(--sov-font-mono, monospace));
  font-size: 12.5px;
  padding: 1px 6px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--sov-ink) 6%, transparent);
  color: var(--sov-ink);
}
[data-sovereign] .sov-code-artifact__cap--row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px 6px;
  border-bottom: 1px solid color-mix(in oklab, var(--sov-ink) 6%, transparent);
  gap: 8px;
}
[data-sovereign] .sov-code-artifact__cap-l {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
[data-sovereign] .sov-code-artifact__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
[data-sovereign] .sov-code-artifact__dot--red {
  background: #b44;
  box-shadow: 0 0 6px color-mix(in oklab, #b44 45%, transparent);
}
[data-sovereign] .sov-code-artifact__dot--amber {
  background: #c9a227;
  box-shadow: 0 0 6px color-mix(in oklab, #c9a227 40%, transparent);
}
[data-sovereign] .sov-code-artifact__fname {
  font-family: var(--sov-font-mono, ui-monospace, monospace);
  font-size: 11.5px;
  color: var(--sov-ink);
  font-weight: 500;
  letter-spacing: 0.02em;
}
[data-sovereign] .sov-code-artifact__lang {
  color: #b8985a;
  letter-spacing: 0.1em;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  flex-shrink: 0;
}
[data-sovereign] .sov-code-artifact__body {
  position: relative;
}
[data-sovereign] .sov-code-artifact__pre {
  margin: 0;
  padding: 14px 16px 16px;
  font-size: 12.5px;
  line-height: 1.6;
  overflow: auto;
  white-space: pre;
  color: #e6e2dc;
  font-family: var(--sov-font-mono, ui-monospace, monospace);
}
[data-sovereign] .sov-code-artifact__pre--dense {
  padding: 10px 14px 12px;
  font-size: 11.5px;
  line-height: 1.5;
}
[data-sovereign] .sov-code-hl__kw {
  color: #b8a0e8;
  font-weight: 500;
}
[data-sovereign] .sov-code-hl__fn {
  color: #7ec8e0;
}
[data-sovereign] .sov-code-hl__ty {
  color: #6cc4c4;
}
[data-sovereign] .sov-code-hl__str {
  color: #d4a574;
}
[data-sovereign] .sov-code-hl__p {
  color: #e8e4de;
}
[data-sovereign] .sov-code-hl__prop {
  color: #8ec8d8;
}
[data-sovereign] .sov-code-hl__c {
  color: var(--sov-muted);
  font-style: italic;
}
[data-sovereign] .sov-code-artifact__pin-suffix {
  color: var(--sov-whisper);
  font-weight: 400;
  font-size: 11px;
}
[data-sovereign] .sov-code-artifact__meta {
  margin: 0;
  padding: 4px 12px 0;
  color: var(--sov-muted);
  font-style: italic;
  font-size: 10.5px;
  letter-spacing: 0.02em;
}
[data-sovereign] .sov-code-artifact--ca3 .sov-code-artifact__fs {
  display: flex;
  min-height: 220px;
  border-radius: inherit;
  overflow: hidden;
}
[data-sovereign] .sov-code-artifact__tree {
  width: 148px;
  flex-shrink: 0;
  padding: 8px 0;
  border-right: 1px solid color-mix(in oklab, var(--sov-ink) 6%, transparent);
  background: color-mix(in oklab, #050608 50%, transparent);
  font-size: 11.5px;
  color: var(--sov-subtle);
}
[data-sovereign] .sov-code-artifact__tree-row[data-active="true"] {
  color: var(--mk-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
}
[data-sovereign] .sov-code-artifact__tree-row[data-kind="folder"] {
  font-weight: 500;
  color: var(--sov-whisper);
}
[data-sovereign] .sov-code-artifact__fs-main {
  flex: 1 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
[data-sovereign] .sov-code-artifact__tabs {
  display: flex;
  gap: 0 8px;
  padding: 6px 8px 0 10px;
  border-bottom: 1px solid color-mix(in oklab, var(--sov-ink) 5%, transparent);
  flex-wrap: wrap;
}
[data-sovereign] .sov-code-artifact__tab {
  position: relative;
  padding: 6px 8px 8px;
  color: var(--sov-whisper);
  letter-spacing: 0.06em;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  cursor: default;
}
[data-sovereign] .sov-code-artifact__tab[data-active="true"] {
  color: var(--sov-ink);
}
[data-sovereign] .sov-code-artifact__tab[data-active="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 1px;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 10px color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
}
[data-sovereign] .sov-code-artifact__pre--editor {
  flex: 1 1;
  min-height: 0;
  white-space: pre-wrap;
  font-size: 12px;
  line-height: 1.55;
  color: #d0ccc4;
  padding: 10px 14px 16px;
}
[data-sovereign] .sov-code-artifact--ca4 {
  min-height: 200px;
  background: var(--sov-color-surface-sunken);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 10%, transparent);
}
[data-sovereign] .sov-code-artifact__map {
  color: #8a8c90;
  padding: 8px 12px 12px;
}
[data-sovereign] .sov-code-artifact__map-box {
  fill: color-mix(in oklab, #0c0e14 90%, #1a1c22);
  stroke: color-mix(in oklab, var(--sov-ink) 20%, transparent);
  stroke-width: 1;
}
[data-sovereign] .sov-code-artifact__map-t {
  fill: var(--sov-subtle);
  font-size: 9.5px;
  font-family: var(--sov-font-mono, monospace);
}
[data-sovereign] .sov-code-artifact--ca5 {
  background: #050608;
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent);
}
[data-sovereign] .sov-code-artifact__term {
  margin: 0;
  padding: 12px 14px 14px;
  font-family: var(--sov-font-mono, monospace);
  font-size: 11.5px;
  line-height: 1.55;
  color: #d0ccc4;
  white-space: pre-wrap;
}
[data-sovereign] .sov-code-artifact__prompt {
  color: #c9a227;
  margin-right: 4px;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
[data-sovereign] .sov-code-artifact__ok {
  color: #5acd8c;
}
[data-sovereign] .sov-code-artifact__skip {
  color: #d88;
}
[data-sovereign] .sov-code-artifact__err {
  color: #f38;
}
[data-sovereign] .sov-code-artifact__cursor {
  color: #c9a227;
  animation: sov-cursor 1.1s step-end infinite;
}
@keyframes sov-cursor {
  50% {
    opacity: 0;
  }
}
[data-sovereign] .sov-code-artifact--ca6 {
  background: var(--sov-color-surface-sunken);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 10%, transparent);
}
[data-sovereign] .sov-code-artifact__cap--preview {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px 6px;
  border-bottom: 1px solid color-mix(in oklab, var(--sov-ink) 6%, transparent);
}
[data-sovereign] .sov-code-artifact__traffic {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  flex-shrink: 0;
}
[data-sovereign] .sov-code-artifact__tlight {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: inline-block;
  box-shadow: inset 0 0 0 0.5px color-mix(in oklab, #000 20%, transparent);
}
[data-sovereign] .sov-code-artifact__tlight--r {
  background: #c44;
}
[data-sovereign] .sov-code-artifact__tlight--y {
  background: #c9a228;
}
[data-sovereign] .sov-code-artifact__tlight--g {
  background: #2d8c5a;
}
[data-sovereign] .sov-code-artifact__preview-ttl {
  flex: 1 1;
  min-width: 0;
  font-size: 10px;
  color: var(--sov-whisper);
  letter-spacing: 0.04em;
  font-family: var(--sov-font-mono, monospace);
}
[data-sovereign] .sov-code-artifact__live-badge {
  color: #4ecf8a;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 8.5px;
  font-weight: 600;
}
[data-sovereign] .sov-code-artifact__preview-body {
  padding: 0;
  background: var(--sov-color-surface-sunken);
  min-height: 120px;
}
[data-sovereign] .sov-code-artifact__preview-spark {
  margin: 0;
  min-height: 120px;
  padding: 20px 18px 22px;
  background: linear-gradient(160deg, #3a0a18 0%, #1a0a2e 50%, #0a0812 100%);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, #fff 6%, transparent);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 6px;
}
[data-sovereign] .sov-code-artifact__spark-ey {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in oklab, #fff 80%, #f5d4c4 20%);
  font-family: var(--sov-font-sans);
}
[data-sovereign] .sov-code-artifact__spark-h {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-size: 17px;
  line-height: 1.35;
  color: #f5f0ea;
  font-weight: 500;
  max-width: 22em;
}
[data-sovereign] .sov-code-artifact__fs-slot {
  flex: 1 1;
  min-height: 0;
  overflow: auto;
  padding: 10px 14px 16px;
  font-size: 12px;
  color: #d0ccc4;
}

/* ---------- Home surface ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-home-deep.html
             § HomeShell. The greeting + activity tiles are the canonical
             sovereign home rhythm. Layout is a vertical flow with generous
             gutter; the greeting is large serif (40px) with an italic
             subtitle in subtle tone and a 620px max width. */
[data-sovereign] .sov-home {
  display: flex;
  flex-direction: column;
  gap: 40px;
}
/* ══ Deprecated (step-14): sov-home__date replaced by SovereignPageContext
 *    primitive. The component renders the same typographic tokens inline
 *    (10px / 600 / 0.12em / uppercase / --sov-whisper) with gold bullet
 *    separators. Consumers migrated 2026-05-11: home-boot, library-boot,
 *    tools. This class block is kept for one cycle as a safety net; no
 *    consumer references it after the migration. Remove after next
 *    production deploy confirms zero visual regressions. */
[data-sovereign] .sov-home__date {
  margin: 0 0 var(--sov-space-1);
  color: var(--sov-whisper);
  letter-spacing: 0.12em;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  font-family: var(--sov-font-sans);
}

/* Page context eyebrow — SovereignPageContext primitive (step-14). */
[data-sovereign] .sov-page-context {
  margin: 0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  min-width: 0;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-micro-size);
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--sov-whisper);
  white-space: nowrap;
}
[data-sovereign] .sov-page-context__item {
  flex-shrink: 0;
}
[data-sovereign] .sov-page-context__sep {
  flex-shrink: 0;
  margin-inline: var(--sov-space-2);
  color: var(--mk-glow-gold);
  opacity: 0.45;
  font-size: var(--sov-text-micro-size);
  font-weight: 600;
}
[data-sovereign] .sov-page-context--rail {
  margin-top: var(--sov-space-4);
  margin-bottom: var(--sov-space-2);
}

[data-sovereign] .sov-home__greeting {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-4);
}
[data-sovereign] .sov-home__greeting-head {
  margin: 0;
  color: var(--sov-ink);
}
[data-sovereign] .sov-home__greeting-name {
  color: var(--mk-glow-gold);
  font-style: italic;
  font-weight: 500;
}
[data-sovereign] .sov-home__greeting-italic {
  margin: 0;
  max-width: 720px;
  color: var(--mk-glow-gold);
  font-size: 19px;
  line-height: 1.5;
  font-style: italic;
  font-weight: 400;
}
[data-sovereign] .sov-home__greeting-sub {
  font-family: var(--sov-font-serif);
  margin: 0;
  line-height: 1.6;
  color: var(--sov-subtle, var(--sov-whisper));
  max-width: 640px;
}
[data-sovereign] .sov-home__greeting-sub em {
  font-style: italic;
  color: var(--sov-subtle);
}

/* Library right rail — page context + daily top note below fast search. */
[data-sovereign] .sov-library-rail-stack {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  padding: 0 var(--sov-rail-pad) var(--sov-space-3);
}
[data-sovereign] .sov-home__greeting--rail {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 0;
}
/* Heading-sized disclosure — serif display trigger, passage body below. */
[data-sovereign] .sov-greeting-disclosure {
  display: flex;
  flex-direction: column;
  gap: 0;
}
[data-sovereign] .sov-greeting-disclosure__trigger {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: var(--sov-space-2);
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--sov-ink);
  text-align: left;
  transition: color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-greeting-disclosure__trigger:hover {
  color: color-mix(in oklab, var(--sov-ink) 88%, var(--mk-glow-gold));
}
[data-sovereign] .sov-greeting-disclosure__trigger:focus-visible {
  outline: 0;
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
  border-radius: var(--sov-radius-sm);
}
[data-sovereign] .sov-greeting-disclosure__label {
  flex: 1 1;
  min-width: 0;
  display: block;
  margin: 0;
  font-family: var(--sov-font-serif);
  font-weight: var(--sov-text-display-weight);
  letter-spacing: var(--sov-text-display-tracking, -0.02em);
  font-size: calc(var(--sov-text-section-size) + var(--sov-space-2));
  line-height: var(--sov-text-section-line);
  color: inherit;
}
[data-sovereign] .sov-greeting-disclosure__chevron {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  margin-top: var(--sov-space-1);
  color: var(--mk-glow-gold);
  transition: transform 180ms var(--sov-ease);
  opacity: 0.7;
}
[data-sovereign] .sov-greeting-disclosure[data-open="true"] .sov-greeting-disclosure__chevron {
  transform: rotate(180deg);
  opacity: 1;
}
[data-sovereign] .sov-greeting-disclosure__body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  padding-top: var(--sov-space-2);
}
[data-sovereign] .sov-home__greeting--rail .sov-home__greeting-italic {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-weight: var(--sov-text-field-weight);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--mk-glow-gold);
  max-width: none;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  overflow: hidden;
  word-break: break-word;
}
[data-sovereign] .sov-home__greeting--rail .sov-home__greeting-sub {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--sov-subtle, var(--sov-whisper));
  max-width: none;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  word-break: break-word;
}

[data-sovereign] .sov-home__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  grid-gap: 16px;
  gap: 16px;
}
[data-sovereign] .sov-home__section-head {
  font-size: 18px;
  font-weight: 500;
  font-family: var(--sov-font-sans);
  color: var(--sov-ink);
  letter-spacing: -0.005em;
  margin: 0 0 14px 0;
}

/* ---------- Catalog surface (tools, business, design) ----------
   Authored: sovereign-design — shared tile grid for studio catalogs.
             Layout + tile typography only; prose lives in surface
             config modules. Token-first — zero inline style objects. */
[data-sovereign] .sov-catalog {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-6);
}
[data-sovereign] .sov-catalog__section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}
[data-sovereign] .sov-catalog__section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sov-space-3);
}
[data-sovereign] .sov-catalog-tile {
  all: unset;
  display: block;
  width: 100%;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
}
[data-sovereign] .sov-catalog-tile__eyebrow {
  display: block;
  font-family: var(--sov-font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-hero-text-meta);
  margin-bottom: 6px;
}
[data-sovereign] .sov-catalog-tile__title {
  display: block;
  font-family: var(--sov-font-serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--sov-hero-text-title);
  line-height: 1.3;
  margin-bottom: 8px;
}
[data-sovereign] .sov-catalog-tile__meta {
  display: block;
  font-family: var(--sov-font-sans);
  font-size: 13px;
  color: var(--sov-hero-text-sub);
  line-height: 1.5;
}
[data-sovereign] .sov-rail-stack {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}
[data-sovereign] .sov-rail-close {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--sov-muted);
  font-size: var(--sov-text-caption-size);
  font-family: inherit;
  padding: 0;
}
[data-sovereign] .sov-rail-catalog {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-atelier {
  gap: var(--sov-space-7);
}

[data-sovereign] .sov-design-boot__section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  scroll-margin-top: 80px;
}

[data-sovereign] .sov-design-boot__grid {
  display: grid;
  grid-gap: var(--sov-space-3);
  gap: var(--sov-space-3);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

[data-sovereign] .sov-design-boot__specimens {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  padding: var(--sov-space-4);
  border-radius: var(--sov-radius-tile);
  background: color-mix(in oklab, var(--sov-surface-raised) 88%, transparent);
  border: 1px solid var(--mk-hairline-gold);
}

/* ─── Specimen gallery (Content Vocabulary / Components / Presets) ─── */

[data-sovereign] .sov-design-boot__specimen-grid {
  display: grid;
  grid-gap: var(--sov-space-3);
  gap: var(--sov-space-3);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

[data-sovereign] .sov-design-specimen {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-specimen--wide {
  grid-column: 1 / -1;
}

[data-sovereign] .sov-design-specimen__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-specimen__kind {
  font-family: var(--sov-font-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--sov-ink);
}

[data-sovereign] .sov-design-specimen__kind-code {
  font-family: var(--sov-font-mono);
  font-size: 10.5px;
  color: var(--sov-whisper);
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
  padding: 2px 6px;
  border-radius: var(--sov-radius-xs);
}

[data-sovereign] .sov-design-specimen__body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  min-height: 60px;
}

[data-sovereign] .sov-design-specimen-layer {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  margin-top: var(--sov-space-3);
}

/* ─── Advanced tokens (collapsed) ───────────────────────────────────── */

[data-sovereign] .sov-design-boot__advanced,
[data-sovereign] .sov-design-boot__expandable {
  margin-top: var(--sov-space-4);
}

[data-sovereign] .sov-design-boot__advanced > summary,
[data-sovereign] .sov-design-boot__expandable > summary {
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: var(--sov-space-2);
  list-style: none;
  padding: var(--sov-space-3) var(--sov-space-4);
  border-radius: var(--sov-radius-tile);
  border: 1px solid var(--mk-hairline-gold);
  background: color-mix(in oklab, var(--sov-veil) 60%, transparent);
}

[data-sovereign] .sov-design-boot__advanced > summary::-webkit-details-marker,
[data-sovereign] .sov-design-boot__expandable > summary::-webkit-details-marker {
  display: none;
}

[data-sovereign] .sov-design-boot__advanced > summary::before,
[data-sovereign] .sov-design-boot__expandable > summary::before {
  content: '▸';
  font-size: 11px;
  color: var(--sov-whisper);
  transition: transform 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-boot__advanced[open] > summary::before,
[data-sovereign] .sov-design-boot__expandable[open] > summary::before {
  transform: rotate(90deg);
}

[data-sovereign] .sov-design-boot__advanced[open] > summary,
[data-sovereign] .sov-design-boot__expandable[open] > summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

/* ─── Design microchat adjuster ─────────────────────────────────────── */

[data-sovereign] .sov-design-microchat {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  position: -webkit-sticky;
  position: sticky;
  top: var(--sov-space-3);
}

[data-sovereign] .sov-design-microchat__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-microchat__reset {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 600;
  color: var(--sov-whisper);
  background: transparent;
  border: 1px solid var(--mk-hairline-gold);
  border-radius: var(--sov-radius-pill);
  padding: 4px 10px;
  cursor: pointer;
  transition: color 160ms var(--sov-ease), border-color 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-microchat__reset:hover {
  color: var(--sov-accent);
  border-color: var(--sov-accent);
}

[data-sovereign] .sov-design-microchat__messages {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  max-height: 180px;
  overflow-y: auto;
  padding: var(--sov-space-1) 0;
}

[data-sovereign] .sov-design-microchat__msg {
  padding: var(--sov-space-1) var(--sov-space-2);
  border-radius: var(--sov-radius-xs);
}

[data-sovereign] .sov-design-microchat__msg--consilience {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
}

[data-sovereign] .sov-design-microchat__msg--user {
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
}

[data-sovereign] .sov-design-microchat__suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

[data-sovereign] .sov-design-microchat__suggestion {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 500;
  color: var(--sov-whisper);
  background: transparent;
  border: 1px solid var(--mk-hairline-gold);
  border-radius: var(--sov-radius-pill);
  padding: 4px 10px;
  cursor: pointer;
  transition: color 160ms var(--sov-ease), border-color 160ms var(--sov-ease),
    background 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-microchat__suggestion:hover {
  color: var(--sov-accent);
  border-color: var(--sov-accent);
  background: color-mix(in oklab, var(--sov-accent) 8%, transparent);
}

[data-sovereign] .sov-design-microchat__form {
  display: flex;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-microchat__input {
  flex: 1 1;
  font-family: var(--sov-font-sans);
  font-size: 13px;
  color: var(--sov-ink);
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
  border: 1px solid var(--mk-hairline-gold);
  border-radius: var(--sov-radius-sm);
  padding: 8px 12px;
  outline: none;
  transition: border-color 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-microchat__input:focus {
  border-color: var(--sov-accent);
}

[data-sovereign] .sov-design-microchat__input::placeholder {
  color: var(--sov-whisper);
}

[data-sovereign] .sov-design-microchat__submit {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  font-weight: 600;
  color: var(--sov-color-bg);
  background: var(--sov-accent);
  border: none;
  border-radius: var(--sov-radius-sm);
  padding: 8px 16px;
  cursor: pointer;
  transition: opacity 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-microchat__submit:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ─── Design token adjuster ─────────────────────────────────────────── */

[data-sovereign] .sov-design-adjuster {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-design-adjuster__control {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

[data-sovereign] .sov-design-adjuster__label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

[data-sovereign] .sov-design-adjuster__label {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  font-weight: 600;
  color: var(--sov-ink);
}

[data-sovereign] .sov-design-adjuster__value {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-design-adjuster__slider {
  -webkit-appearance: none;
  -moz-appearance: none;
       appearance: none;
  width: 100%;
  height: 4px;
  border-radius: var(--sov-radius-pill);
  background: var(--mk-hairline-gold);
  outline: none;
}

[data-sovereign] .sov-design-adjuster__slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--sov-accent);
  cursor: pointer;
  border: 2px solid var(--sov-color-bg);
}

[data-sovereign] .sov-design-adjuster__slider::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--sov-accent);
  cursor: pointer;
  border: 2px solid var(--sov-color-bg);
}

[data-sovereign] .sov-design-adjuster__palette {
  display: flex;
  gap: 8px;
}

[data-sovereign] .sov-design-adjuster__swatch {
  width: 32px;
  height: 32px;
  border-radius: var(--sov-radius-sm);
  border: 2px solid var(--mk-hairline-gold);
  cursor: pointer;
  transition: border-color 160ms var(--sov-ease), transform 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-adjuster__swatch:hover {
  transform: scale(1.1);
}

[data-sovereign] .sov-design-adjuster__swatch--active {
  border-color: var(--sov-accent);
  border-width: 2px;
  box-shadow: 0 0 0 2px var(--sov-color-bg), 0 0 0 4px var(--sov-accent);
}

[data-sovereign] .sov-design-adjuster__toggle {
  display: flex;
  gap: 0;
  border: 1px solid var(--mk-hairline-gold);
  border-radius: var(--sov-radius-sm);
  overflow: hidden;
}

[data-sovereign] .sov-design-adjuster__toggle button {
  flex: 1 1;
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 500;
  color: var(--sov-whisper);
  background: transparent;
  border: none;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 160ms var(--sov-ease), color 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-adjuster__toggle-btn--active,
[data-sovereign] .sov-design-adjuster__toggle button.sov-design-adjuster__toggle-btn--active {
  background: color-mix(in oklab, var(--sov-accent) 15%, transparent);
  color: var(--sov-accent);
}

[data-sovereign] .sov-design-adjuster__divider {
  height: 1px;
  background: var(--mk-hairline-gold);
  margin: var(--sov-space-1) 0;
}

/* ─── Consilience intent indicator ──────────────────────────────────── */

[data-sovereign] .sov-design-intent {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-intent__head {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-intent__moods {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

[data-sovereign] .sov-design-intent__mood {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 500;
  color: var(--sov-whisper);
  background: transparent;
  border: 1px solid var(--mk-hairline-gold);
  border-radius: var(--sov-radius-pill);
  padding: 3px 8px;
  cursor: pointer;
  transition: color 160ms var(--sov-ease), border-color 160ms var(--sov-ease),
    background 160ms var(--sov-ease);
}

[data-sovereign] .sov-design-intent__mood:hover {
  color: var(--sov-persona-accent);
  border-color: var(--sov-persona-accent);
}

[data-sovereign] .sov-design-intent__mood--active {
  color: var(--sov-persona-accent);
  border-color: var(--sov-persona-accent);
  background: color-mix(in oklab, var(--sov-persona-accent) 12%, transparent);
}

[data-sovereign] .sov-design-intent__clear {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 500;
  color: var(--sov-whisper);
  background: transparent;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  align-self: flex-start;
}

/* ════════════════════════════════════════════════════════════════════════
   Consilience-first design atelier — Tier 0 specimen, glow gallery,
   tiered structure, controlled sections, and live-change transitions.
   All added in the 2026-07-12 rebuild. Reads the cascade tokens
   (--sov-persona-*, --mk-glow-*, --sov-veil, --sov-surface-raised)
   so the whole surface responds to rail adjustments in real time.
   ════════════════════════════════════════════════════════════════════════ */

/* ─── Tier 0: the living consilience specimen ───────────────────────────────
   The spine of the page. Her glow reads --sov-persona-presence live,
   so when a mood changes, her dot shifts colour. The dimension bars
   read --sov-persona-accent so they move with her warmth. */

[data-sovereign] .sov-consilience-specimen {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-gap: var(--sov-space-5);
  gap: var(--sov-space-5);
  align-items: start;
  padding: var(--sov-space-6);
  border-radius: var(--sov-radius-tile);
  background:
    radial-gradient(
      120% 80% at 0% 0%,
      color-mix(in oklab, var(--sov-persona-accent, var(--mk-glow-gold)) 8%, transparent),
      transparent 70%
    ),
    color-mix(in oklab, var(--sov-veil) 72%, transparent);
  border: 1px solid var(--mk-hairline-gold);
}

[data-sovereign] .sov-consilience-specimen__presence {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: var(--sov-space-1);
}

[data-sovereign] .sov-consilience-specimen__body {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  grid-gap: var(--sov-space-6);
  gap: var(--sov-space-6);
  align-items: start;
}

[data-sovereign] .sov-consilience-specimen__greeting {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-consilience-specimen__head {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-display-size);
  font-weight: 500;
  line-height: var(--sov-text-display-line);
  color: var(--sov-ink);
}

[data-sovereign] .sov-consilience-specimen__emph {
  color: var(--sov-persona-accent, var(--sov-accent));
  transition: color var(--sov-hush) var(--sov-ease);
}

[data-sovereign] .sov-consilience-specimen__state {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  padding: var(--sov-space-4);
  border-radius: var(--sov-radius-sm);
  background: color-mix(in oklab, var(--sov-surface-sunken) 50%, transparent);
  border: 1px solid var(--mk-hairline-gold);
}

[data-sovereign] .sov-consilience-specimen__dims {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-consilience-specimen__dim {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

[data-sovereign] .sov-consilience-specimen__dim-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-consilience-specimen__dim-poles {
  display: flex;
  gap: var(--sov-space-3);
  font-family: var(--sov-font-mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: var(--sov-whisper);
  text-transform: lowercase;
}

[data-sovereign] .sov-consilience-specimen__dim-track {
  position: relative;
  height: 5px;
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--sov-ink) 8%, transparent);
  overflow: hidden;
}

[data-sovereign] .sov-consilience-specimen__dim-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--sov-persona-accent, var(--mk-glow-gold));
  box-shadow: 0 0 12px -2px var(--sov-persona-accent, var(--mk-glow-gold));
  transition: width var(--sov-d-base) var(--sov-ease),
    background var(--sov-hush) var(--sov-ease),
    box-shadow var(--sov-hush) var(--sov-ease);
}

[data-sovereign] .sov-consilience-specimen__hint {
  color: var(--sov-whisper);
}

@media (max-width: 720px) {
  [data-sovereign] .sov-consilience-specimen {
    grid-template-columns: 1fr;
    gap: var(--sov-space-4);
  }
  [data-sovereign] .sov-consilience-specimen__body {
    grid-template-columns: 1fr;
    gap: var(--sov-space-4);
  }
}

/* ─── Tiered structure ────────────────────────────────────────────────────
   Hierarchy from spacing contrast: Tier 1 breathes (--sov-space-5
   internal, section rung headers); Tier 2 is compact (--sov-space-3,
   caption rung). No new colours — just room and weight. */

[data-sovereign] .sov-design-tier {
  display: flex;
  flex-direction: column;
}

[data-sovereign] .sov-design-tier--primary {
  gap: var(--sov-space-7);
}

[data-sovereign] .sov-design-tier--reference {
  gap: var(--sov-space-3);
  margin-top: var(--sov-space-6);
  padding-top: var(--sov-space-5);
  border-top: 1px solid var(--mk-hairline-gold);
}

[data-sovereign] .sov-design-tier__label {
  color: var(--sov-whisper);
  letter-spacing: 0.12em;
  margin-bottom: var(--sov-space-2);
}

[data-sovereign] .sov-design-tier--reference__families {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-design-boot__count {
  color: var(--sov-whisper);
  padding-top: var(--sov-space-2);
}

/* ─── Controlled section (replaces buggy <details>) ──────────────────────── */

[data-sovereign] .sov-design-section {
  display: flex;
  flex-direction: column;
}

[data-sovereign] .sov-design-section--reference {
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-section__trigger {
  all: unset;
  display: flex;
  align-items: baseline;
  gap: var(--sov-space-2);
  cursor: pointer;
  padding: var(--sov-space-3) var(--sov-space-4);
  border-radius: var(--sov-radius-tile);
  border: 1px solid var(--mk-hairline-gold);
  background: color-mix(in oklab, var(--sov-veil) 60%, transparent);
  transition: background var(--sov-hush) var(--sov-ease),
    border-color var(--sov-hush) var(--sov-ease);
}

[data-sovereign] .sov-design-section--primary .sov-design-section__trigger {
  padding: var(--sov-space-4) var(--sov-space-5);
}

[data-sovereign] .sov-design-section__trigger:hover {
  background: color-mix(in oklab, var(--sov-veil) 80%, transparent);
}

[data-sovereign] .sov-design-section__trigger:focus-visible {
  outline: 1px solid var(--sov-persona-accent, var(--sov-accent));
  outline-offset: 2px;
}

[data-sovereign] .sov-design-section__marker {
  font-size: 10px;
  color: var(--sov-whisper);
  transition: transform var(--sov-hush) var(--sov-ease);
  flex-shrink: 0;
}

[data-sovereign] .sov-design-section__label {
  flex: 1 1;
  min-width: 0;
}

[data-sovereign] .sov-design-section__meta {
  flex-shrink: 0;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-design-section__body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  padding: var(--sov-space-3) var(--sov-space-1) 0;
}

[data-sovereign] .sov-design-section--primary .sov-design-section__body {
  gap: var(--sov-space-4);
  padding-top: var(--sov-space-4);
}

[data-sovereign] .sov-design-section__intro {
  color: var(--sov-whisper);
  max-width: 60ch;
}

/* ─── The poetry-laden glow gallery ────────────────────────────────────────
   Each glow is a card: the live swatch (reads the actual --mk-glow-*
   var), the universal human quality (serif), the longer note, and the
   substrate token name + oklch underneath. The swatch shifts colour
   when the consilience warmth moves the persona accent. */

[data-sovereign] .sov-design-glow-gallery {
  display: grid;
  grid-gap: var(--sov-space-3);
  gap: var(--sov-space-3);
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

[data-sovereign] .sov-design-glow-card {
  display: grid;
  grid-template-columns: 48px 1fr;
  grid-gap: var(--sov-space-3);
  gap: var(--sov-space-3);
  padding: var(--sov-space-3);
  border-radius: var(--sov-radius-sm);
  background: color-mix(in oklab, var(--sov-surface-raised) 60%, transparent);
  border: 1px solid var(--mk-hairline-gold);
  align-items: start;
  transition: background var(--sov-hush) var(--sov-ease),
    border-color var(--sov-hush) var(--sov-ease),
    transform var(--sov-hush) var(--sov-ease);
}

[data-sovereign] .sov-design-glow-card:hover {
  transform: translateY(-1px);
  border-color: color-mix(in oklab, var(--mk-hairline-gold) 60%, var(--sov-persona-accent, var(--sov-accent)));
}

[data-sovereign] .sov-design-glow-card__swatch {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--glow);
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--sov-ink) 8%, transparent),
    0 6px 20px -6px var(--glow);
  transition: background var(--sov-hush) var(--sov-ease),
    box-shadow var(--sov-hush) var(--sov-ease);
}

[data-sovereign] .sov-design-glow-card__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

[data-sovereign] .sov-design-glow-card__quality {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  line-height: 1.45;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-design-glow-card__token {
  display: flex;
  flex-wrap: wrap;
  gap: 4px var(--sov-space-2);
  margin-top: 4px;
}

[data-sovereign] .sov-design-glow-card__token code {
  font-family: var(--sov-font-mono);
  font-size: 9.5px;
  color: var(--sov-whisper);
  background: color-mix(in oklab, var(--sov-surface-sunken) 70%, transparent);
  padding: 1px 5px;
  border-radius: var(--sov-radius-xs);
}

[data-sovereign] .sov-design-glow-card__value {
  color: var(--sov-faint);
}

/* ─── Right rail console ───────────────────────────────────────────────────
   One instrument, three registers. The console stacks the consilience
   intent, the chat-styled microchat, the collapsed fine-controls, and
   the original rail. */

[data-sovereign] .sov-design-rail-console {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-4);
}

/* The microchat is no longer a tile — it's a chat surface. Let it
   breathe like .sov-chat but tighter, suited to the rail width. */
[data-sovereign] .sov-design-microchat {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  padding: var(--sov-space-4);
  border-radius: var(--sov-radius-tile);
  background: color-mix(in oklab, var(--sov-veil) 50%, transparent);
  border: 1px solid var(--mk-hairline-gold);
}

[data-sovereign] .sov-design-microchat__head {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-design-microchat__messages {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  max-height: 260px;
  overflow-y: auto;
  padding: var(--sov-space-1) 0;
}

/* The fine-controls panel sits inside a collapsed section; when open,
   keep its internal tile flush (no double border). */
[data-sovereign] .sov-design-adjuster__panel {
  background: color-mix(in oklab, var(--sov-surface-sunken) 40%, transparent);
}

/* ─── Live-change transitions ──────────────────────────────────────────────
   When an override or the consilience intent changes, specimens
   cross-fade over --sov-hush (220ms) on --sov-ease. This is what turns
   "a form that updates variables" into "a living surface". Cheap CSS
   transitions only — no JS animation. Quiets under reduced motion. */

[data-sovereign] .sov-design-boot__specimens,
[data-sovereign] .sov-design-glow-card,
[data-sovereign] .sov-design-specimen {
  transition:
    background-color var(--sov-hush) var(--sov-ease),
    color var(--sov-hush) var(--sov-ease),
    border-color var(--sov-hush) var(--sov-ease),
    box-shadow var(--sov-hush) var(--sov-ease);
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-consilience-specimen__emph,
  [data-sovereign] .sov-consilience-specimen__dim-fill,
  [data-sovereign] .sov-design-glow-card__swatch,
  [data-sovereign] .sov-design-boot__specimens,
  [data-sovereign] .sov-design-glow-card,
  [data-sovereign] .sov-design-specimen,
  [data-sovereign] .sov-design-section__trigger,
  [data-sovereign] .sov-design-section__marker {
    transition: none;
  }
}

/* ---------- Library surface ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-library-deep.html
             § Shelf. Two grids: a featured "currently reading" row of
             SovereignHeroTile compact cards, then a Hopkins-gradient
             shelf of book covers (2:3 aspect, scrim, last-read marker).
             A filter pill row sits between them. */
[data-sovereign] .sov-library {
  display: flex;
  flex-direction: column;
  gap: 32px;
}
[data-sovereign] .sov-library__header {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
[data-sovereign] .sov-library__filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
[data-sovereign] .sov-library__filter {
  padding: 6px 14px;
  border-radius: var(--sov-radius-pill);
  border: 0;
  cursor: pointer;
  font-family: inherit;
  background: var(--sov-surface-raised);
  color: var(--sov-muted);
}
[data-sovereign] .sov-library__filter[data-active="true"] {
  border: 1px solid var(--mk-hairline-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-library__featured {
  display: grid;
  grid-gap: 16px;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
[data-sovereign] .sov-library__shelf {
  display: grid;
  grid-gap: 20px;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

/* Kind-row library tile — token-charted Hopkins/Rumi cover wash + meta strip.
   Significantly see-through by design: the .halfGlow() helper in
   hopkins-tile-cover-palette.ts builds each stop at 28% opacity (down
   from 62%), the three radial falloffs are widened so the color
   bleeds gently rather than pooling, and the linear corner wash
   drops to 15% so it doesn't accumulate into a solid corner-block.
   Net effect: each tile reads as a tinted watercolor over the
   parchment/dark floor — kind/mood discernible at a glance, never
   loud enough to dominate the row. */
[data-sovereign] .sov-kind-row__cover-gradient {
  position: absolute;
  inset: 0;
  background-color: var(--sov-tile-cover-floor);
  background-image:
    radial-gradient(115% 95% at 78% 16%, var(--sov-tile-cover-a) 0%, transparent 65%),
    radial-gradient(95% 85% at 18% 92%, var(--sov-tile-cover-b) 0%, transparent 70%),
    radial-gradient(150% 130% at 42% 44%, var(--sov-tile-cover-c) 0%, transparent 78%),
    linear-gradient(
      155deg,
      color-mix(in oklab, var(--sov-tile-cover-c) 15%, var(--sov-tile-cover-floor)),
      var(--sov-tile-cover-floor) 82%
    );
  background-size: 160% 160%, 170% 170%, 200% 200%, 100% 100%;
  background-position: 70% 20%, 20% 80%, 50% 50%, 0 0;
  animation: sov-tile-cover-drift 32s var(--sov-ease-out, ease-out) infinite alternate;
}
@keyframes sov-tile-cover-drift {
  from { background-position: 66% 18%, 22% 82%, 48% 50%, 0 0; }
  to { background-position: 78% 26%, 14% 74%, 54% 46%, 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-kind-row__cover-gradient {
    animation: none;
  }
}
[data-sovereign] .sov-kind-row__meta {
  background: var(--sov-tile-meta-bg);
}
[data-sovereign] .sov-kind-row__meta .sov-t-tile {
  color: var(--sov-ink);
}

/* Remove pill — top-right on the cover. Hidden until hover/focus;
 * always visible on touch (no hover). Mirrors .sov-a06-node__delete. */
[data-sovereign] .sov-kind-row__remove {
  position: absolute;
  top: var(--sov-space-2);
  right: var(--sov-space-2);
  z-index: 3;
  width: 24px;
  height: 24px;
  border-radius: var(--sov-radius-pill);
  border: 1px solid color-mix(in oklab, var(--sov-error) 24%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 85%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: color-mix(in oklab, var(--sov-error) 80%, transparent);
  font-family: var(--sov-font-sans);
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0.15s var(--sov-ease),
    background 0.15s var(--sov-ease),
    color 0.15s var(--sov-ease),
    border-color 0.15s var(--sov-ease);
}
[data-sovereign] .sov-kind-row:hover .sov-kind-row__remove,
[data-sovereign] .sov-kind-row:focus-within .sov-kind-row__remove,
[data-sovereign] a:hover .sov-kind-row__remove,
[data-sovereign] a:focus-within .sov-kind-row__remove {
  opacity: 1;
  pointer-events: auto;
}
[data-sovereign] .sov-kind-row__remove:hover {
  background: color-mix(in oklab, var(--sov-error) 14%, var(--sov-bg));
  border-color: color-mix(in oklab, var(--sov-error) 45%, transparent);
  color: var(--sov-error);
}
@media (hover: none) {
  [data-sovereign] .sov-kind-row__remove {
    opacity: 0.9;
    pointer-events: auto;
  }
}

[data-sovereign] .sov-library__card {
  display: flex;
  flex-direction: column;
  gap: 0;
}
[data-sovereign] .sov-library__cover {
  position: relative;
  aspect-ratio: 2 / 3;
  width: 100%;
  border-radius: var(--sov-radius-tile) var(--sov-radius-tile) 0 0;
  overflow: hidden;
}
[data-sovereign] .sov-library__cover-scrim {
  position: absolute;
  inset: 0;
  background: var(--sov-book-cover-scrim);
}
[data-sovereign] .sov-library__cover-marker {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sov-book-last-read);
  box-shadow: 0 0 10px -2px var(--sov-book-last-read);
}
[data-sovereign] .sov-library__card-body {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
[data-sovereign] .sov-library__last-read {
  margin: 0;
  color: var(--sov-book-last-read);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- SovereignPullQuote ----------
   Authored: sovereign-design/kaOS Design System (2)/pr/step-10/
             primitives.html §SovereignPullQuote (lines 582–609,
             dark-canonical). 3px solid gold left border + 5% gold wash on
             surface-raised; serif italic body, sans attribution. */
[data-sovereign] .sov-pull-quote {
  padding: 16px 20px;
  border-radius: 0 12px 12px 0;
  border-left: 3px solid var(--mk-glow-gold);
  background: color-mix(
    in oklab,
    var(--mk-glow-gold) 5%,
    var(--sov-surface-raised)
  );
  box-shadow: inset 0 0 0 1px var(--sov-pullquote-hairline);
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 440px;
}
[data-sovereign] .sov-pull-quote__body {
  margin: 0;
  font-family: var(--sov-font-serif);
  font-size: 16px;
  font-style: italic;
  line-height: 1.65;
  color: var(--sov-subtle);
}
[data-sovereign] .sov-pull-quote__attribution {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  color: var(--sov-muted);
}

/* ---------- SovereignAnnotationPair ----------
   Authored: sovereign-design/kaOS Design System (2)/pr/step-10/
             primitives.html §SovereignAnnotationPair (lines 611–654,
             dark-canonical). User note in pied palette; kaOS reply in
             where-light palette, indented 16px to read as response. */
[data-sovereign] .sov-annotation-pair {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 440px;
}
[data-sovereign] .sov-annotation-pair__card {
  padding: 12px 16px;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
[data-sovereign] .sov-annotation-pair__card--user {
  background: color-mix(
    in oklab,
    var(--mk-glow-pied-beauty) 6%,
    var(--sov-surface-raised)
  );
  box-shadow: inset 0 0 0 1px var(--mk-hairline-pied);
}
[data-sovereign] .sov-annotation-pair__card--kaos {
  margin-left: 16px;
  background: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 6%,
    var(--sov-surface-raised)
  );
  box-shadow: inset 0 0 0 1px var(--mk-hairline-where-light);
}
[data-sovereign] .sov-annotation-pair__head {
  display: flex;
  align-items: center;
  gap: 6px;
}
[data-sovereign] .sov-annotation-pair__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--mk-glow-pied-beauty);
  display: inline-block;
}
[data-sovereign] .sov-annotation-pair__label {
  font-family: var(--sov-font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mk-glow-pied-beauty);
}
[data-sovereign] .sov-annotation-pair__label--kaos {
  color: var(--mk-glow-gold);
}
[data-sovereign] .sov-annotation-pair__source {
  font-family: var(--sov-font-serif);
  font-size: 13px;
  font-style: italic;
  color: var(--sov-muted);
  line-height: 1.5;
  padding-left: 12px;
  border-left: 2px solid var(--mk-hairline-pied);
}
[data-sovereign] .sov-annotation-pair__body {
  font-size: 13px;
  color: var(--sov-subtle);
}
[data-sovereign] .sov-annotation-pair__body--user {
  font-family: var(--sov-font-sans);
  line-height: 1.5;
}
[data-sovereign] .sov-annotation-pair__body--kaos {
  font-family: var(--sov-font-serif);
  line-height: 1.6;
  font-style: italic;
}

/* ---------- SovereignBookmarkGutter ----------
   Authored: sovereign-design/kaOS Design System (3)/source/components/
             reader-bookmark-gutter.html. Vertical 24px progress spine —
             pied hairline track, sanctioned bookmark dots, breathing
             presence dot at the active position. Reduced-motion freezes
             the dot via the global @media rule. */
[data-sovereign] .sov-bookmark-gutter {
  position: relative;
  width: 24px;
  height: 100%;
  flex-shrink: 0;
}
[data-sovereign] .sov-bookmark-gutter__track {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  margin-left: -0.5px;
  background: linear-gradient(
    180deg,
    transparent 0%,
    var(--mk-hairline-pied) 8%,
    var(--mk-hairline-pied) 92%,
    transparent 100%
  );
}
[data-sovereign] .sov-bookmark-gutter__bookmark {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 4px;
  background: transparent;
  border: 0;
}
[data-sovereign] button.sov-bookmark-gutter__bookmark {
  cursor: pointer;
}
[data-sovereign] .sov-bookmark-gutter__dot {
  display: block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--sov-bookmark);
  box-shadow: 0 0 6px color-mix(in oklab, var(--sov-bookmark) 50%, transparent);
}
[data-sovereign] .sov-bookmark-gutter__progress {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---------- Chat page surface ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-chat-deep.html.
   The standalone chat surface (when not opened as the modal chat-room).
   Bubble alignment alternates by speaker; presence dot leads the heading. */
[data-sovereign] .sov-chat-page {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 680px;
  margin-inline: auto;
  width: 100%;
}
[data-sovereign] .sov-chat-page__heading {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
[data-sovereign] .sov-chat-page__presence {
  display: flex;
  align-items: center;
  gap: 8px;
}
[data-sovereign] .sov-chat-page__thread {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
[data-sovereign] .sov-chat-page__turn {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
}
[data-sovereign] .sov-chat-page__turn[data-from="user"] {
  align-items: flex-end;
}
[data-sovereign] .sov-chat-page__bubble-body {
  color: inherit;
  white-space: pre-wrap;
}
[data-sovereign] .sov-chat-page__error {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border-radius: var(--sov-radius-tile);
  background: var(--sov-chat-tool-bg);
  border: 1px solid var(--sov-chat-tool-border);
}
[data-sovereign] .sov-chat-page__retry {
  align-self: flex-start;
  margin-top: 4px;
  padding: 6px 12px;
  border: 0;
  border-radius: var(--sov-radius-pill);
  background: var(--sov-ink);
  color: var(--sov-bg);
  cursor: pointer;
}
[data-sovereign] .sov-chat-page__tail {
  height: 1px;
}

/* ---------- Reader surface ----------
   Authored: sovereign-design/kaOS Design System (3)/canvas-folio-deep.html,
             source/components/reader-passage.html. Two-track grid: a thin
             24px sticky bookmark gutter, then a 640px serif passage column.
             Body prose is the sovereign reading voice (17/1.75/-0.003em). */
[data-sovereign] .sov-reader {
  display: grid;
  grid-template-columns: 24px minmax(0, 640px);
  grid-gap: 24px;
  gap: 24px;
  max-width: 704px;
  margin-inline: auto;
  padding-block: 16px;
}
[data-sovereign] .sov-reader__gutter {
  position: -webkit-sticky;
  position: sticky;
  top: 64px;
  height: min(680px, 82dvh);
}
[data-sovereign] .sov-reader__column {
  display: flex;
  flex-direction: column;
  gap: 28px;
}
[data-sovereign] .sov-reader__heading {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
[data-sovereign] .sov-reader__paragraph {
  margin: 0;
  color: var(--sov-ink);
  line-height: 1.75;
  font-size: 17px;
  letter-spacing: -0.003em;
}
[data-sovereign] .sov-reader__highlight {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
[data-sovereign] .sov-reader__ask-card {
  margin-top: 12px;
  padding: 16px 18px;
  background: var(--sov-interaction-ask-bg);
  border: 1px solid var(--sov-interaction-ask-border);
  border-radius: var(--sov-radius-tile);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
[data-sovereign] .sov-reader__ask-button {
  align-self: flex-start;
  padding: var(--sov-space-2) 14px;
  border-radius: var(--sov-radius-pill);
  border: 1px solid var(--sov-interaction-ask-border);
  background: transparent;
  color: var(--sov-interaction-ask-action);
  cursor: pointer;
  font-family: inherit;
}
[data-sovereign] .sov-reader__pause {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: center;
}
[data-sovereign] .sov-reader__sheet {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
[data-sovereign] .sov-reader__sheet-passage {
  padding: 14px;
  border-radius: var(--sov-radius-tile);
  background: var(--sov-interaction-pull-quote-bg);
  border-left: var(--sov-interaction-pull-quote-border-w) solid
    var(--sov-interaction-pull-quote-border);
}
[data-sovereign] .sov-reader__sheet-textarea {
  width: 100%;
  resize: vertical;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--sov-ink);
  font-family: inherit;
  line-height: 1.6;
}
[data-sovereign] .sov-reader__sheet-send {
  align-self: flex-start;
  padding: 10px 16px;
  border-radius: var(--sov-radius-pill);
  border: 0;
  background: var(--sov-ink);
  color: var(--sov-bg);
  cursor: pointer;
  font-family: inherit;
}

/* ---------- kaOS Wordmark ----------
   Single source: tokens above + this block + COMPOSITION.md § Wordmark.
   `default` / `hopkins` — .sov-wordmark--malaika (sans black, hopkins
   multicolor, @keyframes sov-gold-shimmer, --sov-wordmark-shimmer 22s).
   Other variants — .sov-wordmark--text (serif, glow gradients, 16s cycle). */
[data-sovereign] .sov-wordmark {
  display: inline-block;
  margin: 0;
}
[data-sovereign] .sov-wordmark--malaika {
  line-height: 1;
  font-family: var(--font-sans, var(--sov-font-sans));
  font-size: var(--sov-wordmark-size, 24px);
  font-weight: var(--sov-wordmark-malaika-weight);
  letter-spacing: var(--sov-wordmark-malaika-tracking);
  background-image: var(--sov-wordmark-malaika-gradient);
  background-size: 300% 300%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: sov-gold-shimmer var(--sov-wordmark-shimmer) ease-in-out infinite;
  vertical-align: middle;
}
[data-sovereign] .sov-wordmark--text {
  font-family: var(--sov-font-serif);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  font-size: var(--sov-wordmark-size, 24px);
  background-image: var(
    --sov-wordmark-gradient,
    linear-gradient(
      135deg,
      var(--mk-glow-gold-soft),
      var(--mk-glow-gold),
      var(--mk-glow-gold-deep),
      var(--mk-glow-gold)
    )
  );
  background-size: 300% 300%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: sov-gold-shimmer var(--sov-wordmark-cycle) ease-in-out infinite;
}
[data-sovereign] .sov-wordmark--text[data-variant="kingfishers"] {
  --sov-wordmark-gradient: linear-gradient(
    135deg,
    var(--mk-glow-heaven-haven),
    var(--mk-glow-as-kingfishers-catch-fire),
    var(--mk-glow-inversnaid)
  );
}
[data-sovereign] .sov-wordmark--text[data-variant="rumi"],
[data-sovereign] .sov-wordmark--text[data-variant="where-light-enters"] {
  --sov-wordmark-gradient: linear-gradient(
    135deg,
    var(--mk-glow-ruin-and-treasure),
    var(--mk-glow-where-light-enters),
    var(--mk-glow-morning-breeze)
  );
}
[data-sovereign] .sov-wordmark--text[data-variant="pied"],
[data-sovereign] .sov-wordmark--text[data-variant="pied-beauty"] {
  --sov-wordmark-gradient: linear-gradient(
    135deg,
    var(--mk-glow-spring-and-fall),
    var(--mk-glow-pied-beauty),
    var(--mk-glow-gods-grandeur)
  );
}
[data-sovereign] .sov-wordmark--text[data-variant="windhover"],
[data-sovereign] .sov-wordmark--text[data-variant="the-windhover"] {
  --sov-wordmark-gradient: linear-gradient(
    135deg,
    var(--mk-glow-the-starlight-night),
    var(--mk-glow-the-windhover),
    var(--mk-glow-gods-grandeur)
  );
}
[data-sovereign] .sov-wordmark[data-size="sm"] {
  --sov-wordmark-size: 20px;
}
[data-sovereign] .sov-wordmark[data-size="md"] {
  --sov-wordmark-size: 32px;
}
[data-sovereign] .sov-wordmark[data-size="lg"] {
  --sov-wordmark-size: 48px;
}
/* ── Deleted (step-40): .sov-nav-rail__brand wordmark override — dead component CSS. */
[data-sovereign] .sov-wordmark--text[data-motion="off"] {
  animation: none;
}
[data-sovereign] .sov-wordmark--malaika[data-motion="off"] {
  animation: none;
}

/* ═══════════════════════════════════════════════════════════════════
   PRESENCE SURFACE — Malaika's full-screen voice/video face
   ───────────────────────────────────────────────────────────────────
   The presence surface is what fills the screen when a family member
   is in voice mode (or video mode) with Malaika. Three variants share
   one state machine and one set of word layers:

     • constellation — Consilience: a soft drifting holy-gold rosette
                       at the center, never an iris; family + specialist
                       lights orbit; names appear only on hover.
     • threshold    — a column of light through a door left open;
                       the aperture opens wider when she is listening.
     • hearth       — a single warm halo against the dark; the minimum
                       durable presence. For phones, low bandwidth, or
                       screensaver mode.

   State drives three custom @property values which animate cleanly
   between Hopkins/Rumi seeds. No inline JS animations. No invented
   tokens — every color comes from --mk-glow-* / --sov-presence-*.

   See: sovereign-design/.../Malaika Presence Developed - standalone.html
        packages/kaos-sovereign/components/sovereign-presence-surface.tsx
        packages/kaos-sovereign/hooks/use-presence-state.ts
   ═══════════════════════════════════════════════════════════════════ */

@property --sov-presence-glow {
  syntax: "<color>";
  inherits: true;
  initial-value: oklch(0.82 0.14 80);
}
@property --sov-presence-aperture-w {
  syntax: "<length>";
  inherits: true;
  initial-value: 2px;
}

[data-sovereign] [data-presence-surface] {
  /* Canonical defaults — overridden per [data-presence-state] below. */
  --sov-presence-glow: var(--sov-presence-idle);
  --sov-presence-dur: var(--sov-presence-dur-idle, 4.2s);
  --sov-presence-aperture-w: 2px;

  /* The five state durations live here so consumers can override. */
  --sov-presence-dur-idle: var(--sov-breath, 4.2s);
  --sov-presence-dur-listening: 2.4s;
  --sov-presence-dur-thinking: 1.8s;
  --sov-presence-dur-speaking: 1.2s;
  --sov-presence-dur-paused: 9999s;

  /* Cross-fade glow + aperture between states. The transition is
     deliberately slow (1.5s) so a state change feels like a breath, not
     a switch. Honor reduced-motion via the global block at file end. */
  transition: --sov-presence-glow 1.5s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    --sov-presence-aperture-w 1.3s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));

  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--mk-bg);
  color: var(--mk-fg);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  overflow: hidden;
  contain: layout paint;
  /* The portal wrapper opts out of pointer events; the surface
     opts back in so its click handler (mode toggle) still fires. */
  pointer-events: auto;
}

/* ── Presence modes ─────────────────────────────────────────────
   The surface has two modes:
     • fullscreen → portaled to <body>, sits atop all sovereign
       chrome (rail, composer, topmeta). The default.
     • pocket    → docked compactly at the bottom-center as a
       smaller, persistent presence while the user is on another
       surface. The conversation never stops; the surface just
       takes less room. Tap the dock to expand back to fullscreen.

   When dismissed entirely the host page unmounts the surface; the
   bus stops with it. Dismissal is the X button only — clicking
   outside controls slips the surface into pocket mode. */
[data-sovereign] [data-presence-surface][data-presence-mode="fullscreen"] {
  position: fixed;
  inset: 0;
  border-radius: 0;
  cursor: default;
}
/* Pocket — the docked, persistent presence. The dock now lands
 * inside the right rail's bottom area (above the footer) rather than
 * floating at the viewport's bottom-centre over empty space. The
 * spatial logic is: the right rail is the family's "what's around
 * Malaika right now" column (activity, library tiles, focus
 * controls), and the dock joins it as one more companion at the base
 * — anchored, not orphaned. Width fits within the rail's content
 * area (rail width minus its own padding both sides). Height stays
 * dock-sized at 96px so the constellation core, Malaika's words, and
 * the user's words still read clearly inside it. */
[data-sovereign] [data-presence-surface][data-presence-mode="pocket"] {
  position: fixed;
  inset: auto;
  bottom: var(--sov-gutter, 24px);
  right: var(--sov-rail-pad, 24px);
  left: auto;
  transform: none;
  width: calc(
    var(--sov-layout-right-rail-width, 270px) -
    var(--sov-rail-pad, 24px) *
    2
  );
  height: 96px;
  border-radius: 18px;
  border: 1px solid color-mix(in oklab, var(--mk-fg) 14%, transparent);
  background: color-mix(in oklab, var(--mk-bg) 92%, transparent);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  box-shadow: 0 18px 70px -28px
    color-mix(in oklab, var(--sov-presence-glow) 38%, transparent), 0 1px 0 0
    color-mix(in oklab, var(--mk-fg) 6%, transparent) inset;
  cursor: pointer;
  z-index: 9999;
  transition:
    width 0.6s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    height 0.6s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    bottom 0.6s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    right 0.6s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.6s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    --sov-presence-glow 1.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    --sov-presence-aperture-w 1.3s var(
      --sov-ease-expo,
      cubic-bezier(0.16, 1, 0.3, 1)
    );
}
/* On viewports too narrow for a right-rail-anchored dock (mobile,
 * narrow side panes), fall back to a centred dock so the affordance
 * stays usable. The threshold matches the breakpoint where the rail
 * collapses elsewhere in the system. */
@media (max-width: 720px) {
  [data-sovereign] [data-presence-surface][data-presence-mode="pocket"] {
    right: auto;
    left: 50%;
    transform: translateX(-50%);
    width: clamp(260px, 80vw, 360px);
  }
}
/* Pocket-mode word layers — quieter, single-line, tightly contained. */
[data-sovereign]
  [data-presence-surface][data-presence-mode="pocket"]
  .sov-presence-malaika-words {
  position: absolute;
  inset: auto 56px 8px 56px;
  bottom: 8px;
  font-size: 0.78rem;
  line-height: 1.25;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-height: 1.25em;
}
[data-sovereign]
  [data-presence-surface][data-presence-mode="pocket"]
  .sov-presence-user-words {
  display: none;
}
/* Pocket mode mutes the constellation a touch so the dock reads as
   a quiet companion, not a full surface. */
[data-sovereign]
  [data-presence-surface][data-presence-mode="pocket"]
  .sov-presence-canvas {
  opacity: 0.92;
}

/* ── Chrome (only relevant in fullscreen) ─────────────────────── */
[data-sovereign] .sov-presence-chrome {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}
[data-sovereign] .sov-presence-chrome > * {
  pointer-events: auto;
}
/* Close trigger — the quiet exit from voice or pretext back to the
 * linear surface. At rest it's a calm hairline disc carrying the
 * same `--mk-bg` 72% shell as its sibling chrome (variant picker on
 * the left), so the two read as one family. On approach it warms
 * into the same gold bloom recipe the Go Live and My turn pills use
 * one row down — 10% warm fill, 50% gold border, 18% gold halo,
 * glyph shifts to `--mk-glow-gold`. The chrome answers the paired
 * pills with the same warmth, so the whole surface feels like one
 * choreographed set rather than three unrelated controls. */
[data-sovereign] .sov-presence-close-btn {
  position: absolute;
  top: clamp(14px, 3vh, 28px);
  right: clamp(14px, 3vw, 28px);
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: color-mix(in oklab, var(--mk-bg) 72%, transparent);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 24%, transparent);
  color: var(--mk-fg);
  cursor: pointer;
  opacity: 0.78;
  transition:
    opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-close-btn:hover,
[data-sovereign] .sov-presence-close-btn:focus-visible {
  opacity: 1;
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, var(--mk-bg));
  border-color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
  box-shadow: 0 0 18px 4px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
  color: var(--mk-glow-gold);
  outline: none;
}
[data-sovereign] .sov-presence-close-btn::before,
[data-sovereign] .sov-presence-close-btn::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 1.4px;
  border-radius: 1px;
  background: currentColor;
  transform-origin: center;
}
[data-sovereign] .sov-presence-close-btn::before {
  transform: rotate(45deg);
}
[data-sovereign] .sov-presence-close-btn::after {
  transform: rotate(-45deg);
}

/* Minimise trigger — the explicit "send this to the dock" affordance,
 * anchored at the bottom-right of the fullscreen modal so it reads as
 * the inverse of the close button at the top-right. Same disc
 * geometry, same gold-bloom recipe on hover, same backdrop blur, so
 * the chrome corners feel like one matched pair rather than two
 * unrelated controls. The glyph is a single horizontal bar carrying
 * the same stroke recipe as the close X (14×1.4px, soft caps),
 * positioned slightly below centre — a subtle baseline-rest gesture
 * that signals "settle to the dock" without needing an arrow. */
[data-sovereign] .sov-presence-minimize-btn {
  position: absolute;
  bottom: clamp(14px, 3vh, 28px);
  right: clamp(14px, 3vw, 28px);
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: color-mix(in oklab, var(--mk-bg) 72%, transparent);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 24%, transparent);
  color: var(--mk-fg);
  cursor: pointer;
  opacity: 0.78;
  transition:
    opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-minimize-btn:hover,
[data-sovereign] .sov-presence-minimize-btn:focus-visible {
  opacity: 1;
  background: color-mix(in oklab, var(--mk-glow-gold) 10%, var(--mk-bg));
  border-color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
  box-shadow: 0 0 18px 4px
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
  color: var(--mk-glow-gold);
  outline: none;
}
[data-sovereign] .sov-presence-minimize-btn::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 1.4px;
  border-radius: 1px;
  background: currentColor;
  /* Sit just below centre so the bar reads as a base/dock line. */
  transform: translateY(4px);
}

[data-sovereign] .sov-presence-variant-picker {
  position: absolute;
  top: clamp(14px, 3vh, 28px);
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--mk-bg) 72%, transparent);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 14%, transparent);
  opacity: 0.6;
  transition: opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-variant-picker:hover,
[data-sovereign] .sov-presence-variant-picker:focus-within {
  opacity: 1;
}
[data-sovereign] .sov-presence-variant-picker__btn {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  border: 0;
  color: var(--mk-muted);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-variant-picker__btn[aria-pressed="true"] {
  color: var(--mk-fg);
  background: color-mix(in oklab, var(--sov-presence-glow) 18%, transparent);
}

/* ── Live mode toggle ─────────────────────────────────────────────
   Sits opposite the close button (top-left) so the chrome row is
   balanced: [ Live · variants · X ]. The pill carries a faint
   energy meter — its outer glow rises with --sov-live-energy
   (0..1), feeding back to the family that the mic is hearing them
   without surfacing a literal waveform. */
[data-sovereign] .sov-presence-live-toggle {
  position: absolute;
  top: clamp(14px, 3vh, 28px);
  left: clamp(14px, 3vw, 28px);
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--mk-bg) 72%, transparent);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 14%, transparent);
  color: var(--mk-muted);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0.6;
  --sov-live-energy: 0;
  transition:
    opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    color 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    background 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.25s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-live-toggle:hover,
[data-sovereign] .sov-presence-live-toggle:focus-visible {
  opacity: 1;
  outline: none;
}
[data-sovereign] .sov-presence-live-toggle[data-live="true"] {
  opacity: 1;
  color: var(--mk-fg);
  background: color-mix(
    in oklab,
    var(--sov-presence-listening) 14%,
    var(--mk-bg)
  );
  border-color: color-mix(
    in oklab,
    var(--sov-presence-listening) 36%,
    transparent
  );
  box-shadow: 0 0 18px calc(8px * var(--sov-live-energy))
    color-mix(
      in oklab,
      var(--sov-presence-listening) calc(60% * var(--sov-live-energy)),
      transparent
    );
}
[data-sovereign] .sov-presence-live-toggle__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--mk-fg) 20%, transparent);
  box-shadow: none;
  transition: background 0.3s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)), box-shadow 0.3s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign]
  .sov-presence-live-toggle[data-live="true"]
  .sov-presence-live-toggle__dot {
  background: var(--sov-presence-listening);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-listening) 70%, transparent);
}
/* While Malaika is speaking, the dot tints toward the speaking glow
   so a glance at the chrome reads the room without the family
   needing to look at the surface center. */
[data-sovereign]
  .sov-presence-live-toggle[data-presence-state="speaking"]
  .sov-presence-live-toggle__dot {
  background: var(--sov-presence-speaking);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-speaking) 70%, transparent);
}
[data-sovereign]
  .sov-presence-live-toggle[data-presence-state="thinking"]
  .sov-presence-live-toggle__dot {
  background: var(--sov-presence-thinking);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-thinking) 70%, transparent);
}
[data-sovereign] .sov-presence-live-toggle__label {
  white-space: nowrap;
}

/* Pocket-mode chrome adjustments — the X button hides; tapping the
   dock anywhere expands it back. The variant picker is invisible. */
[data-sovereign]
  [data-presence-surface][data-presence-mode="pocket"]
  .sov-presence-chrome {
  display: none;
}

/* ---------- §17.x Sovereign Voice Composer ----------
   Sanctioned under Charter Rule 5b (Sovereign Design Authority).

   Authored: sovereign-design/kaOS Design System (self-authored)/pr/step-28/PR.md
             — voice composer: from chrome to companion.
   Supersedes the 2026-04-26 visual-language hardening pass for this
   cluster while preserving the layout invariants of that pass
   (positioning, z-index, hidden-in-pocket-mode).

   The voice composer is the single chrome the family touches in
   voice mode: mic button (with an inline dewdrop rosette glyph that
   echoes the central rosette of the constellation), status label, a
   keyboard-shortcut chip in idle push-to-talk, and a rare error
   label. Lives under the presence surface, fixed-bottom-centre,
   raised above the visual-rail pip but never above the surface
   itself.

   Token-first invariants (carried verbatim from step-26):
     - All sizing references --sov-space-*, --sov-radius-*.
     - All colour references --sov-presence-*, --mk-glow-*, --mk-fg,
       --mk-bg.
     - Motion eases on --sov-ease-expo / --sov-ease-spring with the
       canonical cubic-bezier as fallback.
     - Breath cadences mirror the constellation's BREATH_DUR_MS
       table verbatim (2.4s listening, 1.8s thinking — see PR.md
       §Token provenance).
     - Stacking context: the composer is a direct sibling of the
       presence-surface (z=9999) inside `.sov-voice-portal` (z=60),
       so it MUST sit at z=10000 to be reachable. The earlier z=65
       was a footgun — clicks on the My turn / Go Live pills were
       intercepted by the surface's full-viewport `position: fixed;
       inset: 0` div sitting on top of them, which then ran the
       surface's onClick (auto-collapse). Sits just below the
       visual-rail (z=10001) which floats above the composer as the
       canonical content side-channel. */
[data-sovereign] .sov-voice-composer {
  position: fixed;
  bottom: clamp(
    var(--sov-space-7, 48px),
    14vh,
    var(--sov-space-8, 64px) +
    var(--sov-space-7, 48px)
  );
  left: 50%;
  transform: translateX(-50%);
  z-index: 10000;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* § 2026-06-28 — vertical breath. The gap between the control row
   * and the caption was 8px and the pills were 10px tall in padding;
   * both felt cramped against the constellation above. Widened the
   * stack gap to --sov-space-4 (16px) so the caption reads as a
   * separate line, not a continuation of the pills. */
  gap: var(--sov-space-4, 16px);
  pointer-events: auto;
}
[data-sovereign] .sov-voice-composer[data-hidden="true"] {
  /* Pocket mode: the dock takes over as the voice affordance. */
  display: none;
}

/* § 2026-06-28 — Composer stage wrapper.
 *
 * The stage is the surface that carries the controls. It gets a soft
 * glass backdrop so the pills read against any constellation bloom
 * that drifts behind them, plus a hairline inner highlight to feel
 * like a held tray rather than floating chrome. The stage's padding
 * is generous on both axes so the controls feel like they belong to
 * a considered surface, not a tight cluster. */
[data-sovereign] .sov-voice-composer__stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sov-space-3, 12px) var(--sov-space-5, 24px);
  border-radius: var(--sov-radius-pill, 999px);
  background: color-mix(in oklab, var(--mk-bg) 62%, transparent);
  backdrop-filter: blur(24px) saturate(140%);
  -webkit-backdrop-filter: blur(24px) saturate(140%);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 10%, transparent);
  box-shadow:
    0 24px 80px -32px color-mix(in oklab, var(--sov-presence-glow) 38%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 8%, transparent) inset,
    0 -8px 24px -16px color-mix(in oklab, var(--mk-glow-gold) 22%, transparent) inset;
  transition:
    background 0.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
/* When the room is listening or Malaika is speaking, warm the stage's
 * outer glow toward the active presence colour so the whole composer
 * reads as a child of the constellation's current breath. */
[data-sovereign] .sov-voice-composer[data-presence-state="listening"]
  .sov-voice-composer__stage {
  border-color: color-mix(in oklab, var(--sov-presence-listening) 28%, transparent);
  box-shadow:
    0 24px 80px -32px color-mix(in oklab, var(--sov-presence-listening) 32%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 8%, transparent) inset,
    0 -8px 24px -16px color-mix(in oklab, var(--sov-presence-listening) 24%, transparent) inset;
}
[data-sovereign] .sov-voice-composer[data-presence-state="speaking"]
  .sov-voice-composer__stage {
  border-color: color-mix(in oklab, var(--sov-presence-speaking) 28%, transparent);
  box-shadow:
    0 24px 80px -32px color-mix(in oklab, var(--sov-presence-speaking) 32%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 8%, transparent) inset,
    0 -8px 24px -16px color-mix(in oklab, var(--sov-presence-speaking) 24%, transparent) inset;
}
[data-sovereign] .sov-voice-composer[data-presence-state="thinking"]
  .sov-voice-composer__stage {
  border-color: color-mix(in oklab, var(--sov-presence-thinking) 24%, transparent);
  box-shadow:
    0 24px 80px -32px color-mix(in oklab, var(--sov-presence-thinking) 28%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 8%, transparent) inset,
    0 -8px 24px -16px color-mix(in oklab, var(--sov-presence-thinking) 22%, transparent) inset;
}

/* Caption surface — the soft floor under the stage where the status
 * hint and error label live. Sits on its own line so the pills never
 * fight it for vertical room. Width matches the stage so the eye
 * reads the two as one composed column. */
[data-sovereign] .sov-voice-composer__caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sov-space-1, 4px);
  max-width: min(520px, 90vw);
  text-align: center;
}

/* ── Next CSS block ── */

/* The mic button — at rest, a soft warm well rather than a hard pill.
   The well recipe matches the constellation's outer halo gradient
   verbatim (gold at low alpha, fading to transparent), so the
   affordance reads as a child of the rosette above it rather than as
   foreign UI. The hairline border is invisible at rest and returns
   only on :focus-visible (a11y-mandated) and on recording state
   (state-mandated). */
/* My turn — the discrete-utterance affordance.
 *
 * Architecturally a sibling of `.sov-voice-composer__go-live`: same
 * pill shape, same padding rhythm, same font, same border-radius
 * token. The Go Live pill carries a small breathing dot in
 * presence-listening green; the My turn pill carries the rosette
 * glyph in `--mk-glow-gold`. Together they read as one paired set —
 * stay on the line, or claim one turn.
 *
 * State changes (recording, thinking) shift the pill's tint and the
 * rosette's color independently of the label text. The label always
 * sits in `--mk-fg`. The recording state retains the listen-ring
 * (defined below) for visual rhyme with the constellation breath. */
[data-sovereign] .sov-voice-composer__mic {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  position: relative;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 10px;
  /* § 2026-06-28 — taller pills with more vertical room. Was
   * 10px 20px 10px 14px; the new rhythm gives the rosette glyph
   * space to breathe beside the label stack and the whole pill
   * reads as a deliberate surface rather than a tight tag. */
  padding: 14px 24px 14px 16px;
  min-width: 148px;
  min-height: 64px;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--mk-glow-gold) 14%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--mk-glow-gold) 8%, var(--mk-bg));
  color: var(--mk-fg);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 0.3s var(--sov-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
/* The label-stack wrapper inside the mic pill — sits to the right of
 * the rosette glyph, holds the primary label and the sub-label. */
[data-sovereign] .sov-voice-composer__mic-text {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  line-height: 1.1;
}
[data-sovereign] .sov-voice-composer__mic:hover,
[data-sovereign] .sov-voice-composer__mic:focus-visible {
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--mk-glow-gold) 22%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--mk-glow-gold) 14%, var(--mk-bg));
  border-color: color-mix(in oklab, var(--mk-glow-gold) 54%, transparent);
  box-shadow:
    0 0 22px 6px color-mix(in oklab, var(--mk-glow-gold) 22%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 10%, transparent) inset;
  transform: translateY(-1px);
  outline: none;
}
[data-sovereign] .sov-voice-composer__mic:active {
  transform: translateY(0);
}
[data-sovereign] .sov-voice-composer__mic[data-state="recording"] {
  border-color: color-mix(
    in oklab,
    var(--sov-mic-recording) 42%,
    transparent
  );
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--sov-mic-recording) 16%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--sov-mic-recording) 10%, var(--mk-bg));
}
[data-sovereign] .sov-voice-composer__mic[data-state="thinking"] {
  border-color: color-mix(
    in oklab,
    var(--sov-mic-recording) 28%,
    transparent
  );
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--sov-mic-recording) 10%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--sov-mic-recording) 6%, var(--mk-bg));
}

/* My turn label stack — primary label + faint sub-label that names
 * the current mic state in plain language. The sub-label is set in
 * the serif italic so it reads as a soft caption rather than another
 * piece of UI text. */
[data-sovereign] .sov-voice-composer__mic-label {
  color: var(--mk-fg);
  font-size: 13px;
  font-weight: 500;
}
[data-sovereign] .sov-voice-composer__mic-sub {
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--mk-fg) 56%, transparent);
  text-transform: lowercase;
}

/* Recording listen-ring — a single ring expanding outward and fading,
   synced to the constellation's BREATH_DUR_MS.listening cadence
   (2.4s). The ring is the affordance breathing with the rosette
   above it; the synchronisation is the design. Suppressed entirely
   under prefers-reduced-motion (see §reduced-motion block). */
[data-sovereign] .sov-voice-composer__mic[data-state="recording"]::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid
    color-mix(in oklab, var(--sov-mic-recording) 38%, transparent);
  opacity: 0;
  pointer-events: none;
  animation: sov-voice-listen-ring 2.4s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}

@keyframes sov-voice-listen-ring {
  0% {
    transform: scale(0.86);
    opacity: 0;
  }
  28% {
    opacity: 0.7;
  }
  100% {
    transform: scale(1.32);
    opacity: 0;
  }
}

/* The dewdrop rosette — eight petals around a soft inner halo,
   drawn inline as SVG inside the mic button. The motif is lifted
   verbatim from the central rosette in sovereign-presence-surface.tsx
   (drawConstellation §Petals) so the affordance is visibly a
   miniature of the constellation it serves.

   The petals breathe on the constellation's --sov-breath cadence
   when idle. They bloom outward (~12% scale) on listening and
   thinking, on the BREATH_DUR_MS cadences (2.4s, 1.8s) so the
   affordance rhymes with the central rosette's own breath table. */
[data-sovereign] .sov-voice-composer__rosette {
  /* § 2026-06-28 — bumped from 22px to 26px so the glyph holds its
   * own against the taller pills (now 64px min-height). The rosette
   * is the visual anchor of the My turn pill; at 22px it started to
   * feel like a punctuation mark rather than a presence. */
  width: 26px;
  height: 26px;
  display: block;
  pointer-events: none;
  overflow: visible;
  /* The rosette declares its own color (consumed by `currentColor`
   * on the petals + core fills). Decoupled from the parent button so
   * the My turn label can stay in `--mk-fg` while the rosette keeps
   * its own state-driven palette. */
  color: var(--mk-glow-gold);
  flex-shrink: 0;
  transition: color var(--sov-d-base, 280ms)
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-voice-composer__rosette[data-state="recording"] {
  color: var(--sov-mic-recording);
}
[data-sovereign] .sov-voice-composer__rosette[data-state="thinking"] {
  color: var(--sov-mic-recording);
}
[data-sovereign] .sov-voice-composer__rosette .sov-voice-composer__petals {
  transform-origin: 16px 16px;
  transition: transform var(--sov-d-base, 280ms)
    var(--sov-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle {
  fill: currentColor;
  opacity: 0.78;
  transform-origin: 16px 16px;
  animation: sov-voice-rosette-breathe var(--sov-breath, 4.2s)
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(1) {
  animation-delay: 0s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(2) {
  animation-delay: -0.5s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(3) {
  animation-delay: -1.05s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(4) {
  animation-delay: -1.6s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(5) {
  animation-delay: -2.1s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(6) {
  animation-delay: -2.65s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(7) {
  animation-delay: -3.2s;
}
[data-sovereign]
  .sov-voice-composer__rosette
  .sov-voice-composer__petals
  circle:nth-child(8) {
  animation-delay: -3.75s;
}

[data-sovereign] .sov-voice-composer__rosette .sov-voice-composer__core {
  fill: currentColor;
  opacity: 0.55;
}

@keyframes sov-voice-rosette-breathe {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 0.92;
  }
}

[data-sovereign]
  .sov-voice-composer__rosette[data-state="recording"]
  .sov-voice-composer__petals {
  animation: sov-voice-rosette-bloom 2.4s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}
[data-sovereign]
  .sov-voice-composer__rosette[data-state="thinking"]
  .sov-voice-composer__petals {
  animation: sov-voice-rosette-bloom 1.8s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}

@keyframes sov-voice-rosette-bloom {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.12);
  }
}

/* The label — Newsreader italic, lowercase, soft-tracked, at 70%
   foreground. This brings the label into the same typographic
   family as the Hopkins glow names breathing on the surface above,
   replacing the Inter-uppercase-tracked admin register. */
[data-sovereign] .sov-voice-composer__label {
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-size: 13px;
  letter-spacing: 0.005em;
  text-transform: none;
  color: color-mix(in oklab, var(--mk-fg) 70%, transparent);
  text-align: center;
  max-width: 60vw;
}

[data-sovereign] .sov-voice-composer__error {
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-size: 12px;
  letter-spacing: 0.005em;
  color: color-mix(in oklab, var(--sov-presence-error) 70%, var(--mk-fg));
  text-align: center;
  max-width: 70vw;
  margin-top: var(--sov-space-1, 4px);
}

/* ── VoiceComposer Go Live / energy redesign ────────────────────────
   Push-to-talk row: Go Live CTA (primary) + mic icon (secondary).
   Live row: live-pip + LIVE label + energy bar + End Live button.
   The container becomes wider when live to accommodate the energy bar. */

[data-sovereign] .sov-voice-composer__ptt-row,
[data-sovereign] .sov-voice-composer__live-row {
  display: flex;
  align-items: center;
  /* § 2026-06-28 — wider gap so the two pills and the divider
   * between them read as a composed pair, not a tight cluster. */
  gap: var(--sov-space-3, 12px);
}
[data-sovereign] .sov-voice-composer__live-row {
  gap: var(--sov-space-4, 16px);
}

/* Divider — the hairline vertical that separates Go Live from My
 * turn inside the stage. Reads as a quiet gutter between the two
 * affordances so they don't merge into one. */
[data-sovereign] .sov-voice-composer__divider {
  width: 1px;
  height: 36px;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    color-mix(in oklab, var(--mk-fg) 22%, transparent) 50%,
    transparent 100%
  );
  flex-shrink: 0;
}

/* Live-row meta cluster — holds the LIVE label, pip, and energy bar.
 * Sits to the left of the End Live button. */
[data-sovereign] .sov-voice-composer__live-meta {
  display: inline-flex;
  align-items: center;
  gap: var(--sov-space-3, 12px);
  min-width: 0;
}

/* Go Live — the continuous-presence affordance.
 *
 * Architecturally a strict twin of `.sov-voice-composer__mic`: same
 * pill geometry, same padding rhythm, same font, same border-radius
 * token, same gold-tinted idle palette, same hover/focus glow recipe.
 * The pair is authored as one paired set so Kaleeg sees them at idle
 * as siblings, and the only thing that distinguishes them is the
 * glyph inside — a rosette to claim one turn, a beacon to stay on
 * the line. State changes (recording, thinking) shift the pill's tint
 * and the glyph's color independently of the label text. */
[data-sovereign] .sov-voice-composer__go-live {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  position: relative;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 14px 24px 14px 16px;
  min-width: 148px;
  min-height: 64px;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--mk-glow-gold) 14%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--mk-glow-gold) 8%, var(--mk-bg));
  color: var(--mk-fg);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    box-shadow 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 0.3s var(--sov-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
[data-sovereign] .sov-voice-composer__go-live:hover,
[data-sovereign] .sov-voice-composer__go-live:focus-visible {
  background:
    radial-gradient(
      120% 80% at 20% 20%,
      color-mix(in oklab, var(--mk-glow-gold) 22%, transparent) 0%,
      transparent 60%
    ),
    color-mix(in oklab, var(--mk-glow-gold) 14%, var(--mk-bg));
  border-color: color-mix(in oklab, var(--mk-glow-gold) 54%, transparent);
  box-shadow:
    0 0 22px 6px color-mix(in oklab, var(--mk-glow-gold) 22%, transparent),
    0 1px 0 0 color-mix(in oklab, var(--mk-fg) 10%, transparent) inset;
  transform: translateY(-1px);
  outline: none;
}
[data-sovereign] .sov-voice-composer__go-live:active {
  transform: translateY(0);
}
/* The label-stack wrapper inside the go-live pill — mirrors
 * __mic-text so the two pills stay visually paired. */
[data-sovereign] .sov-voice-composer__go-live-text {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  line-height: 1.1;
}

/* Go Live label — verbal complement to the beacon glyph. Same
 * typographic recipe as the My turn label, kept on its own selector
 * so a future label tweak doesn't ripple outward. */
[data-sovereign] .sov-voice-composer__go-live-label {
  color: var(--mk-fg);
  font-size: 13px;
  font-weight: 500;
}
[data-sovereign] .sov-voice-composer__go-live-sub {
  font-family: var(--sov-font-serif);
  font-style: italic;
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--mk-fg) 56%, transparent);
  text-transform: lowercase;
}

/* The beacon glyph — central core with two concentric pulse rings
 * breathing outward in soft antiphase. Same 22px footprint and same
 * `currentColor` plumbing as the rosette so the two glyphs sit as
 * scale-paired siblings in their respective pills. The rings breathe
 * on the constellation's --sov-breath cadence so the Go Live beacon
 * and the My turn rosette breathe in unison when sitting beside each
 * other on the canvas — a small choreography that signals they
 * belong to the same family. */
[data-sovereign] .sov-voice-composer__live-glyph {
  /* § 2026-06-28 — bumped from 22px to 26px to match the rosette so
   * the two pills stay visually paired. */
  width: 26px;
  height: 26px;
  display: block;
  pointer-events: none;
  overflow: visible;
  color: var(--mk-glow-gold);
  flex-shrink: 0;
  transition: color var(--sov-d-base, 280ms)
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-voice-composer__live-glyph[data-state="recording"] {
  color: var(--sov-mic-recording);
}
[data-sovereign] .sov-voice-composer__live-glyph[data-state="thinking"] {
  color: var(--sov-mic-recording);
}
[data-sovereign]
  .sov-voice-composer__live-glyph
  .sov-voice-composer__live-glyph-ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  animation: sov-voice-live-pulse var(--sov-breath, 4.2s)
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}
[data-sovereign]
  .sov-voice-composer__live-glyph
  .sov-voice-composer__live-glyph-ring--outer {
  opacity: 0.45;
}
[data-sovereign]
  .sov-voice-composer__live-glyph
  .sov-voice-composer__live-glyph-ring--inner {
  opacity: 0.7;
  /* Antiphase to the outer ring — when one is bright the other is
     dim, giving a steady "always on" beacon feel. */
  animation-delay: calc(var(--sov-breath, 4.2s) / -2);
}
[data-sovereign]
  .sov-voice-composer__live-glyph
  .sov-voice-composer__live-glyph-core {
  fill: currentColor;
  opacity: 0.78;
}

@keyframes sov-voice-live-pulse {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 0.85;
  }
}

/* Live pip — the coloured state dot when live is active. */
[data-sovereign] .sov-voice-composer__live-pip {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--sov-presence-listening);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-listening) 70%, transparent);
  transition: background 0.3s ease, box-shadow 0.3s ease;
}
[data-sovereign] .sov-voice-composer__live-pip[data-presence-state="thinking"] {
  background: var(--sov-presence-thinking);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-thinking) 70%, transparent);
}
[data-sovereign] .sov-voice-composer__live-pip[data-presence-state="speaking"] {
  background: var(--sov-presence-speaking);
  box-shadow: 0 0 6px 1px
    color-mix(in oklab, var(--sov-presence-speaking) 70%, transparent);
}

[data-sovereign] .sov-voice-composer__live-label {
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: color-mix(in oklab, var(--sov-presence-listening) 80%, var(--mk-fg));
  white-space: nowrap;
}

/* Energy bar — width of the filled portion is driven by
   --sov-vc-energy (0 → 1) via scaleX so the animation is GPU-smooth. */
[data-sovereign] .sov-voice-composer__energy-track {
  flex: 1 1 80px;
  min-width: 48px;
  max-width: 120px;
  height: 3px;
  border-radius: 2px;
  background: color-mix(in oklab, var(--mk-fg) 10%, transparent);
  overflow: hidden;
}
[data-sovereign] .sov-voice-composer__energy-fill {
  height: 100%;
  border-radius: 2px;
  background: color-mix(
    in oklab,
    var(--sov-presence-listening) 80%,
    var(--mk-fg)
  );
  transform-origin: left center;
  transform: scaleX(var(--sov-vc-energy, 0));
  transition: transform 0.06s linear;
}

/* End Live — small pill to stop the session. */
[data-sovereign] .sov-voice-composer__end-live {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid color-mix(in oklab, var(--mk-fg) 16%, transparent);
  background: transparent;
  color: color-mix(in oklab, var(--mk-fg) 60%, transparent);
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s ease, border-color 0.15s ease;
}
[data-sovereign] .sov-voice-composer__end-live:hover,
[data-sovereign] .sov-voice-composer__end-live:focus-visible {
  color: var(--mk-fg);
  border-color: color-mix(in oklab, var(--mk-fg) 32%, transparent);
  outline: none;
}

/* Reduced-motion override — suppresses every breath, bloom, and ring
   in this cluster. The static state colours and the focus-visible
   hairline are unchanged, so reduced-motion users still see correct
   state through colour and shadow. They just don't breathe. */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-voice-composer__mic[data-state="recording"]::after {
    animation: none;
    opacity: 0;
  }
  [data-sovereign]
    .sov-voice-composer__rosette
    .sov-voice-composer__petals
    circle {
    animation: none;
    opacity: 0.78;
  }
  [data-sovereign]
    .sov-voice-composer__rosette[data-state="recording"]
    .sov-voice-composer__petals,
  [data-sovereign]
    .sov-voice-composer__rosette[data-state="thinking"]
    .sov-voice-composer__petals {
    animation: none;
    transform: none;
  }
  [data-sovereign]
    .sov-voice-composer__live-glyph
    .sov-voice-composer__live-glyph-ring {
    animation: none;
  }
  [data-sovereign]
    .sov-voice-composer__live-glyph
    .sov-voice-composer__live-glyph-ring--outer {
    opacity: 0.45;
  }
  [data-sovereign]
    .sov-voice-composer__live-glyph
    .sov-voice-composer__live-glyph-ring--inner {
    opacity: 0.7;
  }
}

/* ── SovereignVoiceWaveform ─────────────────────────────────────────
 * Right-to-left bar animation driven by mic energy. Each bar is a
 * 1px vertical stroke; the height is set by --wv-h (0→1), the color
 * by the mode data attribute. Bars render right-to-left — sound
 * enters from the right and decays leftward.
 *
 * The waveform sits inside the composer stage, between the control
 * pills and the caption. It is hidden (`display:none`) when idle and
 * shown during active (recording) and transcribing modes. */
[data-sovereign] .sov-voice-waveform {
  display: flex;
  flex-direction: row-reverse; /* right-to-left */
  align-items: center;
  justify-content: center;
  gap: 2px;
  height: 28px;
  opacity: 0;
  transition: opacity 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-voice-waveform[data-mode="idle"] {
  display: none;
}
[data-sovereign] .sov-voice-waveform[data-mode="listening"],
[data-sovereign] .sov-voice-waveform[data-mode="active"],
[data-sovereign] .sov-voice-waveform[data-mode="transcribing"] {
  opacity: 1;
}

[data-sovereign] .sov-voice-waveform__bar {
  width: 2px;
  border-radius: 1px;
  background: var(--mk-glow-gold);
  opacity: 0.52;
  transform-origin: bottom center;
  transform: scaleY(var(--wv-h, 0.08));
  transition:
    transform 0.08s linear,
    opacity 0.3s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Listening (armed, waiting for speech): softer gold ambient bars */
[data-sovereign] .sov-voice-waveform[data-mode="listening"]
  .sov-voice-waveform__bar {
  background: var(--mk-glow-gold);
  opacity: 0.36;
}

/* Transcribing mode: gentle pulse, thinking color */
[data-sovereign] .sov-voice-waveform[data-mode="transcribing"]
  .sov-voice-waveform__bar {
  background: var(--sov-presence-thinking);
  opacity: 0.44;
  animation: sov-waveform-think-pulse 1.8s
    var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)) infinite;
}
[data-sovereign] .sov-voice-waveform[data-mode="transcribing"]
  .sov-voice-waveform__bar:nth-child(odd) {
  animation-delay: 0.3s;
}

@keyframes sov-waveform-think-pulse {
  0%, 100% { opacity: 0.44; }
  50% { opacity: 0.7; }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-voice-waveform__bar {
    transition: none;
  }
  [data-sovereign] .sov-voice-waveform[data-mode="transcribing"]
    .sov-voice-waveform__bar {
    animation: none;
  }
}

/* The whole-screen portal that hosts the presence surface + voice
   composer + visual-rail. Token-first replacement for the inline
   styles that used to live on SurfacePortal. The wrapper itself
   never catches clicks; each child opts in via pointer-events:auto.
   z-index is high enough to sit above the SovereignClientShell but
   not so high that it shadows OS overlays (browser dialogs etc.).
   Same-element compound selector — the portal div carries both
   [data-sovereign] and .sov-voice-portal on itself directly in
   <body>; a descendant selector would never match. */
[data-sovereign].sov-voice-portal {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: auto;
  background: var(--mk-bg, #0a0a0a);
}

/* Same-element compound selector — the portal div carries both
   [data-sovereign] and .sov-pretext-portal on itself; a descendant
   selector ([data-sovereign] .sov-pretext-portal) would never match
   because the element has no [data-sovereign] parent in <body>. */
[data-sovereign].sov-pretext-portal {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: auto;
  background: var(--mk-bg, #0a0a0a);
  display: flex;
  flex-direction: column;
}

/* Canvas fills the portal's full viewport height. */
[data-sovereign].sov-pretext-portal .sov-a06-canvas {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
}

/* ── Search portal (§Search) ──────────────────────────────────────
 *   Same full-viewport pattern as the Pretext Forge Canvas (§A06):
 *   fixed fill, z-60, opaque background, column layout. Chrome header
 *   row at top (wordmark · mode tabs · close), scrollable content
 *   below. Sovereign tokens only — no new tokens, no new primitives.
 *   The close button reuses `.sov-presence-close-btn` from the voice
 *   and pretext pages. ──────────────────────────────────────────── */

[data-sovereign].sov-search-portal {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: auto;
  background: var(--mk-bg, #0a0a0a);
  display: flex;
  flex-direction: column;
}

/* Chrome header row — same three-column grid as the A03/A05 head row
 *   so the wordmark lands at the left-rail column, the mode tabs
 *   centre in the content column, and the close button sits at the
 *   right-rail column. Min-height matches the shell's top-chrome row
 *   so it feels like the same surface. Uses the same gap token as
 *   the §03 top-chrome grid cells. */
[data-sovereign].sov-search-portal .sov-search-chrome {
  flex-shrink: 0;
  display: grid;
  grid-template-columns:
    var(--sov-layout-rail-width, 270px)
    minmax(0, 1fr)
    var(--sov-layout-right-rail-width, 270px);
  align-items: center;
  min-height: 56px;
  padding: var(--sov-space-2) var(--sov-space-5);
  border-bottom: 1px solid var(--sov-hairline-quiet, var(--sov-veil));
}

[data-sovereign].sov-search-portal .sov-search-chrome__logo {
  display: flex;
  align-items: center;
}

/* Mode toggle cluster — centred in the content column. Reuses the
 *   `.sov-a03-page-tabs__tab` class so the instant/semantic pills
 *   inherit the same typography, spacing, active underline and
 *   gold-glow animation as the §03 page-tab strip. */
[data-sovereign].sov-search-portal .sov-search-chrome__tabs {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px 20px;
}

/* Close button — reuses `.sov-presence-close-btn` entirely. The only
 *   override is making it grid-relative instead of absolute so it
 *   sits in the right column of the chrome grid. Position reset
 *   honours the same 36px disc geometry as the voice/pretext close. */
[data-sovereign].sov-search-portal .sov-presence-close-btn {
  position: relative;
  top: unset;
  right: unset;
  justify-self: end;
  margin-right: var(--sov-space-1);
}

/* Scrollable content area — fills remaining viewport height. Content
 *   is centred at the same max-width as the §03 content column so
 *   search results feel like they belong to the same surface. */
[data-sovereign].sov-search-portal .sov-search-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sov-space-6) var(--sov-space-5) var(--sov-space-8);
}

[data-sovereign].sov-search-portal .sov-search-content {
  max-width: var(--sov-content-max, 820px);
  margin: 0 auto;
}

/* Overlay chrome portal — sits at z-70, one step above the z-60 canvas
   portals (voice + pretext). Replicates the A05 top-chrome row (mode tabs,
   nav header, user card) so they stay visible when a full-screen canvas
   covers the shell. Same-element compound selector: the div rendered into
   <body> carries both [data-sovereign] and .sov-overlay-chrome-portal.
   IMPORTANT: must reset every [data-sovereign] inherited property that
   would otherwise make this element cover the viewport. */
[data-sovereign].sov-overlay-chrome-portal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* height is content-only — do NOT inherit min-height:100dvh */
  min-height: unset;
  height: auto;
  z-index: 70;
  pointer-events: none;
  /* override [data-sovereign] flex layout */
  display: grid;
  flex-direction: unset;
  grid-template-columns:
    var(--sov-layout-rail-width, 270px)
    minmax(0, 1fr)
    var(--sov-layout-right-rail-width, 270px);
  /* override [data-sovereign] background and overflow */
  background: transparent;
  overflow: visible;
}

[data-sovereign].sov-overlay-chrome-portal > * {
  pointer-events: auto;
}

/* — A · CONSTELLATION — the consilience canvas (no iris). */
/* biome-ignore lint/nursery/noDescendingSpecificity: base class follows higher-specificity @media variants — intentional cascade (@media > outside) */
[data-sovereign] .sov-presence-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* State → glow + duration + aperture-width.
   Aliases to the existing --sov-presence-* tokens (sovereign.css §750). */
[data-sovereign] [data-presence-surface][data-presence-state="idle"] {
  --sov-presence-glow: var(--sov-presence-idle);
  --sov-presence-dur: var(--sov-presence-dur-idle);
  --sov-presence-aperture-w: 2px;
}
[data-sovereign] [data-presence-surface][data-presence-state="listening"] {
  --sov-presence-glow: var(--sov-presence-listening); /* pied-beauty */
  --sov-presence-dur: var(--sov-presence-dur-listening);
  --sov-presence-aperture-w: 9px;
}
[data-sovereign] [data-presence-surface][data-presence-state="thinking"] {
  --sov-presence-glow: var(--sov-presence-thinking); /* where-light */
  --sov-presence-dur: var(--sov-presence-dur-thinking);
  --sov-presence-aperture-w: 2px;
}
[data-sovereign] [data-presence-surface][data-presence-state="speaking"] {
  --sov-presence-glow: var(--sov-presence-speaking); /* kingfishers */
  --sov-presence-dur: var(--sov-presence-dur-speaking);
  --sov-presence-aperture-w: 5px;
}
[data-sovereign] [data-presence-surface][data-presence-state="paused"] {
  --sov-presence-glow: var(--sov-presence-error); /* windhover */
  --sov-presence-dur: var(--sov-presence-dur-paused);
  --sov-presence-aperture-w: 1px;
}

/* ── Variants ──────────────────────────────────────────────────── */

[data-sovereign] .sov-presence-variant {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.9s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
}
[data-sovereign] .sov-presence-variant[data-active="true"] {
  opacity: 1;
  pointer-events: auto;
}

/* — B · THRESHOLD — a column of light. */
[data-sovereign] .sov-presence-threshold-ambient {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 28% 80% at 50% 50%,
    color-mix(in oklab, var(--sov-presence-glow) 10%, transparent) 0%,
    color-mix(in oklab, var(--sov-presence-glow) 4%, transparent) 45%,
    transparent 72%
  );
  animation: sov-presence-breathe var(--sov-presence-dur) ease-in-out infinite;
}
[data-sovereign] .sov-presence-threshold-ceiling {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 400px;
  height: 25%;
  background: radial-gradient(
    ellipse 90% 100% at 50% 100%,
    color-mix(in oklab, var(--sov-presence-glow) 5%, transparent),
    transparent 70%
  );
}
[data-sovereign] .sov-presence-threshold-jamb {
  position: absolute;
  top: 6%;
  bottom: 6%;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    color-mix(in oklab, var(--sov-presence-glow) 38%, transparent) 12%,
    color-mix(in oklab, var(--sov-presence-glow) 24%, transparent) 50%,
    color-mix(in oklab, var(--sov-presence-glow) 38%, transparent) 88%,
    transparent 100%
  );
}
[data-sovereign] .sov-presence-threshold-jamb[data-side="left"] {
  left: calc(50% - 30px);
}
[data-sovereign] .sov-presence-threshold-jamb[data-side="right"] {
  right: calc(50% - 30px);
}
[data-sovereign] .sov-presence-threshold-lintel {
  position: absolute;
  top: 6%;
  left: calc(50% - 30px);
  width: 60px;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    color-mix(in oklab, var(--sov-presence-glow) 38%, transparent) 30%,
    color-mix(in oklab, var(--sov-presence-glow) 38%, transparent) 70%,
    transparent
  );
}
[data-sovereign] .sov-presence-threshold-aperture {
  position: absolute;
  top: 6%;
  bottom: 6%;
  left: 50%;
  transform: translateX(-50%);
  width: var(--sov-presence-aperture-w);
  background: linear-gradient(
    to bottom,
    transparent 0%,
    color-mix(in oklab, var(--sov-presence-glow) 90%, white) 8%,
    color-mix(in oklab, var(--sov-presence-glow) 95%, white) 50%,
    color-mix(in oklab, var(--sov-presence-glow) 90%, white) 92%,
    transparent 100%
  );
  box-shadow: 0 0 48px 24px
    color-mix(in oklab, var(--sov-presence-glow) 24%, transparent), 0 0 120px
    60px color-mix(in oklab, var(--sov-presence-glow) 10%, transparent), 0 0
    260px 130px color-mix(in oklab, var(--sov-presence-glow) 5%, transparent);
  animation: sov-presence-aperture-breathe var(--sov-presence-dur) ease-in-out
    infinite;
}
[data-sovereign] .sov-presence-threshold-sill {
  position: absolute;
  bottom: 6%;
  left: 50%;
  transform: translateX(-50%);
  width: 160px;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    color-mix(in oklab, var(--sov-presence-glow) 30%, transparent) 30%,
    color-mix(in oklab, var(--sov-presence-glow) 30%, transparent) 70%,
    transparent
  );
}
[data-sovereign] .sov-presence-threshold-floor {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 560px;
  height: 44%;
  background: radial-gradient(
    ellipse 100% 60% at 50% 100%,
    color-mix(in oklab, var(--sov-presence-glow) 10%, transparent) 0%,
    transparent 65%
  );
}

/* — C · HEARTH — minimum durable presence. */
[data-sovereign] .sov-presence-hearth {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 60% 60% at 50% 52%,
    color-mix(in oklab, var(--sov-presence-glow) 16%, transparent) 0%,
    color-mix(in oklab, var(--sov-presence-glow) 6%, transparent) 38%,
    transparent 72%
  );
  animation: sov-presence-breathe var(--sov-presence-dur) ease-in-out infinite;
}
[data-sovereign] .sov-presence-hearth-mote {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sov-presence-glow);
  filter: blur(0.5px);
  box-shadow: 0 0 24px 8px
    color-mix(in oklab, var(--sov-presence-glow) 35%, transparent), 0 0 80px
    28px color-mix(in oklab, var(--sov-presence-glow) 12%, transparent);
}

/* ── Word layers — shared across every variant. ────────────────── */

/* Her words: center, Newsreader italic. The reveal cadence comes from
   the canonical word-reveal triplet at sovereign.css §641. */
/* Bottom-subtitle treatment (architect order, 2026-04-30):
 *   Malaika's prose streams along the bottom edge in serif italic
 *   instead of dominating the centre of the canvas. The constellation
 *   gets the vertical it deserves; the words sit close to the voice
 *   composer so the family's eye finds them in the same place where
 *   they're already looking for the My turn / Go Live pills. The user
 *   echo line sits just below Malaika's, tighter and tracked wider
 *   so it reads like a captioning track.
 *
 *   Vertical stack from the bottom (fullscreen), revised 2026-06-28:
 *     1. composer pills        ≈ bottom 14vh (variable; new staged tray)
 *     2. user echo             ≈ bottom 28vh  (above the pills)
 *     3. malaika subtitle      ≈ bottom 36vh  (above the user echo)
 *
 *   § 2026-06-28 (second pass) — the previous pass moved malaika's
 *   words to the top of the page (top 22vh) to escape the rosette
 *   halo. That solved the wash-out but broke the conversation shape:
 *   her streamed reply needs to land in the same place the user's
 *   words just were, so the exchange reads as a turn-by-turn caption
 *   track anchored to the composer. Brought the words back to the
 *   bottom and solved the actual problems directly:
 *     - z-index raised 20 → 60 so the words sit above the canvas AND
 *       above the presence-surface's own stacking (still below the
 *       composer at 10000 and the rails at 50 — but the words live
 *       inside [data-presence-surface], so 60 is plenty inside that
 *       context).
 *     - a soft radial backing plate behind each word block carries
 *       --mk-bg at ~70% opacity so the rosette's gold halo can't
 *       wash the text out — the plate absorbs the bloom and the
 *       serif italic reads cleanly on top.
 *     - text-shadow kept as a second line of defence for any halo
 *       that leaks past the plate's edges.
 *     - line cap raised 3 → 6 so longer spoken replies don't get
 *       clipped mid-sentence. The mask fades top and bottom so the
 *       newest line is always the one in focus.
 *   The stack now reads naturally: user speaks → their echo appears
 *   at 28vh → Malaika's reply streams in just above at 36vh →
 *   scrolls upward as it grows, never colliding with the rosette
 *   core at 50vh until it's already six lines deep. */
/* biome-ignore lint/nursery/noDescendingSpecificity: base class follows higher-specificity @media variants — intentional cascade (@media > outside) */
[data-sovereign] .sov-presence-malaika-words {
  position: absolute;
  bottom: clamp(180px, 36vh, 320px);
  top: auto;
  left: 50%;
  transform: translateX(-50%);
  width: min(720px, 92vw);
  text-align: left;
  font-family: "Newsreader", var(--mk-font-serif, var(--sov-font-serif));
  font-style: italic;
  font-weight: 400;
  font-size: 18px;
  line-height: 1.6;
  color: var(--mk-fg);
  letter-spacing: -0.002em;
  /* Raised from 20 → 60 so the words sit cleanly above the canvas
   * inside the presence-surface stacking context. Still below the
   * composer (10000) and the rails (50 — but rails are outside this
   * surface, so 60 is the right knob here). */
  z-index: 60;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
  /* Soft dark backing plate — a radial gradient that absorbs the
   * constellation's gold halo so the serif italic reads on top
   * instead of being washed out. Sits behind the text via ::before
   * (see below). Without this the halo at the rosette's lower
   * shoulder (which this layer overlaps) makes the text nearly
   * unreadable against the bloom at speaking-state brightness. */
  /* Cap at six lines so a longer spoken reply doesn't get clipped —
   * older lines fade behind the top+bottom mask so the newest reading
   * is always the one in focus. */
  max-height: calc(1.6em * 6);
  overflow: hidden;
  text-shadow:
    0 1px 8px color-mix(in oklab, var(--mk-bg) 90%, transparent),
    0 0 24px color-mix(in oklab, var(--mk-bg) 70%, transparent);
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(0, 0, 0, 1) 14%,
    rgba(0, 0, 0, 1) 86%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(0, 0, 0, 1) 14%,
    rgba(0, 0, 0, 1) 86%,
    transparent 100%
  );
}
/* Backing plate — a soft dark radial behind the word block that
 * carries enough --mk-bg to absorb the constellation halo. Sits
 * behind the text (z-index: -1 within the same stacking context)
 * so the words read on top. Inset slightly so the plate doesn't
 * extend to the full 720px width — keeps it shaped to the text
 * rather than reading as a solid bar. */
[data-sovereign] .sov-presence-malaika-words::before {
  content: "";
  position: absolute;
  inset: -20px -40px;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    ellipse 60% 80% at 50% 60%,
    color-mix(in oklab, var(--mk-bg) 76%, transparent) 0%,
    color-mix(in oklab, var(--mk-bg) 56%, transparent) 45%,
    transparent 75%
  );
  pointer-events: none;
}
[data-sovereign] .sov-presence-malaika-words[data-visible="true"] {
  opacity: 1;
}
[data-sovereign] .sov-presence-malaika-words[data-dim="true"] {
  opacity: 0.4;
}

/* User echo — sits directly under Malaika's subtitle; reads like a
 * captioning line for the family member's own utterance. Same
 * Noto-sans tracking as before so the linguistic register is clearly
 * different from the serif italic above it. Single line cap so the
 * captioning track doesn't grow vertical and crowd the rosette.
 *
 * § 2026-06-28 — raised from bottom 16vh to bottom 28vh so the echo
 * sits ABOVE the new taller composer stage instead of getting hidden
 * under it. z-index matches malaika's layer so both word blocks share
 * the same stacking slot and never z-fight each other. Backing plate
 * added for the same reason as malaika's: the halo doesn't wash the
 * user's own words out while they're reading them back. */
/* biome-ignore lint/nursery/noDescendingSpecificity: base class follows higher-specificity @media variants — intentional cascade (@media > outside) */
[data-sovereign] .sov-presence-user-words {
  position: absolute;
  bottom: clamp(148px, 28vh, 248px);
  left: 50%;
  transform: translateX(-50%);
  width: min(540px, 86vw);
  text-align: center;
  font-family: var(--mk-font-sans, var(--sov-font-sans));
  font-size: 11px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--mk-muted);
  letter-spacing: 0.05em;
  /* Raised to match malaika-words so the two word blocks share one
   * stacking slot. */
  z-index: 60;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
  max-height: 1.5em;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  /* Match malaika's text-shadow so the user echo reads against the
   * halo too — smaller text is even more vulnerable to wash-out. */
  text-shadow:
    0 1px 6px color-mix(in oklab, var(--mk-bg) 90%, transparent),
    0 0 18px color-mix(in oklab, var(--mk-bg) 70%, transparent);
}
[data-sovereign] .sov-presence-user-words[data-visible="true"] {
  opacity: 1;
}

/* Per-word reveal — reuses the canonical word-in keyframes from §966.
   Consumer sets --sov-word-i per span. */
[data-sovereign] .sov-presence-word {
  display: inline;
  opacity: 0;
  animation: sov-word-in var(--sov-word-reveal-dur) var(--sov-ease-expo) both;
  animation-delay: calc(
    var(--sov-word-reveal-lead) +
    var(--sov-word-i, 0) *
    var(--sov-word-reveal-stagger)
  );
}

/* When a sentence is currently being spoken aloud (TTS playback),
   slightly brighten its words. The slave-to-audio ring. */
[data-sovereign] .sov-presence-word[data-spoken="true"] {
  color: color-mix(in oklab, var(--mk-fg) 92%, var(--sov-presence-glow) 8%);
}

/* ── Consilience hover names — appear only on pointer hover or
       keyboard focus, never automatically. The gesture of recognition. */
[data-sovereign] .sov-presence-consilience-name {
  position: absolute;
  font-family: "Newsreader", var(--mk-font-serif, var(--sov-font-serif));
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: color-mix(in oklab, var(--mk-fg) 72%, transparent);
  background: color-mix(in oklab, var(--mk-bg) 70%, transparent);
  padding: 2px 10px;
  border-radius: var(--mk-radius-btn, 10px);
  backdrop-filter: blur(var(--mk-glass-blur-tile, 14px));
  -webkit-backdrop-filter: blur(var(--mk-glass-blur-tile, 14px));
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -150%);
  transition: opacity 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 0.4s var(--sov-ease-expo, cubic-bezier(0.16, 1, 0.3, 1));
  white-space: nowrap;
  z-index: 30;
}
[data-sovereign] .sov-presence-consilience-name[data-visible="true"] {
  opacity: 1;
  transform: translate(-50%, -180%);
}

/* Breath keyframes — separate from sov-breathe so the surface can
   loop at its own state-driven duration without colliding with the
   global presence-dot breath. */
@keyframes sov-presence-breathe {
  0%,
  100% {
    opacity: 0.6;
  }
  50% {
    opacity: 1;
  }
}
@keyframes sov-presence-aperture-breathe {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}

/* Light-theme parity — same surface, lighter base. */
[data-sovereign][data-sovereign-theme="light"] [data-presence-surface] {
  background: var(--sov-color-surface-raised);
  color: var(--sov-color-ink);
}

/* Motion safety — honor reduced-motion for every sovereign effect.
   Per step-09 §6, the ambient wash and any class containing
   "sov-breathe" / "sov-shimmer" pause and stay open at full opacity. */
@media (prefers-reduced-motion: reduce) {
  .sov-canvas::before,
  [class*="sov-breathe"],
  [class*="sov-shimmer"] {
    animation: none;
    opacity: 1;
  }
  [data-sovereign] *,
  [data-sovereign] *::before,
  [data-sovereign] *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
  /* Presence surface — collapse to the still moment per state. */
  [data-sovereign] [data-presence-surface] *,
  [data-sovereign] [data-presence-surface] *::before,
  [data-sovereign] [data-presence-surface] *::after {
    animation: none !important;
  }
  [data-sovereign] .sov-presence-word {
    animation: none !important;
    opacity: 1 !important;
    filter: none !important;
  }
}

/* ============================================================
 * Step-19 — Telnyx call rail (Cycle C.8 Phase 2)
 *
 * Authored: sovereign-design/kaOS Design System (self-authored)/
 *           pr/step-19/PR.md §3 (composition-only).
 *           Sanctioned under Charter Rule 5b.
 *
 * Composes existing tokens for an incoming-call card, an active
 * call panel with duplex transcript, and a floating overlay card
 * for chat-pretext mode. No new tokens are introduced; every
 * value below resolves to a token already in this file.
 *
 * The rail mirrors the .sov-activity-section shape so the right
 * rail reads as one consistent surface — Malaika's incoming
 * conversation is "another lane" of presence, not a new room.
 * ============================================================ */

[data-sovereign] .sov-call-rail {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  width: 100%;
}

[data-sovereign] .sov-call-rail__eyebrow {
  margin: 0;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: var(--sov-rail-toggle-tracking, 0.16em);
  text-transform: uppercase;
  color: var(--sov-whisper);
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-call-rail__eyebrow-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--sov-radius-pill);
  background: var(
    --sov-presence-halo,
    var(--sov-presence-glow, var(--sov-whisper))
  );
  box-shadow: 0 0 10px
    color-mix(
      in oklab,
      var(--sov-presence-halo, var(--sov-whisper)) 50%,
      transparent
    );
  opacity: 0.7;
}

[data-sovereign]
  .sov-call-rail[data-state="ringing"]
  .sov-call-rail__eyebrow-dot,
[data-sovereign]
  .sov-call-rail[data-state="answered"]
  .sov-call-rail__eyebrow-dot {
  opacity: 1;
  animation: sov-call-rail-breathe var(--sov-breath, 4.2s) ease-in-out infinite;
}

/* Card primitive — used for the in-rail card and the floating
 * pretext-mode overlay. The pretext modifier widens the card and
 * raises its z-index without changing the surface treatment. */
[data-sovereign] .sov-call-card {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  padding: var(--sov-space-4) var(--sov-space-4);
  border-radius: var(--sov-radius-tile);
  background: color-mix(
    in oklab,
    var(--sov-veil) calc(var(--sov-glass-mix) * 1%),
    transparent
  );
  backdrop-filter: blur(var(--sov-glass-blur))
    saturate(var(--sov-glass-saturate, 1.4));
  -webkit-backdrop-filter: blur(var(--sov-glass-blur))
    saturate(var(--sov-glass-saturate, 1.4));
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 8%, transparent), var(--sov-shadow-tile);
  color: var(--sov-subtle);
  font-size: var(--sov-text-tile-size);
  line-height: var(--sov-text-tile-line);
}

/* Ringing — Malaika's halo glows on the card edge while the
 * decision is open. Reuses --sov-presence-halo and --sov-breath
 * so the cadence matches the presence surface in voice mode. */
[data-sovereign] .sov-call-card[data-state="ringing"] {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-presence-halo) 40%, transparent), 0 0 32px
    -8px color-mix(in oklab, var(--sov-presence-halo) 55%, transparent),
    var(--sov-shadow-tile);
  animation: sov-call-card-pulse var(--sov-breath, 4.2s) ease-in-out infinite;
}

[data-sovereign] .sov-call-card[data-state="answered"] {
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-presence-halo) 28%, transparent), 0 0 24px
    -10px color-mix(in oklab, var(--sov-presence-halo) 35%, transparent),
    var(--sov-shadow-tile);
}

[data-sovereign] .sov-call-card[data-state="ended"],
[data-sovereign] .sov-call-card[data-state="rejected"] {
  opacity: 0.6;
}

[data-sovereign] .sov-call-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-call-card__name {
  font-size: var(--sov-text-section-size);
  line-height: var(--sov-text-section-line);
  font-weight: var(--sov-text-section-weight);
  color: var(--sov-ink);
  margin: 0;
}

[data-sovereign] .sov-call-card__meta {
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
  letter-spacing: 0.04em;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

[data-sovereign] .sov-call-card__hint {
  margin: 0;
  font-size: var(--sov-text-field-size);
  line-height: var(--sov-text-field-line);
  color: var(--sov-subtle);
}

[data-sovereign] .sov-call-card__hint--placeholder {
  color: var(--sov-whisper);
  font-style: italic;
}

[data-sovereign] .sov-call-card__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: var(--sov-space-2);
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-call-card__actions[data-span="full"] {
  grid-template-columns: 1fr;
}

[data-sovereign] .sov-call-card__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) var(--sov-space-3);
  border-radius: var(--sov-radius-pill);
  border: 0;
  background: color-mix(in oklab, var(--sov-ink) 6%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-ink) 12%, transparent);
  color: var(--sov-ink);
  font-family: inherit;
  font-size: var(--sov-text-tile-size);
  font-weight: var(--sov-text-tile-weight);
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: transform 160ms var(--sov-ease-spring, ease-out), box-shadow 160ms
    var(--sov-ease-spring, ease-out), background 160ms
    var(--sov-ease-spring, ease-out);
}

[data-sovereign] .sov-call-card__action:hover {
  transform: translateY(-1px);
  background: color-mix(in oklab, var(--sov-ink) 10%, transparent);
}

[data-sovereign] .sov-call-card__action:focus-visible {
  outline: 2px solid var(--sov-presence-halo);
  outline-offset: 2px;
}

[data-sovereign] .sov-call-card__action[data-tone="accept"] {
  background: color-mix(in oklab, var(--sov-presence-halo) 22%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-presence-halo) 50%, transparent);
}

[data-sovereign] .sov-call-card__action[data-tone="decline"] {
  background: color-mix(in oklab, var(--sov-ink) 4%, transparent);
  color: var(--sov-whisper);
}

[data-sovereign] .sov-call-card__action[data-tone="handoff"] {
  background: color-mix(in oklab, var(--sov-presence-halo) 14%, transparent);
}

[data-sovereign] .sov-call-card__action:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

/* Duplex transcript — caller lines align left, malaika lines
 * align right so the conversation reads naturally on the rail. */
[data-sovereign] .sov-call-card__transcript {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  max-height: 280px;
  overflow-y: auto;
  padding-right: var(--sov-space-1);
}

[data-sovereign] .sov-call-card__line {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sov-space-2) var(--sov-space-3);
  border-radius: var(--sov-radius-md, 12px);
  font-size: var(--sov-text-tile-size);
  line-height: var(--sov-text-tile-line);
  background: color-mix(in oklab, var(--sov-veil) 50%, transparent);
  color: var(--sov-ink);
  max-width: 92%;
}

[data-sovereign] .sov-call-card__line[data-speaker="caller"] {
  align-self: flex-start;
  border-bottom-left-radius: var(--sov-space-1);
}

[data-sovereign] .sov-call-card__line[data-speaker="malaika"] {
  align-self: flex-end;
  border-bottom-right-radius: var(--sov-space-1);
  background: color-mix(in oklab, var(--sov-presence-halo) 14%, transparent);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--sov-presence-halo) 30%, transparent);
}

[data-sovereign] .sov-call-card__line__speaker {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: var(--sov-rail-toggle-tracking, 0.16em);
  text-transform: uppercase;
  color: var(--sov-whisper);
}

/* Empty / quiet state — when the rail has no calls. */
[data-sovereign] .sov-call-rail__empty {
  margin: 0;
  font-size: var(--sov-text-caption-size);
  line-height: var(--sov-text-caption-line);
  color: var(--sov-whisper);
  font-style: italic;
}

/* Pretext-mode floating overlay. Mounted via a portal so it lives
 * outside the chat scroll surface and reads on top of pretext
 * content without disturbing the layout grid. */
[data-sovereign] .sov-call-overlay {
  position: fixed;
  inset-inline-end: var(--sov-space-5);
  inset-block-end: var(--sov-space-5);
  width: min(420px, calc(100vw - 2 * var(--sov-space-5)));
  z-index: 80;
  pointer-events: auto;
}

@keyframes sov-call-rail-breathe {
  0%,
  100% {
    opacity: 0.7;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.25);
  }
}

@keyframes sov-call-card-pulse {
  0%,
  100% {
    box-shadow: inset 0 0 0 1px
      color-mix(in oklab, var(--sov-presence-halo) 36%, transparent), 0 0 28px
      -10px color-mix(in oklab, var(--sov-presence-halo) 45%, transparent),
      var(--sov-shadow-tile);
  }
  50% {
    box-shadow: inset 0 0 0 1px
      color-mix(in oklab, var(--sov-presence-halo) 55%, transparent), 0 0 40px
      -6px color-mix(in oklab, var(--sov-presence-halo) 70%, transparent),
      var(--sov-shadow-tile);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-call-card[data-state="ringing"] {
    animation: none !important;
  }
  [data-sovereign]
    .sov-call-rail[data-state="ringing"]
    .sov-call-rail__eyebrow-dot,
  [data-sovereign]
    .sov-call-rail[data-state="answered"]
    .sov-call-rail__eyebrow-dot {
    animation: none !important;
  }
}

/* ─── MARKER GRAMMAR (step-26) ──────────────────────────────────────────
 * Render layer for the five sovereign markers. Every declaration here
 * binds to an already-sanctioned token; this block introduces no new
 * tokens of its own.
 *
 * Provenance:
 *   .sov-marker--emph   → step-09 §3 (--sov-accent-ink)
 *   @keyframes sov-marker-fade
 *   .sov-marker--fade   → step-01 §motion (--sov-motion-duration-quick,
 *                          --sov-motion-ease-out)
 *   .sov-marker--img    → step-08 §sheets (--sov-radius-md,
 *                          --sov-shadow-surface)
 *
 * Pending tags (sanction round outstanding):
 *   .sov-marker--emo and .sov-marker--graph render as opaque
 *   placeholders — the markers survive in the DOM (as data-attrs) for
 *   the corpus, but the visual treatment is intentionally inert until
 *   the SDA round lands.
 *
 * Charter compliance: no new tokens, no new colours, no new motion
 * primitives. The five rules below are the entire substrate addition.
 */
[data-sovereign] .sov-marker--emph {
  color: var(--sov-accent-ink);
  font-style: italic;
}

@keyframes sov-marker-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

[data-sovereign] .sov-marker--fade {
  animation: sov-marker-fade var(--sov-motion-duration-quick)
    var(--sov-motion-ease-out) both;
}

[data-sovereign] .sov-marker--img {
  display: inline-block;
  max-width: 100%;
  border-radius: var(--sov-radius-md);
  box-shadow: var(--sov-shadow-surface);
}

[data-sovereign] .sov-marker--pending {
  opacity: 0.5;
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-marker--fade {
    animation: none !important;
  }
}

/* ===========================================================================
 * REVENUE SURFACE — Component-tier rules (v1)
 * ---------------------------------------------------------------------------
 * Authored: sovereign-design/kaOS Design System (revenue)/PR.md
 * Sanctioned under Charter Rule 5a.
 * Zero hardcoded color literals. All lengths reuse existing --sov-radius-*
 * and --sov-shadow-* scales. Selectors prefixed for no cross-surface leak.
 * ========================================================================= */

/* ---------- Verdict pill ---------- */
.sov-verdict-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  font-family: var(--sov-font-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-radius: var(--sov-radius-pill);
}
.sov-verdict-pill__glyph {
  font-family: var(--sov-font-mono);
  font-size: 12px;
}
.sov-verdict-pill[data-verdict="pass"] {
  color: var(--sov-verdict-pass-ink);
  background: color-mix(in oklab, var(--sov-verdict-pass-glow) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-verdict-pass-hairline);
}
.sov-verdict-pill[data-verdict="concern"] {
  color: var(--sov-verdict-concern-ink);
  background: color-mix(
    in oklab,
    var(--sov-verdict-concern-glow) 14%,
    transparent
  );
  box-shadow: inset 0 0 0 1px var(--sov-verdict-concern-hairline);
}
.sov-verdict-pill[data-verdict="block"] {
  color: var(--sov-verdict-block-ink);
  background: color-mix(
    in oklab,
    var(--sov-verdict-block-glow) 14%,
    transparent
  );
  box-shadow: inset 0 0 0 1px var(--sov-verdict-block-hairline);
}

/* ---------- Status badge ---------- */
.sov-status-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--sov-subtle);
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--mk-fg) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mk-fg) 8%, transparent);
}
.sov-status-badge__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px 0 currentColor;
}
.sov-status-badge[data-status="ready"] {
  color: color-mix(in oklab, var(--sov-status-ready-glow) 90%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px var(--sov-status-ready-hairline);
}
.sov-status-badge[data-status="live"] {
  color: color-mix(in oklab, var(--sov-status-live-glow) 90%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px var(--sov-status-live-hairline);
  background: color-mix(in oklab, var(--sov-status-live-glow) 10%, transparent);
}
.sov-status-badge[data-status="paused"] {
  color: color-mix(in oklab, var(--sov-status-paused-glow) 88%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px var(--sov-status-paused-hairline);
}
.sov-status-badge[data-status="completed"] {
  color: color-mix(in oklab, var(--sov-status-completed-glow) 78%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px var(--sov-status-completed-hairline);
}
.sov-status-badge[data-status="killed"] {
  color: color-mix(in oklab, var(--sov-status-killed-glow) 80%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px var(--sov-status-killed-hairline);
}

/* ---------- Stat block ---------- */
.sov-stat-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sov-stat-block__label {
  font-family: var(--sov-font-sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sov-faint);
}
.sov-stat-block__value {
  font-family: var(--sov-font-serif);
  font-weight: 500;
  font-size: 32px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--sov-ink);
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}
.sov-stat-block__unit {
  font-family: var(--sov-font-mono);
  font-size: 13px;
  color: var(--sov-muted);
  letter-spacing: 0.04em;
}
.sov-stat-block__delta {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--sov-delta-flat-ink);
}
.sov-stat-block__delta[data-dir="up"] {
  color: var(--sov-delta-up-ink);
}
.sov-stat-block__delta[data-dir="down"] {
  color: var(--sov-delta-down-ink);
}
.sov-stat-block__delta[data-dir="flat"] {
  color: var(--sov-delta-flat-ink);
}

/* ---------- Sparkline ---------- */
.sov-sparkline {
  width: 100%;
  height: 100px;
  display: block;
}
.sov-sparkline__axis {
  stroke: var(--sov-spark-axis);
  stroke-width: 1;
}
.sov-sparkline__line {
  stroke-width: 1.6;
  fill: none;
}
.sov-sparkline__line--anchor {
  stroke: var(--sov-spark-line-anchor);
}
.sov-sparkline__line--live {
  stroke: var(--sov-spark-line-live);
}
.sov-sparkline__fill--anchor {
  fill: var(--sov-spark-fill-anchor);
}
.sov-sparkline__fill--live {
  fill: var(--sov-spark-fill-live);
}

/* ---------- SovereignChart (multi-series area/line) ----------
   Sanctioned: sovereign-design/kaOS Design System (business)/PR-sovereign-chart.md */
.sov-chart {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}
.sov-chart__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 12px;
  color: var(--sov-muted, var(--mk-fg));
}
.sov-chart__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sov-chart__legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}
.sov-chart__svg {
  width: 100%;
  height: 240px;
  display: block;
}
.sov-chart__grid {
  stroke: var(--sov-chart-grid);
  stroke-width: 1;
}
.sov-chart__line {
  stroke-width: 1.8;
  fill: none;
}
.sov-chart__line--anchor {
  stroke: var(--sov-spark-line-anchor);
}
.sov-chart__line--live {
  stroke: var(--sov-spark-line-live);
}
.sov-chart__line--series-1 {
  stroke: var(--sov-chart-series-1);
}
.sov-chart__line--series-2 {
  stroke: var(--sov-chart-series-2);
}
.sov-chart__line--series-3 {
  stroke: var(--sov-chart-series-3);
}
.sov-chart__fill--anchor {
  fill: var(--sov-spark-fill-anchor);
}
.sov-chart__fill--live {
  fill: var(--sov-spark-fill-live);
}
.sov-chart__fill--series-1 {
  fill: var(--sov-chart-fill-series-1);
}
.sov-chart__fill--series-2 {
  fill: var(--sov-chart-fill-series-2);
}
.sov-chart__fill--series-3 {
  fill: var(--sov-chart-fill-series-3);
}
.sov-chart__x-axis {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--sov-muted, var(--mk-fg));
}

/* ---------- Budget bar ---------- */
.sov-budget-bar {
  position: relative;
  height: 8px;
  background: var(--sov-burndown-track);
  border-radius: 999px;
  overflow: hidden;
}
.sov-budget-bar__spent {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: linear-gradient(
    90deg,
    color-mix(in oklab, var(--mk-glow-gold) 70%, transparent),
    var(--sov-burndown-spent)
  );
  border-radius: 999px 0 0 999px;
}
.sov-budget-bar__projected {
  position: absolute;
  top: 0;
  bottom: 0;
  background: repeating-linear-gradient(
    -45deg,
    var(--sov-burndown-projected) 0 4px,
    transparent 4px 8px
  );
}
.sov-budget-bar__tick {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 1px;
  background: var(--sov-burndown-target-tick);
}

/* ---------- Deeplink row ---------- */
.sov-deeplink {
  display: grid;
  grid-template-columns: 140px 1fr 200px 110px;
  grid-gap: 16px;
  gap: 16px;
  padding: 14px 22px;
  align-items: center;
}
.sov-deeplink + .sov-deeplink {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 5%, transparent);
}
.sov-deeplink__surface {
  font-family: var(--sov-font-serif);
  font-size: 14.5px;
  color: var(--sov-ink);
}
.sov-deeplink__url {
  font-family: var(--sov-font-mono);
  font-size: 11.5px;
  color: var(--sov-muted);
  word-break: break-all;
}
.sov-deeplink__utm {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-faint);
}

/* ---------- Locale priority row ---------- */
.sov-locale-row {
  display: grid;
  grid-template-columns: 32px 80px 1fr 70px;
  grid-gap: 16px;
  gap: 16px;
  padding: 12px 0;
  align-items: baseline;
}
.sov-locale-row + .sov-locale-row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 4%, transparent);
}
.sov-locale-row__rank {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-faint);
}
.sov-locale-row__code {
  font-family: var(--sov-font-mono);
  font-size: 12.5px;
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, var(--mk-fg));
  letter-spacing: 0.04em;
}
.sov-locale-row__reason {
  font-family: var(--sov-font-serif);
  font-size: 14px;
  color: var(--sov-muted);
  line-height: 1.55;
}
.sov-locale-row__weight {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-faint);
  text-align: right;
}

/* ---------- Campaign grid ---------- */
.sov-campaign-grid {
  display: grid;
  grid-template-columns: 2fr 90px 70px 90px 70px 70px 80px 130px;
  grid-gap: 14px;
  gap: 14px;
  padding: 14px 22px;
  align-items: center;
}
.sov-campaign-grid__head {
  font-family: var(--sov-font-sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sov-faint);
  padding-top: 16px;
  padding-bottom: 12px;
}
.sov-campaign-grid__head + .sov-campaign-grid__row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 8%, transparent);
}
.sov-campaign-grid__row + .sov-campaign-grid__row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 5%, transparent);
}
.sov-campaign-grid__id {
  font-family: var(--sov-font-mono);
  font-size: 11.5px;
  color: var(--sov-ink);
  margin-bottom: 2px;
}
.sov-campaign-grid__surface {
  font-family: var(--sov-font-serif);
  font-size: 13px;
  color: var(--sov-muted);
}
.sov-campaign-grid__num {
  font-family: var(--sov-font-mono);
  font-size: 12.5px;
  color: var(--sov-subtle);
  text-align: right;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.sov-campaign-grid__num--strong {
  color: var(--sov-ink);
}
.sov-campaign-grid__num[data-tone="up"] {
  color: var(--sov-delta-up-ink);
}
.sov-campaign-grid__num[data-tone="down"] {
  color: var(--sov-delta-down-ink);
}
.sov-campaign-grid__decision {
  font-family: var(--sov-font-mono);
  font-size: 11.5px;
  text-align: right;
  color: var(--sov-muted);
}
.sov-campaign-grid__decision[data-decision="scale"] {
  color: var(--sov-delta-up-ink);
}
.sov-campaign-grid__decision[data-decision="kill"] {
  color: var(--sov-delta-down-ink);
}

/* ---------- Hero washes (launch page) ---------- */
.lp-hero {
  padding: 38px 40px 32px;
  position: relative;
  overflow: hidden;
}
.lp-hero__wash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    80% 60% at 12% 0%,
    color-mix(in oklab, var(--mk-glow-gold) 14%, transparent),
    transparent 60%
  );
}
.lp-hero__deferred {
  color: var(--sov-faint);
  font-family: var(--sov-font-mono);
  font-size: 11px;
  align-self: center;
}

/* ===========================================================================
 * REVENUE SURFACE — Component-tier rules (v2)
 * ---------------------------------------------------------------------------
 * Authored: sovereign-design/kaOS Design System (revenue)/PR-v2.md
 * Sanctioned under Charter Rule 5a.
 * Additive only — four new selector families. No new tokens. No overrides.
 * ========================================================================= */

/* Upload checklist (Surface A) */
.sov-upload-checklist__row {
  display: grid;
  grid-template-columns: 28px 1fr;
  grid-gap: 14px;
  gap: 14px;
  padding: 12px 0;
  align-items: baseline;
}
.sov-upload-checklist__row + .sov-upload-checklist__row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 4%, transparent);
}
.sov-upload-checklist__num {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, var(--mk-fg));
  padding-top: 2px;
}
.sov-upload-checklist__body {
  font-family: var(--sov-font-serif);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--sov-subtle);
}
/* biome-ignore lint/nursery/noDescendingSpecificity: descendant selector below base class — intentionally overrides general code-property rules set earlier */
.sov-upload-checklist__body code {
  font-family: var(--sov-font-mono);
  font-size: 12px;
  color: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 80%,
    var(--mk-fg)
  );
  background: color-mix(in oklab, var(--mk-fg) 5%, transparent);
  padding: 1px 6px;
  border-radius: 4px;
}

/* Funding ledger card (Surface B) */
.sov-funding-ledger {
  display: block;
  font-family: var(--sov-font-mono);
  font-size: 11px;
}
.sov-funding-ledger__row {
  display: grid;
  grid-template-columns: 90px 100px 60px 80px 1fr 90px;
  grid-gap: 10px;
  gap: 10px;
  padding: 10px 16px;
  align-items: center;
}
.sov-funding-ledger__row + .sov-funding-ledger__row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 4%, transparent);
}
.sov-funding-ledger__row--head {
  color: var(--sov-faint);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding-top: 12px;
  padding-bottom: 8px;
}
.sov-funding-ledger__date {
  color: var(--sov-muted);
}
.sov-funding-ledger__surface {
  color: var(--sov-muted);
}
.sov-funding-ledger__action {
  color: var(--sov-subtle);
  text-transform: lowercase;
}
.sov-funding-ledger__action--deposit {
  color: var(--sov-delta-up-ink);
}
.sov-funding-ledger__action--spend {
  color: var(--sov-faint);
}
.sov-funding-ledger__action--refund {
  color: var(--sov-subtle);
}
.sov-funding-ledger__action--adjust {
  color: var(--sov-faint);
}
.sov-funding-ledger__amt {
  color: var(--sov-ink);
  text-align: right;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
.sov-funding-ledger__ref {
  color: var(--sov-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sov-funding-ledger__bal {
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, var(--mk-fg));
  text-align: right;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}

/* Variant table (Surface A, per-campaign) */
.sov-variant-table {
  background: color-mix(in oklab, var(--mk-bg) 70%, var(--mk-surface-0));
  border-radius: var(--sov-radius-card-sm);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mk-fg) 5%, transparent);
}
.sov-variant-table__row {
  display: grid;
  grid-template-columns: 28px 130px 90px 1fr;
  grid-gap: 12px;
  gap: 12px;
  padding: 10px 14px;
  align-items: center;
}
.sov-variant-table__row + .sov-variant-table__row {
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--mk-fg) 4%, transparent);
}
.sov-variant-table__row--head {
  color: var(--sov-faint);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding-top: 12px;
  padding-bottom: 8px;
}
.sov-variant-table__label {
  font-family: var(--sov-font-mono);
  font-size: 12px;
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, var(--mk-fg));
  text-transform: uppercase;
}
.sov-variant-table__tag {
  font-family: var(--sov-font-mono);
  font-size: 11.5px;
  color: var(--sov-subtle);
}
.sov-variant-table__creative {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-subtle);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sov-variant-table__creative-glyph {
  width: 10px;
  display: inline-flex;
  justify-content: center;
}
.sov-variant-table__creative[data-status="rendered"]
  .sov-variant-table__creative-glyph {
  color: color-mix(
    in oklab,
    var(--mk-glow-where-light-enters) 90%,
    var(--mk-fg)
  );
}
.sov-variant-table__creative[data-status="pending"]
  .sov-variant-table__creative-glyph {
  color: var(--sov-faint);
}
.sov-variant-table__creative[data-status="failed"]
  .sov-variant-table__creative-glyph {
  color: color-mix(in oklab, var(--mk-glow-the-windhover) 88%, var(--mk-fg));
}
.sov-variant-table__link {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: var(--sov-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Role badge (Surface C) */
.sov-role-badge {
  font-family: var(--sov-font-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: var(--sov-radius-pill);
  color: var(--sov-faint);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--mk-fg) 8%, transparent);
}
.sov-role-badge--architect {
  color: color-mix(in oklab, var(--mk-glow-gold) 70%, var(--mk-fg));
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 35%, transparent);
}

/* ─── Tile-grid responsive column overrides · Charter Rule 2 ───────
   Grid columns are governed by `--sov-tiles-grid-columns` (default 3),
   set via the `columns` prop on `SovereignTilesGrid`. On desktop the
   grid renders the chartered number of equal columns. Below
   `--sov-columns-break` (680px), all grids collapse to 2 columns.
   Gaps and track sizing remain in the sovereign spacing scale — no
   hardcoded numeric values. */
@media (max-width: 680px) {
  [data-sovereign] .sov-tiles-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ─── Horizontal-scroll tile shelf · Charter Rule 4 ──────────────
   `sov-tiles-grid--hscroll` switches the grid from auto-fit wrapping
   rows to a single horizontally-scrollable row. Track sizing uses
   the same sanctioned --sov-tiles-grid-track-* tokens; gap stays in
   the sovereign spacing scale. No magic numbers. */
[data-sovereign] .sov-tiles-grid--hscroll {
  grid-auto-flow: column;
  grid-auto-columns: var(--sov-tiles-grid-track-comfortable-base, 220px);
  grid-template-columns: none;
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x proximity;
  /* Silence the scrollbar visually; scroll behaviour is preserved. */
  scrollbar-width: none;
}
[data-sovereign] .sov-tiles-grid--hscroll::-webkit-scrollbar {
  display: none;
}
/* Snappy landing on each tile so the shelf feels composed, not loose. */
[data-sovereign] .sov-tiles-grid--hscroll > * {
  scroll-snap-align: start;
}

/* ─── Flex-wrap tile shelf · Charter Rule 5b (self-authored) ────
   Companion base tokens (--sov-tiles-grid-track-*-base) carry the
   same sanctioned 220px/180px values as the grid minmax tracks.
   Children grow from base width up to fill available space, then
   wrap — same responsive shape as `repeat(auto-fit, minmax())` but
   with per-row-variable heights (no cross-row stretch). */
[data-sovereign] .sov-tiles-grid--flex-wrap > * {
  flex: 1 1 var(--sov-tiles-grid-track-comfortable-base, 220px);
  min-width: 0;
}

/* ───────────────────────────────────────────────────────────────────
 * Projects Rail (Phase 1 — step-39)
 * Right-rail project listing with New Project button, search, toggle,
 * and dropdown project cards. Dark-first with glass morphism.
 *
 * Token purification · 2026-05-11 (step-37)
 * Replaced every hardcoded gap, padding, border-radius, and font-size
 * with sovereign tokens. Authored: pr/step-37/PR.md §2.
 * ──────────────────────────────────────────────────────────────── */

/* .sov-project-rail and .sov-project-rail__content were the original
 * outer/inner wrappers for the project rail. Removed 2026-05-16 when
 * SovereignProjectRail was restructured to return a fragment of
 * siblings (mode-toggle, button, .sov-rail-panel) — the canonical
 * structure shared with SovereignA05RailSessions. The rail-body
 * (.sov-shell__rail-body) and panel (.sov-rail-panel) together now
 * own the column flow, scroll, gap, and L/R rail padding that those
 * project-specific wrappers used to provide locally. Keeping no dead
 * rules behind so consumers don't reach for orphaned selectors. */

.sov-project-rail__new-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 100%;
  height: var(--sov-rail-btn-h);
  padding: 0 var(--sov-space-3);
  border: 0;
  border-radius: var(--sov-radius-pill);
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-subtle);
  background: var(--sov-surface-raised);
  box-shadow: inset 0 0 0 1px
    var(--mk-hairline-gold, var(--sov-composer-border));
  cursor: pointer;
  transition: background var(--sov-d-base) var(--sov-ease-expo), color
    var(--sov-d-base) var(--sov-ease-expo), box-shadow var(--sov-d-base)
    var(--sov-ease-expo);
}

.sov-project-rail__new-btn:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}

.sov-project-rail__new-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Gold accent on the leading "+" — a single visual signature shared by
 * every consumer of .sov-project-rail__new-btn (the projects rail's
 * + New Project and the sessions rail's + New Session). One token,
 * one rule, applied wherever this button is used. */
.sov-project-rail__new-btn-plus {
  color: var(--sov-color-glow-gold);
  font-weight: 600;
  -webkit-margin-end: 0.35em;
          margin-inline-end: 0.35em;
}

.sov-project-rail__status {
  font-family: var(--sov-font-serif);
  font-size: var(--sov-text-caption-size);
  line-height: 1.55;
  color: var(--sov-subtle);
  margin: 0;
}

.sov-project-rail__status--error {
  color: var(--sov-status-error);
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-chip-size);
}

/* The project item HEADER (title + date row) is no longer rendered.
 * 2026-05-16 — SovereignProjectRail now uses the same
 *   .sov-a05-rail__session / .sov-a05-rail__session-row /
 *   .sov-a05-rail__session-button / .sov-a05-rail__session-actions
 * markup as SovereignA05RailSessions. The dropdown EXPAND body below
 * is preserved (.sov-project-rail__item-body and descendants) since
 * project items still expand to show description / badges / Open /
 * Invite — that's the project-specific surface that legitimately
 * differs from sessions. Removed:
 *   .sov-project-rail__list, .sov-project-rail__item,
 *   .sov-project-rail__item-header (+:hover, [aria-expanded='true']),
 *   .sov-project-rail__item-title, .sov-project-rail__item-meta,
 *   .sov-project-rail__item-chevron(--open).
 * Anything that wants a row now reaches for the canonical session
 * tokens above (.sov-a05-rail__session-*). */

.sov-project-rail__item-body {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
  padding: var(--sov-space-2) 0 var(--sov-space-1) var(--sov-space-3);
}

.sov-project-rail__item-desc {
  font-size: var(--sov-text-chip-size);
  color: var(--sov-subtle);
  line-height: 1.5;
  margin: 0;
}

.sov-project-rail__item-info {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2);
}

.sov-project-rail__badge {
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-micro-size);
  padding: 2px 6px;
  border-radius: var(--sov-radius-xs);
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 70%, var(--mk-fg));
}

.sov-project-rail__item-count {
  font-size: var(--sov-text-micro-size);
  color: var(--sov-faint);
}

.sov-project-rail__item-actions {
  display: flex;
  gap: var(--sov-space-1);
}

.sov-project-rail__action-btn {
  font-family: var(--sov-font-mono);
  font-size: var(--sov-text-chip-size);
  padding: var(--sov-space-1) var(--sov-space-3);
  border-radius: var(--sov-radius-sm);
  border: none;
  cursor: pointer;
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 80%, var(--mk-fg));
  transition: background var(--sov-d-fast) var(--sov-ease-expo);
}

.sov-project-rail__action-btn:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 22%, transparent);
}

.sov-project-rail__action-btn--secondary {
  background: color-mix(in oklab, var(--sov-bg) 30%, transparent);
  color: var(--sov-subtle);
}

.sov-project-rail__action-btn--secondary:hover {
  background: color-mix(in oklab, var(--sov-bg) 45%, transparent);
}

/* ───────────────────────────────────────────────────────────────────
 * Project Canvas — the page IS the canvas (2026-05-12)
 *
 * When [data-sov-projects-active] or [data-sov-folio-spread-active] is on
 * [data-sovereign], the root .sov-surface inherits the A06 canvas visual
 * identity (grid pattern, radial gradient, dark backdrop). The rails and
 * composer float over as fixed-position chrome. The inner shell is hidden.
 * Content renders directly inside a pan layer child of .sov-surface.
 *
 * Replaces the old .sov-project-canvas wrapper architecture.
 * ──────────────────────────────────────────────────────────────── */

/* Root-as-canvas: grid + gradient paint on .sov-surface itself when
 * a project is active. Pseudo-element ::after for the grid overlay.
 * Same-node compound selectors — .sov-surface *is* [data-sovereign]. */
[data-sovereign][data-sov-projects-active].sov-surface,
[data-sovereign][data-sov-projects-active].sov-surface {
  background: var(--sov-bg);
  /* The viewport is a WINDOW onto the infinite canvas. The pan-layer is
   * 28000×18000px — far larger than the screen. overflow:hidden clips it to
   * the viewport so only the visible portion renders. The pan/zoom transform
   * moves the massive layer behind this window. This is how every infinite
   * canvas works (Figma, Miro): a huge surface, clipped to a viewport. */
  overflow: hidden;
}

[data-sovereign][data-sov-folio-spread-active].sov-surface,
[data-sovereign][data-sov-constellation-active].sov-surface {
  background: var(--sov-bg);
  /* Folio and constellation keep overflow:visible — folio's pan-layer is
   * constrained (not infinite), and constellation renders via Canvas2D. */
  overflow: visible;
}

/* Only Projects wears the 26px grid overlay. Constellation and folio share
 * the dark backdrop and deep-glass rails, but want a clean field behind
 * their canvases (Architect, 2026-07-11). */
[data-sovereign][data-sov-projects-active].sov-surface::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0.16;
  pointer-events: none;
  background-image: linear-gradient(
      color-mix(in oklab, var(--sov-ink) 14%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      90deg,
      color-mix(in oklab, var(--sov-ink) 14%, transparent) 1px,
      transparent 1px
    );
  background-size: 26px 26px;
}

/* Pan layer — the coordinate space for canvas nodes.
 * Absolute fill of .sov-surface, sits behind rails (z:1).
 * Transform applied via inline style for panning.
 * Explicit width/height so getBoundingClientRect returns correct values
 * for drag coordinate calculations.
 *
 * Cursor: grab hand on idle, open-hand on active drag.
 * touch-action: none prevents browser gesture conflicts (pull-to-refresh,
 * navigation swipe) during canvas panning.
 * Transition: transform var(--sov-d-base) var(--sov-ease-expo) — applies
 * only to programmatic moves (keyboard settle, snap-to). Suppressed during
 * user-driven drag and momentum coast via [data-sov-panning].
 *
 * Authored: sovereign-design/kaOS Design System (self-authored)/pr/step-45/PR.md
 *           §SR-1 infinite canvas pan foundation.
 *           Sanctioned under Charter Rule 5b (Sovereign Design Authority). */
[data-sovereign][data-sov-projects-active] .sov-canvas-pan-layer,
[data-sovereign][data-sov-folio-spread-active] .sov-canvas-pan-layer {
  /* The infinite canvas surface — a LARGE fixed-size element, NOT
   * viewport-sized. Nodes position in canvas-space pixels (stored 0-100 ×
   * 1600/1000 reference). The layer is big enough to hold nodes placed far
   * from the origin. The parent (.sov-surface, overflow:hidden) clips the
   * visible area to the viewport; the pan/zoom transform moves the layer.
   *
   * No margins — top:0, left:0 aligns canvas-space (0,0) with the viewport
   * origin at rest (translate 0,0). Nodes at left:2000px render 2000px right
   * of the viewport origin, clipped until you pan there. */
  position: absolute;
  top: 0;
  left: 0;
  width: 28000px;
  height: 18000px;
  z-index: 1;
  cursor: default;
  transform-origin: 0 0;
}

/* ── Folio spread: constrain the pan layer below the center header
     and above the composer so the grid fills the reading area. ── */
[data-sovereign][data-sov-folio-spread-active] .sov-canvas-pan-layer {
  inset: var(--sov-section-h) 0
    calc(var(--sov-prompt-h-live) + var(--sov-bloom)) 0;
  width: auto;
  height: auto;
}

[data-sovereign][data-sov-projects-active] .sov-canvas-pan-layer {
  touch-action: none;
}

[data-sovereign][data-sov-folio-spread-active] .sov-canvas-pan-layer {
  touch-action: auto;
  overflow: hidden;
  pointer-events: auto;
}

/* ═══════════════════════════════════════════════════════════════════
   Folio spread — project node (single two-column grid, no wrappers)
   ═══════════════════════════════════════════════════════════════════ */

/* Inner folio — single column reading surface. Same tokens as the
   chat surface's sov-adapter-text: sans family, field rung size/weight,
   field line height, ink color. One source, one reading system. */
[data-sovereign] [data-sovereign-folio] {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-field-size);
  font-weight: var(--sov-text-field-weight);
  line-height: var(--sov-text-field-line);
  color: var(--sov-ink);
}

/* Scroll-view prose column — same reading-measure discipline as the
   spread columns. The article shell stays at --sov-canvas-max so wide
   descriptors (tables, plates) can breathe, but body prose is capped
   at the classical measure and centered. */
[data-sovereign] [data-sovereign-folio] .sov-renderer {
  max-width: var(--sov-folio-measure-max);
  margin-inline: auto;
}

/* The grid is the single node — fills the canvas pan layer between
   rails, below the center header, above the composer. Padding-top
   clears the header; padding-bottom clears the composer + prompt bar.
   Width is clamped to two reading-measure columns + the 48px column
   gap + 40px padding so wide screens keep the classical measure;
   auto margins center the clamped spread between the rails. */
[data-sovereign][data-sov-folio-spread-active] .sov-folio-spread-grid {
  position: relative;
  width: min(
    calc(100vw - 48px - 48px),
    calc(2 * var(--sov-folio-measure-max) + 48px + 40px)
  );
  height: 100%;
  overflow: clip;
  box-sizing: border-box;
  margin-inline: auto;
  padding-inline: 20px;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-field-size);
  font-weight: var(--sov-text-field-weight);
  line-height: var(--sov-text-field-line);
  color: var(--sov-ink);
}

/* Cover chapter — full-width container filling the spread grid.
   Landscape cover uses the full width; portrait falls back to
   right-aligned height-constrained display. */
[data-sovereign][data-sov-folio-spread-active] .sov-folio-cover-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
}

[data-sovereign][data-sov-folio-spread-active] .sov-folio-cover-img {
  width: 100%;
  height: auto;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

[data-sovereign][data-sov-folio-spread-active] .sov-folio-spread-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  pointer-events: auto;
}

[data-sovereign][data-sov-folio-spread-active] .sov-folio-spread-nav-title {
  margin: 0;
  font-family: var(--sov-font-sans, "Inter", system-ui, sans-serif);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-muted);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 420px;
}

[data-sovereign][data-sov-folio-spread-active] .sov-folio-spread-nav-btn {
  font: inherit;
  font-family: var(--sov-font-sans, "Inter", system-ui, sans-serif);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.35rem 0.75rem;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid color-mix(in oklab, var(--sov-ink) 18%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 72%, transparent);
  color: var(--sov-muted);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

[data-sovereign][data-sov-folio-spread-active]
  .sov-folio-spread-nav-btn:not(:disabled):hover {
  color: var(--sov-presence);
  border-color: color-mix(in oklab, var(--sov-presence) 48%, transparent);
  background: color-mix(in oklab, var(--sov-presence) 8%, transparent);
}

[data-sovereign][data-sov-folio-spread-active]
  .sov-folio-spread-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* Same nav styling for single-column inner folio view —
 * the portal nav uses the same classes but needs its own
 * data-attribute scope since [data-sov-folio-spread-active]
 * is only set in wide-viewport spread mode. */
[data-sovereign][data-sov-folio-inner-active] .sov-folio-spread-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  pointer-events: auto;
}

[data-sovereign][data-sov-folio-inner-active] .sov-folio-spread-nav-title {
  margin: 0;
  font-family: var(--sov-font-sans, "Inter", system-ui, sans-serif);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sov-muted);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 420px;
}

[data-sovereign][data-sov-folio-inner-active] .sov-folio-spread-nav-btn {
  font: inherit;
  font-family: var(--sov-font-sans, "Inter", system-ui, sans-serif);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.35rem 0.75rem;
  border-radius: var(--sov-radius-pill, 999px);
  border: 1px solid color-mix(in oklab, var(--sov-ink) 18%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 72%, transparent);
  color: var(--sov-muted);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

[data-sovereign][data-sov-folio-inner-active]
  .sov-folio-spread-nav-btn:not(:disabled):hover {
  color: var(--sov-presence);
  border-color: color-mix(in oklab, var(--sov-presence) 48%, transparent);
  background: color-mix(in oklab, var(--sov-presence) 8%, transparent);
}

[data-sovereign][data-sov-folio-inner-active]
  .sov-folio-spread-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* During active drag / momentum coast: gold pointer glow ::before
 * follows the cursor via --sov-pointer-x/y CSS custom properties. */

[data-sovereign][data-sov-projects-active]
  .sov-canvas-pan-layer[data-sov-panning]::before {
  content: "";
  position: fixed;
  left: calc(var(--sov-pointer-x, 0px) - 60px);
  top: calc(var(--sov-pointer-y, 0px) - 60px);
  width: 120px;
  height: 120px;
  border-radius: var(--sov-radius-pill);
  background: radial-gradient(
    circle 60px at center,
    color-mix(in oklab, var(--mk-glow-gold) 18%, transparent),
    transparent 100%
  );
  filter: blur(12px);
  pointer-events: none;
  z-index: 100;
}

/* Reduced-motion: skip transition duration so snaps are instant.
 * hooks into the data-sov-reduced attribute set by SovereignProvider. */
[data-sovereign][data-sov-reduced="true"] .sov-canvas-pan-layer {
  transition: none !important;
}

/* Canvas connections — SVG layer rendered behind nodes (z-index: 0
 * inside the pan layer). Grid-snapped lines using the gold glow token.
 * pointer-events: none so they don't intercept drag/pan/click. */
.sov-canvas-connections {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  width: 100%;
  height: 100%;
}

.sov-canvas-connection-line {
  stroke: var(--sov-canvas-connection-stroke);
  stroke-width: var(--sov-canvas-connection-stroke-width, 4px);
  fill: none;
  transition: d 0.18s var(--sov-ease), stroke 0.18s var(--sov-ease), filter
    0.18s var(--sov-ease);
  filter: var(--sov-canvas-connection-glow-near)
    var(--sov-canvas-connection-glow-far);
}

.sov-canvas-connection-line--hover {
  stroke: var(--sov-canvas-connection-hover-stroke);
  filter: var(--sov-canvas-connection-hover-glow);
  stroke-width: calc(var(--sov-canvas-connection-stroke-width, 4px) * 1.5);
}

.sov-canvas-connection-line--preview {
  stroke-dasharray: var(--sov-canvas-connection-preview-dash, 8px 7px);
  stroke: var(--sov-canvas-connection-preview-stroke);
  stroke-width: var(--sov-canvas-connection-preview-stroke-width, 4px);
  opacity: 0.75;
  filter: var(--sov-canvas-connection-preview-glow);
  animation: var(--sov-canvas-connection-preview-flow);
}

/* Directional current pulse for the TRON preview line.
 * stroke-dashoffset shifts by -15px (full dash cycle: 8px dash + 7px gap) over 800ms. */
@keyframes sov-canvas-connection-flow {
  to {
    stroke-dashoffset: -15px;
  }
}

/* Semantic connection variant — dimmer, thinner gold traces for
 * cosine-similarity relationships between item embeddings.
 * Only visible when the embedding pipeline has computed siblings.
 * Stroke + width live in the shared --sov-canvas-connection-* family. */
.sov-canvas-connection-line--semantic {
  stroke: var(--sov-canvas-connection-semantic-stroke);
  stroke-width: var(--sov-canvas-connection-semantic-stroke-width, 2.5px);
  opacity: 0.8;
  filter: drop-shadow(
    0 0 2px color-mix(in oklab, var(--mk-glow-gold) 12%, transparent)
  );
}

/* Selected-edge highlight — when a node is selected, its edges brighten so
 * the user can see which connections belong to it and find the × handles. */
.sov-canvas-connection-line--selected {
  stroke: var(--sov-canvas-connection-hover-stroke);
  filter: var(--sov-canvas-connection-hover-glow);
}

/* Per-kind edge styling — the data-connection-kind attribute is set on each
 * established edge path. The default ('connected') uses the base gold stroke.
 * Richer verbs (written when judgment is added) get distinct colors + weights
 * so the typed relationship is visible at a glance. Warm amber distinguishes
 * felt/substrate edges (beholding, aesthetic) from computed gold ones. */
.sov-canvas-connection-line[data-connection-kind='coread'] {
  stroke: var(--sov-canvas-connection-coread-stroke);
  stroke-width: var(--sov-canvas-connection-coread-stroke-width, 3px);
}
.sov-canvas-connection-line[data-connection-kind='beholding'] {
  stroke: var(--sov-canvas-connection-beholding-stroke);
  stroke-width: var(--sov-canvas-connection-beholding-stroke-width, 3.5px);
}
.sov-canvas-connection-line[data-connection-kind='aesthetic'] {
  stroke: var(--sov-canvas-connection-aesthetic-stroke);
  stroke-width: var(--sov-canvas-connection-aesthetic-stroke-width, 4px);
}

/* Edge disconnect handles — small × buttons at the midpoint of each edge
 * touching the selected node. Rendered as HTML over the SVG layer so they
 * receive pointer events (the SVG itself is pointer-events: none to avoid
 * intercepting pan/drag). pointer-events: auto re-enables clicks here. */
.sov-canvas-edge-handles {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.sov-canvas-edge-disconnect {
  position: absolute;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 85%, white);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
  -webkit-backdrop-filter: blur(4px);
          backdrop-filter: blur(4px);
  transition: background 0.15s var(--sov-ease), transform 0.15s var(--sov-ease);
}

.sov-canvas-edge-disconnect:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 42%, transparent);
  transform: translate(-50%, -50%) scale(1.15);
}

/* ═══════════════════════════════════════════════════════════════════
   Project share panel — extends sov-user-panel with share-specific
   layout. All tokens from the chartered design system; no inline CSS.
   ═══════════════════════════════════════════════════════════════════ */

/* Email field — full-width input (sov-user-panel__input base + share). */
[data-sovereign] .sov-share-email-field {
  width: 100%;
}

/* Invite button — half-width pill, right-aligned beneath the email field.
   The row wrapper provides the right-alignment; the chip is the pill. */
[data-sovereign] .sov-share-invite-row {
  display: flex;
  justify-content: flex-end;
}
[data-sovereign] .sov-share-invite-btn {
  width: 50%;
  cursor: pointer;
  border: 0;
}
[data-sovereign] .sov-share-invite-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Link box — gold-tinted container for the generated invite link. */
[data-sovereign] .sov-share-link-box {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  padding: var(--sov-space-2);
  border-radius: var(--sov-radius-sm);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}
[data-sovereign] .sov-share-link-label {
  margin: 0;
}
[data-sovereign] .sov-share-link-field {
  width: 100%;
  font-size: 11px;
  text-transform: none;
  letter-spacing: normal;
}
/* Copy button — half-width pill, right-aligned beneath the link field. */
[data-sovereign] .sov-share-copy-row {
  display: flex;
  justify-content: flex-end;
}
[data-sovereign] .sov-share-copy-btn {
  width: 50%;
  cursor: pointer;
  border: 0;
}

/* Invite list item — room for the remove button on the right. */
[data-sovereign] .sov-share-invite-item {
  position: relative;
  padding-right: 32px;
}
[data-sovereign] .sov-share-remove-btn {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--sov-radius-sm);
  background: transparent;
  color: var(--sov-color-muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--sov-d-fast) var(--sov-ease-expo),
    color var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-share-remove-btn:hover {
  background: color-mix(
    in oklab,
    var(--sov-color-glow-kingfishers) 12%,
    transparent
  );
  color: var(--sov-color-glow-kingfishers);
}

[data-sovereign] .sov-share-error {
  color: var(--sov-color-glow-kingfishers);
}

/* ═══════════════════════════════════════════════════════════════════
   Canvas loading + error states — chrome, not nodes. Both render
   outside the pan transform so they hold still while the board moves.
   Loading breathes on the canonical --sov-breath cadence; the error
   banner is a quiet fixed strip at bottom-center using --sov-error ink.
   ═══════════════════════════════════════════════════════════════════ */

.sov-canvas-loading {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: var(--sov-space-1);
  pointer-events: none;
}

.sov-canvas-loading__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--mk-glow-gold) 65%, transparent);
  box-shadow: 0 0 12px color-mix(in oklab, var(--mk-glow-gold) 30%, transparent);
  animation: sov-canvas-loading-breathe var(--sov-breath, 4.2s) ease-in-out
    infinite;
}

@keyframes sov-canvas-loading-breathe {
  0%,
  100% {
    opacity: 0.45;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

.sov-canvas-loading__label {
  font-family: var(--sov-font-sans);
  color: var(--sov-subtle);
  white-space: nowrap;
}

.sov-canvas-error-banner {
  position: fixed;
  bottom: calc(var(--sov-composer-h, 96px) + var(--sov-space-3));
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--sov-space-1);
  max-width: min(560px, 80vw);
  padding: var(--sov-space-1) var(--sov-space-2);
  border-radius: var(--sov-radius-md);
  background: color-mix(in oklab, var(--sov-bg) 88%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
          backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid color-mix(in oklab, var(--sov-error) 24%, transparent);
  box-shadow: 0 2px 12px color-mix(in oklab, var(--sov-error) 8%, transparent);
}

.sov-canvas-error-banner__dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: var(--sov-radius-pill);
  background: color-mix(in oklab, var(--sov-error) 80%, transparent);
  box-shadow: 0 0 8px color-mix(in oklab, var(--sov-error) 35%, transparent);
}

.sov-canvas-error-banner__label {
  font-family: var(--sov-font-sans);
  color: var(--sov-subtle);
  line-height: 1.45;
}

@media (prefers-reduced-motion: reduce) {
  .sov-canvas-loading__dot {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Canvas minimap — floating map body. Portalled to .sov-surface so it
   is outside the pan transform and never moves with the canvas. The
   toggle pill lives inside the composer (.sov-prompt) in the intent-
   pills row; this body opens above it, anchored to the pill. Reuses
   the glass-tile palette + gold accents; no new tokens.
   ═══════════════════════════════════════════════════════════════════ */

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap {
  position: absolute;
  z-index: 12;
  display: flex;
  flex-direction: column;
  border-radius: var(--sov-radius-md);
  background: color-mix(in oklab, var(--sov-bg) 85%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
          backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid color-mix(in oklab, var(--sov-subtle) 20%, transparent);
  box-shadow: 0 2px 16px color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  overflow: hidden;
  touch-action: none;
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  padding: 0 8px 0 12px;
  border-bottom: 1px solid color-mix(in oklab, var(--sov-subtle) 14%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 55%, transparent);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__title {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--sov-subtle);
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__actions {
  display: flex;
  gap: 2px;
}

/* Compact header icon buttons — tight 28px circle with an 18px SVG so
   the icon fills the button without excess padding. Sized for the
   header bar, not the full composer dock. */
[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__btn {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--sov-color-accent, var(--sov-muted));
  background: transparent;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__btn:hover {
  color: var(--sov-ink);
  background: color-mix(in oklab, var(--mk-glow-gold) 16%, transparent);
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__btn svg {
  width: 18px;
  height: 18px;
}

/* Centers the fixed-size content layer within the (possibly larger) box.
   The soft grid lives here — on the growing container — so it expands
   and fills the whole map area when the box enlarges, not just the
   fixed content surface. */
[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__surface-viewport {
  flex: 1 1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background-color: color-mix(in oklab, var(--sov-bg) 92%, transparent);
  background-image: linear-gradient(
      to right,
      color-mix(in oklab, var(--sov-subtle) 12%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      to bottom,
      color-mix(in oklab, var(--sov-subtle) 12%, transparent) 1px,
      transparent 1px
    );
  background-size: 24px 24px;
}

/* Fixed-size content layer — dots + viewport rect are positioned in
   REF-px so they stay at a constant perspective when the box expands. */
[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__surface {
  position: relative;
  cursor: crosshair;
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__dot {
  position: absolute;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: var(--sov-radius-pill);
  /* Default: gold — NOTE / unrecognised types. Full opacity for clarity. */
  background: var(--mk-glow-gold);
  box-shadow: 0 0 5px color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
  pointer-events: none;
}

/* Colour modifiers — distinct hues from the Hopkins glow palette so
   node types are immediately readable on the map. */
[data-sovereign][data-sov-projects-active]
  .sov-canvas-minimap__dot--malaika {
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  background: var(--mk-glow-gold);
  box-shadow: 0 0 8px color-mix(in oklab, var(--mk-glow-gold) 60%, transparent);
}

[data-sovereign][data-sov-projects-active]
  .sov-canvas-minimap__dot--code {
  background: var(--mk-glow-as-kingfishers-catch-fire);
  box-shadow: 0 0 5px
    color-mix(in oklab, var(--mk-glow-as-kingfishers-catch-fire) 50%, transparent);
}

[data-sovereign][data-sov-projects-active]
  .sov-canvas-minimap__dot--quote {
  background: var(--mk-glow-where-light-enters);
  box-shadow: 0 0 5px
    color-mix(in oklab, var(--mk-glow-where-light-enters) 50%, transparent);
}

[data-sovereign][data-sov-projects-active]
  .sov-canvas-minimap__dot--bookcast {
  background: var(--mk-glow-pied-beauty);
  box-shadow: 0 0 5px
    color-mix(in oklab, var(--mk-glow-pied-beauty) 50%, transparent);
}

[data-sovereign][data-sov-projects-active]
  .sov-canvas-minimap__dot--media {
  background: var(--mk-glow-the-windhover);
  box-shadow: 0 0 5px
    color-mix(in oklab, var(--mk-glow-the-windhover) 50%, transparent);
}

[data-sovereign][data-sov-projects-active] .sov-canvas-minimap__viewport {
  position: absolute;
  margin: 0;
  border: 1px solid color-mix(in oklab, var(--mk-glow-gold) 70%, transparent);
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  border-radius: 2px;
  pointer-events: none;
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--sov-bg) 40%, transparent);
}

/* Project metadata — surfaced in the right rail body. */
.sov-project-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--sov-space-2) 0;
}

.sov-project-meta__title {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-body-size);
  font-weight: 600;
  color: var(--sov-ink);
  margin: 0;
}

.sov-project-meta__desc {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-text-caption-size);
  color: var(--sov-subtle);
  margin: 0;
}

.sov-project-meta__error {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: color-mix(in oklab, var(--mk-glow-rose) 80%, var(--mk-fg));
  margin: 0;
}

/* Back-to-projects button — in the right rail header. */
/* ───────────────────────────────────────────────────────────────────
 * Canvas Drop Zone (Phase 3 — step-39)
 * Drag-over overlay with glass backdrop.
 * ──────────────────────────────────────────────────────────────── */

.sov-canvas-drop-zone__overlay {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--sov-bg) 40%, transparent);
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
  border-radius: 12px;
}

.sov-canvas-drop-zone__prompt {
  font-family: var(--sov-font-sans);
  font-size: 16px;
  font-weight: 500;
  color: var(--sov-ink);
  padding: 24px 32px;
  border-radius: 12px;
  background: color-mix(in oklab, var(--sov-bg) 30%, transparent);
}

.sov-canvas-drop-zone__error {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  font-family: var(--sov-font-mono);
  font-size: 11px;
  color: color-mix(in oklab, var(--mk-glow-rose) 85%, var(--mk-fg));
  background: color-mix(in oklab, var(--sov-bg) 60%, transparent);
  padding: 6px 14px;
  border-radius: 8px;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

/* ───────────────────────────────────────────────────────────────────
 * Canvas Media Card (Phase 3 — step-39)
 * Positioned card on the project canvas reading from KaosDocument.
 * ──────────────────────────────────────────────────────────────── */

.sov-media-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 10px;
  background: color-mix(in oklab, var(--sov-bg) 20%, transparent);
  border: 1px solid color-mix(in oklab, var(--sov-subtle) 10%, transparent);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  min-width: 180px;
  max-width: 320px;
  cursor: default;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.sov-media-card:hover {
  border-color: color-mix(in oklab, var(--sov-subtle) 20%, transparent);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
}

.sov-media-card--processing {
  opacity: 0.8;
}

.sov-media-card--failed {
  border-color: color-mix(in oklab, var(--mk-glow-rose) 25%, transparent);
}

.sov-media-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.sov-media-card__type-tag {
  font-family: var(--sov-font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--sov-subtle) 10%, transparent);
  color: var(--sov-subtle);
}

.sov-media-card__badge {
  font-family: var(--sov-font-mono);
  font-size: 9px;
  padding: 2px 6px;
  border-radius: 4px;
}

.sov-media-card__badge--processing {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: color-mix(in oklab, var(--mk-glow-gold) 15%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 75%, var(--mk-fg));
}

.sov-media-card__badge--error {
  background: color-mix(in oklab, var(--mk-glow-rose) 15%, transparent);
  color: color-mix(in oklab, var(--mk-glow-rose) 75%, var(--mk-fg));
}

.sov-media-card__spinner {
  display: inline-block;
  width: 10px;
  height: 10px;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: sov-spin 0.6s linear infinite;
}

@keyframes sov-spin {
  to {
    transform: rotate(360deg);
  }
}

.sov-media-card__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sov-media-card__thumbnail {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 6px;
  overflow: hidden;
  background: color-mix(in oklab, var(--sov-bg) 40%, transparent);
}

.sov-media-card__img,
.sov-media-card__cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sov-media-card__audio {
  padding: 4px 0;
}

.sov-media-card__player {
  width: 100%;
  height: 28px;
}

.sov-media-card__title {
  font-family: var(--sov-font-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--sov-ink);
  margin: 0;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.sov-media-card__subtitle {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  color: var(--sov-subtle);
  margin: 0;
}

.sov-media-card__domain {
  font-family: var(--sov-font-mono);
  font-size: 10px;
  color: var(--sov-faint);
  margin: 0;
}

.sov-media-card__summary {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  color: var(--sov-subtle);
  line-height: 1.5;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.sov-media-card__link {
  font-family: var(--sov-font-mono);
  font-size: 10px;
  color: color-mix(in oklab, var(--mk-glow-gold) 60%, var(--mk-fg));
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sov-media-card__link:hover {
  text-decoration: underline;
}

.sov-media-card__file-info {
  font-family: var(--sov-font-mono);
  font-size: 9px;
  color: var(--sov-faint);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sov-media-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.sov-media-card__tag {
  font-family: var(--sov-font-mono);
  font-size: 9px;
  padding: 2px 6px;
  border-radius: 4px;
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 55%, var(--mk-fg));
}

/* ──────────────────────────────────────────────
   Project Output Bar (Phase 7)
   ────────────────────────────────────────────── */

.sov-project-output-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid
    color-mix(in oklab, var(--sov-subtle) 8%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 5%, transparent);
}
.sov-project-output-bar__actions {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.sov-project-output-bar__btn {
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--sov-muted);
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--sov-subtle) 10%, transparent);
  cursor: pointer;
  transition: var(--sov-d-fast) var(--sov-ease-smooth);
}
.sov-project-output-bar__btn:hover {
  color: var(--sov-fg);
  border-color: var(--sov-gold);
}
.sov-project-output-bar__btn--active {
  color: var(--sov-fg);
  background: color-mix(in oklab, var(--sov-gold) 8%, var(--sov-bg));
  border-color: var(--sov-gold);
}
.sov-project-output-bar__input-group {
  display: flex;
  align-items: center;
  gap: 6px;
}
.sov-project-output-bar__input {
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid color-mix(in oklab, var(--sov-subtle) 12%, transparent);
  background: color-mix(in oklab, var(--sov-bg) 10%, transparent);
  color: var(--sov-fg);
  font-size: 13px;
  min-width: 220px;
}
.sov-project-output-bar__input::placeholder {
  color: var(--sov-muted);
  opacity: 0.6;
}
.sov-project-output-bar__submit {
  padding: 4px 14px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--sov-fg);
  background: var(--sov-gold);
  border: none;
  cursor: pointer;
}
.sov-project-output-bar__submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.sov-project-output-bar__result {
  margin: 0;
  font-size: 12px;
  color: color-mix(in oklab, var(--sov-leaf) 85%, var(--sov-fg));
}
.sov-project-output-bar__error {
  margin: 0;
  font-size: 12px;
  color: var(--sov-error);
}

/* ═══════════════════════════════════════════════════════════════════
 * Single-shell layout · 2026-05-09
 *
 * One surface. Rails float at fixed positions over the center.
 * Only {children} swaps between pages. No A03/A05/A06 switch.
 *
 * Sanctioned: Charter Rule 5b (Sovereign Design Authority).
 * Tokens: --sov-layout-rail-width, --sov-layout-right-rail-width,
 *         --sov-content-max, --sov-space-*, --sov-z-*,
 *         --sov-d-base, --sov-ease-expo.
 * ═══════════════════════════════════════════════════════════════════ */

/* ── Shell — one page, three fixed fixtures (2026-05-12 redesign)
 * Sanctioned: Charter Rule 5b (Sovereign Design Authority).
 * Tokens: --sov-rail-w (dynamic via clamp — 200–300px),
 *         --sov-content-max, --sov-space-*, --sov-z-*,
 *         --sov-d-base, --sov-ease-expo.
 *
 * Rail width is a single dynamic custom property:
 *   --sov-rail-w: clamp(200px, (100vw - 600px) / 2, 300px)
 * This means rails freeze at 300px above 1200px viewport, then
 * contract smoothly to 200px at 1000px, then stay at 200px below
 * that. The center (width: calc(100vw - 2*--sov-rail-w)) stays at
 * 600px from 1200px down to 1000px, then shrinks with the rails
 * at their minimum.
 *
 * Three layout tiers:
 *   1368px+  — full layout: center reaches 768px (capped),
 *              rails at 300px. Every consumer reads --sov-rail-w.
 *   1200–1367 — center shrinks with viewport (no cap active),
 *                rails still at 300px.
 *   1000–1199 — center frozen at 600px, rails contract 300→200.
 *   800–999   — rails at 200px (minimum), center = 100vw - 400.
 *   <800px    — rails become 48px icon strips (viewport-driven compact).
 *   <480px    — rails hidden entirely, center = 100vw (mobile).
 *
 * Structure (above 480px):
 *   Left rail  — position: fixed, top:0, bottom:0, left:0
 *   Right rail — position: fixed, top:0, bottom:0, right:0
 *   Center    — width: calc(100vw - 2*var(--sov-rail-w))
 *   Composer  — same width as center, fixed at bottom
 * ═══════════════════════════════════════════════════════════════════ */

/* ── Rails — fixed to viewport edges, full height always.
 * Unified: one .sov-shell__rail component used for both left and right.
 * Mirrors: .sov-shell__rail--left  (left:0, slides left off-screen)
 *          .sov-shell__rail--right (right:0, slides right off-screen)
 *
 * One attribute governs all density states: [data-sov-chrome]
 *   full      (absent) — rails at full width, composer expanded (default)
 *   collapsed (attr)   — left rail → 48px icon strip, right rail slides off,
 *                        header fades, center expands
 *   minimal   (attr)   — both rails hidden, center full-width,
 *                        composer pills hidden
 *
 * Two mechanisms, zero conflict:
 *
 *   [data-sov-chrome="compact"] — scroll-driven. Set when user scrolls
 *     past 120px, removed when they scroll back to top. Collapses left
 *     rail to 48px icon strip, slides right rail off-screen, fades header.
 *
 *   [data-sov-rail-locked] — combined with [data-sov-chrome="compact"],
 *     disables scroll response. When locked, hovering the left rail
 *     expands it temporarily (var(--sov-d-base) var(--sov-ease-expo)).
 *
 * Scroll controller: SovereignChromeController.
 * Lock toggle: Hide/Show button in right rail footer. ── */
[data-sovereign] .sov-shell__rail {
  position: fixed;
  top: 0;
  bottom: 0;
  z-index: var(--sov-z-sheet);
  width: var(--sov-rail-w);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Rails are transparent on every surface except Projects and Folio
   * (which wear deep glass via [data-sov-projects-active] and
   * [data-sov-folio-spread-active] selectors). Library, tools, chat,
   * and voice all keep the scroll body between the rails — nothing
   * pans behind them, so they don't need glass. */
  background: transparent;
}

/* biome-ignore lint/nursery/noDescendingSpecificity: base rail — follows higher-specificity compact/descendant up-file; overrides apply same-surface */
[data-sovereign] .sov-shell__rail--left {
  left: 0;
}
/* biome-ignore lint/nursery/noDescendingSpecificity: same pattern, sibling rule */
[data-sovereign] .sov-shell__rail--right {
  right: 0;
}

/* ── Compact — icon strip (both scroll-driven and viewport-driven).
 *   Fires on [data-sov-chrome="compact"] (scroll past threshold) OR
 *   [data-sov-viewport-compact] (viewport ≤ 800px). Both set the same
 *   visual: rails → 48px, labels hidden, active nav row gets gold border.
 *   Icon stays in place — no width/height/padding/gap changes.
 *   Hover-to-peek does NOT fire at viewport-compact widths (selector
 *   includes :not([data-sov-viewport-compact])) — the screen is too
 *   narrow for temporary expansion to make sense.
 *   Transition: 280ms expo-out (snappy, trackable). ── */
/* biome-ignore lint/nursery/noDescendingSpecificity: compact rail-left follows higher-specificity up-file — intentional override */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left,
/* biome-ignore lint/nursery/noDescendingSpecificity: compact rail-right follows higher-specificity up-file — intentional override */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--right {
  width: 48px;
}
/* biome-ignore lint/nursery/noDescendingSpecificity: compact left-rail overflow — intentional override */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left {
  overflow: visible;
}
/* Center header (Talk / Text / Workshop / mode tabs) stays fully active
 * when rails compact. Dim + pointer-events:none made nav unusable on
 * scroll; mode tabs must remain clickable on every surface. */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__center-header {
  opacity: 1;
  pointer-events: auto;
}

/* Projects / Folio: header is a direct child of .sov-surface (outside the
 * hidden scroll) and needs explicit width between the compacted 48px rails.
 * No background — header is transparent over the canvas. */
[data-sovereign][data-sov-projects-active] .sov-shell__center-header,
[data-sovereign][data-sov-folio-spread-active] .sov-shell__center-header,
[data-sovereign][data-sov-folio-inner-active] .sov-shell__center-header {
  opacity: 1;
  pointer-events: auto;
  width: calc(100vw - 48px - 48px);
  margin-inline: auto;
  position: relative;
  z-index: 2;
}

/* ── Ghost placeholder breathe animation — soft pulse for the
 *     "type here" indicator on the project canvas. ── */
@keyframes sov-ghost-breathe {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 0.55;
  }
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__scroll {
  width: calc(100vw - 48px - 48px);
}

/* ── Compact — right rail body content hidden but element stays in flex flow
 *   so the footer doesn't collapse. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--right
  .sov-shell__rail-body {
  visibility: hidden;
}
/* ── Compact — left rail body nav rows stay visible as icon-only pills.
 *   Labels are hidden individually (opacity:0 on .nr-row__label) so no
 *   text peeks through. The body must NOT be visibility:hidden — that
 *   kills the icons and the entire nav surface. Overflow:hidden keeps
 *   the 48px strip contained without erasing the icon rows.
 *   The header and footer stay visible for the logo glyph and lock pill. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left
  .sov-shell__rail-body {
  overflow: hidden;
}

/* ── Compact — rail footer shrinks to match the icon-only pill layout.
 *   Left rail: flex-start inset. Right rail: flex-end (right-aligned). ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail-footer {
  height: 56px;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left
  .sov-shell__rail-footer {
  justify-content: flex-start !important;
  padding-left: var(--sov-rail-pad) !important;
  padding-right: 0 !important;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--right
  .sov-shell__rail-footer {
  justify-content: flex-end !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
}
/* ── Compact — composer spans the space between 48px rails instead of
 *   the full --sov-rail-w width. The base rule uses calc(100vw - rail*2)
 *   which at 800px viewport computes to 100vw - 400px (since the clamp
 *   minimum is 200px) — wrong. Override to 100vw - 96px so it matches
 *   the actual compact rail width. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ).sov-surface
  > .sov-prompt {
  width: calc(100vw - 96px);
}

/* ── Compact — fast search circle.
 *   Input hidden, kbd chip centered in a round gold-bordered pill. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-a03-fast-search {
  width: 36px;
  height: 36px;
  justify-content: center;
  padding: 0;
  margin-bottom: 0;
  background: transparent;
  border-radius: var(--sov-radius-pill);
  box-shadow: inset 0 0 0 1px
    color-mix(in oklab, var(--mk-glow-gold) 20%, transparent);
  color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-a03-fast-search__input {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sov-rail-transition);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-a03-fast-search__kbd {
  background: transparent;
  padding: 0;
  color: color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
}

/* ── Compact — footer pills icon-only.
 *   Same tokens as open state; only sizing/padding/gap change. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail-footer
  .nr-utils__pill {
  width: var(--sov-rail-compact-glyph-size);
  height: var(--sov-rail-compact-glyph-size);
  min-height: var(--sov-rail-compact-glyph-size);
  padding: 0;
  gap: 0;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail-footer
  .nr-utils__pill
  span {
  opacity: 0;
  pointer-events: none;
  max-width: 0;
  overflow: hidden;
  transition: opacity var(--sov-rail-transition);
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail-footer
  .nr-utils__pill
  svg {
  width: calc(var(--sov-rail-compact-glyph-size) * 0.5);
  height: calc(var(--sov-rail-compact-glyph-size) * 0.5);
  margin: 0;
}

/* ── Compact — hide-toggle inherits base icon-only sizing above. ── */

/* ── Compact — left rail header: hide wordmark entirely so watermark
 *   images cannot reserve flex width ahead of the favicon. Inset matches
 *   expanded header / nav rows via --sov-rail-pad. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left
  .nr-header__brand
  .sov-kaos-text-logo {
  display: none;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left
  .nr-header__brand {
  width: 100%;
  justify-content: flex-start;
}
/* ── kaOS animated icon — CSS-only, no JS, no Framer Motion.
 *   Six coloured circles spread across the header, subtle float + pulse.
 *   Uses the same HDSC palette as the original KaosLogi component. ── */
[data-sovereign] .sov-kaos-logi-icon {
  display: none;
}
[data-sovereign] .sov-kaos-logi-icon__orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(1.5px);
  opacity: 0.25;
}
/* Each orb starts at a different position — clustered leftward so the
 * icon reads as centered-left in the 48px compact rail header. */
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(1) {
  background: radial-gradient(circle at 40% 40%, oklch(55% 0.22 298.5));
  width: 26px;
  height: 26px;
  top: 10%;
  left: 8%;
  animation: kaos-orb-float 8s ease-in-out infinite;
}
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(2) {
  background: radial-gradient(circle at 40% 40%, oklch(50% 0.25 20.0));
  width: 20px;
  height: 20px;
  top: 45%;
  left: 25%;
  animation: kaos-orb-float 10s ease-in-out infinite 1s;
}
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(3) {
  background: radial-gradient(circle at 40% 40%, oklch(60% 0.11 229.0));
  width: 28px;
  height: 28px;
  top: 50%;
  left: -2%;
  animation: kaos-orb-float 9s ease-in-out infinite 2s;
}
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(4) {
  background: radial-gradient(circle at 40% 40%, oklch(58% 0.15 87.0));
  width: 22px;
  height: 22px;
  top: 5%;
  left: 30%;
  animation: kaos-orb-float 7s ease-in-out infinite 0.5s;
}
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(5) {
  background: radial-gradient(circle at 40% 40%, oklch(52% 0.18 150.0));
  width: 24px;
  height: 24px;
  top: 65%;
  left: 15%;
  animation: kaos-orb-float 11s ease-in-out infinite 3s;
}
[data-sovereign] .sov-kaos-logi-icon__orb:nth-child(6) {
  background: radial-gradient(circle at 40% 40%, oklch(48% 0.2 60.0));
  width: 18px;
  height: 18px;
  top: 30%;
  left: -4%;
  animation: kaos-orb-float 8.5s ease-in-out infinite 1.5s;
}
@keyframes kaos-orb-float {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }
  25% {
    transform: translate(6px, -5px) scale(1.15);
  }
  50% {
    transform: translate(-5px, -3px) scale(0.85);
  }
  75% {
    transform: translate(-7px, 4px) scale(1.1);
  }
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--left
  .sov-shell__rail-header {
  justify-content: flex-start;
  padding-left: var(--sov-rail-pad) !important;
  padding-right: 0 !important;
  overflow: visible;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-kaos-logi-icon {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  transform: rotate(45deg);
}

/* ── Compact — right rail header: avatar-only, hide meta text.
 *   !important overrides the inline padding-right from SovereignRailLayout
 *   so the avatar centers in the 48px compact rail. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-shell__rail--right
  .sov-shell__rail-header {
  padding-left: 0 !important;
  padding-right: 0 !important;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-user-card__meta {
  display: none;
}
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-user-card__main {
  justify-content: center;
  gap: 0;
}
/* ── Compact — the 48px strip is narrower than the 40px avatar plus the
 *   card's default 12px right padding, so the centred avatar was being
 *   clipped on the sides. Zero the padding and let the card centre the
 *   avatar with clean gutters; overflow:visible guards against any
 *   sub-pixel clip at the card edge. ── */
[data-sovereign]:where([data-sov-chrome="compact"], [data-sov-viewport-compact])
  .sov-user-card {
  padding: 0;
  justify-content: center;
  overflow: visible;
}

/* ── Unified rail motion — one reign, every child obeys.
 *   Sanctioned: Charter Rule 5b (Sovereign Design Authority).
 *   Tokens: --sov-d-base (280ms, Step 16 sanctioned),
 *           --sov-ease-expo (cubic-bezier(0.16, 1, 0.3, 1), Step 16 sanctioned).
 *   Ladder step 3: direct analogy to existing transition block.
 *   No new values authored. One named reign. ── */
[data-sovereign] {
  --sov-rail-transition: var(--sov-d-base) var(--sov-ease-expo);
}

/* ── Compact — hover to peek (UNLOCKED and NOT viewport-compact).
 *   When rails are compacted by scroll and NOT locked, hovering the rail
 *   expands to full width. The :not([data-sov-viewport-compact])
 *   guard prevents this at viewport-driven compact widths (≤ 800px) —
 *   the screen is too narrow for temporary expansion to make sense.
 *   .nr-row hover-to-peek restore rules live with the base .nr-row block. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover {
  width: var(--sov-rail-w);
}

/* ── Hover — left rail: restore kaOS text logo, hide round icon. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .nr-header__brand
  .sov-kaos-text-logo {
  display: flex;
  align-items: center;
  opacity: 1;
  pointer-events: auto;
  max-width: 100%;
  width: auto;
  flex: 0 0 auto;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-shell__rail-header {
  justify-content: initial;
  padding-left: var(--sov-rail-pad) !important;
  padding-right: 0 !important;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-kaos-logi-icon {
  display: none;
}

/* ── Hover — right rail: show body content and restore user card meta. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-shell__rail-body {
  visibility: visible;
}
/* ── Hover — left rail: show body content so nav row labels reappear on hover. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-shell__rail-body {
  visibility: visible;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-user-card__meta {
  display: flex;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-user-card__main {
  justify-content: flex-start;
  gap: var(--sov-user-card-gap);
}

/* ── Hover — restore fast-search to full-width. ── */
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-a03-fast-search,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-a03-fast-search {
  width: auto;
  height: auto;
  padding: var(--sov-space-2) var(--sov-search-pill-pad-x);
  border-radius: 8px;
  box-shadow: none;
  color: var(--sov-color-muted);
  margin-bottom: initial;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-a03-fast-search__input,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-a03-fast-search__input {
  opacity: 1;
  pointer-events: auto;
}
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--left:hover
  .sov-a03-fast-search__kbd,
[data-sovereign]:where(
    [data-sov-chrome="compact"],
    [data-sov-viewport-compact]
  ):not([data-sov-rail-locked]):not([data-sov-viewport-compact])
  .sov-shell__rail--right:hover
  .sov-a03-fast-search__kbd {
  color: var(--sov-color-muted);
}

/* ── Transitions — var(--sov-rail-transition) on rail layout properties.
 *   The rail width drives the visual effect. Children respond naturally
 *   to their parent's size change. Center header and scroll adjust in sync.
 *   Reduced-motion: @media block follows. ── */
[data-sovereign] .sov-shell__rail,
[data-sovereign] .sov-shell__center-header,
[data-sovereign] .sov-shell__scroll,
[data-sovereign] .sov-prompt {
  transition: width var(--sov-rail-transition), opacity
    var(--sov-rail-transition);
}

/* ── Reduced motion — freeze all rail transitions.
 *   Charter Rule self-review gate compliance. ── */
@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-shell__rail,
  [data-sovereign] .sov-shell__center-header,
  [data-sovereign] .sov-shell__scroll,
  [data-sovereign] .sov-prompt {
    transition: none;
  }
}

/* ── Rail header — fixed height matching center header. Same for both sides.
 *   Surface-level padding provides the horizontal inset; header children
 *   carry zero internal padding.
 *
 *   The right rail header owns the ambient gold halo — the user card
 *   radiates no glow of its own; the header div behind it does. ── */
/* biome-ignore lint/nursery/noDescendingSpecificity: base rail-header follows higher-specificity @media override — intentional cascade */
[data-sovereign] .sov-shell__rail-header {
  flex-shrink: 0;
  height: var(--sov-section-h);
  display: flex;
  align-items: center;
  padding: 0;
}

/* ── Rail body — scrollable, flex-fills remaining space.
 *   Column flex with 16px top padding only.
 *   Horizontal padding is the canonical single source for every component
 *   below — nothing else in the rail supplies left/right spacing.
 *   2026-05-11: added padding-inline so no child component needs its own L/R pad. ── */
/* biome-ignore lint/nursery/noDescendingSpecificity: base rail-body follows higher-specificity @media override — intentional cascade */
[data-sovereign] .sov-shell__rail-body {
  flex: 1 1;
  min-height: 0;
  overflow-y: auto;
  padding-top: 16px;
  padding-inline: var(--sov-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

/* Right rail body — position: relative so the user panel (absolutely
 * positioned child) anchors correctly within the scroll area. The panel
 * itself is a portal target into the outer rail, absolutely positioned
 * to match the body area exactly. */
[data-sovereign] .sov-shell__rail--right .sov-shell__rail-body {
  position: relative;
}

/* Left rail body nav rows — tighter gap than the generic rail body.
 *   s1 (4px) keeps files/projects/tools snug. ── */
[data-sovereign] .sov-shell__rail--left .sov-shell__rail-body {
  gap: var(--sov-space-1);
}

/* ── Rail footer — flex-shrink:0, vertically centered.
 *   Height matches the sovereign prompt's total resting footprint
 *   (composer body + bottom padding) so the footer and prompt
 *   bottom edges are aligned.
 *   Horizontal alignment set inline per surface (left=flex-start, right=flex-end). ── */
[data-sovereign] .sov-shell__rail-footer {
  flex-shrink: 0;
  height: calc(var(--sov-prompt-h) + var(--sov-space-4));
  display: flex;
  align-items: center;
}

/* Right rail footer — toggle pill right-aligned in all states. */
[data-sovereign] .sov-shell__rail--right .sov-shell__rail-footer {
  justify-content: flex-end;
}

/* ── Rail comms toggle — icon-only phone glyph (left rail footer). ── */
[data-sovereign] .sov-rail-comms-toggle {
  width: var(--sov-rail-compact-glyph-size);
  height: var(--sov-rail-compact-glyph-size);
  min-height: var(--sov-rail-compact-glyph-size);
  padding: 0;
  gap: 0;
  transition: color var(--sov-rail-transition), background
    var(--sov-rail-transition);
}
[data-sovereign] .sov-rail-comms-toggle svg {
  width: calc(var(--sov-rail-compact-glyph-size) * 0.5);
  height: calc(var(--sov-rail-compact-glyph-size) * 0.5);
  margin: 0;
  flex-shrink: 0;
}
[data-sovereign] .sov-rail-comms-toggle:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}

/* ── Rail collapse toggle — icon-only pill in every chrome state.
 *   Panel-open / panel-close glyphs (not lock). No label text. ── */
[data-sovereign] .sov-rail-hide-toggle {
  width: var(--sov-rail-compact-glyph-size);
  height: var(--sov-rail-compact-glyph-size);
  min-height: var(--sov-rail-compact-glyph-size);
  padding: 0;
  gap: 0;
  transition: color var(--sov-rail-transition), background
    var(--sov-rail-transition);
}
[data-sovereign] .sov-rail-hide-toggle svg {
  width: calc(var(--sov-rail-compact-glyph-size) * 0.55);
  height: calc(var(--sov-rail-compact-glyph-size) * 0.55);
  margin: 0;
  flex-shrink: 0;
}
[data-sovereign] .sov-rail-hide-toggle:hover {
  color: var(--sov-color-glow-gold);
  background: color-mix(in oklab, var(--mk-glow-gold) 6%, transparent);
}

/* ── Center header — sticky tabs strip inside the scroll area.
   No background — fully transparent. ── */
[data-sovereign] .sov-shell__center-header {
  flex-shrink: 0;
  height: var(--sov-section-h);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sov-gutter);
}

/* Inner stack — lets the page-context eyebrow sit above the page-mode
   tabs without disturbing the header's centered horizontal layout.
   The eyebrow is opt-in (rendered only when a page publishes items),
   so when no eyebrow is present the stack collapses to a single row
   and the tabs render exactly as before. */
[data-sovereign] .sov-shell__center-header-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

/* Scrollable body inside .sov-shell__scroll — the actual content area.
   Fills remaining space below the fixed header; content scrolls here,
   never beneath the header. 20px horizontal padding for comfortable
   reading inset. */
[data-sovereign] .sov-shell__scroll-body {
  flex: 1 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* Reserve the vertical scrollbar gutter permanently. Without this, the
     content width shrinks by the scrollbar width the instant a surface's
     content grows past the viewport. Any descendant that measures its own
     width (SovereignTile via useMeasuredWidth) and turns that width into
     reserved height (SovereignField line-clamp minHeight) can then tip the
     content height back under the viewport, hiding the scrollbar, widening
     the content, and re-firing the measurement — a bistable width↔scrollbar
     oscillation that surfaces as "Maximum update depth exceeded". A stable
     gutter keeps the measured width constant whether or not the bar shows. */
  scrollbar-gutter: stable;
  padding: 16px 20px 0;
}

/* Center scroll — single surface between left/right rails. Absorbs the
   column positioning previously split across two divs (sov-shell__center +
   sov-shell__scroll). Margin clears the fixed rails on each side;
   bottom padding reserves space for the fixed composer. */
[data-sovereign] .sov-shell__scroll {
  flex: 1 1;
  width: calc(100vw - var(--sov-rail-w) * 2);
  max-width: var(--sov-content-max);
  margin-inline: auto;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 0;
  /* Reserve bottom space — the transparent composer overlays this zone.
     Box-sizing is border-box, so this reduces the flex child's content-box,
     pushing the scroll-body's bottom edge up above the composer.
     --sov-prompt-h-live is the composer's full rendered footprint (border-
     box), published by SovereignPrompt via ResizeObserver; falls back to
     --sov-prompt-h + --sov-composer-wrap-pad-b when the composer is
     unmounted. Adding one breathing rung keeps Malaika's last line clear
     of the composer at every scroll position — one token, one consumer,
     every surface. */
  padding-bottom: calc(var(--sov-prompt-h-live) + var(--sov-space-4));
  box-sizing: border-box;
  min-height: 0;
  background: var(--sov-bg);
  color: var(--sov-ink);
}

/* ── Cross-page presence strip (M7, 2026-06-08).
 *
 *   A thin ambient breath at the very top of the sovereign shell.
 *   The model is the substrate's ambient identity, not a feature
 *   that appears when summoned. The strip is a single small orb
 *   followed by a breath line — three readable states that mirror
 *   the substrate's identity:
 *
 *     resting  — slow breath (4s cycle), muted color, soft glow.
 *     working  — faster breath (1.6s cycle), accent color, brighter.
 *     handoff  — steady glow (no breath), a "deep" label appears
 *                so the user knows the work is being carried by a
 *                deeper body, not stalled.
 *
 *   The strip sits above every page including the compact-chrome
 *   projects / folio / voice / revenue modes. When the voice stage
 *   is active the strip is unmounted by the shell (voice owns its
 *   own presence via the constellation). The strip is hidden during
 *   page transitions and when prefers-reduced-motion is set — a
 *   presence strip should never induce motion sickness.
 *
 *   Sovereign-design compliance: no new color tokens, no new
 *   primitive, no new vocabulary. Color is sourced from --sov-ink
 *   and --sov-accent (both shipped). The orb is a 4px dot, the
 *   line is 1px tall — small enough to read as ambient, not
 *   chrome. ── */
[data-sovereign] .sov-presence-strip {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  display: flex;
  align-items: center;
  padding: 0 16px;
  z-index: 50;
  pointer-events: none;
  background: transparent;
}

[data-sovereign] .sov-presence-strip__orb {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(
    --sov-ink-soft,
    color-mix(in oklab, var(--sov-ink) 60%, transparent)
  );
  box-shadow: 0 0 6px color-mix(in oklab, var(--sov-ink) 30%, transparent);
  transition: background 600ms ease, box-shadow 600ms ease, transform 600ms ease;
}

[data-sovereign] .sov-presence-strip__line {
  flex: 1 1;
  height: 1px;
  margin-left: 8px;
  background: linear-gradient(
    to right,
    color-mix(in oklab, var(--sov-ink) 18%, transparent) 0%,
    color-mix(in oklab, var(--sov-ink) 6%, transparent) 100%
  );
  transform-origin: left center;
  transition: background 600ms ease;
}

[data-sovereign]
  .sov-presence-strip[data-state="resting"]
  .sov-presence-strip__orb {
  animation: sov-presence-breathe 4s ease-in-out infinite;
}

[data-sovereign]
  .sov-presence-strip[data-state="working"]
  .sov-presence-strip__orb {
  background: var(--sov-accent, var(--sov-ink));
  box-shadow: 0 0 10px
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 50%, transparent);
  animation: sov-presence-breathe 1.6s ease-in-out infinite;
}

[data-sovereign]
  .sov-presence-strip[data-state="working"]
  .sov-presence-strip__line {
  background: linear-gradient(
    to right,
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 40%, transparent) 0%,
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 12%, transparent) 100%
  );
}

[data-sovereign]
  .sov-presence-strip[data-state="handoff"]
  .sov-presence-strip__orb {
  background: var(--sov-accent, var(--sov-ink));
  box-shadow: 0 0 14px
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 60%, transparent);
  animation: none;
  transform: scale(1.4);
}

[data-sovereign]
  .sov-presence-strip[data-state="handoff"]
  .sov-presence-strip__line {
  background: linear-gradient(
    to right,
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 55%, transparent) 0%,
    color-mix(in oklab, var(--sov-accent, var(--sov-ink)) 18%, transparent) 100%
  );
  animation: none;
}

@keyframes sov-presence-breathe {
  0%,
  100% {
    opacity: 0.5;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1.1);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign]
    .sov-presence-strip[data-state="resting"]
    .sov-presence-strip__orb,
  [data-sovereign]
    .sov-presence-strip[data-state="working"]
    .sov-presence-strip__orb {
    animation: none;
  }
}

/* ── Composer — fixed to viewport bottom, spans the center column
  between the two rails. Content self-centers via --sov-content-max.
  Horizontal padding matches .sov-shell__scroll-body (20px).
  No background — transparent over the scrolling content. ── */
[data-sovereign].sov-surface > .sov-prompt {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  width: calc(100vw - var(--sov-rail-w) * 2);
  max-width: var(--sov-content-max);
  margin-inline: auto;
  box-sizing: border-box;
  min-width: 0;
  padding-inline: 20px;
  padding-bottom: max(var(--sov-space-5), env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  align-items: stretch;
  z-index: 65;
}

/* ── Projects-active: hide inner shell, reveal the page-canvas.
 *   Rails stay visible as fixed chrome. The center header stays visible
 *   (it carries the mode tabs). Only the scroll body is hidden.
 *   display:none removes it from layout so the pan layer fills the viewport. ── */
[data-sovereign][data-sov-projects-active] .sov-shell__scroll,
[data-sovereign][data-sov-folio-spread-active] .sov-shell__scroll,
[data-sovereign][data-sov-constellation-active] .sov-shell__scroll {
  display: none;
}

/* ── Constellation-active: keep center header visible for surface
 *   navigation (the library mode tabs render inside the header in this
 *   mode). Mirrors the projects/voice pattern: scroll body hidden, pan
 *   layer fills the viewport, rails float over as compact chrome. ── */
[data-sovereign][data-sov-constellation-active] .sov-shell__center-header {
  opacity: 1;
  pointer-events: auto;
  width: calc(100vw - 48px - 48px);
  margin-inline: auto;
  position: relative;
  z-index: 2;
}

/* Constellation pan layer — fills the viewport behind the rails.
 * Same absolute fill as projects, but without touch-action:none so
 * the constellation's own pointer handlers take precedence. */
[data-sovereign][data-sov-constellation-active] .sov-canvas-pan-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  cursor: default;
}

/* Root-as-canvas for constellation is now the SAME route as Projects:
 * [data-sov-constellation-active].sov-surface is folded into the
 * [data-sov-projects-active] surface + ::after grid block (search:
 * "Project Canvas — the page IS the canvas") and into the deep-glass
 * rails block (search: "Deep sovereign glass — the canonical recipe").
 * Unified 2026-07-11 — do not re-add a constellation-only surface bg
 * here or the drift returns. */

/* ── Projects-active: rails wear deep glass.
 *
 *   Projects is the only surface where the chrome floats over an
 *   infinite canvas — nodes pan past where the rails sit, and without
 *   any chrome backdrop the sprawl bleeds visibly through the rails
 *   and reads as visual noise. Every other surface (library, tools,
 *   chat, voice) is linear: the scroll body sits between the rails,
 *   nothing pans behind them, and the rails want to stay transparent
 *   so the page beneath shows through cleanly.
 *
 *   The actual glass declarations live with the consolidated
 *   .sov-glass-strong recipe near the top of this file (search:
 *   "Deep sovereign glass — the canonical recipe"). The Projects rails
 *   are one of three entry points painted by that single block, so the
 *   auth overlay, the user popover, and the Projects rails all share
 *   one tunable knob (--sov-glass-mix-strong). Do not redeclare
 *   background or backdrop-filter on these rails here — that recreates
 *   the drift this consolidation removed. ── */

/* ── Voice-active: hide inner shell, reveal the voice stage.
 *
 *   Mirrors the projects-active pattern. The shell mounts
 *   <SovereignVoiceStage /> as a sibling of the canvas pan layer
 *   when [data-sov-voice-active] is set. The stage paints its
 *   PresenceSurface fixed/inset:0/z:9999 over the viewport, the
 *   VoiceComposer paints fixed at center-bottom in the same screen
 *   slot the suppressed shell composer would have occupied, and the
 *   side rails compact to 48 px because the shell also stamps
 *   [data-sov-chrome="compact"]. The center header stays visible —
 *   it still carries the LINEAR / VOICE tabs, which the family uses
 *   to hop back to text without ever leaving the conversation.
 *
 *   No router transition. No fresh shell mount. No orphaned
 *   ChatSession row. The shared SovereignChatSessionProvider keeps
 *   the kaos_session_id stable across the modality flip. ── */
[data-sovereign][data-sov-voice-active] .sov-shell__scroll {
  display: none;
}
[data-sovereign][data-sov-voice-active] .sov-shell__center-header {
  opacity: 1;
  pointer-events: auto;
  width: calc(100vw - 48px - 48px);
  margin-inline: auto;
  /* Above the presence surface (z:30) so TEXT / TALK tabs stay
   * visible and tappable on the voice page. */
  position: relative;
  z-index: 55;
}

/* ── Voice surface: let the collapsed rails sit above the presence canvas.
 *
 *   § 2026-06-28 — Kaleeg noticed the rails were invisible on the voice
 *   page even though [data-sov-chrome="compact"] had collapsed them to
 *   48px strips. The reason: the SovereignPresenceSurface paints at
 *   z:9999 with position:fixed inset:0, which covers the entire
 *   viewport including the 48px rail gutters. The rails are at z:50
 *   (--sov-z-sheet), so they were trapped under the surface.
 *
 *   The projects surface solves the same problem by sitting BELOW the
 *   rails (canvas z:10, rails z:50). Voice takes the opposite path:
 *   the constellation wants to feel room-filling. The compromise is
 *   to keep the surface fullscreen but (a) drop its z-index below the
 *   rails, and (b) inset it horizontally by the compact rail width so
 *   the rail strips have nothing painted behind them anyway. The
 *   constellation's radial gradients are centred, so the 48px inlay
 *   on each side reads as a soft vignette rather than a hard gutter.
 *
 *   The composer follows the same inset so it stays centred in the
 *   rail-to-rail gutter rather than spanning under the rail strips.
 *   Its z-index stays at 10000 so it remains the topmost touchable
 *   element — the family needs to reach the mic. */
[data-sovereign][data-sov-voice-active] [data-presence-surface] {
  /* Below the rails (z:50) and the composer (z:10000), above the
   * canvas pan layer (z:10). 30 is a clean step. */
  z-index: 30;
  /* Inset by the compact rail width so the constellation doesn't
   * paint under the rail strips. The rails have their own glass
   * surface already; painting behind them would just blur through. */
  left: 48px;
  right: 48px;
  /* Stay full-height — the constellation should still fill the
   * vertical room. Only the horizontal sides step in. */
  inset-block: 0;
}
[data-sovereign][data-sov-voice-active] .sov-voice-composer {
  /* Keep the composer above the rails (z:10000 from the base rule)
   * but inset it horizontally so it centres in the gutter, not
   * under the rail strips. Without this the composer's hit target
   * overlaps the rail and taps land on the wrong affordance. */
  /* The transform: translateX(-50%) from the base rule keeps it
   * centred; we just constrain its max-width so it can't extend
   * into the rail gutter on narrower viewports. */
  max-width: calc(100vw - 48px - 48px - var(--sov-space-5, 24px));
}
/* On viewports too narrow for rail gutters (phone portrait), the
 * density controller has already collapsed the rails to 0 width via
 * [data-sov-viewport-compact], so the surface and composer return to
 * true full-bleed. */
@media (max-width: 480px) {
  [data-sovereign][data-sov-voice-active] [data-presence-surface] {
    left: 0;
    right: 0;
  }
  [data-sovereign][data-sov-voice-active] .sov-voice-composer {
    max-width: calc(100vw - var(--sov-space-5, 24px));
  }
}

/* ── Rail compact — handled by SovereignViewportDensityController.
 *   At ≤ 800px viewport, the JS hook sets [data-sov-viewport-compact] +
 *   [data-sov-chrome="compact"] on [data-sovereign], and the unified
 *   compact CSS system fires — same visual as scroll-driven compact
 *   (rails 48px, labels hidden, nav rows pill-shaped, etc.), via the
 *   same selector group. No media-query CSS duplication needed.
 *
 *   At ≤ 480px (phone portrait), rails disappear entirely and the center
 *   + composer go full width. */
/* ── Rails hidden: at 480px and below (phone portrait), rails disappear
   entirely. Center and composer go full-width, stacking into what
   effectively becomes a mobile layout. */
@media (max-width: 480px) {
  [data-sovereign] .sov-shell__rail {
    display: none;
  }
  [data-sovereign] .sov-shell__scroll {
    width: 100vw;
  }
  [data-sovereign].sov-surface > .sov-prompt {
    width: 100vw;
  }
}

/* ── User Panel (fly-in from right) · step-38 ──
 *
 * A fixed-position panel that slides in from the right edge of the viewport.
 * Renders above the rail (--sov-z-drawer) with a glass backdrop.
 *
 * Sanctioned: step-38 self-authored mode 5b.
 * Tokens consumed: --sov-z-drawer, --sov-radius-sheet, --sov-radius-sm,
 *   --sov-radius-pill, --sov-color-surface-raised, --sov-color-surface-sunken,
 *   --sov-color-ink, --sov-color-muted, --sov-color-glow-kingfishers,
 *   --sov-shadow-surface, --mk-glow-gold-hairline, --mk-glow-gold,
 *   --sov-font-sans, --sov-text-tile-size, --sov-space-1 through --sov-space-3,
 *   --sov-ease-expo, --sov-d-base, --sov-d-fast.
 * Rationale: fly-in panel pattern per Sovereign design charter. */

/* ── Panel — portaled into .sov-shell__rail--right .sov-shell__rail-body.
 *   The body has position: relative, so the panel fills it completely
 *   with inset: 0. Physically can't extend into header or footer.
 *   Glass-morphic, no gold borders. ── */
[data-sovereign] .sov-user-panel {
  position: absolute;
  inset: 0;
  z-index: var(--sov-z-drawer);
  display: flex;
  flex-direction: column;
  /* Background + backdrop-filter intentionally omitted — supplied by
   * the consolidated .sov-glass-strong recipe (search the file for
   * "Deep sovereign glass — the canonical recipe"). One token,
   * one rule, three surfaces. */
  box-shadow: var(--sov-shadow-surface), -4px 0 24px rgba(0, 0, 0, 0.08);
  overflow-y: auto;
  overflow-x: hidden;
  animation: sov-panel-in var(--sov-d-base) var(--sov-ease-expo) both;
}

@keyframes sov-panel-in {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-sovereign] .sov-user-panel {
    animation: none;
  }
}

/* ── Close button — round, gold hairline border, gold icon.
 *   Dimmed at rest (opacity 0.6), prominent on hover (opacity 1,
 *   gold fill behind the icon). All tokens shipped. ── */
[data-sovereign] .sov-user-panel__close {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 1px solid var(--mk-hairline-gold);
  background: transparent;
  color: var(--mk-glow-gold);
  cursor: pointer;
  opacity: 0.6;
  padding: 0;
  transition: opacity var(--sov-d-fast) var(--sov-ease-expo), background
    var(--sov-d-fast) var(--sov-ease-expo), box-shadow var(--sov-d-fast)
    var(--sov-ease-expo);
}
[data-sovereign] .sov-user-panel__close:hover,
[data-sovereign] .sov-user-panel__close:focus-visible {
  opacity: 1;
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  box-shadow: 0 0 0 1px var(--mk-glow-gold-ring);
  outline: none;
}

/* ── Panel body — scoped to the panel's own flex layout.
 *     padding-top clears the absolute close button (32px + 12px top).
 *     padding-inline mirrors .sov-shell__rail-body — the panel is
 *     position:absolute inset:0 so it does not inherit the rail's
 *     horizontal pad and must restate it. ── */
[data-sovereign] .sov-user-panel__body {
  flex: 1 1;
  padding: 44px var(--sov-rail-pad) var(--sov-space-4);
  display: flex;
  flex-direction: column;
  /* Canonical panel-section rhythm. One token governs the gap between
   * every direct child of the body (label, toggle, item row, hint,
   * status slot, shortcut disclosure) so THEME → chips, PROFILE → Avatar,
   * SECURITY → Change-password, SESSION → Lock, and COGNITION →
   * Chat-model all land at the same vertical distance. The previous
   * `space-1` left COGNITION feeling cramped because it had no
   * label-to-first-item anchor of its own. */
  gap: var(--sov-space-3);
}

/* Section labels — margin-based (not padding-based) so siblings are
 * positioned by the parent gap token, not by stacking padding. The
 * previous padding-based rule was the source of the visual asymmetry
 * between THEME (sitting beside the rail-mode-toggle's explicit 16px
 * margin) and the others (sitting only inside the parent gap). One
 * source of truth now: the body gap. */
[data-sovereign] .sov-user-panel__section-label {
  font-family: var(--sov-font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-color-muted);
  margin: 0;
  padding: 0;
}

/* User-panel theme toggle — adopts the body gap above and below, so
 * it sits at the same vertical distance as every other item. The
 * prior 16px top-and-bottom margin pushed THEME→chips out of the
 * canonical rhythm. */
[data-sovereign] .sov-user-panel .sov-rail-mode-toggle {
  margin: 0;
}

/* Cognition role choices — selectable rows in the edit panel. */
[data-sovereign] .sov-user-panel__choice-list {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  max-height: min(52vh, 360px);
  overflow-y: auto;
  padding-right: 2px;
}

[data-sovereign] .sov-user-panel__choice-list--compact {
  max-height: min(28vh, 180px);
}

[data-sovereign] .sov-user-panel__secret-row {
  display: flex;
  gap: var(--sov-space-2);
  align-items: center;
}

[data-sovereign] .sov-user-panel__input--grow {
  flex: 1 1 auto;
  min-width: 0;
}

[data-sovereign] .sov-user-panel__choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  text-align: left;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: transparent;
  border: 0;
  border-radius: var(--sov-radius-sm);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  color: var(--sov-color-ink);
  cursor: pointer;
  font-family: var(--sov-font-sans);
  padding: var(--sov-space-2) var(--sov-space-3);
  transition:
    background var(--sov-d-fast) var(--sov-ease-expo),
    box-shadow var(--sov-d-fast) var(--sov-ease-expo);
}

[data-sovereign] .sov-user-panel__choice:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
}

[data-sovereign] .sov-user-panel__choice[aria-selected='true'] {
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  color: var(--mk-glow-gold);
}

[data-sovereign] .sov-user-panel__choice-label {
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 600;
  line-height: var(--sov-text-tile-line);
}

[data-sovereign] .sov-user-panel__choice-hint {
  font-size: 11px;
  line-height: 1.35;
  color: var(--sov-color-muted);
  font-weight: 400;
}

[data-sovereign] .sov-user-panel__choice[aria-selected='true'] .sov-user-panel__choice-hint {
  color: color-mix(in oklab, var(--mk-glow-gold) 70%, var(--sov-color-muted));
}

/* Cognition block — group of four item rows (Chat / Embeddings / STT /
 * Endpoint) under the COGNITION section label. The block wrapper is the
 * direct child of the body; the body gap lands above and below the block
 * but not between the label and items inside it. A flex-column with the
 * same gap token as the body aligns the label→first-item spacing with
 * every other section in the panel. margin/padding stay at zero so the
 * body gap is the sole vertical anchor. */
[data-sovereign] .sov-user-panel__cognition-block {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  margin: 0;
  padding: 0;
}

/* System-status slot — hosts the ops disclosure moved out of the right
 * rail. Adopts the body gap on both sides so it sits at the same
 * vertical distance as every other item. The previous asymmetric
 * margin (space-2 above, space-1 below) made the slot pinch upward
 * against the Session hint. */
[data-sovereign] .sov-user-panel__status-slot {
  margin: 0;
}

/* ── Branding rows — light/dark logo + favicon upload slots ── */
[data-sovereign] .sov-user-panel__branding-row {
  display: flex;
  gap: var(--sov-space-2);
  align-items: flex-start;
  padding: var(--sov-space-2) 0;
  box-shadow: inset 0 -1px 0 0 var(--mk-hairline-gold);
}

[data-sovereign] .sov-user-panel__branding-row:last-of-type {
  box-shadow: none;
}

[data-sovereign] .sov-user-panel__branding-preview {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--sov-radius-xs);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  background: var(--sov-surface-raised);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

[data-sovereign] .sov-user-panel__branding-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

[data-sovereign] .sov-user-panel__branding-meta {
  flex: 1 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
}

[data-sovereign] .sov-user-panel__branding-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sov-space-1);
  align-items: center;
  margin-top: var(--sov-space-1);
}

[data-sovereign] .sov-user-panel__branding-actions .sov-user-panel__btn {
  min-height: var(--sov-rail-btn-h);
  padding-inline: var(--sov-space-3);
}

[data-sovereign] .sov-user-panel__file-input {
  display: none;
}

[data-sovereign] .sov-user-panel__avatar-edit {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-user-panel__avatar-preview {
  width: 72px;
  height: 72px;
  border-radius: 999px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  color: var(--mk-glow-gold);
  font-family: var(--sov-font-sans);
  font-size: 28px;
  font-weight: 600;
}

[data-sovereign] .sov-user-panel__avatar-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Panel items — standard sovereign button size (40px), gold hairline ring,
 *     gold-mix background on hover. Tokens: --sov-rail-btn-h (40px),
 *     --mk-hairline-gold, --mk-glow-gold-ring, --sov-ease-expo, --sov-d-fast. ── */
[data-sovereign] .sov-user-panel__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sov-space-2);
  width: 100%;
  height: var(--sov-rail-btn-h); /* 40px */
  padding: 0 var(--sov-space-3);
  border: 0;
  border-radius: var(--sov-radius-sm);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  color: var(--sov-color-ink);
  cursor: pointer;
  font: inherit;
  text-align: start;
  transition: background var(--sov-d-fast) var(--sov-ease-expo), box-shadow
    var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-user-panel__item:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}

[data-sovereign] .sov-user-panel__item--static {
  cursor: default;
  pointer-events: none;
}

[data-sovereign] .sov-user-panel__item-label {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--sov-color-ink);
  line-height: 1;
}

[data-sovereign] .sov-user-panel__item-value {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 400;
  color: var(--sov-color-muted);
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
}

/* Panel hint — sits below a button (e.g. Lock session) to explain what
 * happens. Small but not microscopic; uses the existent muted-warm token.
 * Spacing comes from the parent body's gap token (one source of truth)
 * — the prior `margin-top: space-1` doubled the rhythm under every
 * hint and was the asymmetry source. */
[data-sovereign] .sov-user-panel__hint {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--sov-color-muted);
  padding: 0 var(--sov-space-3);
  margin: 0;
}

[data-sovereign] .sov-user-panel__hint--flush {
  margin: 0;
  padding: 0;
}

/* ── Compact shortcut rows — reference only, not action tiles ── */
[data-sovereign] .sov-user-panel__shortcut-list {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
}

[data-sovereign] .sov-user-panel__shortcut-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sov-space-2);
  padding: var(--sov-space-1) 0;
}

[data-sovereign] .sov-user-panel__shortcut-label {
  font-family: var(--sov-font-sans);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.3;
  color: var(--sov-color-ink);
}

[data-sovereign] .sov-user-panel__shortcut-keys {
  font-family: var(--sov-font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--sov-color-muted);
  white-space: nowrap;
}

[data-sovereign] .sov-user-panel__item--danger {
  color: var(--sov-color-glow-kingfishers);
}
[data-sovereign] .sov-user-panel__item--danger:hover {
  background: color-mix(
    in oklab,
    var(--sov-color-glow-kingfishers) 8%,
    transparent
  );
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}

[data-sovereign] .sov-user-panel__item-icon {
  flex-shrink: 0;
  margin-right: 2px;
}

/* ── Edit section ── */
[data-sovereign] .sov-user-panel__edit-section {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-2);
}

[data-sovereign] .sov-user-panel__input {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  line-height: var(--sov-text-tile-line);
  color: var(--sov-color-ink);
  background: transparent;
  border: 0;
  border-radius: var(--sov-radius-sm);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  min-height: var(--sov-rail-btn-h);
  padding: 0 var(--sov-space-3);
  outline: none;
  transition:
    background var(--sov-d-fast) var(--sov-ease-expo),
    box-shadow var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-user-panel__input:focus {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}
[data-sovereign] .sov-user-panel__input--error {
  box-shadow: inset 0 0 0 1px var(--sov-color-glow-kingfishers);
}

[data-sovereign] .sov-user-panel__edit-actions {
  display: flex;
  gap: var(--sov-space-2);
  justify-content: flex-end;
  margin-top: var(--sov-space-1);
}

[data-sovereign] .sov-user-panel__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sov-font-sans);
  font-size: var(--sov-rail-btn-font-size);
  font-weight: 400;
  line-height: 1;
  border: 0;
  border-radius: var(--sov-radius-sm);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold);
  min-height: var(--sov-rail-btn-h);
  padding: 0 var(--sov-space-4);
  cursor: pointer;
  background: transparent;
  color: var(--sov-color-ink);
  transition:
    background var(--sov-d-fast) var(--sov-ease-expo),
    box-shadow var(--sov-d-fast) var(--sov-ease-expo),
    opacity var(--sov-d-fast) var(--sov-ease-expo);
}
[data-sovereign] .sov-user-panel__btn:disabled {
  opacity: 0.5;
  cursor: default;
}

[data-sovereign] .sov-user-panel__btn--ghost {
  background: transparent;
  color: var(--sov-color-ink);
}
[data-sovereign] .sov-user-panel__btn--ghost:hover:not(:disabled) {
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}

[data-sovereign] .sov-user-panel__btn--primary {
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
  color: var(--sov-color-ink);
  box-shadow: inset 0 0 0 1px var(--mk-glow-gold-ring);
}
[data-sovereign] .sov-user-panel__btn--primary:hover:not(:disabled) {
  background: color-mix(in oklab, var(--mk-glow-gold) 18%, transparent);
}

/* ── Error message ── */
[data-sovereign] .sov-user-panel__error {
  font-family: var(--sov-font-sans);
  font-size: var(--sov-nav-item-font-size);
  color: var(--sov-color-glow-kingfishers);
  padding: var(--sov-space-2) 0 0;
}

/* ═══════════════════════════════════════════════════════════════════════
 * DESIGN-TEST · malaika-content review surface (step-19)
 *
 * This block styles the sanctioned review page at
 * `apps/sovereign/app/[locale]/design-test/malaika-content/page.tsx`,
 * which renders every ContentDescriptor kind inside a real
 * `SovereignChatBubble role="malaika"`. It is the single sanctioned
 * surface for tuning the adapter / renderer / rhythm token families
 * (`--sov-renderer-gap*`, `--sov-adapter-*`, `--sov-text-*`).
 *
 * The visual treatment is deliberately quiet — no rival aesthetic — so
 * the eye lands on the descriptor output, not the scaffold around it.
 * Every value below is a token; nothing here will outlive its purpose.
 * ═══════════════════════════════════════════════════════════════════════ */

/* The sovereign app's `apps/sovereign/app/sovereign-html.css` locks
   `html, body { overflow: hidden; height: 100% }` because the live
   shell manages its own internal scroll containers. Design-test
   surfaces live outside the (sovereign) route group and therefore
   need their OWN scroll container, scoped to the review root so we
   never have to fight the global body lock. */
[data-sovereign] .sov-review {
  height: 100dvh; /* dvh used: vh fallback redundant */
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--sov-bg);
  color: var(--sov-ink);
  padding: var(--sov-space-7) var(--sov-space-5) var(--sov-space-8);
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-7);
}

[data-sovereign] .sov-review__hero {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
  text-align: center;
}

[data-sovereign] .sov-review__hero-eyebrow {
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sov-whisper);
}

[data-sovereign] .sov-review__hero-lede {
  color: var(--sov-subtle, var(--sov-ink));
  max-width: 56ch;
  margin: 0 auto;
}

[data-sovereign] .sov-review__column {
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-7);
}

[data-sovereign] .sov-review__sample {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-3);
}

[data-sovereign] .sov-review__sample-head {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1);
  padding-bottom: var(--sov-space-2);
  border-bottom: 1px solid var(--sov-adapter-hairline);
}

[data-sovereign] .sov-review__sample-title {
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mk-glow-gold, var(--sov-ink));
}

[data-sovereign] .sov-review__sample-intro {
  /* The sample intro is the quiet preface to each adapter — half a
   * sentence of context under the gold section title. The size stays at
   * the caption rung (set by `.sov-t-caption`) so it never competes
   * with the body it introduces, but family and leading shift toward
   * the chapter register: serif (Newsreader / Noto Serif) and body-line
   * leading (1.65) so the preface reads like the opening of a paragraph
   * rather than a metadata strip. Measure widens to 66ch so the intro
   * and the narrative body beneath it share a right edge — a clean
   * visual rhyme between the head trio and the prose it announces. */
  font-family: var(--sov-font-serif);
  line-height: var(--sov-text-body-line);
  color: var(--sov-whisper);
}
/* ════════════════════════════════════════════════════════════════════════
 * Concilience deployment — CSS-driven UI simplification.
 *
 * When NEXT_PUBLIC_SOVEREIGN_DEPLOYMENT_MODE=concilience, the shell stamps
 * [data-deployment="concilience"] on the root. CSS here hides sovereign-
 * specific chrome (no comms button in left rail, no right rail services
 * beyond TOC) without touching any component logic. The light theme is
 * applied via data-sovereign-theme="light" stamped by the same useEffect.
 *
 * § Deployed 2026-05-28 for the student-pack surface at concilience.ai.
 * ════════════════════════════════════════════════════════════════════════ */

/* ── Left rail footer: hide the Comms button (phone icon) ── */
[data-sovereign][data-deployment="concilience"]
  .sov-rail-comms-toggle {
  display: none;
}

/* ── Right rail: hide the Lock/Unlock toggle ── */
[data-sovereign][data-deployment="concilience"]
  .nr-utils__pill.sov-rail-hide-toggle {
  display: none;
}

/* ── Right rail chat surface: hide the mode toggle (Sessions/Activity),
     session list, and section eyebrows — concilience is search-only
     in the chat rail. The fast-search input stays visible. ── */
[data-sovereign][data-deployment="concilience"] .sov-rail-mode-toggle,
[data-sovereign][data-deployment="concilience"] .sov-a05-rail__sessions,
[data-sovereign][data-deployment="concilience"] .sov-a05-rail__eyebrow {
  display: none;
}

/* ───────────────────────────────────────────────────────────
 * § 2026-06-24 — Multi-Session Tabs
 *
 * Horizontal scrollable tab strip for multiple concurrent chat
 * sessions. Sits above the chat surface. Uses sovereign glass
 * tokens — same visual language as SovereignRailModeToggle.
 * ─────────────────────────────────────────────────────────── */

[data-sovereign] .sov-session-tabs {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
  flex-shrink: 0;
}

[data-sovereign] .sov-session-tabs::-webkit-scrollbar {
  display: none;
}

[data-sovereign] .sov-session-tabs__pill {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 160px;
  height: 32px;
  padding: 0 10px 0 12px;
  border-radius: 9999px;
  border: 1px solid var(--sov-hairline, rgba(255, 255, 255, 0.06));
  background: var(--sov-glass-bg, rgba(255, 255, 255, 0.03));
  color: var(--sov-whisper, rgba(255, 255, 255, 0.4));
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  position: relative;
}

[data-sovereign] .sov-session-tabs__pill:hover {
  background: var(--sov-glass-bg-hover, rgba(255, 255, 255, 0.06));
  color: var(--sov-subtle, rgba(255, 255, 255, 0.7));
}

[data-sovereign] .sov-session-tabs__pill--active {
  border-color: var(--sov-gold, rgba(212, 175, 55, 0.5));
  color: var(--sov-gold, #d4af37);
  background: color-mix(in oklab, var(--mk-glow-gold) 8%, transparent);
}

[data-sovereign] .sov-session-tabs__pill--active:hover {
  background: color-mix(in oklab, var(--mk-glow-gold) 12%, transparent);
}

[data-sovereign] .sov-session-tabs__label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Close button — visible on hover, muted */
[data-sovereign] .sov-session-tabs__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 10px;
  color: var(--sov-whisper, rgba(255, 255, 255, 0.3));
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
  cursor: pointer;
  flex-shrink: 0;
}

[data-sovereign] .sov-session-tabs__pill:hover .sov-session-tabs__close {
  opacity: 1;
}

[data-sovereign] .sov-session-tabs__close:hover {
  color: var(--mk-glow-the-windhover);
  background: color-mix(in oklab, var(--mk-glow-the-windhover) 10%, transparent);
}

/* Unread dot — 6px gold circle */
[data-sovereign] .sov-session-tabs__unread-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sov-gold, #d4af37);
  flex-shrink: 0;
  animation: sov-session-tabs__pulse 2s ease-in-out infinite;
}

/* Streaming indicator — small pulsing dot */
[data-sovereign] .sov-session-tabs__stream-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sov-gold, #d4af37);
  flex-shrink: 0;
  animation: sov-session-tabs__pulse 0.8s ease-in-out infinite;
  box-shadow: 0 0 6px color-mix(in oklab, var(--mk-glow-gold) 50%, transparent);
}

@keyframes sov-session-tabs__pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* New session button — dashed border pill */
[data-sovereign] .sov-session-tabs__new {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 9999px;
  border: 1px dashed var(--sov-hairline, rgba(255, 255, 255, 0.12));
  background: transparent;
  color: var(--sov-whisper, rgba(255, 255, 255, 0.4));
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

[data-sovereign] .sov-session-tabs__new:hover {
  border-color: var(--sov-gold, rgba(212, 175, 55, 0.4));
  color: var(--sov-gold, #d4af37);
  background: color-mix(in oklab, var(--mk-glow-gold) 5%, transparent);
}

/* ───────────────────────────────────────────────────────────
 * Multi-Session Stack — pane container for all chat surfaces.
 * Each pane uses [hidden] so background surfaces stay mounted
 * and their SSE streams keep flowing.
 * ─────────────────────────────────────────────────────────── */

[data-sovereign] .sov-multi-session-stack {
  display: flex;
  flex-direction: column;
  flex: 1 1;
  min-height: 0;
  position: relative;
}

[data-sovereign] .sov-multi-session-pane {
  display: flex;
  flex-direction: column;
  flex: 1 1;
  min-height: 0;
}

[data-sovereign] .sov-multi-session-pane[hidden] {
  display: none;
}

/* ───────────────────────────────────────────────────────────────────────
 * Neuromorphic wake tiers · tokens/tokens.json wake.*
 * Added 2026-07-05 (Piece 5 of the tokens audit) — encodes the consilience
 * direction (sparse, event-driven, stateful, role-specialized, energy-
 * efficient) directly into the design language.
 *
 * A surface that opts into wake-tier behavior declares its default tier
 * via a data attribute and lets the substrate CSS drive the transition.
 * The token values are $themable: a user's tolerance for ambient motion
 * and visual fade is personal (see tokens/CONTRIBUTING.md § `$themable`).
 *
 * Tier semantics:
 *   instant  — active, full attention, fully rendered
 *   warm     — cached in memory, the user's last-touched surface
 *   cold     — paged out, visible but out of focus
 *   dormant  — not running, awaiting an event to wake it
 *
 * Hovering or focusing a surface lifts it to instant for the duration of
 * the interaction, then settles back to its declared tier.
 * ─────────────────────────────────────────────────────────────────────── */

[data-sovereign] .sov-wake {
  transition-property: opacity, filter, transform, box-shadow;
  transition-duration: var(--sov-wake-tier-transition);
  transition-timing-function: var(--sov-motion-ease-out);
  will-change: opacity, filter, transform;
}

[data-sovereign] .sov-wake[data-wake-tier='instant'] {
  opacity: var(--sov-wake-tier-instant-opacity);
  filter: blur(var(--sov-wake-tier-instant-blur));
  transform: scale(var(--sov-wake-tier-instant-scale));
}

[data-sovereign] .sov-wake[data-wake-tier='warm'] {
  opacity: var(--sov-wake-tier-warm-opacity);
  filter: blur(var(--sov-wake-tier-warm-blur));
  transform: scale(var(--sov-wake-tier-warm-scale));
}

[data-sovereign] .sov-wake[data-wake-tier='cold'] {
  opacity: var(--sov-wake-tier-cold-opacity);
  filter: blur(var(--sov-wake-tier-cold-blur));
  transform: scale(var(--sov-wake-tier-cold-scale));
}

[data-sovereign] .sov-wake[data-wake-tier='dormant'] {
  opacity: var(--sov-wake-tier-dormant-opacity);
  filter: blur(var(--sov-wake-tier-dormant-blur));
  transform: scale(var(--sov-wake-tier-dormant-scale));
}

/* Hover and focus lift any tier to instant. The transition is symmetric
 * so the surface settles back to its declared tier cleanly. */
[data-sovereign] .sov-wake:hover,
[data-sovereign] .sov-wake:focus-within {
  opacity: var(--sov-wake-tier-instant-opacity);
  filter: blur(var(--sov-wake-tier-instant-blur));
  transform: scale(var(--sov-wake-tier-instant-scale));
}

/* Quiescent state — opt in via .sov-wake--quiescent for surfaces that
 * want to express the breath between touches more strongly (deeper
 * content dim, slightly recessed scale). */
[data-sovereign] .sov-wake--quiescent:not(:hover):not(:focus-within) {
  opacity: calc(var(--sov-wake-tier-warm-opacity, 1) * var(--sov-wake-quiescent-dim, 1));
  filter: blur(var(--sov-wake-quiescent-blur));
  transform: scale(var(--sov-wake-quiescent-scale));
}

/* ═══════════════════════════════════════════════════════════════════════
 * AUTH FORM — sign-in page (outside [data-sovereign] scope)
 *
 * The sign-in page at /[locale]/auth/sign-in renders outside the
 * sovereign shell (no rails, no composer). These styles give it a
 * clean, centred card that feels like the shell's design language
 * without depending on the [data-sovereign] scope.
 * ═══════════════════════════════════════════════════════════════════════ */

.sov-auth-form-section {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sov-space-5, 24px);
  background: var(--sov-color-bg, #0a0a0a);
  color: var(--sov-color-ink, #f0f0f0);
  font-family: var(--sov-font-sans, system-ui, sans-serif);
}

.sov-auth-form-section--unlock .sov-auth-form-card {
  max-width: 320px;
  gap: var(--sov-space-4, 16px);
  align-items: stretch;
}

.sov-auth-unlock-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sov-space-2, 8px);
  text-align: center;
}

.sov-auth-unlock-avatar {
  width: 64px;
  height: 64px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: 24px;
  font-weight: 600;
  color: var(--mk-glow-gold, rgba(212, 175, 55, 1));
  background: color-mix(in oklab, var(--mk-glow-gold, #d4af37) 12%, transparent);
  box-shadow: inset 0 0 0 1px var(--mk-hairline-gold, rgba(212, 175, 55, 0.15));
}

.sov-auth-unlock-email {
  margin: 0;
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: 13px;
  line-height: 1.3;
  color: var(--sov-color-muted, rgba(255, 255, 255, 0.5));
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sov-auth-form-card {
  width: 100%;
  max-width: 400px;
  padding: var(--sov-space-6, 32px);
  border: 1px solid var(--mk-hairline-gold, rgba(212, 175, 55, 0.15));
  border-radius: var(--sov-radius-sheet, 16px);
  background: var(--sov-color-surface-raised, rgba(255, 255, 255, 0.04));
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-5, 24px);
}

.sov-auth-form-title {
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-display-size, 28px);
  font-weight: 600;
  line-height: 1.2;
  color: var(--sov-color-ink, #f0f0f0);
  margin: 0;
}

.sov-auth-form-subtitle {
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-tile-size, 14px);
  line-height: var(--sov-text-tile-line, 1.5);
  color: var(--sov-color-muted, rgba(255, 255, 255, 0.5));
  margin: 0;
}

.sov-auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-4, 16px);
}

.sov-auth-field {
  display: flex;
  flex-direction: column;
  gap: var(--sov-space-1, 4px);
}

.sov-auth-field-label {
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-nav-item-font-size, 11px);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sov-color-muted, rgba(255, 255, 255, 0.5));
}

.sov-auth-input {
  height: 44px;
  padding: 0 var(--sov-space-3, 12px);
  border: 1px solid var(--mk-hairline-gold, rgba(212, 175, 55, 0.15));
  border-radius: var(--sov-radius-sm, 8px);
  background: var(--sov-color-surface-sunken, rgba(0, 0, 0, 0.3));
  color: var(--sov-color-ink, #f0f0f0);
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-tile-size, 14px);
  outline: none;
  transition: border-color 150ms var(--sov-ease-out, ease);
}

.sov-auth-input:focus {
  border-color: var(--mk-glow-gold, rgba(212, 175, 55, 0.6));
  box-shadow: 0 0 0 1px var(--mk-glow-gold-ring, rgba(212, 175, 55, 0.2));
}

.sov-auth-input:disabled {
  opacity: 0.5;
}

.sov-auth-error {
  padding: var(--sov-space-2, 8px) var(--sov-space-3, 12px);
  border-radius: var(--sov-radius-sm, 8px);
  background: color-mix(in oklab, var(--sov-color-glow-kingfishers, #e74c3c) 12%, transparent);
  color: var(--sov-color-glow-kingfishers, #e74c3c);
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-tile-size, 14px);
  line-height: var(--sov-text-tile-line, 1.5);
}

.sov-auth-button {
  height: 44px;
  border: 0;
  border-radius: var(--sov-radius-pill, 9999px);
  background: var(--sov-color-glow-gold, rgba(212, 175, 55, 1));
  color: var(--sov-color-bg, #0a0a0a);
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-tile-size, 14px);
  font-weight: 600;
  cursor: pointer;
  transition: opacity 150ms var(--sov-ease-out, ease);
  display: flex;
  align-items: center;
  justify-content: center;
}

.sov-auth-button:hover:not(:disabled) {
  opacity: 0.9;
}

.sov-auth-button:disabled {
  opacity: 0.4;
  cursor: default;
}

.sov-auth-switch {
  margin-top: var(--sov-space-4, 16px);
  text-align: center;
  font-family: var(--sov-font-sans, system-ui, sans-serif);
  font-size: var(--sov-text-tile-size, 14px);
  color: var(--sov-color-muted, rgba(255, 255, 255, 0.5));
}

.sov-auth-switch a {
  color: var(--sov-color-glow-gold, rgba(212, 175, 55, 1));
  text-decoration: none;
}

.sov-auth-switch a:hover {
  text-decoration: underline;
}

.sov-auth-switch-btn {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  color: var(--sov-color-glow-gold, rgba(212, 175, 55, 1));
  cursor: pointer;
}

.sov-auth-switch-btn:hover {
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  .sov-auth-input,
  .sov-auth-button {
    transition: none;
  }
}

/* ── Canvas library picker ── */

.sov-canvas-picker__overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--sov-bg) 70%, transparent);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
}

.sov-canvas-picker__panel {
  width: min(680px, 90vw);
  max-height: 75vh;
  display: flex;
  flex-direction: column;
  background: var(--sov-surface, #1a1a1e);
  border: 1px solid color-mix(in oklab, var(--sov-border, #333) 60%, transparent);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
}

.sov-canvas-picker__header {
  display: flex;
  gap: 8px;
  padding: 16px 18px;
  border-bottom: 1px solid color-mix(in oklab, var(--sov-border, #333) 40%, transparent);
}

.sov-canvas-picker__search {
  flex: 1 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--sov-text, #e0e0e0);
  font-size: 16px;
  font-family: inherit;
}

.sov-canvas-picker__search::placeholder {
  color: color-mix(in oklab, var(--sov-text, #e0e0e0) 40%, transparent);
}

.sov-canvas-picker__close {
  background: transparent;
  border: none;
  color: var(--sov-text, #e0e0e0);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.6;
  padding: 0 4px;
}
.sov-canvas-picker__close:hover { opacity: 1; }

.sov-canvas-picker__status,
.sov-canvas-picker__error {
  padding: 32px 18px;
  text-align: center;
  color: color-mix(in oklab, var(--sov-text, #e0e0e0) 50%, transparent);
  font-size: 14px;
}

.sov-canvas-picker__error { color: var(--sov-error, #e57373); }

.sov-canvas-picker__list {
  list-style: none;
  margin: 0;
  padding: 8px;
  overflow-y: auto;
  flex: 1 1;
}

.sov-canvas-picker__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  transition: background 0.12s;
}

.sov-canvas-picker__item:hover:not(:disabled) {
  background: color-mix(in oklab, var(--sov-text, #e0e0e0) 8%, transparent);
}

.sov-canvas-picker__item:disabled {
  opacity: 0.5;
  cursor: default;
}

.sov-canvas-picker__thumb {
  width: 36px;
  height: 48px;
  border-radius: 3px;
  object-fit: cover;
  flex-shrink: 0;
}

.sov-canvas-picker__thumb--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in oklab, var(--sov-text, #e0e0e0) 12%, transparent);
  font-size: 10px;
  font-weight: 600;
  color: color-mix(in oklab, var(--sov-text, #e0e0e0) 50%, transparent);
}

.sov-canvas-picker__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1;
}

.sov-canvas-picker__title {
  color: var(--sov-text, #e0e0e0);
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sov-canvas-picker__kind {
  color: color-mix(in oklab, var(--sov-text, #e0e0e0) 40%, transparent);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.sov-canvas-picker__spinner {
  width: 14px;
  height: 14px;
  border: 2px solid color-mix(in oklab, var(--sov-text, #e0e0e0) 20%, transparent);
  border-top-color: var(--sov-text, #e0e0e0);
  border-radius: 50%;
  animation: sov-spin 0.6s linear infinite;
  flex-shrink: 0;
}

.sov-a06-empty__library-btn {
  margin-top: 8px;
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--sov-text, #e0e0e0) 25%, transparent);
  color: color-mix(in oklab, var(--sov-text, #e0e0e0) 70%, transparent);
  padding: 6px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.sov-a06-empty__library-btn:hover {
  border-color: color-mix(in oklab, var(--sov-text, #e0e0e0) 50%, transparent);
  color: var(--sov-text, #e0e0e0);
}


/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../packages/kaos-sovereign/styles/reading/sovereign-reading.css ***!
  \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ═══════════════════════════════════════════════════════════════════════
   sovereign-reading.css
   The reading-surface tier for kaOS — tokens + adapter rules.

   Authored under CHARTER.md Rule 5b (Sovereign Design Authority).
   Provenance: sovereign-design/kaOS Design System / Consilience Reader
   (scroll + codex reading surface, 2026-05). Every value below was
   authored against the canonical kaOS palette and the existing
   `sov-adapter-*` vocabulary; see README.md for the per-decision log.

   THREE TIERS (Charter Rule 2 — token-first, zero inline values):
     1. PALETTE   — referenced, never redefined here (`--mk-glow-*`).
     2. SEMANTIC  — `--sov-read-*`, declared once under [data-sovereign].
                    Each binds a palette glow to a reading role.
     3. COMPONENT — `.sov-adapter-*` / `.sov-*` rules consume tier 2 only.

   COMPAT: every role falls back through `var(--sov-color-*, var(--mk-*))`
   so this file drops into a system that already defines `--sov-color-*`
   OR one that only carries the canonical `--mk-*` palette. Nothing here
   invents a raw color, radius, or duration outside the token block.

   NO DOM ASSUMPTIONS: these are pure visual tokens + class contracts.
   Pretext (or any non-DOM layout engine) positions; this file paints.
   ═══════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────
   TIER 2 · SEMANTIC TOKENS  (declare once; rebind here to retheme)
   ─────────────────────────────────────────────────────────────────────── */
[data-sovereign] {

  /* fonts — reference the canonical pairing (Newsreader/Inter/JetBrains) */
  --sov-read-font-serif: var(--sov-font-serif, var(--mk-font-serif));
  --sov-read-font-sans:  var(--sov-font-sans,  var(--mk-font-sans));
  --sov-read-font-mono:  var(--sov-font-mono,  var(--mk-font-mono));

  /* body face — the role token for primary reading text. Defaults to sans
     (Inter) so the body contrasts with serif headers. The [data-read-font]
     toggle remaps this single token, leaving display/header face untouched. */
  --sov-read-body-face:   var(--sov-read-font-sans);
  --sov-read-display-face: var(--sov-read-font-serif);

  /* neutral roles */
  --sov-read-ink:        var(--sov-color-ink,     var(--mk-fg));
  --sov-read-subtle:     var(--sov-color-subtle,  var(--mk-subtle));
  --sov-read-muted:      var(--sov-color-muted,   var(--mk-muted));
  --sov-read-bg:         var(--sov-color-bg,      var(--mk-bg));
  --sov-read-surface:    var(--sov-color-surface-raised, var(--mk-surface-raised));
  --sov-read-sunken:     var(--sov-color-surface-sunken, var(--mk-surface-sunken));
  --sov-read-hairline:   var(--sov-hairline, var(--mk-hairline));

  /* role glows (palette tier) */
  --sov-read-gold:       var(--mk-glow-gold);
  --sov-read-gold-deep:  var(--mk-glow-gold-deep);
  --sov-read-gold-soft:  var(--mk-glow-gold-soft);
  --sov-read-insight:    var(--mk-glow-where-light-enters);   /* annotation · reflection */
  --sov-read-audio:      var(--mk-glow-as-kingfishers-catch-fire); /* listen · speaking */

  /* role hairlines (1px color-mix stripes; borders are 0 at the base) */
  --sov-read-hairline-gold:    color-mix(in oklab, var(--sov-read-gold) 35%, transparent);
  --sov-read-hairline-insight: color-mix(in oklab, var(--sov-read-insight) 32%, transparent);
  --sov-read-hairline-audio:   color-mix(in oklab, var(--sov-read-audio) 30%, transparent);

  /* ── READING MEASURE & RHYTHM — three levels (S · M · L) ───────────── */
  --sov-read-measure:    36rem;      /* M — the body column cap */
  --sov-read-measure-s:  32rem;
  --sov-read-measure-l:  42rem;
  --sov-read-size:       19px;       /* M — passage font-size */
  --sov-read-size-s:     17px;
  --sov-read-size-l:     22px;
  --sov-read-line:       1.78;       /* passage line-height (M) */
  --sov-read-line-s:     1.7;        /* S — tighter, smaller body only */
  --sov-read-line-l:     1.83;       /* L — more generous */
  --sov-read-track:      -0.003em;   /* passage tracking */
  --sov-read-para-gap:   1.15em;     /* space between paragraphs */
  /* Folio paragraph gap — a unitless multiplier of body line-height, used
     by the canvas's Pretext pagination so DOM and canvas share one rhythm.
     0.68 ≈ 1.15em of a 1.7 line-height, the historical DOM value. */
  --sov-folio-para-gap:  0.68;

  /* ── TYPE RUNGS — display / section / field / caption / kicker ─────── */
  --sov-read-display-size:   clamp(30px, 4.4vw, 44px);  /* chapter title */
  --sov-read-display-line:   1.08;
  --sov-read-display-track:  -0.02em;
  --sov-read-section-size:   1.32em;   /* h2 within passage (em of body) */
  --sov-read-section-line:   1.2;
  --sov-read-field-size:     1.12em;   /* h3 — semibold, slightly above body */
  --sov-read-field-line:     1.3;
  --sov-read-kicker-size:    11px;     /* eyebrow / ALL-CAPS label */
  --sov-read-kicker-track:   0.18em;
  --sov-read-caption-size:   12.5px;

  /* ── DROP CAP — three levels of drop (2/3/4 lines) ─────────────────── */
  --sov-read-dropcap-size:   3.5em;    /* L3 (≈3 lines) — default */
  --sov-read-dropcap-size-2: 2.6em;
  --sov-read-dropcap-size-4: 4.6em;
  --sov-read-dropcap-line:   0.78;
  --sov-read-dropcap-ink:    color-mix(in oklab, var(--sov-read-gold) 64%, var(--sov-read-ink));

  /* ── VERSE (poetry) ────────────────────────────────────────────────── */
  --sov-read-verse-size:     0.95em;
  --sov-read-verse-line:     1.7;
  --sov-read-verse-indent:   2.2em;
  --sov-read-verse-rule:     var(--sov-read-hairline-gold);
  --sov-read-verse-ink:      color-mix(in oklab, var(--sov-read-ink) 94%, var(--sov-read-gold));

  /* ── PULLQUOTE / EPIGRAPH ──────────────────────────────────────────── */
  --sov-read-quote-size:     1.18em;   /* L1/L2 body */
  --sov-read-quote-display:  1.7em;    /* L3 epigraph display */
  --sov-read-quote-rule:     var(--sov-read-gold);
  --sov-read-quote-wash:     color-mix(in oklab, var(--sov-read-gold) 14%, transparent);

  /* ── FIGURE — Hopkins-wash default fill (no stock imagery, per brand) ─ */
  --sov-read-fig-radius:     var(--sov-radius-card, var(--mk-radius-card));
  --sov-read-fig-a:          oklch(0.70 0.14 50);    /* wash light-source  */
  --sov-read-fig-b:          oklch(0.42 0.10 200);   /* wash mid-body      */
  --sov-read-fig-c:          oklch(0.30 0.06 70);    /* wash deep-ground   */

  /* ── NOTES / CITATIONS ─────────────────────────────────────────────── */
  --sov-read-note-ink:       var(--sov-read-insight);
  --sov-read-note-size:      14px;

  /* ── LIST · sov-adapter-list ────────────────────────────────────────────
     kind: list | component: <List ordered items>                           */
  --sov-read-list-padding:        1.4em;
  --sov-read-list-nested-indent:  1.2em;
  --sov-read-list-marker-gap:     0.35em;
  --sov-read-list-marker:         color-mix(in oklab, var(--sov-read-gold) 60%, var(--sov-read-muted));

  /* ── INTERACTION GLOWS — highlight · annotate · listen · ask ───────── */
  --sov-read-hl-gold:        color-mix(in oklab, var(--sov-read-gold) 24%, transparent);
  --sov-read-hl-gold-hover:  color-mix(in oklab, var(--sov-read-gold) 36%, transparent);
  --sov-read-hl-insight:     color-mix(in oklab, var(--sov-read-insight) 22%, transparent);
  --sov-read-hl-faint:       color-mix(in oklab, var(--sov-read-gold) 12%, transparent);
  --sov-read-speak-wash:     color-mix(in oklab, var(--sov-read-audio) 26%, transparent);

  /* radii / motion — reference canonical scale */
  --sov-read-radius-card:    var(--sov-radius-card, var(--mk-radius-card));
  --sov-read-radius-pill:    var(--sov-radius-pill, var(--mk-radius-btn-pill));
  --sov-read-ease:           var(--sov-motion-ease-out, var(--mk-ease-expo));
  --sov-read-dur:            var(--sov-motion-duration-base, var(--mk-dur-base));
}

/* Reading-size & measure levels — set [data-read-size] / [data-measure]
   on any sovereign container to step the whole surface. */
[data-sovereign][data-read-size="s"] { --sov-read-size: var(--sov-read-size-s); --sov-read-line: var(--sov-read-line-s); }
[data-sovereign][data-read-size="l"] { --sov-read-size: var(--sov-read-size-l); --sov-read-line: var(--sov-read-line-l); }
[data-sovereign][data-measure="s"]   { --sov-read-measure: var(--sov-read-measure-s); }
[data-sovereign][data-measure="l"]   { --sov-read-measure: var(--sov-read-measure-l); }

/* ── FOLIO-SCOPED DEFAULT STEP — one step down from chat (17px / 1.7).
   The folio reading surface carries [data-sovereign-folio]; these overrides
   keep chat text at 19px while books enjoy a slightly tighter, faster read. */
[data-sovereign] [data-sovereign-folio] {
  --sov-read-size:  17px;
  --sov-read-line:  1.7;
}
/* Reading-font toggle — flips the BODY face only. Display/header face stays
   on --sov-read-font-serif. Default body is sans; "serif" toggle swaps body
   to serif so the body and the headers contrast each other. */
[data-sovereign][data-read-font="serif"] { --sov-read-body-face: var(--sov-read-font-serif); }

/* ═══════════════════════════════════════════════════════════════════════
   TIER 3 · COMPONENT RULES — consume the semantic tier only
   ═══════════════════════════════════════════════════════════════════════ */

/* ── TEXT · sov-adapter-text — four voices (tones) ──────────────────────
   kind: text | component: <Text tone>                                     */
.sov-adapter-text {
  font-family: var(--sov-read-body-face);
  font-weight: 400;
  font-size: var(--sov-read-size);
  line-height: var(--sov-read-line);
  letter-spacing: var(--sov-read-track);
  color: var(--sov-read-ink);
  text-wrap: pretty;
  font-optical-sizing: auto;
  margin: 0 0 calc(var(--sov-folio-para-gap) * var(--sov-read-line) * var(--sov-read-size));
}
/* .sov-adapter-text--narrative: base reading voice — inherits defaults, no overrides needed */
.sov-adapter-text--instructive { font-family: var(--sov-read-font-sans); font-size: calc(var(--sov-read-size) - 2px); line-height: 1.6; }
.sov-adapter-text--intimate    { font-style: italic; color: var(--sov-read-subtle); }
.sov-adapter-text--diagnostic  { font-family: var(--sov-read-font-mono); font-size: calc(var(--sov-read-size) - 4px); line-height: 1.6; color: var(--sov-read-subtle); }
/* lead paragraph carries the drop cap (see dropcap block) */

/* justification (opt-in level) */
.sov-adapter-text[data-justify="on"] { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }

/* inline marks (within Text) */
.sov-adapter-text__bold   { font-weight: 600; color: var(--sov-read-ink); }
.sov-adapter-text__italic { font-style: italic; }
.sov-adapter-text__inline-code { font-family: var(--sov-read-font-mono); font-size: 0.86em; padding: 0.1em 0.34em; border-radius: 5px; background: color-mix(in oklab, var(--sov-read-ink) 7%, transparent); box-shadow: inset 0 0 0 1px var(--sov-read-hairline); }
.sov-adapter-text__link   { color: color-mix(in oklab, var(--sov-read-insight) 70%, var(--sov-read-ink)); text-decoration: none; box-shadow: inset 0 -1px 0 color-mix(in oklab, var(--sov-read-insight) 40%, transparent); transition: box-shadow var(--sov-read-dur) var(--sov-read-ease); }
.sov-adapter-text__link:hover { box-shadow: inset 0 -2px 0 var(--sov-read-insight); }
.sov-adapter-text__sub { font-size: 0.78em; vertical-align: sub; line-height: 0; }
.sov-adapter-text__sup { font-size: 0.78em; vertical-align: super; line-height: 0; }
.sov-adapter-text__smallcaps { font-feature-settings: "smcp"; font-variant: small-caps; letter-spacing: 0.04em; }

/* ── HEADING · sov-adapter-heading — three levels ───────────────────────
   kind: heading | component: <Heading level={1|2|3}>                      */
.sov-adapter-heading { font-family: var(--sov-read-font-serif); font-weight: 500; color: var(--sov-read-ink); text-wrap: balance; }
.sov-adapter-heading--1 { font-size: var(--sov-read-display-size); line-height: var(--sov-read-display-line); letter-spacing: var(--sov-read-display-track); margin: 0 0 0.5em; }
.sov-adapter-heading--2 { font-size: var(--sov-read-section-size); line-height: var(--sov-read-section-line); letter-spacing: -0.01em; margin: 1.9em 0 0.7em; }
.sov-adapter-heading--3 { font-size: var(--sov-read-field-size); font-weight: 600; line-height: var(--sov-read-field-line); margin: 1.5em 0 0.5em; }
.sov-adapter-heading .sov-adapter-text__smallcaps { color: color-mix(in oklab, var(--sov-read-gold) 40%, var(--sov-read-ink)); }

/* ── FOLIO OVERRIDE — undo chat-surface gold-eyebrow H2 inside folio ────
   The chat surface styles all .sov-adapter-heading--2 as a sans-serif
   gold section-break label (specificity 0,2,0). Inside [data-sovereign-folio]
   reading surfaces, we reset to the reading-surface tokens above. */
[data-sovereign] [data-sovereign-folio] .sov-renderer > .sov-adapter-heading--2 {
  font-family: var(--sov-read-font-serif);
  font-size: var(--sov-read-section-size);
  font-weight: 500;
  line-height: var(--sov-read-section-line);
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--sov-read-ink);
  padding-top: 0;
  padding-bottom: 0;
  border-bottom: none;
  margin: 1.9em 0 0.7em;
}
[data-sovereign] [data-sovereign-folio] .sov-renderer > .sov-adapter-heading--2 + .sov-adapter-text {
  font-family: var(--sov-read-font-serif);
  font-size: var(--sov-read-size, 19px);
  font-weight: 400;
  line-height: var(--sov-read-line, 1.78);
  letter-spacing: var(--sov-read-track, -0.003em);
  color: var(--sov-read-ink);
  max-width: none;
}

/* ── CHAPTER OPEN · sov-chapter-open — composed header ──────────────────
   variants: --foot (default) · --plate · --crown                         */
.sov-chapter-open { margin: 0 0 2.4em; display: flex; flex-direction: column; }
.sov-chapter-open__eyebrow {
  font-family: var(--sov-read-font-sans); font-size: var(--sov-read-kicker-size); font-weight: 600;
  letter-spacing: var(--sov-read-kicker-track); text-transform: uppercase;
  color: color-mix(in oklab, var(--sov-read-gold) 60%, var(--sov-read-muted));
  margin: 0 0 1em; display: flex; align-items: center; gap: 12px;
}
.sov-chapter-open__eyebrow::before { content: ""; width: 30px; height: 1px; background: linear-gradient(90deg, var(--sov-read-gold), transparent); }
.sov-chapter-open__num { font-family: var(--sov-read-font-serif); font-style: italic; font-size: 15px; color: var(--sov-read-muted); margin: 0 0 6px; }
.sov-chapter-open__title { font-family: var(--sov-read-font-serif); font-weight: 500; font-size: var(--sov-read-display-size); line-height: var(--sov-read-display-line); letter-spacing: var(--sov-read-display-track); margin: 0; color: var(--sov-read-gold); text-wrap: balance; }
.sov-chapter-open__rule { height: 1px; margin: 1.2em 0 0; background: linear-gradient(90deg, var(--sov-read-hairline-gold), var(--sov-read-hairline) 55%, transparent); }
.sov-chapter-open--crown { text-align: center; }
.sov-chapter-open--crown .sov-chapter-open__eyebrow { justify-content: center; }
.sov-chapter-open--crown .sov-chapter-open__eyebrow::before { display: none; }
.sov-chapter-open--crown .sov-chapter-open__rule { width: 24%; margin-inline: auto; background: linear-gradient(90deg, transparent, var(--sov-read-hairline-gold), transparent); }
.sov-chapter-open--plate { padding: 1.6em 1.8em; border-radius: var(--sov-read-radius-card); background: color-mix(in oklab, var(--sov-read-gold) 5%, transparent); box-shadow: inset 0 0 0 1px var(--sov-read-hairline-gold); }

/* ── DROP CAP · sov-dropcap — opt-in, three drop levels ─────────────────
   apply .sov-dropcap to the lead paragraph; modifier sets the drop.       */
.sov-dropcap::first-letter {
  font-family: var(--sov-read-font-serif); font-weight: 500;
  font-size: var(--sov-read-dropcap-size); line-height: var(--sov-read-dropcap-line);
  float: left; padding: 0.04em 0.1em 0 0; margin: 0.02em 0.04em 0 0;
  color: var(--sov-read-dropcap-ink);
  text-shadow: 0 2px 22px color-mix(in oklab, var(--sov-read-gold) 30%, transparent);
}
.sov-dropcap--2::first-letter { font-size: var(--sov-read-dropcap-size-2); }
.sov-dropcap--4::first-letter { font-size: var(--sov-read-dropcap-size-4); }
.sov-dropcap--plain::first-letter { color: var(--sov-read-ink); text-shadow: none; }

/* ── VERSE (poetry) · sov-adapter-verse — variants: rule · plate · center
   not produced by converters today; authored rung for line-broken text.  */
.sov-adapter-verse {
  margin: 1.8em 0; padding: 0.2em 0 0.2em 1.6em; position: relative;
  font-family: var(--sov-read-font-serif); font-size: var(--sov-read-verse-size);
  line-height: var(--sov-read-verse-line); color: var(--sov-read-verse-ink);
  box-shadow: inset 2px 0 0 var(--sov-read-verse-rule);
}
.sov-adapter-verse__stanza { margin: 0 0 1.05em; }
.sov-adapter-verse__stanza:last-child { margin-bottom: 0; }
.sov-adapter-verse__line { display: block; }
.sov-adapter-verse__line--indent { padding-left: var(--sov-read-verse-indent); }
.sov-adapter-verse__title { display: block; font-style: italic; color: var(--sov-read-muted); font-size: 0.86em; letter-spacing: 0.02em; margin-bottom: 0.5em; }
.sov-adapter-verse__attr { display: block; margin-top: 0.7em; font-family: var(--sov-read-font-sans); font-size: 0.66em; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sov-read-muted); clear: both; }
.sov-adapter-verse--plate { box-shadow: none; padding: 1.4em 1.6em; border-radius: var(--sov-read-radius-card); background: color-mix(in oklab, var(--sov-read-gold) 4%, transparent); }
.sov-adapter-verse--center { text-align: center; box-shadow: none; padding-left: 0; }

/* ── PULLQUOTE / BLOCKQUOTE · sov-adapter-pullquote — four levels ───────
   kind: pullquote | component: <Pullquote body attribution>
   L1 hairline (default) · L2 plate · L3 epigraph · L4 bridge             */
.sov-adapter-pullquote {
  margin: 1.9em 0; padding: 0.4em 0 0.4em 1.7em; position: relative;
  display: flex; flex-direction: column; gap: 0.7em;
  box-shadow: inset 3px 0 0 var(--sov-read-quote-rule);
}
.sov-adapter-pullquote::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 30px; pointer-events: none;
  background: linear-gradient(90deg, var(--sov-read-quote-wash), transparent);
}
.sov-adapter-pullquote__body {
  font-family: var(--sov-read-font-serif); font-style: italic; font-weight: 400;
  font-size: var(--sov-read-quote-size); line-height: 1.5; color: var(--sov-read-ink); margin: 0; text-wrap: pretty;
}
.sov-adapter-pullquote__attribution {
  display: block; font-family: var(--sov-read-font-sans); font-style: normal;
  font-weight: 600; font-size: 0.62em; letter-spacing: 0.14em; text-transform: uppercase;
  color: color-mix(in oklab, var(--sov-read-gold) 55%, var(--sov-read-muted));
}
/* L2 — plate */
.sov-adapter-pullquote--plate { box-shadow: none; padding: 1.4em 1.7em; border-radius: var(--sov-read-radius-card); background: color-mix(in oklab, var(--sov-read-gold) 5%, transparent); }
.sov-adapter-pullquote--plate::after { display: none; }
/* L3 — epigraph display (large, centered, no rule) */
.sov-adapter-pullquote--epigraph { box-shadow: none; padding: 0; text-align: center; align-items: center; max-width: 32ch; margin-inline: auto; }
.sov-adapter-pullquote--epigraph::after { display: none; }
.sov-adapter-pullquote--epigraph .sov-adapter-pullquote__body { font-size: var(--sov-read-quote-display); line-height: 1.32; }
/* L4 — bridge (insight glow, for cross-references / relation) */
.sov-adapter-pullquote--bridge { box-shadow: inset 3px 0 0 var(--mk-glow-love-is-the-bridge); }
.sov-adapter-pullquote--bridge::after { background: linear-gradient(90deg, color-mix(in oklab, var(--mk-glow-love-is-the-bridge) 14%, transparent), transparent); }

/* ── FIGURE + CAPTION · sov-adapter-figure — variants: wash · image · plate · bleed
   kind: raw_html→image | component: <Image src alt caption>              */
.sov-adapter-figure { margin: 2em 0; }
.sov-adapter-figure__frame {
  position: relative; aspect-ratio: 16 / 10; border-radius: var(--sov-read-fig-radius);
  overflow: hidden; isolation: isolate; background: var(--sov-read-sunken);
  box-shadow: 0 18px 40px -22px rgba(0,0,0,0.6), inset 0 0 0 1px var(--sov-read-hairline);
}
.sov-adapter-figure__frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* cover-less default — a Hopkins gradient wash (brand: kaOS does not draw) */
.sov-adapter-figure__wash {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 100% at 76% 14%, var(--sov-read-fig-a) 0%, transparent 54%),
    radial-gradient(100% 90% at 16% 92%, var(--sov-read-fig-b) 0%, transparent 58%),
    linear-gradient(155deg, color-mix(in oklab, var(--sov-read-fig-c) 60%, var(--sov-read-bg)), var(--sov-read-bg) 84%);
  animation: sov-read-drift 36s var(--sov-read-ease) infinite alternate;
}
.sov-adapter-figure__grain { position: absolute; inset: 0; opacity: 0.1; mix-blend-mode: overlay; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.sov-adapter-figure--plate .sov-adapter-figure__frame { aspect-ratio: 3 / 2; }
.sov-adapter-figure--bleed { margin-inline: calc(-1 * var(--sov-read-bleed, 4vw)); }
.sov-adapter-figure--bleed .sov-adapter-figure__frame { border-radius: 0; }
/* MDX placement overrides — width: column (default, no class) · inset · wide · full;
   align: left · center · right (meaningful with --w-inset)               */
.sov-adapter-figure--w-inset { max-width: var(--sov-read-fig-inset-max, 62%); }
.sov-adapter-figure--w-wide { margin-inline: calc(-1 * var(--sov-read-fig-wide-out, 2.5vw)); }
.sov-adapter-figure--w-full { margin-inline: calc(-1 * var(--sov-read-bleed, 4vw)); }
.sov-adapter-figure--align-left { margin-right: auto; }
.sov-adapter-figure--align-center { margin-inline: auto; }
.sov-adapter-figure--align-right { margin-left: auto; }
.sov-adapter-figure__caption {
  margin-top: 12px; font-family: var(--sov-read-font-sans); font-size: var(--sov-read-caption-size);
  line-height: 1.5; color: var(--sov-read-muted); display: flex; gap: 10px;
}
.sov-adapter-figure__caption .n { font-family: var(--sov-read-font-mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: color-mix(in oklab, var(--sov-read-gold) 55%, var(--sov-read-muted)); flex: none; padding-top: 1px; }
.sov-adapter-figure__caption b { color: var(--sov-read-subtle); font-weight: 600; }
@keyframes sov-read-drift { from { background-position: 66% 18%, 22% 82%, 0 0; } to { background-position: 78% 26%, 14% 74%, 0 0; } }
@media (prefers-reduced-motion: reduce) { .sov-adapter-figure__wash { animation: none; } }

/* ── NOTES · sov-adapter-note — ref + endnotes + popover ────────────────
   new sovereign components: <NoteRef> <Endnotes> <Endnote> <NotePopover> */
.sov-noteref {
  font-family: var(--sov-read-font-sans); font-size: 0.62em; font-weight: 600;
  vertical-align: super; line-height: 0; color: var(--sov-read-note-ink);
  padding: 0 0.1em; cursor: pointer; transition: color var(--sov-read-dur) var(--sov-read-ease);
}
.sov-noteref::before { content: "["; opacity: 0.5; }
.sov-noteref::after  { content: "]"; opacity: 0.5; }
.sov-noteref:hover, .sov-noteref[aria-expanded="true"] { color: color-mix(in oklab, var(--sov-read-insight) 60%, var(--sov-read-ink)); }
.sov-endnotes { margin: 3em 0 0; padding-top: 1.4em; box-shadow: 0 1px 0 var(--sov-read-hairline) inset, 0 -1px 0 var(--sov-read-hairline-gold); }
.sov-endnotes__title { font-family: var(--sov-read-font-sans); font-size: 10px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--sov-read-muted); margin: 0 0 14px; }
.sov-endnote { display: grid; grid-template-columns: 26px 1fr; grid-gap: 8px; gap: 8px; margin: 0 0 12px; }
.sov-endnote__n { font-family: var(--sov-read-font-mono); font-size: 11px; color: var(--sov-read-note-ink); padding-top: 2px; }
.sov-endnote__body { font-family: var(--sov-read-body-face); font-size: var(--sov-read-note-size); line-height: 1.55; color: var(--sov-read-subtle); }
.sov-endnote__body cite { font-style: italic; color: var(--sov-read-muted); }

/* ── CITATION CHIP · sov-chip-citation — neutral · sacred ───────────────
   kind: citation | component: <Citation source quote>                    */
.sov-chip-citation {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px;
  border-radius: var(--sov-read-radius-pill); font-family: var(--sov-read-font-sans);
  font-size: 0.78em; font-weight: 500; cursor: pointer;
  color: color-mix(in oklab, var(--sov-read-gold) 60%, var(--sov-read-ink));
  background: color-mix(in oklab, var(--sov-read-gold) 8%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-read-hairline-gold);
}
.sov-chip-citation--neutral { color: var(--sov-read-muted); background: color-mix(in oklab, var(--sov-read-ink) 5%, transparent); box-shadow: inset 0 0 0 1px var(--sov-read-hairline); }

/* ── SECTION BREAK · sov-adapter-rule — ornament · hairline · blank ─────
   parser emits empty-body heading for `---`; render as a rest in the read */
.sov-adapter-rule { border: 0; height: auto; margin: 2.2em 0; display: flex; align-items: center; justify-content: center; gap: 14px; color: color-mix(in oklab, var(--sov-read-gold) 55%, var(--sov-read-muted)); }
.sov-adapter-rule::before, .sov-adapter-rule::after { content: ""; height: 1px; width: 64px; background: linear-gradient(90deg, transparent, currentColor); }
.sov-adapter-rule::after { background: linear-gradient(90deg, currentColor, transparent); }
.sov-adapter-rule span { font-size: 13px; opacity: 0.8; }
.sov-adapter-rule--hairline { color: var(--sov-read-hairline-gold); }
.sov-adapter-rule--hairline::before { width: 100%; } .sov-adapter-rule--hairline::after { display: none; }
.sov-adapter-rule--blank { margin: 3.2em 0; } .sov-adapter-rule--blank::before, .sov-adapter-rule--blank::after { display: none; }

/* ── LIST · sov-adapter-list ────────────────────────────────────────────
   kind: list | component: <List ordered items>                           */
.sov-adapter-list { font-family: var(--sov-read-body-face); font-size: var(--sov-read-size); line-height: 1.6; color: var(--sov-read-ink); margin: 0 0 calc(var(--sov-folio-para-gap) * var(--sov-read-line) * var(--sov-read-size)); padding-left: var(--sov-read-list-padding, 1.4em); }
.sov-adapter-list li { margin: 0 0 0.5em; }
.sov-adapter-list li::marker { color: var(--sov-read-list-marker, color-mix(in oklab, var(--sov-read-gold) 60%, var(--sov-read-muted))); }
.sov-adapter-list .sov-adapter-list { padding-left: var(--sov-read-list-nested-indent, 1.2em); }

/* ── TABLE · sov-adapter-table ──────────────────────────────────────────
   kind: table | component: <Table headers rows>                          */
.sov-adapter-table { width: 100%; border-collapse: collapse; font-family: var(--sov-read-font-sans); font-size: 0.82em; margin: 1.8em 0; }
.sov-adapter-table th { text-align: left; font-weight: 600; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--sov-read-muted); padding: 8px 14px 8px 0; }
.sov-adapter-table td { padding: 10px 14px 10px 0; color: var(--sov-read-subtle); box-shadow: 0 1px 0 var(--sov-read-hairline); vertical-align: top; line-height: 1.45; }

/* ── CODE · sov-code-artifact — CA-1 (doc) · CA-5 (terminal) ────────────
   kind: code | component: <Code language runnable={false}>               */
.sov-code-artifact { font-family: var(--sov-read-font-mono); font-size: 0.8em; line-height: 1.7; color: var(--sov-read-subtle); background: var(--sov-read-bg); border-radius: var(--sov-read-radius-card); box-shadow: inset 0 0 0 1px var(--sov-read-hairline); padding: 18px 20px; margin: 1.6em 0; overflow-x: auto; white-space: pre; }
.sov-code-artifact--ca5 { box-shadow: inset 0 0 0 1px var(--sov-read-hairline-audio); }

/* ── HIGHLIGHT · sov-mark — gold · insight · annotated · faint ──────────
   the kaOS "highlight" interaction point.                                */
.sov-mark { background: var(--sov-read-hl-gold); color: var(--sov-read-ink); border-radius: 2px; padding: 0.5px 1px; box-decoration-break: clone; -webkit-box-decoration-break: clone; cursor: pointer; transition: background var(--sov-read-dur) var(--sov-read-ease); }
.sov-mark:hover { background: var(--sov-read-hl-gold-hover); }
.sov-mark--insight { background: var(--sov-read-hl-insight); }
.sov-mark--faint   { background: var(--sov-read-hl-faint); }
.sov-mark--annotated { box-shadow: 0 2px 0 -1px color-mix(in oklab, var(--sov-read-insight) 70%, transparent); }

/* ── ANNOTATION · sov-annotation — insight (default) · gold · your-note ─
   the margin card the "annotate" interaction point produces.             */
.sov-annotation {
  padding: 13px 15px; border-radius: 12px; margin: 0 0 10px;
  background: color-mix(in oklab, var(--sov-read-insight) 5%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-read-hairline-insight), 0 0 24px -14px color-mix(in oklab, var(--sov-read-insight) 70%, transparent);
  transition: transform var(--sov-read-dur) var(--sov-read-ease), box-shadow var(--sov-read-dur) var(--sov-read-ease);
}
.sov-annotation__kicker { font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 600; color: color-mix(in oklab, var(--sov-read-insight) 60%, var(--sov-read-ink)); margin: 0 0 5px; display: flex; align-items: center; gap: 7px; }
.sov-annotation__kicker .who { margin-left: auto; color: var(--sov-read-muted); font-weight: 500; letter-spacing: 0.06em; }
.sov-annotation__body { font-family: var(--sov-read-body-face); font-size: 13.5px; line-height: 1.5; margin: 0; color: var(--sov-read-subtle); }
.sov-annotation__kaos { margin-top: 9px; padding-top: 9px; box-shadow: 0 -1px 0 var(--sov-read-hairline-insight); font-family: var(--sov-read-body-face); font-size: 12.5px; line-height: 1.5; color: var(--sov-read-muted); font-style: italic; }
.sov-annotation__kaos::before { content: "kaOS"; font-weight: 600; font-style: normal; letter-spacing: 0.04em; color: color-mix(in oklab, var(--sov-read-insight) 62%, var(--sov-read-ink)); margin-right: 7px; }
.sov-annotation--gold { background: color-mix(in oklab, var(--sov-read-gold) 5%, transparent); box-shadow: inset 0 0 0 1px var(--sov-read-hairline-gold), 0 0 24px -14px color-mix(in oklab, var(--sov-read-gold) 60%, transparent); }
.sov-annotation--gold .sov-annotation__kicker { color: color-mix(in oklab, var(--sov-read-gold) 60%, var(--sov-read-ink)); }

/* ── LISTEN / NARRATION · sov-listen — the audio interaction point ──────
   pill states + the reading cursor (block-level) the narration walks.     */
.sov-listen-pill {
  display: inline-flex; align-items: center; gap: 9px; padding: 8px 15px;
  border-radius: var(--sov-read-radius-pill); font-family: var(--sov-read-font-sans);
  font-size: 12.5px; font-weight: 500; color: var(--sov-read-subtle);
  background: color-mix(in oklab, var(--sov-read-ink) 5%, transparent);
  box-shadow: inset 0 0 0 1px var(--sov-read-hairline);
  transition: all var(--sov-read-dur) var(--sov-read-ease);
}
.sov-listen-pill .dot { width: 8px; height: 8px; border-radius: 99px; background: var(--sov-read-muted); }
.sov-listen-pill[aria-pressed="true"] { color: var(--sov-read-ink); background: color-mix(in oklab, var(--sov-read-audio) 14%, transparent); box-shadow: inset 0 0 0 1px var(--sov-read-hairline-audio), 0 0 26px -12px color-mix(in oklab, var(--sov-read-audio) 60%, transparent); }
.sov-listen-pill[aria-pressed="true"] .dot { background: var(--sov-read-audio); box-shadow: 0 0 10px var(--sov-read-audio); animation: sov-read-breathe 4.2s ease-in-out infinite; }
/* reading cursor — the passage block currently being spoken */
.sov-speaking { color: var(--sov-read-ink); box-shadow: inset 3px 0 0 var(--sov-read-audio); background: linear-gradient(90deg, color-mix(in oklab, var(--sov-read-audio) 9%, transparent), transparent 70%); border-radius: 0 8px 8px 0; }
.sov-spoken   { color: color-mix(in oklab, var(--sov-read-ink) 78%, transparent); }
.sov-upcoming { color: color-mix(in oklab, var(--sov-read-ink) 46%, transparent); }
/* word-level fade (when pretext emits per-word marks) */
.sov-word { display: inline; transition: color 360ms var(--sov-read-ease); }
.sov-word--speaking { background: var(--sov-read-speak-wash); border-radius: 3px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
@keyframes sov-read-breathe { 0%,100% { opacity: 0.5; transform: scale(0.85); } 50% { opacity: 1; transform: scale(1.1); } }
@media (prefers-reduced-motion: reduce) { .sov-listen-pill[aria-pressed="true"] .dot { animation: none; } }

/* ── INTERACTION TOOLBAR · sov-interact — highlight·annotate·ask·listen ─
   the four kaOS interaction points, surfaced on a selection.             */
.sov-interact { display: inline-flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--sov-read-radius-pill); background: color-mix(in oklab, var(--sov-read-surface) 86%, transparent); -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%); box-shadow: inset 0 0 0 1px var(--sov-read-hairline-gold), 0 18px 44px -18px rgba(0,0,0,0.7), 0 0 30px -14px color-mix(in oklab, var(--sov-read-gold) 50%, transparent); }
.sov-interact button { display: inline-flex; align-items: center; gap: 7px; padding: 8px 13px; border-radius: var(--sov-read-radius-pill); font-family: var(--sov-read-font-sans); font-size: 12.5px; font-weight: 500; color: var(--sov-read-subtle); background: transparent; border: 0; cursor: pointer; transition: background var(--sov-read-dur) var(--sov-read-ease), color var(--sov-read-dur) var(--sov-read-ease); }
.sov-interact button:hover { background: color-mix(in oklab, var(--sov-read-ink) 8%, transparent); color: var(--sov-read-ink); }
.sov-interact button[data-act="highlight"]:hover { color: var(--sov-read-gold); }
.sov-interact button[data-act="annotate"]:hover { color: color-mix(in oklab, var(--sov-read-insight) 60%, var(--sov-read-ink)); }
.sov-interact button[data-act="listen"]:hover   { color: var(--sov-read-audio); }
.sov-interact .sep { width: 1px; height: 20px; background: var(--sov-read-hairline); margin: 0 1px; }

/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../packages/kaos-sovereign/styles/reading/brand/mark.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ═══════════════════════════════════════════════════════════════════════
   mark.css — the Consilience Press imprint, usable right away.
   Authored under CHARTER.md Rule 5b. Token-first; consumes the gold glow.

   Three ways to use it:
     1. As a file — <img src="brand/consilience-mark.svg"> · favicon ·
        consilience-lockup.svg for the full horizontal lockup.
     2. Inline mono SVG that inherits text color — paste consilience-mark-mono.svg
        inside .sov-imprint__mark and it picks up currentColor + the halo.
     3. The HTML lockup below (.sov-imprint) — mark + two-weight wordmark,
        scales with --sov-imprint-size.
   ═══════════════════════════════════════════════════════════════════════ */

[data-sovereign] {
  --sov-imprint-size:  26px;   /* mark height; wordmark scales from it */
  --sov-imprint-gold:  var(--mk-glow-gold);
  --sov-imprint-glow:  color-mix(in oklab, var(--mk-glow-gold) 40%, transparent);
  --sov-imprint-ink:   var(--sov-color-subtle, var(--mk-subtle));
  --sov-imprint-faint: var(--sov-color-muted, var(--mk-muted));
}

/* Horizontal lockup in HTML (mark + CONSILIENCE PRESS) */
.sov-imprint { display: inline-flex; align-items: center; gap: 11px; }
.sov-imprint__mark {
  width: var(--sov-imprint-size); height: var(--sov-imprint-size); flex: none;
  color: var(--sov-imprint-gold);
  filter: drop-shadow(0 0 7px var(--sov-imprint-glow));
}
.sov-imprint__mark svg { width: 100%; height: 100%; display: block; }
.sov-imprint__name {
  font-family: var(--sov-font-sans, var(--mk-font-sans)); font-weight: 600;
  font-size: calc(var(--sov-imprint-size) * 0.42);
  letter-spacing: 0.26em; text-transform: uppercase; line-height: 1; white-space: nowrap;
  color: var(--sov-imprint-ink);
}
.sov-imprint__name b    { font-weight: 600; color: var(--sov-imprint-ink); }
.sov-imprint__name span { font-weight: 400; color: var(--sov-imprint-faint); }

/* Stand-alone mark sizes */
.sov-imprint--sm { --sov-imprint-size: 18px; }
.sov-imprint--lg { --sov-imprint-size: 40px; }
.sov-imprint--xl { --sov-imprint-size: 72px; }

/* Gold gradient variant for the inline mark (when not using currentColor).
   Wrap the mono SVG and let it inherit the gold; for the true gradient,
   embed consilience-mark.svg instead. */
.sov-imprint--gold .sov-imprint__mark { color: var(--sov-imprint-gold); }

/*!**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./app/sovereign-html.css ***!
  \**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ── Sovereign Evolve — root HTML/BODY reset ── */
/* Full-viewport canvas behind the sovereign provider. */
/* Mirrors apps/sovereign/app/sovereign-html.css */

/*
 * Theme-aware HTML shim.
 *
 * The <body> element sits OUTSIDE the [data-sovereign] scope, so it cannot
 * inherit the --sov-* token cascade (CSS variables cascade down, not up).
 * These --sov-html-* variables are declared on :root and keyed to a
 * data-sov-theme attribute stamped on <html> by the pre-hydration script
 * in app/layout.tsx (before React mounts) and kept in sync by the
 * useSovereignTheme hook. This prevents a flash of the wrong-coloured
 * background on first paint.
 *
 * Dark values mirror the canonical --sov-* dark tokens (step-09).
 * Light values mirror the sovereign web app palette (parchment, charcoal,
 * jade) — see tokens.json palette-light.web.
 */
:root,
:root[data-sov-theme='dark'] {
  --sov-html-bg: oklch(0.17 0.005 260);
  --sov-html-ink: oklch(0.75 0.02 260);
  --sov-html-muted: oklch(0.55 0.02 260);
  --sov-html-border: oklch(0.35 0.02 260);
  --sov-html-surface: oklch(0.22 0.02 260);
  --sov-html-surface-hover: oklch(0.28 0.02 260);
  --sov-html-spinner-track: oklch(0.3 0.02 260);
  --sov-html-spinner-top: oklch(0.55 0.05 260);
}
:root[data-sov-theme='light'] {
  --sov-html-bg: oklch(0.9798 0.0086 84.57); /* #fbf8f2 parchment */
  --sov-html-ink: oklch(0.4456 0.0197 79.21); /* #5a5348 ink-soft */
  --sov-html-muted: oklch(0.5991 0.0290 76.63); /* #8a7e6d ink-faint */
  --sov-html-border: oklch(0.8845 0.0221 83.26); /* #e0d8c9 divider */
  --sov-html-surface: oklch(1 0 0); /* #ffffff card-surface */
  --sov-html-surface-hover: oklch(0.9511 0.0148 80.71); /* #f4eee4 parchment-warm */
  --sov-html-spinner-track: oklch(0.9 0.005 80);
  --sov-html-spinner-top: oklch(0.5646 0.1120 240.83); /* #2a7db1 jade */
}

html {
  overflow: hidden;
  height: 100%;
  scrollbar-width: none;
  box-sizing: border-box;
}
html::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}
*,
*::before,
*::after {
  box-sizing: inherit;
}
body {
  margin: 0;
  overflow: hidden;
  height: 100%;
  background-color: var(--sov-html-bg);
  scrollbar-width: none;
}

/*
 * Typography — wire next/font (--font-* on html) into token stacks.
 * Must load after tokens.css + sovereign.css. Never bridge --font-sans
 * back to --sov-font-sans on this node (circular with tokens).
 */
[data-sovereign] {
  --sov-typography-font-sans: var(--font-sans), system-ui, -apple-system,
    sans-serif;
  --sov-typography-font-serif: var(--font-serif), Georgia, 'Times New Roman',
    serif;
  --sov-typography-font-mono: var(--font-mono), ui-monospace, 'SF Mono', Menlo,
    monospace;
  --sov-font-sans: var(--sov-typography-font-sans);
  --sov-font-serif: var(--sov-typography-font-serif);
  --sov-font-mono: var(--sov-typography-font-mono);
  font-family: var(--sov-font-sans);
  font-feature-settings: "ss01", "cv01";
}

/*
 * Two-tone frame — the opened base for the provider root.
 *
 * The root element is [data-sovereign].sov-surface (same node). The
 * substrate's raised-surface rule is a descendant selector
 * ([data-sovereign] .sov-surface) so it never matches the root.
 *
 * Previously applied a raised-surface background here to create a
 * lighter-frame / darker-center two-tone. Removed per architect
 * directive — the surface should be fully transparent, with the
 * body's --sov-bg showing through uniformly. No background of any
 * color or shade.
 */
/* [data-sovereign].sov-surface background override removed — zero background */
body::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

/* ── Content error boundary — chunk load failure recovery ── */

.sov-content-error {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  padding: 2rem;
}

.sov-content-error__inner {
  text-align: center;
  max-width: 360px;
}

.sov-content-error__label {
  font-family: var(--font-mono, monospace);
  font-size: 0.8125rem;
  color: var(--sov-html-muted);
  margin: 0 0 0.375rem;
  letter-spacing: 0.02em;
}

.sov-content-error__hint {
  font-size: 0.78125rem;
  color: var(--sov-html-muted);
  margin: 0 0 1rem;
  line-height: 1.4;
}

.sov-content-error__retry,
.sov-error-page__retry {
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--sov-html-border);
  border-radius: 6px;
  background: var(--sov-html-surface);
  color: var(--sov-html-ink);
  font-size: 0.78125rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.sov-content-error__retry:hover,
.sov-error-page__retry:hover {
  background: var(--sov-html-surface-hover);
  border-color: var(--sov-html-muted);
}

/* ── Content loading spinner (Suspense fallback) ── */

.sov-content-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  padding: 2rem;
}

.sov-content-loading__spinner {
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--sov-html-spinner-track);
  border-top-color: var(--sov-html-spinner-top);
  border-radius: 50%;
  animation: sov-spin 0.6s linear infinite;
}

@keyframes sov-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Route / global error pages ── */

.sov-error-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem;
  background-color: var(--sov-html-bg);
  color: var(--sov-html-ink);
}

.sov-error-page__inner {
  text-align: center;
  max-width: 420px;
}

.sov-error-page__title {
  font-family: var(--font-mono, monospace);
  font-size: 1rem;
  font-weight: 500;
  margin: 0 0 0.5rem;
  letter-spacing: 0.02em;
}

.sov-error-page__message {
  font-size: 0.8125rem;
  color: var(--sov-html-muted);
  margin: 0 0 1.25rem;
  line-height: 1.5;
}

/* ── Skeleton shimmer (SovereignSkeleton primitive) ──
 * Drives the where-light shimmer on every bar/row/card rendered by
 * apps/sovereign-evolve/components/shared/sovereign-skeleton.tsx. The
 * keyframe sweeps a translucent band across each bar; the bar itself
 * remains a stable low-contrast pill so the layout does not jump when
 * the real content lands. Honors the cascade's own --sov-ease for the
 * rhythm. The skeleton component itself disables the animation when
 * prefers-reduced-motion is set (via useSovereignMotion). */
@keyframes sov-skeleton-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

/* ── Today-empty halo breathe (SovereignTodayIcon primitive) ──
 * (Removed 2026-07-14: the icon now stands on its own without a
 * halo or background. The empty-state composition carries the
 * visual weight; the icon is the subject, not the frame.) */

/* ── Skeleton geometry system ─────────────────────────────────────────
 * One place that owns every pixel of the skeleton. The
 * SovereignSkeleton primitive in apps/sovereign-evolve/components/shared/
 * sovereign-skeleton.tsx consumes these tokens and the matching classes;
 * callers (TodayMailBody, TodayCalendarBody, TodayMotionBody, HomeStrip
 * loading) pick a `density` ("comfortable" by default, "compact" for
 * tight rows) and inherit the geometry from the cascade.
 *
 * Why centralized: previously the bar height, row padding, gap and
 * radius lived as inline numbers inside the React component. That meant
 * adjusting the "feel" of a placeholder required hunting through JSX.
 * The whole system lives here now — one block of CSS, one set of
 * numbers, and every surface in the app reads the same values. If a
 * design pass needs more vertical air in the row, this is the only
 * place to change.
 *
 * The four bar weights map to the canonical sovereign typography
 * rungs (caption → field → section), so the skeleton's primary bar
 * always reads as the same vertical weight as the real subject line it
 * replaces. ──────────────────────────────────────────────────────── */

[data-sovereign] {
  /* Bar heights — each weight is the canonical "comfortable" amount. */
  --sov-skeleton-bar-hairline: 8px;
  --sov-skeleton-bar-thin: 14px;
  --sov-skeleton-bar-normal: 18px;
  --sov-skeleton-bar-wide: 28px;

  /* Bar radii — half the height for the canonical pill shape. */
  --sov-skeleton-radius-hairline: 4px;
  --sov-skeleton-radius-thin: 7px;
  --sov-skeleton-radius-normal: 9px;
  --sov-skeleton-radius-wide: 14px;

  /* Internal padding — vertical air inside the bar's bounding box, so
   * the shimmer band sits inside a slightly taller envelope than the
   * bar's visual weight. This is what makes a "subject" line read as
   * "this is a sentence-shaped thing" instead of "this is a stripe." */
  --sov-skeleton-bar-pad-y: 4px;
  --sov-skeleton-bar-pad-x: 2px;

  /* Row geometry — the comfortable default. */
  --sov-skeleton-row-pad-y: 12px;
  --sov-skeleton-row-pad-x: 10px;
  --sov-skeleton-row-gap: 9px;
  --sov-skeleton-row-min-h: 52px;

  /* Compact density — for tight surfaces (small tiles, side rails). */
  --sov-skeleton-row-pad-y-compact: 8px;
  --sov-skeleton-row-pad-x-compact: 6px;
  --sov-skeleton-row-gap-compact: 6px;
  --sov-skeleton-row-min-h-compact: 36px;

  /* Card geometry — the home strip / media-panel tile cover.
   *   1/1 (square) is the chartered default for media panels; the
   *   book shape (2/3) is reserved for the folio reader, not the
   *   library shelf. The token is named so a future design pass that
   *   wants a different cover ratio changes one value, not every
   *   call site. */
  --sov-skeleton-card-aspect: 1 / 1;
  --sov-skeleton-card-radius: 10px;
}

/* The row primitive. Two density variants — comfortable (default) and
 * compact (for tight surfaces). The class is applied to the row
 * container; children inherit the bar geometry from the cascade. */
.sov-skeleton-row {
  display: flex;
  align-items: center;
  gap: var(--sov-space-2, 8px);
  min-height: var(--sov-skeleton-row-min-h);
  padding-block: var(--sov-skeleton-row-pad-y);
  padding-inline: var(--sov-skeleton-row-pad-x);
}
.sov-skeleton-row[data-density='compact'] {
  min-height: var(--sov-skeleton-row-min-h-compact);
  padding-block: var(--sov-skeleton-row-pad-y-compact);
  padding-inline: var(--sov-skeleton-row-pad-x-compact);
  gap: var(--sov-skeleton-row-gap-compact);
}

/* The bar primitive. The vertical padding inside the bar's box gives
 * every bar the same "this is a sentence" feel as the real type
 * placeholder it replaces, regardless of which weight tier it sits in. */
.sov-skeleton-bar {
  display: block;
  position: relative;
  overflow: hidden;
  padding-block: var(--sov-skeleton-bar-pad-y);
  padding-inline: var(--sov-skeleton-bar-pad-x);
}
.sov-skeleton-bar > .sov-skeleton-bar__fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: color-mix(in oklab, var(--sov-color-subtle) 22%, transparent);
}
.sov-skeleton-bar[data-weight='hairline'] {
  height: calc(
    var(--sov-skeleton-bar-hairline) +
      (var(--sov-skeleton-bar-pad-y) * 2)
  );
  border-radius: var(--sov-skeleton-radius-hairline);
}
.sov-skeleton-bar[data-weight='thin'] {
  height: calc(
    var(--sov-skeleton-bar-thin) + (var(--sov-skeleton-bar-pad-y) * 2)
  );
  border-radius: var(--sov-skeleton-radius-thin);
}
.sov-skeleton-bar[data-weight='normal'] {
  height: calc(
    var(--sov-skeleton-bar-normal) + (var(--sov-skeleton-bar-pad-y) * 2)
  );
  border-radius: var(--sov-skeleton-radius-normal);
}
.sov-skeleton-bar[data-weight='wide'] {
  height: calc(
    var(--sov-skeleton-bar-wide) + (var(--sov-skeleton-bar-pad-y) * 2)
  );
  border-radius: var(--sov-skeleton-radius-wide);
}

/* The shimmer overlay — the moving band that sweeps across the bar
 * fill. Sits on top of the bar fill so the fill's solid colour stays
 * underneath as a stable base. */
.sov-skeleton-bar > .sov-skeleton-bar__shimmer {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    color-mix(in oklab, var(--sov-color-subtle) 0%, transparent) 0%,
    color-mix(in oklab, var(--sov-color-subtle) 28%, transparent) 50%,
    color-mix(in oklab, var(--sov-color-subtle) 0%, transparent) 100%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: sov-skeleton-shimmer 1.6s var(--sov-ease) infinite;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .sov-skeleton-bar > .sov-skeleton-bar__shimmer {
    animation: none;
  }
}

/* The inner column of bars inside a row — the gap between bars
 * inherits from the row's gap token unless overridden. */
.sov-skeleton-row__stack {
  flex: 1 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: inherit;
}


/*!******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../packages/sovereign-ui/src/styles/keyframes.css ***!
  \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* AUTO-AUTHORED · keyframes for sovereign-ui primitives. */
/* Provenance: pr/step-09/PR.md (motion tokens) · Charter Rule 5a. */

@keyframes sov-breathe {
  0%, 100% { opacity: 0.45; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.10); }
}

@keyframes sov-breathe-pulse {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1; }
}

@keyframes sov-gold-shimmer {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

@keyframes sov-word-fade {
  from { opacity: 0; filter: blur(3px); }
  to   { opacity: 1; filter: blur(0); }
}

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

@keyframes sov-thinking-dot {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.3; }
  40%           { transform: scale(1);   opacity: 1; }
}

@keyframes sov-toast-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes sov-ambient-breathe {
  0%, 100% { opacity: 0.7; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  [data-kaos-component] *,
  [data-kaos-component]::before,
  [data-kaos-component]::after {
    animation: none !important;
    transition: none !important;
  }
}

/*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/font/google/target.css?{"path":"fonts.ts","import":"Inter","arguments":[{"subsets":["latin"],"variable":"--font-sans","display":"swap"}],"variableName":"sovereignSans"} ***!
  \*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/ba9851c3c22cd980-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/21350d82a1f187e9-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/c5fe6dc8356a8c31-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/19cfc7226ec3afaa-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/df0a9ae256c0569c-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/8e9860b6e62d6359-s.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/_next/static/media/e4af272ccee01ff0-s.p.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}@font-face {font-family: 'Inter Fallback';src: local("Arial");ascent-override: 90.44%;descent-override: 22.52%;line-gap-override: 0.00%;size-adjust: 107.12%
}.__className_f367f3 {font-family: 'Inter', 'Inter Fallback';font-style: normal
}.__variable_f367f3 {--font-sans: 'Inter', 'Inter Fallback'
}

/*!****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/font/google/target.css?{"path":"fonts.ts","import":"Newsreader","arguments":[{"subsets":["latin"],"variable":"--font-serif","display":"swap"}],"variableName":"sovereignSerif"} ***!
  \****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(/_next/static/media/7088c2b12ccac062-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(/_next/static/media/665e920483964785-s.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(/_next/static/media/5611c55482296524-s.p.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}@font-face {font-family: 'Newsreader Fallback';src: local("Times New Roman");ascent-override: 69.68%;descent-override: 25.12%;line-gap-override: 0.00%;size-adjust: 105.48%
}.__className_64b714 {font-family: 'Newsreader', 'Newsreader Fallback';font-style: normal
}.__variable_64b714 {--font-serif: 'Newsreader', 'Newsreader Fallback'
}

/*!******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!../../node_modules/.pnpm/next@15.3.6_@babel+core@7.29.7_@opentelemetry+api@1.9.1_react-dom@19.1.2_react@19.1.2__react@19.1.2/node_modules/next/font/google/target.css?{"path":"fonts.ts","import":"JetBrains_Mono","arguments":[{"subsets":["latin"],"variable":"--font-mono","display":"swap"}],"variableName":"sovereignMono"} ***!
  \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/886030b0b59bc5a7-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/0aa834ed78bf6d07-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/67957d42bae0796d-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/f911b923c6adde36-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/939c4f875ee75fbb-s.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url(/_next/static/media/bb3ef058b751a6ad-s.p.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}@font-face {font-family: 'JetBrains Mono Fallback';src: local("Arial");ascent-override: 75.79%;descent-override: 22.29%;line-gap-override: 0.00%;size-adjust: 134.59%
}.__className_3c557b {font-family: 'JetBrains Mono', 'JetBrains Mono Fallback';font-style: normal
}.__variable_3c557b {--font-mono: 'JetBrains Mono', 'JetBrains Mono Fallback'
}

