/* sw4p design tokens. OS-desktop grammar, original visual identity. */
:root {
    /* Surface palette */
    --xp-window-bg: #FAFBFC;
    --xp-window-bg-legacy: #ECE9D8;
    --xp-toast-bg: #FFFFE1;
    --xp-titlebar-flat: #0046A4;
    --xp-titlebar-flat-hover: #003A8A;

    /* Legacy XP blue (kept during migration; do not use in new code) */
    --xp-blue-primary: #0054E3;
    --xp-blue-hover: #0044BB;
    --xp-blue-titlebar-start: #0058EE;
    --xp-blue-titlebar-end: #0369FC;

    /* Border tokens */
    --xp-border-light: #FFFFFF;
    --xp-border-medium: #D0C6B0;
    --xp-border-dark: #003C74;
    --xp-border-input: #7F9DB9;
    --xp-border-card: rgba(15, 30, 60, 0.10);
    --xp-border-frame: rgba(0, 0, 0, 0.08);

    /* Button accents */
    --xp-close-red: #E44132;
    --xp-close-red-hover: #F24C5B;
    --xp-close-red-active: #C72A34;

    /* Text */
    --xp-text-dark: #000000;
    --xp-text-gray: #666666;
    --xp-text-muted: #444444;
    --xp-text-ink: #1A2540;
    --xp-text-on-primary: #FFFFFF;
    --xp-text-disabled: rgba(0, 0, 0, 0.40);
    --sw4p-text-on-light-surface: #1A2540;
    --sw4p-text-on-light-surface-muted: rgba(26, 37, 64, 0.62);
    --sw4p-text-on-light-surface-disabled: rgba(26, 37, 64, 0.42);

    /* Window chrome shadows (flattened) */
    --xp-shadow-window: 0 8px 32px rgba(0, 0, 0, 0.12);
    --xp-shadow-window-legacy: 2px 2px 10px rgba(0, 0, 0, 0.4);
    --xp-shadow-toast: 0 2px 8px rgba(0, 0, 0, 0.15);
    --xp-shadow-inset: inset 0 0 2px rgba(255, 255, 255, 0.8);

    /* ButtonCard elevation ramp */
    --btn-radius: 4px;
    --btn-border: 1px solid var(--xp-border-card);
    --btn-shadow-rest: 0 1px 0 rgba(0, 0, 0, 0.04), 0 2px 8px rgba(15, 30, 60, 0.08);
    --btn-shadow-hover: 0 1px 0 rgba(0, 0, 0, 0.04), 0 4px 14px rgba(15, 30, 60, 0.12);
    --btn-shadow-press: inset 0 1px 2px rgba(15, 30, 60, 0.10);
    --btn-shadow-rest-primary: 0 1px 0 rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 70, 164, 0.18);
    --btn-shadow-hover-primary: 0 1px 0 rgba(0, 0, 0, 0.06), 0 4px 16px rgba(0, 70, 164, 0.28);
    --btn-shadow-press-primary: inset 0 1px 3px rgba(0, 0, 0, 0.22);

    /* Easing + timing (Emil strong ease-out) */
    --ease-xp-out: cubic-bezier(0.23, 1, 0.32, 1);
    --tx-btn-fast: 90ms;
    --tx-btn-slow: 140ms;

    /* Press motion budget */
    --btn-press-y: 1.5px;
    --btn-hover-y: -1px;

    /* Pill variant palette */
    --xp-pill-blue-bg: #D3E5FA;
    --xp-pill-blue-fg: #003C74;
    --xp-pill-blue-border: #94BAE7;

    --xp-pill-stack-bg: #FFFFFF;
    --xp-pill-stack-fg: #003C74;
    --xp-pill-stack-border: #94BAE7;

    --xp-pill-green-bg: #C1F0B7;
    --xp-pill-green-fg: #1B4D04;
    --xp-pill-green-border: #3C8D0D;

    --xp-pill-amber-bg: #FFEAB3;
    --xp-pill-amber-fg: #5C3A00;
    --xp-pill-amber-border: #E5A100;
}

/* ===== v2 design tokens (refined-minimal inner surfaces) ===== */
:root {
  /* Surfaces -- tinted-warm toward brand blue */
  --sw4p-surface-1: oklch(99.5% 0.003 250);
  --sw4p-surface-2: oklch(97.5% 0.005 250);
  --sw4p-surface-3: oklch(94.5% 0.008 250);

  /* Text -- tinted-warm, hierarchical */
  --sw4p-text-strong: oklch(22% 0.012 250);
  --sw4p-text:        oklch(34% 0.008 250);
  --sw4p-text-muted:  oklch(56% 0.010 250);
  --sw4p-text-faint:  oklch(74% 0.008 250);

  /* Action -- brand blue family, role-differentiated */
  --sw4p-action-primary:        var(--xp-titlebar-flat);
  --sw4p-action-primary-hover:  oklch(36% 0.18 250);
  --sw4p-action-subtle-bg:      oklch(94% 0.05 250);
  --sw4p-action-subtle-text:    var(--sw4p-action-primary);
  --sw4p-action-accent:         var(--sw4p-action-primary);

  /* Status (promoted from StatusLed values) */
  --sw4p-status-success: oklch(50% 0.15 145);
  --sw4p-status-warning: oklch(70% 0.16 75);
  --sw4p-status-error:   oklch(50% 0.20 25);

  /* Alpha-suffixed tokens (Tailwind /opacity does not compose with raw var()) */
  --sw4p-status-error-10:     oklch(50% 0.20 25 / 0.1);
  --sw4p-action-primary-05:   oklch(36% 0.18 250 / 0.05);

  /* Motion durations -- Emil's brackets */
  --sw4p-motion-fast:    100ms;
  --sw4p-motion-base:    160ms;
  --sw4p-motion-medium:  220ms;
  --sw4p-motion-slow:    320ms;

  /* Motion easing for inner surfaces (outer chrome keeps --ease-xp-out) */
  --sw4p-ease-out:    cubic-bezier(0.2, 0.8, 0.2, 1);
  --sw4p-ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1);

  /* Leading -- for text consumers that want explicit line-height tokens */
  --sw4p-leading-tight:   1.1;   /* hero, display */
  --sw4p-leading-normal:  1.4;   /* body, table cells */
  --sw4p-leading-relaxed: 1.55;  /* form helper text */

  /* Press scale -- semantic by button role */
  --sw4p-press-primary:  0.97;
  --sw4p-press-icon:     0.94;
  --sw4p-press-subtle:   0.99;
}

/* ===== Typography tokens (theme-independent) ===== */
:root {
  /* XP/vintage typography: the OS shell and transaction controls share the
     same Tahoma/Geneva lineage, while large amounts use terminal faces with
     slashed-zero forms. Lucida Console is intentionally excluded because it
     falls back to Verdana on macOS; Courier New is last because its zero is
     plain on common installs. */
  --sw4p-font-shell: Tahoma, Geneva, 'MS Sans Serif', 'Lucida Grande', Arial, sans-serif;
  --sw4p-font-ui: var(--sw4p-font-shell);
  --sw4p-font-mono: Monaco, Menlo, 'SFMono-Regular', Consolas, 'Courier New', Courier, ui-monospace, monospace;
  --sw4p-font-body: var(--sw4p-font-shell);
  --sw4p-font-size-base: 16px;
}

/* ===== v3 theme tokens (transaction console light/dark) ===== */
:root,
[data-theme="light"] {
  --sw4p-bg-desktop: oklch(94% 0.025 238);
  --sw4p-bg-window: oklch(96.5% 0.009 250);
  --sw4p-bg-card: oklch(99.2% 0.004 250);
  --sw4p-bg-card-raised: oklch(98.2% 0.006 250);
  --sw4p-bg-input: oklch(99.4% 0.003 250);
  --sw4p-bg-menu: oklch(99.2% 0.004 250);
  --sw4p-bg-titlebar-active: oklch(45% 0.19 256);
  --sw4p-bg-titlebar-inactive: oklch(37% 0.16 256);
  --sw4p-border-subtle: oklch(86% 0.018 250);
  --sw4p-border-strong: oklch(75% 0.034 250);
  --sw4p-border-focus: oklch(59% 0.19 256);
  --sw4p-text-primary: oklch(22% 0.018 250);
  --sw4p-text-secondary: oklch(39% 0.016 250);
  --sw4p-text-muted: oklch(52% 0.014 250);
  --sw4p-text-faint: oklch(70% 0.012 250);
  --sw4p-text-inverse: oklch(98% 0.006 250);
  --sw4p-action-primary: var(--sw4p-bg-titlebar-active);
  --sw4p-action-primary-hover: var(--sw4p-bg-titlebar-inactive);
  --sw4p-action-secondary-bg: oklch(94.5% 0.034 256);
  --sw4p-action-danger: oklch(59% 0.21 28);
  --sw4p-action-link: var(--sw4p-bg-titlebar-active);
  --sw4p-status-live: oklch(55% 0.16 142);
  --sw4p-status-building: var(--sw4p-border-focus);
  --sw4p-status-warning: oklch(74% 0.15 78);
  --sw4p-status-error: oklch(59% 0.21 28);
  --sw4p-shadow-window: 0 18px 64px oklch(24% 0.06 250 / 0.22);
  --sw4p-shadow-card: 0 8px 24px oklch(30% 0.04 250 / 0.10);

  --xp-window-bg: var(--sw4p-bg-window);
  --xp-titlebar-flat: var(--sw4p-bg-titlebar-active);
  --xp-titlebar-flat-hover: var(--sw4p-bg-titlebar-inactive);
  --xp-border-card: var(--sw4p-border-subtle);
  --xp-border-frame: oklch(22% 0.018 250 / 0.08);
  --xp-border-input: var(--sw4p-border-strong);
  --xp-shadow-window: var(--sw4p-shadow-window);
  --xp-close-red: var(--sw4p-action-danger);
  --xp-text-dark: var(--sw4p-text-primary);
  --xp-text-gray: var(--sw4p-text-muted);
  --xp-text-muted: var(--sw4p-text-secondary);
  --xp-text-ink: var(--sw4p-text-primary);
  --xp-text-on-primary: var(--sw4p-text-inverse);
  --xp-text-disabled: oklch(22% 0.018 250 / 0.40);
  --xp-toast-bg: oklch(97% 0.038 94);
}

[data-theme="dark"] {
  --sw4p-bg-desktop: oklch(15% 0.026 250);
  --sw4p-bg-window: oklch(18% 0.026 250);
  --sw4p-bg-card: oklch(22% 0.028 250);
  --sw4p-bg-card-raised: oklch(25% 0.030 250);
  --sw4p-bg-input: oklch(19% 0.026 250);
  --sw4p-bg-menu: oklch(22% 0.028 250);
  --sw4p-bg-titlebar-active: oklch(47% 0.19 256);
  --sw4p-bg-titlebar-inactive: oklch(36% 0.15 256);
  --sw4p-border-subtle: oklch(35% 0.035 250);
  --sw4p-border-strong: oklch(46% 0.052 250);
  --sw4p-border-focus: oklch(63% 0.20 256);
  --sw4p-text-primary: oklch(94% 0.010 250);
  --sw4p-text-secondary: oklch(82% 0.014 250);
  --sw4p-text-muted: oklch(68% 0.016 250);
  --sw4p-text-faint: oklch(50% 0.020 250);
  --sw4p-text-inverse: oklch(98% 0.006 250);
  --sw4p-action-primary: var(--sw4p-border-focus);
  --sw4p-action-primary-hover: oklch(57% 0.19 256);
  --sw4p-action-secondary-bg: oklch(29% 0.055 256);
  --sw4p-action-danger: oklch(65% 0.21 28);
  --sw4p-action-link: oklch(76% 0.13 256);
  --sw4p-status-live: oklch(64% 0.16 142);
  --sw4p-status-building: var(--sw4p-border-focus);
  --sw4p-status-warning: oklch(79% 0.14 78);
  --sw4p-status-error: oklch(65% 0.21 28);
  --sw4p-shadow-window: 0 18px 72px oklch(8% 0.018 250 / 0.58);
  --sw4p-shadow-card: 0 8px 30px oklch(8% 0.018 250 / 0.40);

  --xp-window-bg: var(--sw4p-bg-window);
  --xp-titlebar-flat: var(--sw4p-bg-titlebar-active);
  --xp-titlebar-flat-hover: var(--sw4p-bg-titlebar-inactive);
  --xp-border-card: var(--sw4p-border-subtle);
  --xp-border-frame: oklch(95% 0.010 250 / 0.10);
  --xp-border-input: var(--sw4p-border-strong);
  --xp-shadow-window: var(--sw4p-shadow-window);
  --xp-close-red: var(--sw4p-action-danger);
  --xp-text-dark: var(--sw4p-text-primary);
  --xp-text-gray: var(--sw4p-text-muted);
  --xp-text-muted: var(--sw4p-text-secondary);
  --xp-text-ink: var(--sw4p-text-primary);
  --xp-text-on-primary: var(--sw4p-text-inverse);
  --xp-text-disabled: oklch(94% 0.010 250 / 0.40);
  --xp-toast-bg: oklch(28% 0.034 94);
}

/* Shared XP text utilities.
   Callers may apply these directly without going through a React component. */
.xp-heading {
    font-family: 'Tahoma', sans-serif;
}

/* Shared sw4p animation keyframes.
   Originally inlined as <style> blocks in BridgeApp.tsx and the swap-card
   component. Promoted here so portaled surfaces (e.g. SettingsCog) can use
   them without depending on Bridge being mounted. */
@keyframes sw4pFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes sw4pPop {
    from { opacity: 0; transform: scale(0.96) translateY(4px); }
    to   { opacity: 1; transform: scale(1)    translateY(0);   }
}
@keyframes sw4pDisclosureEnter {
    from { opacity: 0; transform: translateY(-2px); }
    to   { opacity: 1; transform: translateY(0);    }
}
@keyframes sw4pLabelSwap {
    from { opacity: 0.4; filter: blur(2px); }
    to   { opacity: 1;   filter: blur(0);   }
}

/* ----- WindowFrame primitive ----- */
/* Outer chrome of every XP window. Responsive width clamps from 95% on
   narrow viewports to 90% on tablet+ so adjacent windows can breathe;
   maxWidth (prop) caps the final size on desktop. */

.xp-window {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    width: 95%;
    background: var(--xp-window-bg);
    border: 1px solid var(--xp-border-frame);
    border-radius: 6px;
    box-shadow: var(--xp-shadow-window);
    /* Re-assert the canonical body token at window scope so intermediate
       wrapper divs cannot fall back to Tailwind CDN's preflight defaults
       (frontend + console load tailwindcss CDN at runtime, which can
       re-anchor font-family on element-level cascades and leave window
       content rendering ui-sans-serif instead of Tahoma). */
    font-family: var(--sw4p-font-body);
}

.os-window {
    font-family: var(--sw4p-font-body);
}

/* Override sizing constraints when window is within the OS positioner wrapper */
.os-window .xp-window {
    width: 100%;
    height: 100%;
    max-width: 100%;
}

/* Active / Inactive states for window chrome */
.xp-window--inactive {
    opacity: 0.85;
}

.xp-window--inactive .xp-window__titlebar {
    background: var(--xp-titlebar-flat-hover);
}

/* Maximized / Fullscreen window state */
.xp-window--maximized {
    border: none;
    border-radius: 0;
    box-shadow: none;
}

.xp-window--maximized .xp-window__titlebar {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

@media (min-width: 768px) {
    .xp-window {
        width: 90%;
    }
}

.xp-window__titlebar {
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 12px;
    padding-right: 4px;
    user-select: none;
    background: var(--xp-titlebar-flat);
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
}

.xp-window__title {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #FFFFFF;
    flex: 1;
    min-width: 0;
}

.xp-window__title-text {
    font-size: 13px;
    pointer-events: none;
    font-weight: 600;
    letter-spacing: 0.01em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.xp-window__icon {
    width: 16px;
    height: 16px;
    pointer-events: none;
}

.xp-window__controls {
    display: flex;
    align-items: center;
    gap: 3px;
}

.xp-window__control {
    appearance: none;
    border: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.10);
}

/* Interactive variant: opt-in when the WindowFrame is given an onMinimize
   or onMaximize callback. The base background drops to transparent and the
   hover / active palette matches the frontend's reference WindowFrame so
   the wrapper can stop overriding once it adopts this primitive. */
.xp-window__control--interactive {
    background: transparent;
    cursor: pointer;
    outline: none;
}

.xp-window__control--interactive:hover {
    background: rgba(255, 255, 255, 0.15);
}

.xp-window__control--interactive:active {
    background: rgba(255, 255, 255, 0.25);
}

.xp-window__control--interactive:focus-visible {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.6);
}

.xp-window__control--close {
    background: var(--xp-close-red);
    margin-left: 2px;
}

.xp-window__body {
    flex: 1;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: var(--xp-window-bg);
}

/* Opt-in body content padding. .xp-window__body itself has zero padding
 * so consumers can render edge-to-edge content (tables, charts). When the
 * window's content wants landing-grade 16px breathing room around it,
 * the inner wrapper opts in with this modifier instead of an arbitrary
 * Tailwind padding utility. Keeps body padding canonical across surfaces. */
.xp-window__body--padded {
    padding: 16px;
}

/* ----- ButtonCard primitive ----- */
/* Elevated, tactile, card-like buttons. The primary interactive surface. */

.btn-card {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    box-sizing: border-box;
    padding: 10px 16px;
    min-height: 40px;
    border-radius: var(--btn-radius);
    border: var(--btn-border);
    background: #FFFFFF;
    color: var(--sw4p-text-on-light-surface);
    font-family: var(--sw4p-font-ui);
    font-weight: 600;
    font-size: 13px;
    line-height: 1.1;
    letter-spacing: 0.01em;
    cursor: pointer;
    user-select: none;
    text-decoration: none;
    box-shadow: var(--btn-shadow-rest);
    transition:
        transform var(--tx-btn-slow) var(--ease-xp-out),
        box-shadow var(--tx-btn-slow) var(--ease-xp-out),
        background-color var(--tx-btn-slow) var(--ease-xp-out),
        border-color var(--tx-btn-slow) var(--ease-xp-out);
    will-change: transform;
}

.btn-card:hover {
    transform: translateY(var(--btn-hover-y));
    box-shadow: var(--btn-shadow-hover);
}

.btn-card:active {
    transform: translateY(var(--btn-press-y));
    box-shadow: var(--btn-shadow-press);
    transition:
        transform var(--tx-btn-fast) var(--ease-xp-out),
        box-shadow var(--tx-btn-fast) var(--ease-xp-out);
}

.btn-card:focus-visible {
    outline: 2px solid var(--xp-titlebar-flat);
    outline-offset: 2px;
}

/* Sizes */
.btn-card.btn-card--sm {
    padding: 8px 12px;
    min-height: 36px;
    font-size: 12px;
    gap: 6px;
}

.btn-card.btn-card--lg {
    padding: 14px 22px;
    min-height: 48px;
    font-size: 14px;
    gap: 10px;
}

/* Variants */
.btn-card.btn-card--primary {
    background: var(--xp-titlebar-flat);
    color: var(--xp-text-on-primary);
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: var(--btn-shadow-rest-primary);
}

.btn-card.btn-card--primary:hover {
    background: var(--xp-titlebar-flat-hover);
    box-shadow: var(--btn-shadow-hover-primary);
}

.btn-card.btn-card--primary:active {
    background: var(--xp-titlebar-flat-hover);
    box-shadow: var(--btn-shadow-press-primary);
}

.btn-card.btn-card--ghost {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--xp-text-muted);
}

.btn-card.btn-card--ghost:hover {
    background: rgba(15, 30, 60, 0.04);
    box-shadow: none;
    transform: translateY(0);
    color: var(--xp-text-ink);
}

.btn-card.btn-card--ghost:active {
    background: rgba(15, 30, 60, 0.08);
    box-shadow: none;
    transform: translateY(0);
}

/* Disabled (Goblin Mode strikethrough) */
.btn-card[disabled],
.btn-card.btn-card--disabled,
.btn-card[aria-disabled="true"] {
    background: #F5F5F5;
    color: var(--sw4p-text-on-light-surface-disabled);
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
    text-decoration-color: rgba(0, 0, 0, 0.30);
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
    border-color: rgba(0, 0, 0, 0.08);
}

.btn-card[disabled]:hover,
.btn-card.btn-card--disabled:hover,
.btn-card[aria-disabled="true"]:hover {
    transform: none;
    box-shadow: none;
    background: #F5F5F5;
}

/* Dark mode: the disabled CTA must flip off the hardcoded near-white surface so
   it does not render as a glaring white block (the Enter Amount / Enter Recipient
   states on the bridge card). These tokens flip with the theme; the XP
   strikethrough grammar from the base rule is retained, only its colors flip. */
[data-theme="dark"] .btn-card[disabled],
[data-theme="dark"] .btn-card.btn-card--disabled,
[data-theme="dark"] .btn-card[aria-disabled="true"] {
    background: var(--sw4p-bg-card-raised);
    color: var(--sw4p-text-faint);
    border-color: var(--sw4p-border-subtle);
    text-decoration-color: var(--sw4p-text-faint);
}

[data-theme="dark"] .btn-card[disabled]:hover,
[data-theme="dark"] .btn-card.btn-card--disabled:hover,
[data-theme="dark"] .btn-card[aria-disabled="true"]:hover {
    background: var(--sw4p-bg-card-raised);
}

@media (prefers-reduced-motion: reduce) {
    .btn-card,
    .btn-card:hover,
    .btn-card:active {
        transform: none;
        transition: background-color 0ms, box-shadow 0ms, border-color 0ms;
    }
}

/* ----- InputBox primitive ----- */
/* Faithful port of sw4p-console's `.xp-input` selector. XP 2002 text
   input grammar: thin 7F9DB9 border, Tahoma 11px, white fill, focus
   ring swaps the border to the titlebar accent (no outline). The
   `hasError` prop opts into a red-tinted danger surface that mirrors
   the original console pattern (`border-red-500 bg-red-50`). The
   class is namespaced `xp-input-box` to avoid colliding with the
   pre-existing `.xp-input` selector in sw4p-console/src/index.css. */

.xp-input-box {
    border: 1px solid #7F9DB9;
    padding: 4px 6px;
    font-family: Tahoma, 'Segoe UI', sans-serif;
    font-size: 11px;
    background: white;
    color: var(--xp-text-ink);
    box-sizing: border-box;
}

.xp-input-box:focus {
    outline: none;
    border-color: var(--xp-titlebar-flat);
}

.xp-input-box--error {
    border-color: #EF4444;
    background: #FEF2F2;
}

/* ----- Pill primitive ----- */
/* Base chip type, then per-variant sizing and color. The font-weight and
   font stack are kept in the base so callers can opt into a single variant
   without losing typography. */

.xp-pill {
    display: inline-block;
    font-weight: 700;
    font-family: 'Trebuchet MS', 'Tahoma', system-ui, sans-serif;
    letter-spacing: 0.01em;
}

.xp-pill--blue {
    padding: 4px 12px; font-size: 11px;
    background: var(--xp-pill-blue-bg);
    color: var(--xp-pill-blue-fg);
    border: 1px solid var(--xp-pill-blue-border);
}
.xp-pill--stack {
    padding: 2px 8px; font-size: 10px;
    background: var(--xp-pill-stack-bg);
    color: var(--xp-pill-stack-fg);
    border: 1px solid var(--xp-pill-stack-border);
}
.xp-pill--green {
    padding: 4px 12px; font-size: 11px;
    background: var(--xp-pill-green-bg);
    color: var(--xp-pill-green-fg);
    border: 1px solid var(--xp-pill-green-border);
}
.xp-pill--amber {
    padding: 4px 12px; font-size: 11px;
    background: var(--xp-pill-amber-bg);
    color: var(--xp-pill-amber-fg);
    border: 1px solid var(--xp-pill-amber-border);
}

/* ----- StatBox primitive ----- */
/* Labelled numeric tile used to surface a single stat (count, percent,
   etc.) above a caption. */

.xp-stat-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 8px;
    background: #EDF4FE;
    border: 1px solid var(--xp-border-card);
}

.xp-stat-box__value {
    font-size: 22px;
    font-weight: 700;
    color: var(--xp-titlebar-flat);
    font-family: 'Trebuchet MS', 'Tahoma', system-ui, sans-serif;
    letter-spacing: 0.01em;
}

.xp-stat-box__label {
    font-size: 10px;
    color: #444;
    text-align: center;
}

/* ----- FeatureCard primitive ----- */
/* Bordered XP-grammar content card with an optional header strip.
   Consolidates the inline `border border-[var(--xp-border-card)] +
   bg-white` markup landing previously hand-rolled. Two header tones
   match the existing landing variants: 'muted' (HowItWorks) and
   'titlebar' (Kit). The body is the caller's children rendered
   directly inside the outer container, with no implicit wrapper or
   padding, so the resulting DOM stays byte-identical to the previous
   inline markup. */

.xp-feature-card {
    background: #FFFFFF;
    border: 1px solid var(--xp-border-card);
}

.xp-feature-card__header {
    font-size: 10px;
    font-weight: 700;
    border-bottom: 1px solid var(--xp-border-card);
}

.xp-feature-card__header--muted {
    padding: 6px 12px;
    color: var(--xp-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: #F3F4F6;
}

.xp-feature-card__header--titlebar {
    padding: 4px 8px;
    color: var(--xp-titlebar-flat);
    background: #EDF4FE;
}

/* ----- SectionCard XP-grammar primitive (divided mode) ----- */
/* Pixel-faithful extraction of landing's hand-rolled
   `border border-[var(--xp-border-card)] + bg-white` `<dl>` wrappers in
   AboutSection / TrustSection / OverviewRoadmapSection. The `--divided`
   modifier draws a top stroke between immediate children, for callers
   that want the parent card to own row separators (vs each row drawing
   its own border-bottom). Used by SectionCard when `divided` is set; the
   pre-existing `variant`-style props are unchanged. */

.xp-section-card {
    background: #FFFFFF;
    border: 1px solid var(--xp-border-card);
}

.xp-section-card--divided > * + * {
    border-top: 1px solid var(--xp-border-card);
}

/* ----- StatusLed keyframes ----- */
/* Verbatim from sw4p-landing/src/styles/globals.css to preserve the live /
   building / horizon / inactive motion grammar that callers see today. */

@keyframes ledPulseLive {
    0%, 100% { box-shadow: 0 0 0 0 rgba(60, 141, 13, 0.6); }
    50%      { box-shadow: 0 0 0 4px rgba(60, 141, 13, 0); }
}

@keyframes ledSweep {
    0%   { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

@keyframes ledIdle {
    0%, 100% { opacity: 0.45; }
    50%      { opacity: 1; }
}

/* ----- Taskbar primitive ----- */
/* Hoisted from landing's LandingTaskbar.tsx so frontend and console share
   the same 32px chrome. Visual grammar: flat brand-blue background, 1px
   white-alpha top border, soft drop shadow, Tahoma stack. No gradients,
   no clip paths, no italic text, no heavy drop shadows. */

.xp-taskbar {
    left: 0;
    bottom: 0;
    width: 100%;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    z-index: 50;
    user-select: none;
    background: var(--xp-titlebar-flat);
    border-top: 1px solid rgba(255, 255, 255, 0.10);
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.10);
}

.xp-taskbar--fixed {
    position: fixed;
}

.xp-taskbar--absolute {
    position: absolute;
}

/* Start button */
.xp-taskbar__start {
    height: 26px;
    padding: 0 12px 0 8px;
    margin-left: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    background: #3C8D0D;
    border-radius: var(--btn-radius);
    border: none;
    color: #FFFFFF;
}

.xp-taskbar__start-logo {
    width: 18px;
    height: 18px;
    background: rgba(255, 255, 255, 0.95);
    border-radius: 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.xp-taskbar__start-mark {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    width: 10px;
    height: 10px;
}

.xp-taskbar__start-mark-cell[data-cell="tl"] { background: #F3622D; }
.xp-taskbar__start-mark-cell[data-cell="tr"] { background: #6BBC2B; }
.xp-taskbar__start-mark-cell[data-cell="bl"] { background: #2F83DA; }
.xp-taskbar__start-mark-cell[data-cell="br"] { background: #FDB900; }

.xp-taskbar__start-label {
    color: #FFFFFF;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 0.025em;
}

/* Middle items strip */
.xp-taskbar__items {
    flex: 1;
    display: flex;
    align-items: center;
    padding-left: 12px;
    gap: 6px;
    overflow: hidden;
}

/* Individual item tile (section nav button on landing, open-window tile
   on frontend and console). */
.xp-taskbar__item {
    height: 22px;
    display: flex;
    align-items: center;
    padding: 0 10px;
    gap: 6px;
    cursor: pointer;
    font-size: 11px;
    font-weight: 500;
    max-width: 160px;
    border-radius: var(--btn-radius);
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.05);
    color: rgba(255, 255, 255, 0.80);
    transition: background-color 140ms var(--ease-xp-out);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.xp-taskbar__item:hover {
    background: rgba(255, 255, 255, 0.12);
}

.xp-taskbar__item--active {
    background: rgba(255, 255, 255, 0.15);
    color: #FFFFFF;
}

/* System tray (right-hand cluster) */
.xp-taskbar__tray {
    height: 100%;
    display: flex;
    align-items: center;
    padding: 0 12px 0 16px;
    gap: 12px;
    background: rgba(0, 0, 0, 0.18);
    border-left: 1px solid rgba(255, 255, 255, 0.08);
    color: #FFFFFF;
}

/* ----- sw4p app shell surfaces ----- */
/* Frontend-only shell components use these shared selectors so theme changes
   stay token-driven across the desktop, Start menu, taskbar, and popovers. */

.sw4p-start-menu {
    border: 1px solid var(--xp-border-frame);
    border-bottom: none;
    background: var(--sw4p-bg-menu);
    box-shadow: var(--xp-shadow-window);
    color: var(--sw4p-text-primary);
}

.sw4p-start-menu__header {
    border-bottom: 1px solid oklch(100% 0 0 / 0.10);
    background: var(--xp-titlebar-flat);
}

.sw4p-start-menu__avatar {
    border-color: oklch(100% 0 0 / 0.40);
    background: var(--sw4p-bg-card);
}

.sw4p-start-menu__body {
    background: var(--xp-window-bg);
}

.sw4p-start-menu__footer {
    border-top: 1px solid oklch(100% 0 0 / 0.08);
    background: var(--xp-titlebar-flat-hover);
}

.sw4p-start-menu__footer-button {
    color: var(--sw4p-text-inverse);
}

.sw4p-start-menu__footer-button:hover {
    opacity: 0.85;
}

.sw4p-start-menu__item {
    color: var(--sw4p-text-primary);
}

.sw4p-start-menu__item:hover:not(:disabled),
.sw4p-start-menu__item:focus-visible:not(:disabled) {
    background: var(--xp-titlebar-flat);
    color: var(--sw4p-text-inverse);
}

.sw4p-start-menu__item:focus-visible {
    outline: 2px solid var(--sw4p-border-focus);
    outline-offset: -2px;
}

.sw4p-start-menu__item--disabled {
    color: var(--sw4p-text-faint);
    opacity: 0.55;
}

.sw4p-taskbar {
    border-top: 1px solid oklch(100% 0 0 / 0.12);
    background: var(--xp-titlebar-flat);
}

.sw4p-start-button {
    background: var(--sw4p-status-live);
    box-shadow: 0 1px 2px oklch(8% 0.02 250 / 0.22);
}

.sw4p-start-button__edge {
    pointer-events: none;
    border-right: 1px solid oklch(8% 0.02 250 / 0.20);
}

.sw4p-start-button__orb {
    background: var(--sw4p-bg-card);
}

.sw4p-start-button__label {
    color: var(--sw4p-text-inverse);
    text-shadow: 0 1px 0 oklch(8% 0.02 250 / 0.28);
}

.sw4p-taskbar__separator {
    background: oklch(8% 0.02 250 / 0.12);
    opacity: 0.55;
}

.sw4p-taskbar__window {
    border: 1px solid oklch(100% 0 0 / 0.18);
    color: oklch(100% 0 0 / 0.92);
}

.sw4p-taskbar__window--active {
    background: oklch(8% 0.02 250 / 0.24);
    color: var(--sw4p-text-inverse);
}

.sw4p-taskbar__window--inactive {
    background: oklch(100% 0 0 / 0.10);
}

.sw4p-taskbar__window--inactive:hover {
    background: oklch(100% 0 0 / 0.16);
}

.sw4p-taskbar__tray {
    border-left: 1px solid oklch(100% 0 0 / 0.15);
    background: var(--xp-titlebar-flat-hover);
}

.sw4p-theme-toggle {
    position: relative;
    display: inline-flex;
    width: 22px;
    height: 22px;
    min-width: 22px;
    align-items: center;
    justify-content: center;
    border: 1px solid oklch(100% 0 0 / 0.16);
    border-radius: var(--btn-radius);
    background: linear-gradient(180deg, oklch(100% 0 0 / 0.14), oklch(100% 0 0 / 0.03));
    box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.18);
    cursor: pointer;
    transition:
        background-color 140ms var(--ease-xp-out),
        border-color 140ms var(--ease-xp-out),
        transform 140ms var(--ease-xp-out);
}

.sw4p-theme-toggle:hover {
    border-color: oklch(100% 0 0 / 0.32);
    background: linear-gradient(180deg, oklch(100% 0 0 / 0.22), oklch(100% 0 0 / 0.08));
}

.sw4p-theme-toggle:active {
    transform: translateY(1px);
}

.sw4p-theme-toggle:focus-visible {
    outline: none;
    box-shadow:
        0 0 0 1px oklch(100% 0 0 / 0.8),
        0 0 0 3px oklch(59% 0.19 256 / 0.45),
        inset 0 1px 0 oklch(100% 0 0 / 0.18);
}

.sw4p-theme-toggle__orb {
    position: relative;
    width: 12px;
    height: 12px;
    border-radius: 999px;
    background: oklch(98% 0.004 250);
    box-shadow:
        0 0 0 1px oklch(0% 0 0 / 0.25),
        0 0 8px oklch(100% 0 0 / 0.5);
}

.sw4p-theme-toggle__cut {
    position: absolute;
    inset: 2px auto auto 5px;
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: var(--xp-titlebar-flat);
    opacity: 0;
    transition: opacity 140ms var(--ease-xp-out);
}

.sw4p-theme-toggle[data-theme-state="dark"] .sw4p-theme-toggle__orb {
    background: oklch(94% 0.04 94);
    box-shadow:
        0 0 0 1px oklch(0% 0 0 / 0.28),
        0 0 8px oklch(94% 0.04 94 / 0.52);
}

.sw4p-theme-toggle[data-theme-state="dark"] .sw4p-theme-toggle__cut {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .sw4p-theme-toggle,
    .sw4p-theme-toggle__cut {
        transition: none;
    }
}

.sw4p-taskbar__clock {
    color: var(--sw4p-text-inverse);
}

.sw4p-desktop-icon:hover:not(.sw4p-desktop-icon--disabled) {
    background: oklch(100% 0 0 / 0.10);
}

.sw4p-desktop-icon--selected {
    border-color: var(--sw4p-border-focus);
    background: color-mix(in oklch, var(--sw4p-border-focus) 36%, transparent);
}

.sw4p-desktop-icon--disabled {
    opacity: 0.42;
    filter: grayscale(1);
}

.sw4p-desktop-icon__label {
    text-shadow: 0 1px 1px oklch(8% 0.02 250 / 0.92);
}

.sw4p-desktop-icon__label--selected {
    background: var(--sw4p-border-focus);
    color: var(--sw4p-text-inverse);
    text-shadow: none;
}

.sw4p-xp-select__trigger,
.sw4p-xp-select__menu,
.sw4p-settings-cog,
.sw4p-settings-menu,
.sw4p-app-header {
    border-color: var(--xp-border-card);
    background: var(--sw4p-bg-card);
    color: var(--sw4p-text-primary);
}

.sw4p-xp-select__trigger {
    border: 1px solid var(--xp-border-card);
}

.sw4p-xp-select__trigger:hover,
.sw4p-settings-cog:hover {
    border-color: var(--sw4p-border-focus);
}

.sw4p-xp-select__menu,
.sw4p-settings-menu {
    border: 1px solid var(--xp-border-card);
    box-shadow: var(--xp-shadow-window);
}

.sw4p-xp-select__option:hover,
.sw4p-xp-select__option:focus-visible {
    background: var(--xp-titlebar-flat);
    color: var(--sw4p-text-inverse);
}

.sw4p-xp-select__option--disabled {
    background: color-mix(in oklch, var(--sw4p-bg-card-raised) 70%, var(--sw4p-bg-window));
    color: var(--sw4p-text-faint);
    opacity: 0.70;
}

.sw4p-xp-select__badge,
.sw4p-asset-menu__badge {
    background: color-mix(in oklch, var(--sw4p-status-warning) 28%, var(--sw4p-bg-card));
    color: var(--sw4p-text-primary);
}

.sw4p-app-header {
    border-bottom: 1px solid var(--xp-border-card);
    background: var(--sw4p-bg-card);
}

.sw4p-base-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-width: 0;
    border: 1px solid var(--sw4p-border-subtle);
    border-radius: 5px;
    background: var(--sw4p-bg-card-raised);
    color: var(--sw4p-text-primary);
    font-family: var(--sw4p-font-ui);
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    transition:
        border-color var(--sw4p-motion-fast, 120ms) var(--ease-xp-out),
        background var(--sw4p-motion-fast, 120ms) var(--ease-xp-out),
        box-shadow var(--sw4p-motion-fast, 120ms) var(--ease-xp-out),
        transform var(--sw4p-motion-fast, 120ms) var(--ease-xp-out);
}

.sw4p-base-button:hover {
    border-color: var(--sw4p-border-focus);
}

.sw4p-base-button:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px color-mix(in oklch, var(--sw4p-border-focus) 42%, transparent);
}

.sw4p-base-button:active {
    transform: scale(0.985);
}

.sw4p-base-button:disabled,
.sw4p-base-button[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.58;
    transform: none;
}

.sw4p-base-button--sm {
    min-height: 30px;
    padding: 0 9px;
    font-size: 11px;
}

.sw4p-base-button--md {
    min-height: 36px;
    padding: 0 12px;
    font-size: 12px;
}

.sw4p-base-button--lg {
    min-height: 44px;
    padding: 0 14px;
    font-size: 13px;
}

.sw4p-base-button--primary {
    border-color: var(--sw4p-bg-titlebar-active);
    background: var(--sw4p-action-primary);
    color: var(--sw4p-text-inverse);
}

.sw4p-base-button--ghost {
    border-color: transparent;
    background: transparent;
    box-shadow: none;
}

.sw4p-base-button--selector {
    align-items: stretch;
    justify-content: stretch;
    padding: 0;
    overflow: hidden;
    background:
        linear-gradient(180deg, color-mix(in oklch, var(--sw4p-bg-card-raised) 92%, white 8%), var(--sw4p-bg-card-raised));
    box-shadow:
        inset 0 1px 0 oklch(100% 0 0 / 0.55),
        0 1px 2px oklch(24% 0.04 250 / 0.08);
}

[data-theme="dark"] .sw4p-base-button--selector {
    background:
        linear-gradient(180deg, color-mix(in oklch, var(--sw4p-bg-card-raised) 88%, white 5%), var(--sw4p-bg-card-raised));
    box-shadow:
        inset 0 1px 0 oklch(100% 0 0 / 0.08),
        0 1px 2px oklch(8% 0.02 250 / 0.30);
}

.sw4p-base-button--menu-item {
    justify-content: flex-start;
    width: 100%;
    min-height: 38px;
    border-color: transparent;
    background: transparent;
    box-shadow: none;
    padding: 7px 8px;
    text-align: left;
}

.sw4p-base-button--menu-item:hover,
.sw4p-base-button--menu-item:focus-visible,
.sw4p-base-button--menu-item[data-active="true"] {
    background: var(--sw4p-action-subtle-bg);
    border-color: color-mix(in oklch, var(--sw4p-border-focus) 35%, transparent);
}

.sw4p-asset-menu {
    background: var(--sw4p-bg-menu);
    color: var(--sw4p-text-primary);
}

.sw4p-asset-menu-shell {
    display: grid;
    gap: 6px;
    overflow: hidden;
    border: 1px solid var(--sw4p-border-subtle);
    border-radius: 6px;
    background: var(--sw4p-bg-card);
    box-shadow: var(--sw4p-shadow-window);
    padding: 7px;
}

.sw4p-asset-menu-shell__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-width: 0;
    border-bottom: 1px solid var(--sw4p-border-subtle);
    padding: 0 1px 5px;
}

.sw4p-asset-menu-shell__copy {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.sw4p-asset-menu-shell__eyebrow {
    color: var(--sw4p-text-muted);
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.12em;
    line-height: 1;
    text-transform: uppercase;
}

.sw4p-asset-menu-shell__title {
    color: var(--sw4p-text-primary);
    font-size: 12px;
    font-weight: 800;
    line-height: 1.15;
}

.sw4p-asset-menu-shell__body {
    min-width: 0;
    min-height: 0;
}

.sw4p-asset-menu-shell__empty {
    display: grid;
    gap: 4px;
    min-height: 66px;
    align-content: center;
    border: 1px solid var(--sw4p-border-subtle);
    border-radius: 4px;
    background: color-mix(in oklch, var(--sw4p-bg-card-raised) 76%, var(--sw4p-bg-card) 24%);
    color: var(--sw4p-text-secondary);
    padding: 12px 14px;
}

.sw4p-asset-menu-shell__empty strong {
    color: var(--sw4p-text-primary);
    font-size: 12px;
    font-weight: 800;
    line-height: 1.15;
}

.sw4p-asset-menu-shell__empty span {
    color: var(--sw4p-text-muted);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.35;
}

.sw4p-asset-menu-shell__columns {
    display: flex;
    align-items: flex-start;
    gap: 5px;
    min-width: 0;
}

.sw4p-price-info-card {
    border: 1px solid var(--sw4p-border-subtle);
    background: var(--sw4p-bg-card);
    box-shadow: var(--xp-shadow-window);
}

/* ----- Drawer / Sheet primitive ----- */
/* The canonical disclosure-overlay chrome behind the <Drawer> component.
   Behavior (backdrop, focus-trap, Escape, focus-return, portal, role/aria)
   lives in Drawer.tsx; this file owns the visual grammar: side/bottom
   placement, the 220ms (--sw4p-motion-medium) panel motion, the flattened-
   modern bevel, env(safe-area-inset-bottom) for the bottom sheet, and the
   44px close target. Only canon tokens (tokens.css) are referenced; no
   invented values. Consumers may layer a surface-specific skin class
   (e.g. .sw4p-history-sheet) over .sw4p-drawer to reuse existing CSS while
   this primitive owns the behavior. */

.sw4p-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 10060;
    display: flex;
    background: color-mix(in oklch, var(--sw4p-bg-desktop) 22%, transparent);
    padding: 0;
}

/* Side placement of the panel within the backdrop. */
.sw4p-drawer-backdrop--right {
    align-items: stretch;
    justify-content: flex-end;
}

.sw4p-drawer-backdrop--left {
    align-items: stretch;
    justify-content: flex-start;
}

.sw4p-drawer-backdrop--bottom {
    align-items: flex-end;
    justify-content: center;
    padding: 0 0 env(safe-area-inset-bottom, 0);
}

.sw4p-drawer {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--sw4p-bg-card);
    color: var(--sw4p-text-primary);
    border: 1px solid var(--sw4p-border-subtle);
    box-shadow: var(--sw4p-shadow-window);
    outline: none;
}

/* Right/left side drawer: full-height, clamped readable width (~40vw), the
   canonical small radius on the inner corners only, soft inset highlight. */
.sw4p-drawer--right,
.sw4p-drawer--left {
    width: clamp(360px, 40vw, 560px);
    max-width: 100%;
    height: 100dvh;
}

.sw4p-drawer--right {
    border-right: 0;
    border-radius: 6px 0 0 6px;
    box-shadow:
        -24px 0 44px color-mix(in oklch, var(--sw4p-bg-desktop) 30%, transparent),
        inset 1px 0 0 color-mix(in oklch, white 18%, transparent);
    animation: sw4pDrawerEnterRight var(--sw4p-motion-medium) var(--sw4p-ease-out);
}

.sw4p-drawer--left {
    border-left: 0;
    border-radius: 0 6px 6px 0;
    box-shadow:
        24px 0 44px color-mix(in oklch, var(--sw4p-bg-desktop) 30%, transparent),
        inset -1px 0 0 color-mix(in oklch, white 18%, transparent);
    animation: sw4pDrawerEnterLeft var(--sw4p-motion-medium) var(--sw4p-ease-out);
}

/* Bottom sheet (mobile): docked to the bottom edge, full width, capped
   height, rounded top corners, safe-area padding handled on the backdrop. */
.sw4p-drawer--bottom {
    width: 100%;
    max-height: min(76dvh, 620px);
    border-bottom: 0;
    border-radius: 6px 6px 0 0;
    box-shadow:
        0 -18px 44px color-mix(in oklch, var(--sw4p-bg-desktop) 30%, transparent),
        inset 0 1px 0 color-mix(in oklch, white 18%, transparent);
    animation: sw4pDrawerEnterBottom var(--sw4p-motion-medium) var(--sw4p-ease-out);
}

/* Grab-handle "eyebrow" for bottom sheets (canon: the founder's .dwgrab). A
   centered pill at the top edge that signals the sheet is draggable/dismissable.
   The element renders on every drawer but is hidden until the panel is actually
   a bottom sheet: shown for an explicit side="bottom", and for the responsive
   surface skins (e.g. .sw4p-history-sheet) at mobile width via their own media
   query. Desktop side drawers keep it hidden. */
.sw4p-drawer__grab {
    display: none;
    flex-shrink: 0;
    /* Enlarged drag target: the whole top strip (the "eyebrow" area) is
       draggable-to-dismiss, not just the 40x5 pill. The visible pill is drawn
       centered via ::before. touch-action:none so the vertical drag dismisses
       the sheet instead of scrolling the page. */
    position: relative;
    width: 100%;
    height: 28px;
    margin: 0;
    touch-action: none;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
}

.sw4p-drawer__grab::before {
    content: '';
    position: absolute;
    top: 9px;
    left: 50%;
    transform: translateX(-50%);
    width: 40px;
    height: 5px;
    border-radius: 3px;
    background: var(--sw4p-border-subtle);
}

.sw4p-drawer__grab:active {
    cursor: grabbing;
}

.sw4p-drawer--bottom > .sw4p-drawer__grab {
    display: block;
}

/* Optional built-in header strip (showHeader). Mirrors the disclosure-sheet
   header grammar so a Drawer without a custom header still matches canon. */
.sw4p-drawer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-shrink: 0;
    border-bottom: 1px solid var(--sw4p-border-subtle);
    padding: 12px;
}

.sw4p-drawer__title {
    color: var(--sw4p-text-primary);
    font-family: var(--sw4p-font-body);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.2;
    min-width: 0;
}

.sw4p-drawer__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px minimum tap target (root DESIGN.md accessibility rule). */
    width: 44px;
    min-width: 44px;
    height: 44px;
    min-height: 44px;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--xp-close-red);
    cursor: pointer;
    padding: 0;
    transition: background-color var(--sw4p-motion-fast) var(--sw4p-ease-out);
}

.sw4p-drawer__close:hover {
    background: color-mix(in oklch, var(--xp-close-red) 12%, transparent);
}

.sw4p-drawer__close:focus-visible {
    outline: 2px solid var(--sw4p-border-focus);
    outline-offset: 1px;
}

.sw4p-drawer__close-icon {
    display: block;
    width: 14px;
    height: 14px;
}

@keyframes sw4pDrawerEnterRight {
    from { opacity: 0; transform: translateX(16px); }
    to   { opacity: 1; transform: translateX(0);    }
}

@keyframes sw4pDrawerEnterLeft {
    from { opacity: 0; transform: translateX(-16px); }
    to   { opacity: 1; transform: translateX(0);     }
}

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

/* Respect prefers-reduced-motion: keep the open/close as an instant state
   change (the canon requires every motion rule to carry this guard). */
@media (prefers-reduced-motion: reduce) {
    .sw4p-drawer--right,
    .sw4p-drawer--left,
    .sw4p-drawer--bottom {
        animation: none;
    }

    .sw4p-drawer__close {
        transition: none;
    }
}
