/* ============================================================================
   LAYERING POLICY — this file is core/, the bottom layer. See the full
   explanation at the top of core/ui-system.css for the three-layer split
   (core/ = tokens + primitives + reset, features/<area>/ = domain layout,
   <Component>.razor.css = component-private). The short version for this
   file specifically:

     - Tokens only. No selectors that style an element, no page- or
       feature-named classes — those belong in features/ or a .razor.css.
     - The semantic contract below is canonical. Legacy colour names remain
       compatibility aliases only; new feature styles must use the semantic
       names and the aliases must not introduce another raw colour value.
   ============================================================================ */

:root {
    /* Shared responsive contract. Feature styles may use these values when
       introducing a new layout breakpoint; existing legacy breakpoints are
       being retired toward this small set. */
    --sp-bp-xs: 520px;
    --sp-bp-sm: 700px;
    --sp-bp-md: 900px;
    --sp-bp-lg: 1180px;
    --sp-bp-xl: 1280px;
    --sp-font-size-body: 0.9375rem;
    --sp-font-size-h1: clamp(1.65rem, 1.25rem + 1vw, 2.35rem);
    --sp-font-size-h2: clamp(1.3rem, 1.1rem + 0.55vw, 1.75rem);
    --sp-font-size-h3: clamp(1.1rem, 1rem + 0.3vw, 1.35rem);
    --sp-motion-duration-fast: 120ms;
    --sp-motion-duration-base: 180ms;
    --sp-motion-duration-slow: 240ms;
    --sp-motion-duration-exit: 220ms;
    --sp-motion-duration-remove: 160ms;
    --sp-motion-stagger-step: 45ms;
    --sp-motion-ease-exit: cubic-bezier(0.4, 0, 1, 1);
    --sp-motion-distance-panel: 1.5rem;
    --sp-motion-ease-standard: cubic-bezier(0.2, 0, 0, 1);
    --sp-motion-ease-enter: cubic-bezier(0.22, 1, 0.36, 1);
    --sp-motion-distance-sm: 0.3rem;
    /* Loading feedback waits this long before it paints, so a fast request
       swaps straight to its content instead of flashing a placeholder. */
    --sp-motion-delay-loading: 160ms;
    /* Stale content under a pending navigation or background refresh stays
       legible: dimmed enough to read as "updating", never washed out. */
    --sp-opacity-refreshing: 0.6;
    /* Composite motion: the only animation and transition values feature styles
       use. Keyframes live in ui-motion.css; durations above stay the source. */
    --sp-motion-fade-in: ui-motion-fade-in var(--sp-motion-duration-base) var(--sp-motion-ease-enter) backwards;
    --sp-motion-fade-out: ui-motion-fade-out var(--sp-motion-duration-exit) var(--sp-motion-ease-exit) both;
    --sp-motion-rise-in: ui-motion-enter var(--sp-motion-duration-base) var(--sp-motion-ease-enter) backwards;
    --sp-motion-swap-in: ui-motion-swap var(--sp-motion-duration-fast) var(--sp-motion-ease-standard) backwards;
    --sp-motion-pop-in: ui-motion-pop-in var(--sp-motion-duration-base) var(--sp-motion-ease-enter) backwards;
    --sp-motion-pop-out: ui-motion-pop-out var(--sp-motion-duration-fast) var(--sp-motion-ease-exit) both;
    --sp-motion-dialog-in: ui-motion-dialog-in var(--sp-motion-duration-slow) var(--sp-motion-ease-enter) backwards;
    --sp-motion-dialog-out: ui-motion-dialog-out var(--sp-motion-duration-exit) var(--sp-motion-ease-exit) both;
    --sp-motion-drawer-in: ui-motion-drawer-in var(--sp-motion-duration-slow) var(--sp-motion-ease-enter) backwards;
    --sp-motion-drawer-out: ui-motion-drawer-out var(--sp-motion-duration-exit) var(--sp-motion-ease-exit) both;
    --sp-motion-scale-in: ui-motion-scale-in var(--sp-motion-duration-slow) var(--sp-motion-ease-enter) backwards;
    --sp-motion-remove: ui-motion-remove var(--sp-motion-duration-remove) var(--sp-motion-ease-exit) both;
    --sp-motion-highlight: ui-motion-highlight 1.6s var(--sp-motion-ease-enter);
    --sp-motion-spin: ui-motion-spin 0.75s linear infinite;
    --sp-motion-shimmer: ui-motion-shimmer 1.35s ease-in-out infinite;
    /* Placeholders stay invisible for the loading delay, then fade in and shimmer. */
    --sp-motion-skeleton:
        ui-motion-fade-in var(--sp-motion-duration-base) var(--sp-motion-ease-enter) var(--sp-motion-delay-loading)
            backwards,
        ui-motion-shimmer 1.6s ease-in-out var(--sp-motion-delay-loading) infinite;
    /* Delayed status feedback: route progress and background-refresh markers. */
    --sp-motion-loading-in: ui-motion-fade-in var(--sp-motion-duration-base) var(--sp-motion-ease-enter)
        var(--sp-motion-delay-loading) backwards;
    /* Indeterminate progress: one bar segment travels across its track. */
    --sp-motion-progress: ui-motion-progress 1.2s var(--sp-motion-ease-standard) infinite;
    /* Notifications slide in from the inline end and leave the same way. */
    --sp-motion-notify-in: ui-motion-drawer-in var(--sp-motion-duration-slow) var(--sp-motion-ease-enter) backwards;
    --sp-motion-notify-out: ui-motion-drawer-out var(--sp-motion-duration-remove) var(--sp-motion-ease-exit) both;
    --sp-motion-transition-control:
        background-color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        border-color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        box-shadow var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        outline-color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        opacity var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        transform var(--sp-motion-duration-fast) var(--sp-motion-ease-standard),
        translate var(--sp-motion-duration-fast) var(--sp-motion-ease-standard);
    /* Hover tint for table rows and list surfaces: colour only, never geometry. */
    --sp-motion-transition-surface: background-color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard);
    --sp-motion-transition-transform: transform var(--sp-motion-duration-base) var(--sp-motion-ease-standard);
    /* Interactive cards rise by two pixels and deepen their shadow. */
    --sp-motion-transition-lift:
        transform var(--sp-motion-duration-base) var(--sp-motion-ease-standard),
        box-shadow var(--sp-motion-duration-base) var(--sp-motion-ease-standard),
        border-color var(--sp-motion-duration-fast) var(--sp-motion-ease-standard);
    /* Stale content dims only when a navigation outlasts the loading delay. */
    --sp-motion-transition-pending: opacity var(--sp-motion-duration-base) var(--sp-motion-ease-standard)
        var(--sp-motion-delay-loading);
    /* Always-mounted surfaces toggled by a state class (menus, drawers). Visibility
       flips immediately when shown and after the fade when concealed. */
    --sp-motion-transition-reveal:
        opacity var(--sp-motion-duration-base) var(--sp-motion-ease-enter),
        transform var(--sp-motion-duration-base) var(--sp-motion-ease-enter), visibility 0s linear 0s;
    --sp-motion-transition-conceal:
        opacity var(--sp-motion-duration-fast) var(--sp-motion-ease-exit),
        transform var(--sp-motion-duration-fast) var(--sp-motion-ease-exit),
        visibility 0s linear var(--sp-motion-duration-fast);
    /* Sidebar motion is compositor-only; its layout track changes once per toggle. */
    --sp-motion-transition-sidebar-open:
        transform var(--sp-motion-duration-slow) var(--sp-motion-ease-standard),
        opacity var(--sp-motion-duration-slow) var(--sp-motion-ease-standard), visibility 0s linear 0s;
    --sp-motion-transition-sidebar-close:
        transform var(--sp-motion-duration-slow) var(--sp-motion-ease-standard),
        opacity var(--sp-motion-duration-slow) var(--sp-motion-ease-standard),
        visibility 0s linear var(--sp-motion-duration-slow);
    /* Owned disclosures only: the one sanctioned grid-track animation. */
    --sp-motion-transition-expand:
        grid-template-rows var(--sp-motion-duration-slow) var(--sp-motion-ease-enter),
        opacity var(--sp-motion-duration-base) var(--sp-motion-ease-standard), visibility 0s linear 0s;
    --sp-motion-transition-collapse:
        grid-template-rows var(--sp-motion-duration-slow) var(--sp-motion-ease-enter),
        opacity var(--sp-motion-duration-base) var(--sp-motion-ease-standard),
        visibility 0s linear var(--sp-motion-duration-slow);
    color-scheme: light;

    --sp-color-ink: #10223a;
    --sp-color-ink-muted: var(--sp-semantic-text-muted);
    --sp-color-ink-muted-strong: #475569;
    --sp-color-ink-strong: var(--sp-semantic-text-primary);
    --sp-color-ink-deep: #1e293b;
    --sp-color-ink-dark: #111827;
    --sp-color-ink-secondary: var(--sp-semantic-text-secondary);
    --sp-color-ink-subtle: #57677c;
    --sp-color-ink-faint: #94a3b8;
    --sp-color-white: #ffffff;
    --sp-color-black: #000000;
    --sp-color-surface: var(--sp-semantic-surface-base);
    --sp-color-surface-raised: var(--sp-semantic-surface-raised);
    --sp-color-surface-muted: var(--sp-semantic-surface-muted);
    --sp-color-surface-info: var(--sp-semantic-status-info-surface);
    --sp-color-surface-warning: var(--sp-semantic-status-warning-surface);
    --sp-color-surface-success: var(--sp-semantic-status-success-surface);
    --sp-color-surface-danger: var(--sp-semantic-status-danger-surface);
    --sp-color-canvas: #eaf3fc;
    --sp-color-border: var(--sp-semantic-border-default);
    --sp-color-border-strong: var(--sp-semantic-border-strong);
    /* Unchecked check/radio outline: at least 3:1 against card surfaces. */
    --sp-color-border-control: #7b8ba0;
    --sp-color-border-subtle: #e2e8f0;
    --sp-color-border-soft: #dbe3ee;
    --sp-color-brand: #0136ff;
    --sp-color-brand-text: #002bd1;
    --sp-color-brand-strong: #002bd1;
    --sp-color-brand-button: var(--sp-semantic-action-primary);
    --sp-color-brand-soft: #eaf2ff;
    --sp-color-brand-border: #93c5fd;
    --sp-color-brand-soft-border: #bfdbfe;
    --sp-color-button-primary: var(--sp-semantic-action-primary);
    --sp-color-button-primary-hover: var(--sp-semantic-action-primary-hover);
    --sp-color-button-primary-active: #1e40af;
    --sp-color-button-on-primary: #ffffff;
    /* Secondary line inside a primary button (5.6:1 on the light primary); opacity would fall below 4.5:1 in dark. */
    --sp-color-button-on-primary-muted: #dbe4ff;
    --sp-color-info: var(--sp-semantic-status-info-base);
    --sp-color-info-text: var(--sp-semantic-status-info-text);
    --sp-color-info-button: #0284c7;
    --sp-color-info-strong: var(--sp-semantic-status-info-text);
    --sp-color-info-deep: #075985;
    --sp-color-info-soft: var(--sp-semantic-status-info-surface);
    --sp-color-success: var(--sp-semantic-status-success-base);
    --sp-color-success-text: var(--sp-semantic-status-success-text);
    --sp-color-success-button: #15803d;
    --sp-color-success-strong: var(--sp-semantic-status-success-text);
    --sp-color-success-border: var(--sp-semantic-status-success-border);
    --sp-color-success-soft: var(--sp-semantic-status-success-surface);
    --sp-color-success-surface: #dcfce7;
    --sp-color-success-solid: #16a34a;
    --sp-color-success-emerald: #059669;
    --sp-color-warning: var(--sp-semantic-status-warning-base);
    --sp-color-warning-text: var(--sp-semantic-status-warning-text);
    --sp-color-warning-button: #b45309;
    --sp-color-warning-strong: #92400e;
    --sp-color-warning-border: var(--sp-semantic-status-warning-border);
    --sp-color-warning-bright: #fbbf24;
    --sp-color-warning-soft: var(--sp-semantic-status-warning-surface);
    --sp-color-warning-deep: var(--sp-semantic-status-warning-text);
    --sp-color-danger: var(--sp-semantic-status-danger-base);
    --sp-color-danger-text: var(--sp-semantic-status-danger-text);
    --sp-color-danger-button: #b91c1c;
    --sp-color-danger-strong: #991b1b;
    --sp-color-danger-border: var(--sp-semantic-status-danger-border);
    --sp-color-danger-soft: var(--sp-semantic-status-danger-surface);
    --sp-color-danger-solid: #dc2626;
    --sp-color-danger-dark: #b91c1c;
    --sp-color-danger-border-strong: #fca5a5;
    --sp-color-danger-surface-strong: #fef2f2;
    --sp-color-danger-surface: #fee2e2;
    --sp-color-accent: #fca311;
    --sp-color-accent-soft: #fff7e8;
    --sp-color-orange: #f97316;
    --sp-color-orange-strong: #ea580c;
    --sp-color-orange-deep: #9a3412;
    --sp-color-orange-soft: #fff7ed;
    /* Filled orange call to action: white text keeps 4.5:1 in both themes. */
    --sp-color-orange-button: #c2410c;
    --sp-color-orange-button-strong: #9a3412;
    --sp-color-violet: #7c3aed;
    --sp-color-violet-button: #7c3aed;
    --sp-color-violet-strong: #5b21b6;
    --sp-color-violet-soft: #ede9fe;
    --sp-color-brand-deep: #1e40af;
    --sp-color-violet-deep: #5b21b6;
    --sp-color-teal: #0f766e;
    --sp-color-yellow-soft: #fef08a;
    --sp-color-map-snow-low: #dbeafe;
    --sp-color-map-snow-blue: #60a5fa;
    --sp-color-map-cyan: #22d3ee;
    --sp-color-map-green: #34d399;
    --sp-color-map-yellow: #facc15;
    --sp-color-map-orange: #fb923c;
    --sp-color-map-red: #dc2626;
    --sp-color-route-violet: #9333ea;
    --sp-color-route-cyan: #0891b2;
    --sp-color-route-rose: #be123c;
    --sp-color-route-indigo: #4f46e5;
    --sp-color-editor-highlight: #fff59d;
    /* Email content is composed on a white Outlook canvas in both app themes. */
    --sp-color-email-body-text: #111827;
    /* Outgoing email paper and placeholder; fixed in both themes so the composer previews the email. */
    --sp-color-email-body-background: #ffffff;
    --sp-color-email-placeholder: #6b7280;
    --sp-color-email-highlight: #fff59d;
    --sp-color-sidebar: #10223a;
    --sp-color-sidebar-raised: #17233b;
    --sp-color-sidebar-text: #f8fafc;
    --sp-color-sidebar-muted: #cbd5e1;
    --sp-color-sidebar-subtle: #94a3b8;
    --sp-color-auth-bg-from: #10223a;
    --sp-color-auth-bg-via: #10223a;
    --sp-color-auth-bg-to: #10223a;

    /* Semantic contract for primitives and feature sheets. Keep component
       styles on these names; the legacy aliases above can be consolidated or
       retuned without making every feature choose a colour variant. */
    --sp-semantic-surface-base: #ffffff;
    --sp-semantic-surface-raised: #f3f7ff;
    --sp-semantic-surface-muted: #eaf3fc;
    --sp-semantic-text-primary: #10223a;
    --sp-semantic-text-secondary: #334155;
    --sp-semantic-text-muted: #4f5f75;
    --sp-semantic-border-default: #d6e4f3;
    --sp-semantic-border-strong: #c9d9ee;
    --sp-semantic-action-primary: #0136ff;
    --sp-semantic-action-primary-hover: #002bd1;
    --sp-semantic-action-danger: #d92d20;
    --sp-semantic-status-info-base: #0284c7;
    --sp-semantic-status-info-text: #0369a1;
    --sp-semantic-status-info-surface: #e3ebff;
    --sp-semantic-status-info-border: #7dd3fc;
    --sp-semantic-status-success-base: #15803d;
    --sp-semantic-status-success-text: #166534;
    --sp-semantic-status-success-surface: #ecfdf3;
    --sp-semantic-status-success-border: #86efac;
    --sp-semantic-status-warning-base: #a16207;
    --sp-semantic-status-warning-text: #854d0e;
    --sp-semantic-status-warning-surface: #fffbeb;
    --sp-semantic-status-warning-border: #f59e0b;
    --sp-semantic-status-danger-base: #d92d20;
    --sp-semantic-status-danger-text: #b42318;
    --sp-semantic-status-danger-surface: #fff1f0;
    --sp-semantic-status-danger-border: #fecaca;
    --sp-semantic-status-info: var(--sp-semantic-status-info-base);
    --sp-semantic-status-success: var(--sp-semantic-status-success-base);
    --sp-semantic-status-warning: var(--sp-semantic-status-warning-base);
    --sp-semantic-status-danger: var(--sp-semantic-status-danger-base);
    --sp-semantic-focus-ring: var(--sp-focus-ring);

    --sp-rgb-ink: 15 23 42;
    --sp-rgb-black: 0 0 0;
    --sp-rgb-white: 255 255 255;
    --sp-rgb-brand: 1 54 255;
    --sp-rgb-brand-strong: 0 43 209;
    --sp-rgb-brand-button: 1 54 255;
    /* Bootstrap uses comma-alpha rgba(); native tokens retain space channels. */
    --sp-rgb-brand-button-comma: 1, 54, 255;
    --sp-rgb-brand-bright: 59 130 246;
    --sp-rgb-info: 56 189 248;
    --sp-rgb-info-alt: 14 165 233;
    --sp-rgb-accent: 252 163 17;
    --sp-rgb-orange: 249 115 22;
    --sp-rgb-warning: 245 158 11;
    --sp-rgb-warning-pale: 254 249 195;
    --sp-rgb-warning-yellow: 234 179 8;
    --sp-rgb-warning-deep: 124 45 18;
    --sp-rgb-success: 22 163 74;
    --sp-rgb-success-deep: 22 101 52;
    --sp-rgb-danger: 220 38 38;
    --sp-rgb-danger-alt: 239 68 68;
    --sp-rgb-danger-deep: 127 29 29;
    --sp-rgb-danger-soft: 254 202 202;
    --sp-rgb-muted: 148 163 184;
    --sp-rgb-ink-base: 16 34 58;
    --sp-rgb-surface: 248 250 252;
    --sp-rgb-canvas: 234 243 252;
    --sp-rgb-sidebar: 16 34 58;
    --sp-rgb-dark: 4 10 24;
    --sp-rgb-purple: 76 29 149;

    --sp-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --sp-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --sp-font-signature: "Brush Script MT", "Segoe Script", "Snell Roundhand", cursive;
    --sp-font-size-signature: 20px;
    --bs-font-sans-serif: var(--sp-font-sans);
    --bs-body-font-family: var(--sp-font-sans);
    --bs-font-monospace: var(--sp-font-mono);
    --sp-font-size-sm: 0.8125rem;
    --sp-font-size-xs: 0.6875rem;
    --sp-line-height-tight: 1.2;
    --sp-line-height-body: 1.45;

    --sp-space-1: 0.25rem;
    --sp-space-2: 0.5rem;
    --sp-space-3: 0.75rem;
    --sp-space-4: 1rem;
    --sp-space-5: 1.25rem;
    --sp-space-6: 1.5rem;
    --sp-space-8: 2rem;

    --sp-radius-sm: 0.5rem;
    --sp-radius-md: 0.625rem;
    --sp-radius-lg: 0.75rem;
    --sp-radius-dialog: 0.875rem;
    --sp-control-height: 2.125rem;
    --sp-control-height-sm: 1.75rem;
    --sp-control-height-touch: 2.75rem;
    --sp-form-width: 47.5rem;
    --sp-panel-padding: 1.125rem;
    --sp-table-heading-size: 0.6875rem;
    --sp-table-heading-tracking: 0.04em;
    --sp-radius-pill: 999px;
    --sp-control-radius: 0.5625rem;
    --sp-shadow-sm: 0 1px 2px rgb(var(--sp-rgb-ink) / 0.04);
    --sp-shadow-md: 0 8px 24px rgb(var(--sp-rgb-ink) / 0.12);
    --sp-shadow-drawer: 10px 0 32px rgb(var(--sp-rgb-ink) / 0.3);
    --sp-focus-ring: 0 0 0 3px rgb(var(--sp-rgb-brand) / 0.24);

    --sp-skeleton-base: #e5ebf2;
    --sp-skeleton-highlight: #f8fafc;
    --sp-skeleton-radius: var(--sp-radius-sm);
    --sp-skeleton-text-height: 0.85em;
    --sp-skeleton-block-height: 8rem;
    --sp-skeleton-circle-size: 2.5rem;
    --sp-skeleton-gap: var(--sp-space-3);
}

html[data-theme="dark"] {
    color-scheme: dark;

    --sp-color-ink: #f8fafc;
    --sp-color-ink-muted: var(--sp-semantic-text-muted);
    --sp-color-ink-muted-strong: #cbd5e1;
    --sp-color-ink-subtle: #9aaac0;
    --sp-color-ink-strong: var(--sp-semantic-text-primary);
    --sp-color-ink-deep: #cbd5e1;
    --sp-color-ink-dark: #f8fafc;
    --sp-color-ink-secondary: var(--sp-semantic-text-secondary);
    --sp-color-ink-faint: #a8b8cc;
    --sp-color-white: #ffffff;
    --sp-color-black: #000000;
    --sp-color-surface: var(--sp-semantic-surface-base);
    --sp-color-surface-raised: var(--sp-semantic-surface-raised);
    --sp-color-surface-muted: var(--sp-semantic-surface-muted);
    --sp-color-surface-info: var(--sp-semantic-status-info-surface);
    --sp-color-surface-warning: var(--sp-semantic-status-warning-surface);
    --sp-color-surface-success: var(--sp-semantic-status-success-surface);
    --sp-color-surface-danger: var(--sp-semantic-status-danger-surface);
    --sp-color-canvas: #0a1120;
    --sp-color-border: var(--sp-semantic-border-default);
    --sp-color-border-strong: var(--sp-semantic-border-strong);
    --sp-color-border-control: #5c7390;
    --sp-color-border-subtle: #344860;
    --sp-color-border-soft: #344860;
    --sp-color-brand: #2563eb;
    --sp-color-brand-text: #93c5fd;
    --sp-color-brand-strong: #93c5fd;
    --sp-color-brand-button: var(--sp-semantic-action-primary);
    --sp-color-brand-soft: #172554;
    --sp-color-brand-border: #bfdbfe;
    --sp-color-brand-soft-border: #1d4ed8;
    --sp-color-button-primary: var(--sp-semantic-action-primary);
    --sp-color-button-primary-hover: var(--sp-semantic-action-primary-hover);
    --sp-color-button-primary-active: #1d4ed8;
    --sp-color-button-on-primary: #ffffff;
    /* 4.65:1 on the dark primary #2563eb, where 75% white was 3.61:1. */
    --sp-color-button-on-primary-muted: #eef3fe;
    --sp-color-info: var(--sp-semantic-status-info-base);
    --sp-color-info-text: var(--sp-semantic-status-info-text);
    --sp-color-info-button: #0369a1;
    --sp-color-info-strong: var(--sp-semantic-status-info-border);
    --sp-color-info-deep: #bae6fd;
    --sp-color-info-soft: var(--sp-semantic-status-info-surface);
    --sp-color-success: var(--sp-semantic-status-success-base);
    --sp-color-success-text: var(--sp-semantic-status-success-text);
    --sp-color-success-button: #15803d;
    --sp-color-success-strong: #bbf7d0;
    --sp-color-success-border: var(--sp-semantic-status-success-border);
    --sp-color-success-soft: var(--sp-semantic-status-success-surface);
    --sp-color-success-surface: #14532d;
    --sp-color-success-solid: #15803d;
    --sp-color-success-emerald: #34d399;
    --sp-color-warning: var(--sp-semantic-status-warning-base);
    --sp-color-warning-text: var(--sp-semantic-status-warning-text);
    --sp-color-warning-button: #92400e;
    --sp-color-warning-strong: #fde68a;
    --sp-color-warning-border: var(--sp-semantic-status-warning-border);
    --sp-color-warning-bright: #fbbf24;
    --sp-color-warning-soft: var(--sp-semantic-status-warning-surface);
    --sp-color-warning-deep: var(--sp-semantic-status-warning-text);
    --sp-color-danger: var(--sp-semantic-status-danger-base);
    --sp-color-danger-text: var(--sp-semantic-status-danger-text);
    --sp-color-danger-button: #b91c1c;
    --sp-color-danger-strong: #fecaca;
    --sp-color-danger-border: var(--sp-semantic-status-danger-border);
    --sp-color-danger-soft: var(--sp-semantic-status-danger-surface);
    --sp-color-danger-solid: #b91c1c;
    --sp-color-danger-dark: #fca5a5;
    --sp-color-danger-border-strong: #f87171;
    --sp-color-danger-surface-strong: #450a0a;
    --sp-color-danger-surface: #450a0a;
    --sp-color-accent: #fbbf24;
    --sp-color-accent-soft: #422006;
    --sp-color-orange: #fb923c;
    --sp-color-orange-strong: #f97316;
    --sp-color-orange-deep: #fdba74;
    --sp-color-orange-soft: #431407;
    /* Filled orange call to action: white text keeps 4.5:1 in both themes. */
    --sp-color-orange-button: #c2410c;
    --sp-color-orange-button-strong: #9a3412;
    --sp-color-violet: #a78bfa;
    --sp-color-violet-button: #7c3aed;
    --sp-color-violet-strong: #c4b5fd;
    --sp-color-violet-soft: #2e1065;
    --sp-color-brand-deep: #bfdbfe;
    --sp-color-violet-deep: #c4b5fd;
    --sp-color-teal: #5eead4;
    --sp-color-yellow-soft: #854d0e;
    --sp-color-map-snow-low: #1e3a8a;
    --sp-color-map-snow-blue: #60a5fa;
    --sp-color-map-cyan: #22d3ee;
    --sp-color-map-green: #34d399;
    --sp-color-map-yellow: #facc15;
    --sp-color-map-orange: #fb923c;
    --sp-color-map-red: #dc2626;
    --sp-color-route-violet: #c084fc;
    --sp-color-route-cyan: #22d3ee;
    --sp-color-route-rose: #fb7185;
    --sp-color-route-indigo: #818cf8;
    --sp-color-editor-highlight: #854d0e;
    --sp-color-sidebar: #080f1d;
    --sp-color-sidebar-raised: #17233b;
    --sp-color-sidebar-text: #f8fafc;
    --sp-color-sidebar-muted: #cbd5e1;
    --sp-color-sidebar-subtle: #a8b8cc;
    --sp-color-auth-bg-from: #070d18;
    --sp-color-auth-bg-via: #0d1a2e;
    --sp-color-auth-bg-to: #08111f;

    --sp-semantic-surface-base: #131d2d;
    --sp-semantic-surface-raised: #1b283b;
    --sp-semantic-surface-muted: #26364b;
    --sp-semantic-text-primary: #e2e8f0;
    --sp-semantic-text-secondary: #cbd5e1;
    --sp-semantic-text-muted: #b7c3d4;
    --sp-semantic-border-default: #40536b;
    --sp-semantic-border-strong: #5c7390;
    --sp-semantic-action-primary: #2563eb;
    --sp-semantic-action-primary-hover: #3b82f6;
    --sp-semantic-action-danger: #b91c1c;
    --sp-semantic-status-info-base: #0284c7;
    --sp-semantic-status-info-text: #7dd3fc;
    --sp-semantic-status-info-surface: #082f49;
    --sp-semantic-status-info-border: #0369a1;
    --sp-semantic-status-success-base: #86efac;
    --sp-semantic-status-success-text: #86efac;
    --sp-semantic-status-success-surface: #052e16;
    --sp-semantic-status-success-border: #22c55e;
    --sp-semantic-status-warning-base: #fcd34d;
    --sp-semantic-status-warning-text: #fde68a;
    --sp-semantic-status-warning-surface: #422006;
    --sp-semantic-status-warning-border: #b45309;
    --sp-semantic-status-danger-base: #fca5a5;
    --sp-semantic-status-danger-text: #fca5a5;
    --sp-semantic-status-danger-surface: #450a0a;
    --sp-semantic-status-danger-border: #f87171;
    --sp-semantic-status-info: var(--sp-semantic-status-info-base);
    --sp-semantic-status-success: var(--sp-semantic-status-success-base);
    --sp-semantic-status-warning: var(--sp-semantic-status-warning-base);
    --sp-semantic-status-danger: var(--sp-semantic-status-danger-base);
    --sp-semantic-focus-ring: var(--sp-focus-ring);
    --sp-rgb-ink: 0 0 0;
    --sp-rgb-brand: 96 165 250;
    --sp-rgb-brand-strong: 147 197 253;
    --sp-rgb-brand-button: 37 99 235;
    --sp-rgb-brand-button-comma: 37, 99, 235;
    --sp-rgb-brand-bright: 96 165 250;
    --sp-rgb-info: 56 189 248;
    --sp-rgb-info-alt: 14 165 233;
    --sp-rgb-accent: 251 191 36;
    --sp-rgb-orange: 251 146 60;
    --sp-rgb-warning: 251 191 36;
    --sp-rgb-warning-pale: 66 32 6;
    --sp-rgb-warning-yellow: 245 158 11;
    --sp-rgb-warning-deep: 180 83 9;
    --sp-rgb-success: 34 197 94;
    --sp-rgb-success-deep: 22 101 52;
    --sp-rgb-danger: 220 38 38;
    --sp-rgb-danger-alt: 248 113 113;
    --sp-rgb-danger-deep: 127 29 29;
    --sp-rgb-danger-soft: 254 202 202;
    --sp-rgb-muted: 148 163 184;
    --sp-rgb-ink-base: 226 232 240;
    --sp-rgb-surface: 38 52 73;
    --sp-rgb-canvas: 11 18 32;
    --sp-rgb-sidebar: 8 15 29;
    --sp-rgb-dark: 4 10 24;
    --sp-rgb-purple: 124 58 237;
    --sp-shadow-sm: 0 1px 3px rgb(var(--sp-rgb-ink) / 0.32);
    --sp-shadow-md: 0 8px 24px rgb(var(--sp-rgb-ink) / 0.42);
    --sp-shadow-drawer: 10px 0 32px rgb(var(--sp-rgb-ink) / 0.55);
    --sp-focus-ring: 0 0 0 3px rgb(var(--sp-rgb-brand) / 0.35);
    --sp-skeleton-base: #263449;
    --sp-skeleton-highlight: #3a4b65;
}

/* Bootstrap reads its own custom properties; point them at the semantic
   palette so Bootstrap primitives follow the active application theme. */
html[data-theme="light"],
html[data-theme="dark"] {
    --bs-body-bg: var(--sp-color-canvas);
    --bs-body-color: var(--sp-color-ink);
    --bs-secondary-color: var(--sp-color-ink-muted);
    --bs-tertiary-bg: var(--sp-color-surface-muted);
    --bs-border-color: var(--sp-color-border);
    --bs-emphasis-color: var(--sp-color-ink-strong);
    --bs-primary: var(--sp-color-brand-button);
    --bs-primary-rgb: var(--sp-rgb-brand-button-comma);
    --bs-link-color: var(--sp-color-brand-text);
    --bs-link-hover-color: var(--sp-color-brand-strong);
    --bs-secondary-bg: var(--sp-color-surface-raised);
    --bs-border-radius: var(--sp-radius-md);
    --bs-border-radius-sm: var(--sp-radius-sm);
    --bs-border-radius-lg: var(--sp-radius-lg);
}

/* Phone workspace header geometry. WorkspaceHeader is sticky at the top of
   the phone viewport, so a sticky bar inside a workspace uses
   `top: var(--sp-workspace-sticky-top)` to stay below it. The phone shell also
   covers short touch screens such as a phone in landscape (MainLayout.razor.css);
   outside it the header scrolls away and the offset is zero. */
:root {
    --sp-workspace-sticky-top: 0px;
}

@media (max-width: 700px), (max-height: 500px) and (pointer: coarse) {
    :root {
        --sp-workspace-phone-pad-y: 0.3125rem;
        --sp-workspace-phone-row: 2.375rem;
        /* Row, vertical padding and the 1px bottom border. */
        --sp-workspace-sticky-top: calc(var(--sp-workspace-phone-row) + 2 * var(--sp-workspace-phone-pad-y) + 1px);
    }
}

/* Touch phones use the shared 44px target for the header row. */
@media (max-width: 700px) and (pointer: coarse), (max-height: 500px) and (pointer: coarse) {
    :root {
        --sp-workspace-phone-row: 2.75rem;
    }
}
