@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/space-grotesk-500.woff2') format('woff2');}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/space-grotesk-600.woff2') format('woff2');}
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/space-grotesk-700.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:400;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/hanken-grotesk-400.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:500;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/hanken-grotesk-500.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:600;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/hanken-grotesk-600.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:700;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/hanken-grotesk-700.woff2') format('woff2');}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;src:url('https://app.whooshly.co/assets/fonts/space-mono-400.woff2') format('woff2');}
/* ============================================================
   Whooshly — Color tokens
   Base ramps + shadcn/ui semantic aliases (light + dark)
   ============================================================ */
:root {
  /* ---- Brand: Whoosh Violet (primary) ---- */
  --violet-50:#F1ECFE; --violet-100:#E5DBFD; --violet-200:#CDB9FB;
  --violet-300:#AD8DF8; --violet-400:#8A5DF4; --violet-500:#5B33F0;
  --violet-600:#4D1FE0; --violet-700:#3F16BD; --violet-800:#341499;
  --violet-900:#2A1378; --violet-950:#1A0B4D;

  /* ---- Brand: Coral Pop (signature accent / spark) ---- */
  --coral-50:#FFF0F2; --coral-100:#FFE1E5; --coral-200:#FFC7CF;
  --coral-300:#FFA0AD; --coral-400:#FF7888; --coral-500:#FF5C72;
  --coral-600:#F23355; --coral-700:#C9203F; --coral-800:#A11C36;
  --coral-900:#821B31; --coral-950:#470A17;

  /* ---- Velocity Cyan (gradient tail only — not a standalone UI color) ---- */
  --cyan-300:#7DEAF2; --cyan-400:#3FDDEA; --cyan-500:#16D8E6; --cyan-600:#0FAEBC;

  /* ---- Cool neutrals (violet-tinted slate) ---- */
  --n-0:#FFFFFF; --n-25:#FBFBFE; --n-50:#F6F6FB; --n-100:#EEEEF5;
  --n-200:#E2E2EC; --n-300:#CBCBD9; --n-400:#9D9DB2; --n-500:#6E6E86;
  --n-600:#52526A; --n-700:#3C3C50; --n-800:#26263A; --n-900:#181826;
  --n-950:#0E0E1A;

  /* ---- Semantic hues ---- */
  --success:#12B981; --success-fg:#FFFFFF; --success-soft:#D8F7EC; --success-ink:#0A7A52;
  --warning:#F5A524; --warning-fg:#3C2A00; --warning-soft:#FDEFD2; --warning-ink:#9A6500;
  --error:#E11D48;   --error-fg:#FFFFFF;   --error-soft:#FCE2E8;   --error-ink:#A1102F;
  --info:#3B82F6;    --info-fg:#FFFFFF;    --info-soft:#DBE9FE;    --info-ink:#1D4FB8;

  /* ---- Signature whoosh gradient: cool→warm, left-to-right momentum ---- */
  --whoosh:linear-gradient(100deg, #5B33F0 0%, #8A39E8 38%, #DA3B86 72%, #FF5C72 100%); /* @kind color */
  --whoosh-soft:linear-gradient(100deg, #F1ECFE 0%, #F7E9FB 50%, #FFE1E5 100%); /* @kind color */
  --whoosh-cool:linear-gradient(100deg, #5B33F0 0%, #5E5BF4 55%, #16D8E6 100%); /* @kind color */

  /* =========================================================
     shadcn/ui semantic aliases — LIGHT (default)
     ========================================================= */
  --background:var(--n-25);
  --foreground:var(--n-900);
  --card:var(--n-0);
  --card-foreground:var(--n-900);
  --popover:var(--n-0);
  --popover-foreground:var(--n-900);

  --primary:var(--violet-500);
  --primary-foreground:#FFFFFF;
  --primary-hover:var(--violet-600);
  --primary-active:var(--violet-700);

  --secondary:var(--n-100);
  --secondary-foreground:var(--n-800);

  --accent:var(--coral-500);
  --accent-foreground:#FFFFFF;
  --accent-ink:var(--coral-700);
  --accent-soft:var(--coral-100);

  --muted:var(--n-100);
  --muted-foreground:var(--n-500);

  --destructive:var(--error);
  --destructive-foreground:#FFFFFF;

  --border:var(--n-200);
  --input:var(--n-200);
  --ring:var(--violet-500);

  /* surfaces & elevation tints */
  --surface-sunken:var(--n-50);
  --surface-raised:var(--n-0);
  --surface-overlay:rgba(14,14,26,.45);
}

/* =========================================================
   shadcn/ui semantic aliases — DARK
   Applied via .dark class OR system preference.
   ========================================================= */
.dark {
  --background:var(--n-950);
  --foreground:var(--n-50);
  --card:var(--n-900);
  --card-foreground:var(--n-50);
  --popover:#1C1C2C;
  --popover-foreground:var(--n-50);

  --primary:var(--violet-500);
  --primary-foreground:#FFFFFF;
  --primary-hover:var(--violet-400);
  --primary-active:var(--violet-300);

  --secondary:#22223200;
  --secondary:#23233A;
  --secondary-foreground:var(--n-100);

  --accent:var(--coral-500);
  --accent-foreground:#2A0A11;
  --accent-ink:var(--coral-300);
  --accent-soft:rgba(255,92,114,.16);

  --muted:#1E1E2E;
  --muted-foreground:var(--n-400);

  --destructive:#F4365A;
  --destructive-foreground:#FFFFFF;

  --border:#2C2C40;
  --input:#2C2C40;
  --ring:var(--violet-400);

  --success-soft:rgba(18,185,129,.16); --success-ink:#3FDFA3;
  --warning-soft:rgba(245,165,36,.16); --warning-ink:#F7BE5C;
  --error-soft:rgba(225,29,72,.18);    --error-ink:#FF8DA3;
  --info-soft:rgba(59,130,246,.18);    --info-ink:#86B2FB;

  --surface-sunken:var(--n-950);
  --surface-raised:var(--n-900);
  --surface-overlay:rgba(0,0,0,.6);
}

/* ============================================================
   Whooshly — Typography tokens
   Display = Space Grotesk (momentum). Body/UI = Hanken Grotesk
   (warm, legible). Mono = Space Mono (link strings ONLY).
   ============================================================ */
:root {
  /* ---- Families ---- */
  --font-display:'Space Grotesk', ui-sans-serif, system-ui, sans-serif; /* @kind font */
  --font-sans:'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, sans-serif; /* @kind font */
  --font-mono:'Space Mono', ui-monospace, 'SF Mono', Menlo, monospace; /* @kind font */

  /* ---- Weights ---- */
  --fw-regular:400; /* @kind font */
  --fw-medium:500; /* @kind font */
  --fw-semibold:600; /* @kind font */
  --fw-bold:700; /* @kind font */
  --fw-black:800; /* @kind font */

  /* ---- Type scale (px) — fluid where it matters ---- */
  --fs-display:clamp(44px, 6vw, 76px); /* @kind font */
  --fs-h1:clamp(34px, 4vw, 48px); /* @kind font */
  --fs-h2:clamp(26px, 3vw, 32px); /* @kind font */
  --fs-h3:24px; /* @kind font */
  --fs-h4:20px; /* @kind font */
  --fs-lg:18px; /* @kind font */
  --fs-body:16px; /* @kind font */
  --fs-sm:14px; /* @kind font */
  --fs-xs:12px; /* @kind font */
  --fs-caption:11px; /* @kind font */

  /* ---- Line heights ---- */
  --lh-tight:1.05; /* @kind font */
  --lh-snug:1.2; /* @kind font */
  --lh-normal:1.55; /* @kind font */
  --lh-relaxed:1.7; /* @kind font */

  /* ---- Letter spacing ---- */
  --ls-display:-0.035em; /* @kind font */
  --ls-heading:-0.02em; /* @kind font */
  --ls-normal:0; /* @kind font */
  --ls-wide:0.05em; /* @kind font */
  --ls-caps:0.16em; /* @kind font */
}

/* ============================================================
   Whooshly — Spacing, radius & layout tokens
   4px base unit. Radii lean gently rounded (friendly-fast).
   ============================================================ */
:root {
  /* ---- Spacing scale (4px base) ---- */
  --sp-0:0; /* @kind spacing */
  --sp-1:4px;   --sp-2:8px;   --sp-3:12px;  --sp-4:16px;
  --sp-5:20px;   --sp-6:24px;  --sp-8:32px;  --sp-10:40px; --sp-12:48px;
  --sp-14:56px;  --sp-16:64px; --sp-20:80px; --sp-24:96px; --sp-32:128px;

  /* ---- Radius ---- */
  --r-sm:6px;    --r-md:10px;  --r-lg:14px;  --r-xl:20px;
  --r-2xl:28px;  --r-full:999px;
  --radius:var(--r-md);   /* shadcn default alias */

  /* ---- Borders ---- */
  --bw-hair:1px; --bw-1:1px; --bw-2:1.5px; --bw-3:2px;

  /* ---- Layout / containers ---- */
  --container-sm:640px; --container-md:768px; --container-lg:1024px;
  --container-xl:1200px; --container-2xl:1320px;
  --gutter:24px;
  --sidebar-w:260px; --topbar-h:64px;

  /* ---- Min touch target (a11y) ---- */
  --touch-min:44px;
}

/* ============================================================
   Whooshly — Elevation
   Soft, layered, violet-tinted shadows. Light, never heavy —
   "air" with just enough lift to feel like arrival.
   ============================================================ */
:root {
  --sh-xs:0 1px 1px rgba(26,11,77,.04);
  --sh-sm:0 1px 2px rgba(26,11,77,.06), 0 1px 1px rgba(26,11,77,.04);
  --sh-md:0 4px 12px -2px rgba(26,11,77,.10), 0 2px 6px -2px rgba(26,11,77,.06);
  --sh-lg:0 16px 40px -8px rgba(26,11,77,.16), 0 6px 14px -6px rgba(26,11,77,.08);
  --sh-xl:0 28px 64px -12px rgba(26,11,77,.22), 0 10px 24px -10px rgba(26,11,77,.10);

  /* coloured glows — for primary CTA + coral spark moments */
  --sh-glow:0 8px 30px -6px rgba(91,51,240,.42);
  --sh-glow-coral:0 8px 30px -6px rgba(255,92,114,.45);

  /* focus ring (paired with --ring colour) */
  --ring-w:3px; /* @kind other */
  --ring-offset:2px; /* @kind other */
}

.dark {
  --sh-xs:0 1px 1px rgba(0,0,0,.4);
  --sh-sm:0 1px 2px rgba(0,0,0,.5), 0 1px 1px rgba(0,0,0,.35);
  --sh-md:0 4px 14px -2px rgba(0,0,0,.55), 0 2px 6px -2px rgba(0,0,0,.4);
  --sh-lg:0 18px 44px -8px rgba(0,0,0,.62), 0 6px 14px -6px rgba(0,0,0,.45);
  --sh-xl:0 30px 70px -12px rgba(0,0,0,.7), 0 12px 26px -10px rgba(0,0,0,.5);
  --sh-glow:0 8px 32px -4px rgba(123,82,255,.5);
  --sh-glow-coral:0 8px 32px -4px rgba(255,92,114,.5);
}

/* ============================================================
   Whooshly — Motion tokens (THE BRAND)
   Motion is defined as rigorously as colour. The signature
   "whoosh" ease accelerates away then decelerates on arrival.
   Everything below respects prefers-reduced-motion.
   ============================================================ */
:root {
  /* ---- Easing curves ---- */
  --ease-whoosh:cubic-bezier(.45, 0, .10, 1); /* @kind other */
  --ease-arrive:cubic-bezier(.16, 1, .3, 1); /* @kind other */
  --ease-spring:cubic-bezier(.34, 1.56, .64, 1); /* @kind other */
  --ease-standard:cubic-bezier(.4, 0, .2, 1); /* @kind other */
  --ease-in:cubic-bezier(.4, 0, 1, 1); /* @kind other */
  --ease-out:cubic-bezier(0, 0, .2, 1); /* @kind other */

  /* ---- Duration scale ---- */
  --d-instant:100ms; /* @kind other */
  --d-fast:150ms; /* @kind other */
  --d-base:250ms; /* @kind other */
  --d-slow:400ms; /* @kind other */
  --d-slower:600ms; /* @kind other */

  /* ---- Named transition shorthands ---- */
  --t-button:transform var(--d-fast) var(--ease-spring), box-shadow var(--d-base) var(--ease-whoosh), background-color var(--d-fast) var(--ease-standard); /* @kind other */
  --t-lift:transform var(--d-base) var(--ease-whoosh), box-shadow var(--d-base) var(--ease-whoosh); /* @kind other */
  --t-fade:opacity var(--d-base) var(--ease-standard); /* @kind other */
  --t-colors:color var(--d-fast) var(--ease-standard), background-color var(--d-fast) var(--ease-standard), border-color var(--d-fast) var(--ease-standard); /* @kind other */
}

/* ===== Keyframes ===== */
@keyframes wsh-whoosh-in   { from { opacity:0; transform:translateX(-28px); } to { opacity:1; transform:none; } }
@keyframes wsh-whoosh-up   { from { opacity:0; transform:translateY(16px) scale(.96); } to { opacity:1; transform:none; } }
@keyframes wsh-reveal      { from { opacity:0; transform:translateY(18px) scale(.92); } to { opacity:1; transform:none; } }
@keyframes wsh-toast-in    { from { opacity:0; transform:translateX(40px); } to { opacity:1; transform:none; } }
@keyframes wsh-fade-in     { from { opacity:0; } to { opacity:1; } }
@keyframes wsh-pop         { 0%{transform:scale(.8);opacity:0;} 60%{transform:scale(1.05);} 100%{transform:scale(1);opacity:1;} }
@keyframes wsh-streak      { 0%{transform:translateX(-110%);} 55%{transform:translateX(120%);} 100%{transform:translateX(120%);} }
@keyframes wsh-sheen       { 0%{left:-30%;} 60%{left:120%;} 100%{left:120%;} }
@keyframes wsh-loader      { 0%{left:-45%;} 100%{left:105%;} }
@keyframes wsh-pulse       { 0%{box-shadow:0 0 0 0 rgba(18,185,129,.5);} 70%{box-shadow:0 0 0 7px rgba(18,185,129,0);} 100%{box-shadow:0 0 0 0 rgba(18,185,129,0);} }
@keyframes wsh-spin        { to { transform:rotate(360deg); } }
@keyframes wsh-check       { from { stroke-dashoffset:24; } to { stroke-dashoffset:0; } }
@keyframes wsh-shimmer     { 0%{background-position:-200% 0;} 100%{background-position:200% 0;} }

/* ===== Utility classes ===== */
.wsh-anim-whoosh-in { animation:wsh-whoosh-in var(--d-base) var(--ease-whoosh); }
.wsh-anim-whoosh-up { animation:wsh-whoosh-up var(--d-base) var(--ease-arrive); }
.wsh-anim-reveal    { animation:wsh-reveal var(--d-slower) var(--ease-arrive); }
.wsh-anim-toast-in  { animation:wsh-toast-in var(--d-base) var(--ease-whoosh); }
.wsh-anim-fade-in   { animation:wsh-fade-in var(--d-base) var(--ease-standard); }
.wsh-anim-pop       { animation:wsh-pop var(--d-base) var(--ease-spring); }
.wsh-spin           { animation:wsh-spin 800ms linear infinite; }

/* Reduced-motion: disable non-essential motion, keep instant fades */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* ============================================================
   Whooshly — Base layer
   Element resets + brand defaults built on the tokens.
   ============================================================ */
*, *::before, *::after { box-sizing:border-box; }

html { scroll-behavior:smooth; -webkit-text-size-adjust:100%; }

body {
  margin:0;
  font-family:var(--font-sans);
  font-size:var(--fs-body);
  line-height:var(--lh-normal);
  color:var(--foreground);
  background-color:var(--background);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

h1,h2,h3,h4,h5 {
  font-family:var(--font-display);
  font-weight:var(--fw-semibold);
  letter-spacing:var(--ls-heading);
  line-height:var(--lh-snug);
  margin:0;
  color:var(--foreground);
  text-wrap:balance;
}

p { margin:0; text-wrap:pretty; }

a { color:var(--primary); text-decoration:none; }
a:not([class]):hover { text-decoration:underline; }

code, kbd, samp { font-family:var(--font-mono); }

::selection { background:var(--coral-200); color:var(--violet-950); }

/* Brand utility helpers */
.wsh-display   { font-family:var(--font-display); font-weight:var(--fw-bold); letter-spacing:var(--ls-display); line-height:var(--lh-tight); }
.wsh-mono      { font-family:var(--font-mono); }
.wsh-eyebrow   { font-family:var(--font-mono); font-size:var(--fs-xs); letter-spacing:var(--ls-caps); text-transform:uppercase; color:var(--muted-foreground); }
/* Gradient-on-type is deprecated: type stays flat near-black for confidence.
   Gradient is reserved for full-bleed art panels (hero washes, closing CTA,
   sign-in brand panel) — never headlines. Class kept for back-compat. */
.wsh-gradient-text {
  color:var(--foreground);
}
.wsh-gradient-bg { background:var(--whoosh); }

/* Whoosh streak motif — a directional speed line */
.wsh-streak { position:relative; height:3px; border-radius:var(--r-full); background:var(--whoosh); overflow:hidden; }
.wsh-streak::after {
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.85), transparent);
  transform:translateX(-100%); animation:wsh-streak 2.2s var(--ease-whoosh) infinite;
}

/* Accessible focus ring — paired with --ring */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline:none;
  box-shadow:0 0 0 var(--ring-offset) var(--background), 0 0 0 calc(var(--ring-offset) + var(--ring-w)) var(--ring);
  border-radius:var(--r-sm);
}

/* Shimmer surface for skeletons */
.wsh-shimmer {
  background:linear-gradient(90deg, var(--muted) 25%, color-mix(in srgb, var(--muted) 60%, var(--card)) 50%, var(--muted) 75%);
  background-size:200% 100%;
  animation:wsh-shimmer 1.4s linear infinite;
}

/* ============================================================
   Whooshly — component styles (.wsh-*)
   Extracted VERBATIM from the design-system component source
   (the `const CSS` blocks that each .jsx used to self-inject).
   No values were rounded, cleaned, or re-derived; every rule still
   reads the token vars (var(--…)) so it stays theme- and dark-mode-aware.
   Source of truth: .claude/skills/whooshly-design/whooshly-design-system/components/
   ============================================================ */

/* ===== Button  ·  components/forms/Button.jsx ===== */
.wsh-btn{
  --_h:40px; --_px:18px; --_fs:15px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--font-display); font-weight:600; font-size:var(--_fs);
  height:var(--_h); min-height:var(--_h); padding:0 var(--_px);
  border-radius:var(--r-md); border:1px solid transparent; cursor:pointer;
  white-space:nowrap; text-decoration:none; line-height:1; position:relative; isolation:isolate;
  transition:var(--t-button);
}
.wsh-btn:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }
.wsh-btn:disabled,.wsh-btn[aria-disabled="true"]{ opacity:.5; cursor:not-allowed; box-shadow:none !important; transform:none !important; }
.wsh-btn--sm{ --_h:32px; --_px:13px; --_fs:13px; }
.wsh-btn--lg{ --_h:48px; --_px:24px; --_fs:17px; }
.wsh-btn--block{ width:100%; }

.wsh-btn--primary{ background:var(--primary); color:var(--primary-foreground); box-shadow:var(--sh-glow); }
.wsh-btn--primary:hover:not(:disabled){ background:var(--primary-hover); transform:translateY(-2px); box-shadow:0 12px 34px -8px rgba(91,51,240,.5); }
.wsh-btn--primary:active:not(:disabled){ transform:scale(.96); background:var(--primary-active); }

.wsh-btn--accent{ background:var(--accent); color:#fff; box-shadow:var(--sh-glow-coral); }
.wsh-btn--accent:hover:not(:disabled){ background:var(--coral-600); transform:translateY(-2px); }
.wsh-btn--accent:active:not(:disabled){ transform:scale(.96); }

.wsh-btn--secondary{ background:var(--card); color:var(--secondary-foreground); border-color:var(--border); box-shadow:var(--sh-xs); }
.wsh-btn--secondary:hover:not(:disabled){ background:var(--muted); transform:translateY(-1px); box-shadow:var(--sh-sm); }
.wsh-btn--secondary:active:not(:disabled){ transform:scale(.97); }

.wsh-btn--ghost{ background:transparent; color:var(--foreground); }
.wsh-btn--ghost:hover:not(:disabled){ background:var(--muted); }
.wsh-btn--ghost:active:not(:disabled){ transform:scale(.97); }

.wsh-btn--destructive{ background:var(--destructive); color:var(--destructive-foreground); }
.wsh-btn--destructive:hover:not(:disabled){ filter:brightness(1.06); transform:translateY(-1px); }
.wsh-btn--destructive:active:not(:disabled){ transform:scale(.96); }

.wsh-btn.is-loading{ color:transparent !important; pointer-events:none; }
.wsh-btn__spin{ position:absolute; inset:0; margin:auto; width:18px; height:18px; border-radius:50%;
  border:2px solid currentColor; border-top-color:transparent; color:inherit; opacity:.9; }
.wsh-btn--primary.is-loading .wsh-btn__spin,.wsh-btn--accent.is-loading .wsh-btn__spin,.wsh-btn--destructive.is-loading .wsh-btn__spin{ border-color:#fff; border-top-color:transparent; }
@media (prefers-reduced-motion: no-preference){ .wsh-btn.is-loading .wsh-btn__spin{ animation:wsh-spin .8s linear infinite; } }
.wsh-btn svg{ width:1.15em; height:1.15em; flex-shrink:0; }

/* ===== IconButton  ·  components/forms/IconButton.jsx ===== */
.wsh-iconbtn{
  --_s:40px;
  display:inline-flex; align-items:center; justify-content:center;
  width:var(--_s); height:var(--_s); border-radius:var(--r-md);
  border:1px solid transparent; cursor:pointer; color:var(--foreground);
  background:transparent; transition:var(--t-button); position:relative;
}
.wsh-iconbtn svg{ width:20px; height:20px; }
.wsh-iconbtn--sm{ --_s:32px; } .wsh-iconbtn--sm svg{ width:17px; height:17px; }
.wsh-iconbtn--lg{ --_s:48px; } .wsh-iconbtn--lg svg{ width:22px; height:22px; }
.wsh-iconbtn:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }
.wsh-iconbtn:disabled{ opacity:.45; cursor:not-allowed; }
.wsh-iconbtn--ghost:hover:not(:disabled){ background:var(--muted); }
.wsh-iconbtn--ghost:active:not(:disabled){ transform:scale(.92); }
.wsh-iconbtn--outline{ border-color:var(--border); background:var(--card); box-shadow:var(--sh-xs); }
.wsh-iconbtn--outline:hover:not(:disabled){ background:var(--muted); transform:translateY(-1px); }
.wsh-iconbtn--outline:active:not(:disabled){ transform:scale(.93); }
.wsh-iconbtn--primary{ background:var(--primary); color:var(--primary-foreground); box-shadow:var(--sh-glow); }
.wsh-iconbtn--primary:hover:not(:disabled){ background:var(--primary-hover); transform:translateY(-2px); }
.wsh-iconbtn--primary:active:not(:disabled){ transform:scale(.92); }

/* ===== Input  ·  components/forms/Input.jsx ===== */
.wsh-input-wrap{ display:flex; align-items:stretch; width:100%;
  border:1px solid var(--input); border-radius:var(--r-md); background:var(--card);
  transition:var(--t-colors), box-shadow var(--d-fast) var(--ease-standard); overflow:hidden; }
.wsh-input-wrap:hover{ border-color:var(--n-300); }
.wsh-input-wrap.is-focused{ border-color:var(--ring); box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent); }
.wsh-input-wrap.is-error{ border-color:var(--error); }
.wsh-input-wrap.is-error.is-focused{ box-shadow:0 0 0 3px var(--error-soft); }
.wsh-input-wrap.is-disabled{ background:var(--muted); opacity:.7; cursor:not-allowed; }
.wsh-input{ flex:1; min-width:0; border:0; outline:0; background:transparent;
  font-family:var(--font-sans); font-size:15px; color:var(--foreground);
  padding:0 13px; height:42px; line-height:42px; }
.wsh-input.is-mono{ font-family:var(--font-mono); font-size:14px; }
.wsh-input::placeholder{ color:var(--muted-foreground); }
.wsh-input:disabled{ cursor:not-allowed; }
.wsh-affix{ display:flex; align-items:center; padding:0 11px; color:var(--muted-foreground);
  font-family:var(--font-mono); font-size:13px; background:var(--muted); white-space:nowrap; }
.wsh-affix--plain{ background:transparent; }
.wsh-affix svg{ width:18px; height:18px; }
.wsh-input--sm .wsh-input{ height:34px; line-height:34px; font-size:14px; }

/* ===== Textarea  ·  components/forms/Textarea.jsx ===== */
.wsh-textarea{ width:100%; font-family:var(--font-sans); font-size:15px; color:var(--foreground);
  background:var(--card); border:1px solid var(--input); border-radius:var(--r-md);
  padding:11px 13px; line-height:1.5; resize:vertical; min-height:84px;
  transition:var(--t-colors), box-shadow var(--d-fast) var(--ease-standard); }
.wsh-textarea::placeholder{ color:var(--muted-foreground); }
.wsh-textarea:hover{ border-color:var(--n-300); }
.wsh-textarea:focus-visible{ outline:none; border-color:var(--ring); box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent); }
.wsh-textarea:disabled{ background:var(--muted); opacity:.7; cursor:not-allowed; }
.wsh-textarea.is-error{ border-color:var(--error); }
.wsh-textarea.is-mono{ font-family:var(--font-mono); font-size:14px; }

/* ===== Select  ·  components/forms/Select.jsx ===== */
.wsh-select{ position:relative; display:inline-flex; width:100%; }
.wsh-select select{ appearance:none; width:100%; font-family:var(--font-sans); font-size:15px;
  color:var(--foreground); background:var(--card); border:1px solid var(--input);
  border-radius:var(--r-md); height:42px; padding:0 38px 0 13px; cursor:pointer;
  transition:var(--t-colors), box-shadow var(--d-fast) var(--ease-standard); }
.wsh-select select:hover{ border-color:var(--n-300); }
.wsh-select select:focus-visible{ outline:none; border-color:var(--ring); box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent); }
.wsh-select select:disabled{ background:var(--muted); opacity:.6; cursor:not-allowed; }
.wsh-select.is-error select{ border-color:var(--error); }
.wsh-select__chev{ position:absolute; right:12px; top:50%; transform:translateY(-50%);
  pointer-events:none; color:var(--muted-foreground); width:18px; height:18px; }
.wsh-select--sm select{ height:34px; font-size:14px; }

/* ===== Checkbox  ·  components/forms/Checkbox.jsx ===== */
.wsh-check{ display:inline-flex; align-items:flex-start; gap:10px; cursor:pointer; user-select:none; }
.wsh-check input{ position:absolute; opacity:0; width:0; height:0; }
.wsh-check__box{ width:20px; height:20px; border-radius:6px; border:1.5px solid var(--n-300);
  background:var(--card); display:flex; align-items:center; justify-content:center; flex-shrink:0;
  transition:var(--t-colors); margin-top:1px; }
.wsh-check__box svg{ width:13px; height:13px; color:#fff; stroke-width:3.5;
  opacity:0; transform:scale(.5); transition:transform var(--d-fast) var(--ease-spring), opacity var(--d-fast); }
.wsh-check input:checked + .wsh-check__box{ background:var(--primary); border-color:var(--primary); }
.wsh-check input:checked + .wsh-check__box svg{ opacity:1; transform:scale(1); }
.wsh-check input:indeterminate + .wsh-check__box{ background:var(--primary); border-color:var(--primary); }
.wsh-check input:focus-visible + .wsh-check__box{ box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }
.wsh-check input:disabled + .wsh-check__box{ opacity:.5; cursor:not-allowed; }
.wsh-check__label{ font-size:14px; color:var(--foreground); line-height:1.5; }
.wsh-check__label small{ display:block; color:var(--muted-foreground); font-size:12.5px; }

/* ===== Radio  ·  components/forms/Radio.jsx ===== */
.wsh-radio-group{ display:flex; flex-direction:column; gap:10px; }
.wsh-radio-group[data-row="true"]{ flex-direction:row; flex-wrap:wrap; gap:16px; }
.wsh-radio{ display:inline-flex; align-items:flex-start; gap:10px; cursor:pointer; user-select:none; }
.wsh-radio input{ position:absolute; opacity:0; width:0; height:0; }
.wsh-radio__dot{ width:20px; height:20px; border-radius:999px; border:1.5px solid var(--n-300);
  background:var(--card); display:flex; align-items:center; justify-content:center; flex-shrink:0;
  transition:var(--t-colors); margin-top:1px; }
.wsh-radio__dot::after{ content:""; width:9px; height:9px; border-radius:999px; background:#fff;
  transform:scale(0); transition:transform var(--d-fast) var(--ease-spring); }
.wsh-radio input:checked + .wsh-radio__dot{ background:var(--primary); border-color:var(--primary); }
.wsh-radio input:checked + .wsh-radio__dot::after{ transform:scale(1); }
.wsh-radio input:focus-visible + .wsh-radio__dot{ box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }
.wsh-radio input:disabled + .wsh-radio__dot{ opacity:.5; cursor:not-allowed; }
.wsh-radio__label{ font-size:14px; color:var(--foreground); line-height:1.5; }
.wsh-radio__label small{ display:block; color:var(--muted-foreground); font-size:12.5px; }

/* ===== Switch  ·  components/forms/Switch.jsx ===== */
.wsh-switch{ display:inline-flex; align-items:center; gap:10px; cursor:pointer; user-select:none; }
.wsh-switch input{ position:absolute; opacity:0; width:0; height:0; }
.wsh-switch__track{ width:44px; height:26px; border-radius:999px; background:var(--n-300);
  position:relative; transition:background-color var(--d-base) var(--ease-whoosh); flex-shrink:0; }
.wsh-switch__thumb{ position:absolute; top:3px; left:3px; width:20px; height:20px; border-radius:999px;
  background:#fff; box-shadow:var(--sh-sm); transition:transform var(--d-base) var(--ease-spring); }
.wsh-switch input:checked + .wsh-switch__track{ background:var(--primary); }
.wsh-switch input:checked + .wsh-switch__track .wsh-switch__thumb{ transform:translateX(18px); }
.wsh-switch input:focus-visible + .wsh-switch__track{ box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }
.wsh-switch input:disabled + .wsh-switch__track{ opacity:.5; cursor:not-allowed; }
.wsh-switch__label{ font-size:14px; color:var(--foreground); }
.wsh-switch--sm .wsh-switch__track{ width:36px; height:21px; }
.wsh-switch--sm .wsh-switch__thumb{ width:16px; height:16px; }
.wsh-switch--sm input:checked + .wsh-switch__track .wsh-switch__thumb{ transform:translateX(15px); }

/* ===== Slider  ·  components/forms/Slider.jsx ===== */
.wsh-slider{ width:100%; display:flex; align-items:center; gap:12px; }
.wsh-slider input[type=range]{ -webkit-appearance:none; appearance:none; flex:1; height:6px;
  border-radius:999px; background:var(--muted); outline:none; cursor:pointer; }
.wsh-slider input[type=range]::-webkit-slider-thumb{ -webkit-appearance:none; appearance:none;
  width:20px; height:20px; border-radius:999px; background:var(--primary); border:3px solid var(--card);
  box-shadow:var(--sh-sm); transition:transform var(--d-fast) var(--ease-spring); }
.wsh-slider input[type=range]::-webkit-slider-thumb:hover{ transform:scale(1.15); }
.wsh-slider input[type=range]::-moz-range-thumb{ width:20px; height:20px; border-radius:999px;
  background:var(--primary); border:3px solid var(--card); box-shadow:var(--sh-sm); }
.wsh-slider input[type=range]:focus-visible{ box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 24%, transparent); }
.wsh-slider input[type=range]:disabled{ opacity:.5; cursor:not-allowed; }
.wsh-slider__val{ font-family:var(--font-mono); font-size:13px; color:var(--foreground); min-width:42px; text-align:right; }

/* ===== Field  ·  components/forms/Field.jsx ===== */
.wsh-field{ display:flex; flex-direction:column; gap:7px; width:100%; }
.wsh-field__label{ font-family:var(--font-sans); font-size:14px; font-weight:600; color:var(--foreground); display:flex; align-items:center; gap:6px; }
.wsh-field__req{ color:var(--accent); }
.wsh-field__opt{ font-weight:400; color:var(--muted-foreground); font-size:12px; }
.wsh-field__help{ font-size:13px; color:var(--muted-foreground); line-height:1.4; }
.wsh-field__error{ font-size:13px; color:var(--error-ink); line-height:1.4; display:flex; align-items:center; gap:5px; }
.wsh-field__error svg{ width:14px; height:14px; }

/* ===== Card  ·  components/display/Card.jsx ===== */
.wsh-card{ background:var(--card); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--sh-sm); overflow:hidden; transition:var(--t-lift); }
.wsh-card--hover:hover{ transform:translateY(-4px); box-shadow:var(--sh-lg); }
.wsh-card--pad{ padding:20px; }
.wsh-card--flush{ padding:0; }
.wsh-card--gradient{ position:relative; }
.wsh-card--gradient::before{ content:""; position:absolute; inset:0 0 auto 0; height:4px; background:var(--whoosh); }
.wsh-card__header{ padding:18px 20px 0; }
.wsh-card__title{ font-family:var(--font-display); font-weight:600; font-size:18px; color:var(--card-foreground); letter-spacing:-.01em; }
.wsh-card__desc{ font-size:13.5px; color:var(--muted-foreground); margin-top:3px; }
.wsh-card__body{ padding:16px 20px 20px; }
.wsh-card__footer{ padding:14px 20px; border-top:1px solid var(--border); background:var(--surface-sunken); display:flex; align-items:center; gap:10px; }

/* ===== Badge  ·  components/display/Badge.jsx ===== */
.wsh-badge{ display:inline-flex; align-items:center; gap:6px; font-family:var(--font-sans);
  font-weight:600; font-size:12px; line-height:1; padding:4px 10px; border-radius:999px; white-space:nowrap; }
.wsh-badge svg{ width:13px; height:13px; }
.wsh-badge--neutral{ background:var(--muted); color:var(--muted-foreground); }
.wsh-badge--primary{ background:var(--violet-50); color:var(--violet-700); }
.wsh-badge--accent{ background:var(--accent-soft); color:var(--accent-ink); }
.wsh-badge--success{ background:var(--success-soft); color:var(--success-ink); }
.wsh-badge--warning{ background:var(--warning-soft); color:var(--warning-ink); }
.wsh-badge--error{ background:var(--error-soft); color:var(--error-ink); }
.wsh-badge--info{ background:var(--info-soft); color:var(--info-ink); }
.wsh-badge--solid{ background:var(--primary); color:#fff; }
.wsh-badge__dot{ width:6px; height:6px; border-radius:999px; background:currentColor; }
.wsh-badge--live .wsh-badge__dot{ background:var(--success); }
@media (prefers-reduced-motion: no-preference){
  .wsh-badge--live .wsh-badge__dot{ animation:wsh-pulse 1.8s infinite; }
}

/* ===== Tag  ·  components/display/Tag.jsx ===== */
.wsh-tag{ display:inline-flex; align-items:center; gap:6px; font-family:var(--font-sans);
  font-size:13px; font-weight:500; padding:4px 10px; border-radius:var(--r-sm);
  background:var(--muted); color:var(--foreground); border:1px solid transparent; transition:var(--t-colors); }
.wsh-tag--outline{ background:transparent; border-color:var(--border); }
.wsh-tag--primary{ background:var(--violet-50); color:var(--violet-700); }
.wsh-tag__x{ display:inline-flex; cursor:pointer; color:var(--muted-foreground); border-radius:999px;
  width:16px; height:16px; align-items:center; justify-content:center; margin-right:-3px; transition:var(--t-colors); }
.wsh-tag__x:hover{ background:var(--n-200); color:var(--foreground); }
.wsh-tag__x svg{ width:11px; height:11px; }
.wsh-tag__k{ color:var(--muted-foreground); font-family:var(--font-mono); font-size:12px; }

/* ===== Avatar  ·  components/display/Avatar.jsx ===== */
.wsh-avatar{ position:relative; display:inline-flex; align-items:center; justify-content:center;
  border-radius:999px; font-family:var(--font-display); font-weight:600; color:#fff;
  background:var(--whoosh); overflow:hidden; flex-shrink:0; user-select:none; }
.wsh-avatar img{ width:100%; height:100%; object-fit:cover; }
.wsh-avatar--ring{ box-shadow:0 0 0 2px var(--card), 0 0 0 4px transparent; background-clip:padding-box; }
.wsh-avatar--ring::after{ content:""; position:absolute; inset:-4px; border-radius:999px; padding:2px;
  background:var(--whoosh); -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude; }
.wsh-avatar__status{ position:absolute; right:-1px; bottom:-1px; width:30%; height:30%;
  border-radius:999px; border:2px solid var(--card); background:var(--success); }

/* ===== StatTile  ·  components/display/StatTile.jsx ===== */
.wsh-stat{ background:var(--card); border:1px solid var(--border); border-radius:var(--r-lg);
  padding:18px 20px; box-shadow:var(--sh-sm); transition:var(--t-lift); }
.wsh-stat--hover:hover{ transform:translateY(-3px); box-shadow:var(--sh-md); }
.wsh-stat__head{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
.wsh-stat__k{ font-size:13px; font-weight:500; color:var(--muted-foreground); display:flex; align-items:center; gap:7px; }
.wsh-stat__k svg{ width:15px; height:15px; }
.wsh-stat__v{ font-family:var(--font-display); font-weight:700; font-size:34px; letter-spacing:-.03em;
  line-height:1.1; color:var(--card-foreground); margin-top:6px; }
.wsh-stat__d{ font-size:12.5px; font-weight:600; margin-top:3px; display:flex; align-items:center; gap:4px; }
.wsh-stat__d--up{ color:var(--success-ink); } .wsh-stat__d--down{ color:var(--error-ink); }
.wsh-stat__d--flat{ color:var(--muted-foreground); }
.wsh-stat__spark{ margin-top:12px; }

/* ===== Tabs  ·  components/display/Tabs.jsx ===== */
.wsh-tabs{ display:flex; gap:4px; border-bottom:1px solid var(--border); position:relative; }
.wsh-tabs--pill{ border:0; gap:6px; background:var(--muted); padding:4px; border-radius:var(--r-md); }
.wsh-tab{ appearance:none; border:0; background:none; cursor:pointer; font-family:var(--font-sans);
  font-weight:600; font-size:14px; color:var(--muted-foreground); padding:11px 14px; position:relative;
  transition:color var(--d-fast) var(--ease-standard); display:inline-flex; align-items:center; gap:7px; white-space:nowrap; }
.wsh-tab svg{ width:16px; height:16px; }
.wsh-tab:hover{ color:var(--foreground); }
.wsh-tab.is-active{ color:var(--primary); }
.wsh-tab__count{ font-family:var(--font-mono); font-size:11px; background:var(--muted); color:var(--muted-foreground);
  padding:1px 6px; border-radius:999px; }
.wsh-tab.is-active .wsh-tab__count{ background:var(--violet-50); color:var(--violet-700); }
.wsh-tabs__ink{ position:absolute; bottom:-1px; height:2.5px; border-radius:999px; background:var(--whoosh);
  transition:left var(--d-base) var(--ease-whoosh), width var(--d-base) var(--ease-whoosh); }
.wsh-tabs--pill .wsh-tab{ border-radius:var(--r-sm); padding:8px 14px; }
.wsh-tabs--pill .wsh-tab.is-active{ background:var(--card); color:var(--foreground); box-shadow:var(--sh-xs); }
.wsh-tabs--pill .wsh-tabs__ink{ display:none; }

/* ===== Progress  ·  components/display/Progress.jsx ===== */
.wsh-progress{ width:100%; height:8px; border-radius:999px; background:var(--muted); overflow:hidden; position:relative; }
.wsh-progress--lg{ height:12px; }
.wsh-progress__fill{ height:100%; border-radius:999px; background:var(--whoosh);
  transition:width var(--d-slow) var(--ease-whoosh); }
.wsh-progress--indeterminate .wsh-progress__fill{ width:42% !important; position:absolute; left:0; }
@media (prefers-reduced-motion: no-preference){
  .wsh-progress--indeterminate .wsh-progress__fill{ animation:wsh-loader 1.5s var(--ease-whoosh) infinite; }
}

/* ===== Skeleton  ·  components/display/Skeleton.jsx ===== */
.wsh-skel{ display:block; background:var(--muted); border-radius:var(--r-sm); position:relative; overflow:hidden; }
.wsh-skel::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, color-mix(in srgb, var(--card) 60%, transparent), transparent);
  transform:translateX(-100%); }
@media (prefers-reduced-motion: no-preference){
  .wsh-skel::after{ animation:wsh-loader 1.4s var(--ease-standard) infinite; }
}
.wsh-skel--text{ height:.8em; border-radius:999px; }
.wsh-skel--circle{ border-radius:999px; }

/* ===== Toast  ·  components/feedback/Toast.jsx ===== */
.wsh-toast-viewport{ position:fixed; bottom:20px; right:20px; z-index:9999; display:flex;
  flex-direction:column; gap:10px; width:360px; max-width:calc(100vw - 40px); pointer-events:none; }
.wsh-toast{ pointer-events:auto; display:flex; align-items:flex-start; gap:12px; padding:14px;
  background:var(--popover); color:var(--popover-foreground); border:1px solid var(--border);
  border-radius:var(--r-lg); box-shadow:var(--sh-lg); position:relative; overflow:hidden; }
.wsh-toast__icon{ flex-shrink:0; width:34px; height:34px; border-radius:var(--r-md); display:flex; align-items:center; justify-content:center; background:var(--violet-50); color:var(--primary); }
.wsh-toast--success .wsh-toast__icon{ background:var(--success-soft); color:var(--success); }
.wsh-toast--error .wsh-toast__icon{ background:var(--error-soft); color:var(--error); }
.wsh-toast--accent .wsh-toast__icon{ background:var(--accent-soft); color:var(--accent-ink); }
.wsh-toast__icon svg{ width:19px; height:19px; }
.wsh-toast__body{ flex:1; min-width:0; }
.wsh-toast__title{ font-weight:600; font-size:14px; }
.wsh-toast__text{ font-size:13px; color:var(--muted-foreground); margin-top:2px; }
.wsh-toast__action{ margin-top:9px; }
.wsh-toast__close{ cursor:pointer; background:none; border:0; color:var(--muted-foreground); padding:2px; border-radius:var(--r-sm); }
.wsh-toast__close:hover{ background:var(--muted); color:var(--foreground); }
.wsh-toast__close svg{ width:15px; height:15px; }
.wsh-toast{ animation:wsh-toast-in var(--d-base) var(--ease-whoosh); }

/* ===== Tooltip  ·  components/feedback/Tooltip.jsx ===== */
.wsh-tip{ position:relative; display:inline-flex; }
.wsh-tip__pop{ position:absolute; z-index:60; pointer-events:none; opacity:0;
  background:var(--n-900); color:#fff; font-family:var(--font-sans); font-size:12.5px; font-weight:500;
  padding:6px 10px; border-radius:var(--r-sm); white-space:nowrap; box-shadow:var(--sh-md);
  transition:opacity var(--d-fast) var(--ease-standard), transform var(--d-fast) var(--ease-arrive); }
.wsh-tip__pop::after{ content:""; position:absolute; width:7px; height:7px; background:var(--n-900); transform:rotate(45deg); }
.wsh-tip__pop[data-side="top"]{ bottom:calc(100% + 8px); left:50%; transform:translate(-50%, 4px); }
.wsh-tip__pop[data-side="top"]::after{ top:100%; left:50%; margin:-3.5px 0 0 -3.5px; }
.wsh-tip__pop[data-side="bottom"]{ top:calc(100% + 8px); left:50%; transform:translate(-50%, -4px); }
.wsh-tip__pop[data-side="bottom"]::after{ bottom:100%; left:50%; margin:0 0 -3.5px -3.5px; }
.wsh-tip:hover .wsh-tip__pop, .wsh-tip:focus-within .wsh-tip__pop{ opacity:1; transform:translate(-50%, 0); }
.dark .wsh-tip__pop, .dark .wsh-tip__pop::after{ background:var(--n-800); }

/* ===== Banner  ·  components/feedback/Banner.jsx ===== */
.wsh-banner{ display:flex; align-items:flex-start; gap:12px; padding:14px 16px; border-radius:var(--r-lg);
  border:1px solid var(--border); background:var(--card); position:relative; overflow:hidden; }
.wsh-banner__icon{ flex-shrink:0; width:20px; height:20px; margin-top:1px; }
.wsh-banner__icon svg{ width:20px; height:20px; }
.wsh-banner__body{ flex:1; min-width:0; }
.wsh-banner__title{ font-weight:600; font-size:14px; color:var(--foreground); }
.wsh-banner__text{ font-size:13.5px; color:var(--muted-foreground); margin-top:2px; line-height:1.45; }
.wsh-banner__actions{ display:flex; gap:8px; margin-top:10px; }
.wsh-banner__close{ flex-shrink:0; cursor:pointer; color:var(--muted-foreground); background:none; border:0; padding:2px; border-radius:var(--r-sm); }
.wsh-banner__close:hover{ background:var(--muted); color:var(--foreground); }
.wsh-banner__close svg{ width:16px; height:16px; }
.wsh-banner--info{ background:var(--info-soft); border-color:transparent; } .wsh-banner--info .wsh-banner__icon{ color:var(--info); }
.wsh-banner--success{ background:var(--success-soft); border-color:transparent; } .wsh-banner--success .wsh-banner__icon{ color:var(--success); }
.wsh-banner--warning{ background:var(--warning-soft); border-color:transparent; } .wsh-banner--warning .wsh-banner__icon{ color:var(--warning-ink); }
.wsh-banner--error{ background:var(--error-soft); border-color:transparent; } .wsh-banner--error .wsh-banner__icon{ color:var(--error); }
.wsh-banner--pro{ background:linear-gradient(100deg, var(--violet-50), var(--coral-50)); border-color:var(--coral-200); }
.wsh-banner--pro .wsh-banner__icon{ color:var(--accent-ink); }
/* pro tint is always light (both themes), so pin text to dark violet ink for contrast in dark mode */
.wsh-banner--pro .wsh-banner__title{ color:var(--violet-950); }
.wsh-banner--pro .wsh-banner__text{ color:var(--violet-800); }
.wsh-banner--pro .wsh-banner__close{ color:var(--violet-700); }

/* ===== Dialog  ·  components/feedback/Dialog.jsx ===== */
.wsh-dialog__scrim{ position:fixed; inset:0; z-index:1000; background:var(--surface-overlay);
  backdrop-filter:blur(2px); display:flex; align-items:center; justify-content:center; padding:20px;
  animation:wsh-fade-in var(--d-fast) var(--ease-standard); }
.wsh-dialog{ background:var(--card); color:var(--card-foreground); border:1px solid var(--border);
  border-radius:var(--r-xl); box-shadow:var(--sh-xl); width:100%; max-width:480px; max-height:90vh;
  overflow:auto; animation:wsh-whoosh-up var(--d-base) var(--ease-arrive); }
.wsh-dialog--lg{ max-width:680px; }
.wsh-dialog__head{ display:flex; align-items:flex-start; gap:14px; padding:22px 22px 0; }
.wsh-dialog__head-text{ flex:1; }
.wsh-dialog__title{ font-family:var(--font-display); font-weight:600; font-size:20px; letter-spacing:-.01em; }
.wsh-dialog__desc{ font-size:14px; color:var(--muted-foreground); margin-top:4px; line-height:1.45; }
.wsh-dialog__close{ cursor:pointer; background:none; border:0; color:var(--muted-foreground); padding:4px; border-radius:var(--r-sm); }
.wsh-dialog__close:hover{ background:var(--muted); color:var(--foreground); }
.wsh-dialog__close svg{ width:18px; height:18px; }
.wsh-dialog__body{ padding:18px 22px; }
.wsh-dialog__foot{ display:flex; justify-content:flex-end; gap:10px; padding:0 22px 22px; }

/* ===== EmptyState  ·  components/feedback/EmptyState.jsx ===== */
.wsh-empty{ display:flex; flex-direction:column; align-items:center; text-align:center;
  padding:48px 28px; border-radius:var(--r-xl); background:var(--card); border:1px dashed var(--border);
  position:relative; overflow:hidden; }
.wsh-empty--air{ background:radial-gradient(120% 80% at 50% -10%, var(--violet-50), var(--card) 60%); }
.wsh-empty__streak{ width:120px; height:4px; border-radius:999px; background:var(--whoosh); margin-bottom:22px; position:relative; overflow:hidden; }
.wsh-empty__streak::after{ content:""; position:absolute; inset:0; background:linear-gradient(90deg,transparent,rgba(255,255,255,.9),transparent); transform:translateX(-100%); }
@media (prefers-reduced-motion: no-preference){ .wsh-empty__streak::after{ animation:wsh-streak 2.4s var(--ease-whoosh) infinite; } }
.wsh-empty__icon{ width:56px; height:56px; border-radius:var(--r-lg); display:flex; align-items:center; justify-content:center;
  background:var(--violet-50); color:var(--primary); margin-bottom:18px; }
.wsh-empty__icon svg{ width:28px; height:28px; }
.wsh-empty__title{ font-family:var(--font-display); font-weight:600; font-size:21px; color:var(--foreground); letter-spacing:-.01em; }
.wsh-empty__text{ font-size:14.5px; color:var(--muted-foreground); margin-top:7px; max-width:42ch; line-height:1.5; }
.wsh-empty__actions{ display:flex; gap:10px; margin-top:22px; flex-wrap:wrap; justify-content:center; }

/* ===== CreateLinkCard  ·  components/app/CreateLinkCard.jsx ===== */
.wsh-create{ background:var(--card); border:1px solid var(--border); border-radius:var(--r-xl);
  box-shadow:var(--sh-md); padding:22px; position:relative; overflow:hidden; }
.wsh-create__head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:16px; }
.wsh-create__title{ font-family:var(--font-display); font-weight:600; font-size:19px; letter-spacing:-.01em; color:var(--card-foreground); }
.wsh-create__row{ display:flex; gap:10px; align-items:stretch; margin-top:10px; flex-wrap:wrap; }
.wsh-create__row > .wsh-input-wrap{ flex:1; min-width:200px; }
.wsh-create__opts{ display:flex; gap:8px; margin-top:14px; flex-wrap:wrap; }
.wsh-arrow{ width:17px; height:17px; }
.wsh-slug-meta{ display:flex; align-items:center; gap:9px; margin-top:8px; min-height:18px; font-size:12.5px; flex-wrap:wrap; }
.wsh-slug-hint{ color:var(--muted-foreground); }
.wsh-slug-link{ background:none; border:none; padding:0; font:inherit; font-weight:600; color:var(--primary); cursor:pointer; }
.wsh-slug-link:hover{ text-decoration:underline; }
.wsh-dice{ flex-shrink:0; width:42px; display:inline-flex; align-items:center; justify-content:center;
  border:1px solid var(--border); border-radius:var(--r-md); background:var(--card); color:var(--muted-foreground);
  cursor:pointer; transition:color .15s,border-color .15s,background .15s; }
.wsh-dice:hover{ color:var(--primary); border-color:var(--primary); background:var(--violet-50); }
.wsh-dice svg{ width:18px; height:18px; }
.wsh-dice.spin svg{ animation:wsh-dice-spin .5s cubic-bezier(.4,.1,.2,1); }
@keyframes wsh-dice-spin{ from{ transform:rotate(0); } to{ transform:rotate(360deg); } }
.wsh-status{ display:inline-flex; align-items:center; gap:5px; font-weight:600; }
.wsh-status svg{ width:14px; height:14px; }
.wsh-status--ok{ color:var(--success, #0f9d6b); }
.wsh-status--bad{ color:var(--coral-600); }
.wsh-status--checking{ color:var(--muted-foreground); font-weight:500; }
.wsh-status__spin{ width:12px; height:12px; border:2px solid var(--border); border-top-color:var(--muted-foreground);
  border-radius:50%; animation:wsh-status-spin .6s linear infinite; }
@keyframes wsh-status-spin{ to{ transform:rotate(360deg); } }

/* ===== AnalyticsTile  ·  components/app/AnalyticsTile.jsx ===== */
.wsh-atile{ background:var(--card); border:1px solid var(--border); border-radius:var(--r-lg);
  box-shadow:var(--sh-sm); padding:16px 18px; transition:var(--t-lift); }
.wsh-atile--hover:hover{ transform:translateY(-3px); box-shadow:var(--sh-md); }
.wsh-atile__top{ display:flex; align-items:center; gap:10px; justify-content:space-between; }
.wsh-atile__link{ font-family:var(--font-mono); font-size:13.5px; color:var(--foreground); min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.wsh-atile__link b{ color:var(--primary); font-weight:700; }
.wsh-atile__mid{ display:flex; align-items:flex-end; gap:18px; margin-top:14px; }
.wsh-atile__metric .n{ font-family:var(--font-display); font-weight:700; font-size:26px; letter-spacing:-.03em; line-height:1; color:var(--card-foreground); }
.wsh-atile__metric .l{ font-size:12px; color:var(--muted-foreground); margin-top:4px; display:flex; align-items:center; gap:5px; }
.wsh-atile__metric .l .dot{ width:7px; height:7px; border-radius:999px; }
.wsh-atile__spark{ margin-left:auto; }
.wsh-atile__delta{ font-size:12px; font-weight:600; }
.wsh-atile__delta.up{ color:var(--success-ink); } .wsh-atile__delta.down{ color:var(--error-ink); }

/* ===== QRPreview  ·  components/app/QRPreview.jsx ===== */
.wsh-qr{ display:inline-flex; flex-direction:column; gap:0; border-radius:var(--r-lg);
  background:var(--card); }
.wsh-qr__frame{ position:relative; border-radius:var(--r-md); overflow:hidden; }
.wsh-qr__logo{ position:absolute; inset:0; margin:auto; width:24%; height:24%; border-radius:7px;
  background:var(--card); display:flex; align-items:center; justify-content:center; box-shadow:0 0 0 4px var(--card); }
.wsh-qr__logo span{ width:64%; height:64%; border-radius:999px; background:var(--whoosh); }

/* ===== VCardPreview  ·  components/app/VCardPreview.jsx ===== */
.wsh-phone{ width:264px; border-radius:34px; background:var(--n-950); padding:11px;
  box-shadow:var(--sh-xl), inset 0 0 0 1px rgba(255,255,255,.06); position:relative; }
.wsh-phone__notch{ position:absolute; top:20px; left:50%; transform:translateX(-50%); width:90px; height:22px;
  background:var(--n-950); border-radius:999px; z-index:3; }
.wsh-phone__screen{ border-radius:25px; overflow:hidden; background:var(--n-0); position:relative; height:480px; }
.wsh-vc__cover{ height:128px; position:relative; }
.wsh-vc__avatar{ position:absolute; left:50%; bottom:-34px; transform:translateX(-50%); width:84px; height:84px;
  border-radius:999px; border:4px solid #fff; background:var(--whoosh); display:flex; align-items:center;
  justify-content:center; color:#fff; font-family:var(--font-display); font-weight:700; font-size:30px; box-shadow:var(--sh-md); }
.wsh-vc__body{ padding:48px 22px 22px; text-align:center; }
.wsh-vc__name{ font-family:var(--font-display); font-weight:600; font-size:21px; color:var(--n-900); letter-spacing:-.01em; }
.wsh-vc__role{ font-size:13.5px; color:var(--n-500); margin-top:3px; }
.wsh-vc__rows{ margin-top:20px; display:flex; flex-direction:column; gap:9px; text-align:left; }
.wsh-vc__row{ display:flex; align-items:center; gap:11px; padding:10px 12px; border-radius:var(--r-md);
  background:var(--n-50); font-size:13px; color:var(--n-700); }
.wsh-vc__row svg{ width:16px; height:16px; flex-shrink:0; }
.wsh-vc__save{ margin-top:18px; width:100%; height:44px; border:0; border-radius:var(--r-md); cursor:pointer;
  font-family:var(--font-display); font-weight:600; font-size:15px; color:#fff; display:flex; align-items:center;
  justify-content:center; gap:8px; }

/* ===== UTMBuilder  ·  components/app/UTMBuilder.jsx ===== */
.wsh-utm{ background:var(--card); border:1px solid var(--border); border-radius:var(--r-xl); box-shadow:var(--sh-sm); overflow:hidden; }
.wsh-utm__form{ padding:20px; }
.wsh-utm__grid{ display:grid; grid-template-columns:1fr 1fr; gap:13px; margin-top:13px; }
.wsh-utm__lbl{ font-size:13px; font-weight:600; color:var(--foreground); display:block; margin-bottom:5px; }
.wsh-utm__lbl small{ font-family:var(--font-mono); font-weight:400; color:var(--muted-foreground); margin-left:5px; font-size:11px; }
.wsh-utm__preview{ background:var(--surface-sunken); border-top:1px solid var(--border); padding:16px 20px; }
.wsh-utm__plabel{ font-size:12px; font-weight:600; color:var(--muted-foreground); text-transform:uppercase; letter-spacing:.06em; margin-bottom:8px; display:flex; align-items:center; gap:8px; }
.wsh-utm__url{ font-family:var(--font-mono); font-size:13px; line-height:1.6; color:var(--foreground); word-break:break-all;
  background:var(--card); border:1px solid var(--border); border-radius:var(--r-md); padding:11px 13px; }
.wsh-utm__url .base{ color:var(--foreground); } .wsh-utm__url .q{ color:var(--muted-foreground); }
.wsh-utm__url .k{ color:var(--violet-600); } .wsh-utm__url .v{ color:var(--coral-600); }
.wsh-utm__actions{ display:flex; gap:9px; margin-top:13px; flex-wrap:wrap; }
@media (max-width:520px){ .wsh-utm__grid{ grid-template-columns:1fr; } }@media (max-width:860px){ .lp .navlinks{ display:none !important; } .lp .wrap{ padding-left:20px !important; padding-right:20px !important; } .lp [style*='grid-template-columns']{ grid-template-columns:1fr !important; } .lp [style*='grid-template-columns'] > *{ min-width:0; } .lp .wsh-card{ min-width:0; } .lp .wsh-input-wrap, .lp .wsh-input, .lp input, .lp img{ min-width:0 !important; max-width:100%; } .lp .cmp-tbl{ overflow-x:auto !important; } .lp .cmp-tbl > div{ grid-template-columns:1.5fr 1fr 1fr !important; } .lp .cmp-tbl > div > div{ padding-left:11px !important; padding-right:11px !important; } .lp .cmp-tbl [style*='font-size:16px']{ font-size:13.5px !important; } }

/* ===== ProLock  ·  components/app/ProLock.jsx ===== */
.wsh-prolock{ position:relative; border-radius:var(--r-lg); overflow:hidden; }
.wsh-prolock__content{ filter:blur(3px) saturate(.7); opacity:.55; pointer-events:none; user-select:none; }
.wsh-prolock__veil{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; padding:24px; gap:6px;
  background:linear-gradient(180deg, color-mix(in srgb, var(--card) 55%, transparent), var(--card) 78%); }
.wsh-prolock__badge{ display:inline-flex; align-items:center; gap:7px; font-family:var(--font-display);
  font-weight:600; font-size:12px; color:#fff; background:var(--whoosh); padding:5px 12px; border-radius:999px;
  box-shadow:var(--sh-glow-coral); margin-bottom:6px; }
.wsh-prolock__badge svg{ width:13px; height:13px; }
.wsh-prolock__title{ font-family:var(--font-display); font-weight:600; font-size:18px; color:var(--foreground); letter-spacing:-.01em; }
.wsh-prolock__text{ font-size:13.5px; color:var(--muted-foreground); max-width:34ch; line-height:1.5; margin-top:2px; }
.wsh-prolock__actions{ margin-top:14px; display:flex; gap:9px; }
/* inline lock chip variant */
.wsh-prochip{ display:inline-flex; align-items:center; gap:6px; font-family:var(--font-sans); font-weight:600;
  font-size:12px; color:var(--accent-ink); background:var(--accent-soft); padding:4px 10px; border-radius:999px; }
.wsh-prochip svg{ width:13px; height:13px; }

/* ===== ColorSwatches  ·  DS accent picker, authored from the vCard/QR template .wsh-swatch spec ===== */
.wsh-swatches{ display:flex; gap:10px; flex-wrap:wrap; }
.wsh-swatch{ width:30px; height:30px; border-radius:8px; cursor:pointer; border:2px solid transparent;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.08); transition:transform .12s var(--ease-whoosh); padding:0; }
.wsh-swatch:hover{ transform:translateY(-2px); }
.wsh-swatch[data-on]{ border-color:var(--foreground); }
.wsh-swatch:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--background), 0 0 0 5px var(--ring); }

/* Whooshly marketing site — shared layout classes (built on the design tokens).
   Served (concatenated with the tokens + components CSS) at /_b/site.css by the redirect worker. */
.lp { overflow-x: hidden; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 28px; }

.nav { position: sticky; top: 0; z-index: 50; height: 68px; display: flex; align-items: center;
  background: color-mix(in srgb, var(--background) 82%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); }
.nav a:not(.wsh-btn) { color: var(--muted-foreground); font-size: 14.5px; font-weight: 500; text-decoration: none; }
.nav a:not(.wsh-btn):hover { color: var(--foreground); }
.logo { display: inline-flex; align-items: center; gap: 9px; font-family: var(--font-display); font-weight: 700; font-size: 22px; letter-spacing: -.04em; color: var(--foreground); text-decoration: none; }

.eyebrow { font-family: var(--font-mono); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted-foreground); }
h2.sec { font-family: var(--font-display); font-weight: 700; font-size: clamp(28px, 3.6vw, 42px); letter-spacing: -.03em; line-height: 1.05; margin: 0; }
.lede { font-size: 18px; color: var(--muted-foreground); line-height: 1.55; margin: 0; }

.air { background:
  radial-gradient(60% 50% at 92% 0%, rgba(255, 92, 114, .10), transparent 60%),
  radial-gradient(60% 55% at 4% 2%, rgba(91, 51, 240, .12), transparent 55%); }

.feature { border: 1px solid var(--border); border-radius: var(--r-xl); background: var(--card); box-shadow: var(--sh-sm);
  padding: 26px; transition: transform var(--d-base) var(--ease-whoosh), box-shadow var(--d-base) var(--ease-whoosh);
  position: relative; overflow: hidden; }
.feature::before { content: ""; position: absolute; top: 0; left: 0; height: 3px; width: 100%;
  background: linear-gradient(90deg, transparent 0%, var(--primary) 35%, var(--coral-500) 65%, transparent 100%);
  transform: translateX(-101%); transition: transform .6s var(--ease-whoosh); will-change: transform; }
.feature:hover { transform: translateY(-5px); box-shadow: var(--sh-lg); }
.feature:hover::before { transform: translateX(101%); }
.ficon { width: 48px; height: 48px; border-radius: var(--r-md); display: flex; align-items: center; justify-content: center; color: #fff; margin-bottom: 16px; transition: transform var(--d-base) var(--ease-whoosh); }
.feature:hover .ficon { transform: translateY(-3px) scale(1.05); }

.check { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--foreground); }
.check svg { color: var(--success); flex-shrink: 0; }
.x { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--muted-foreground); }
.x svg { color: var(--n-400); flex-shrink: 0; }

.step-num { width: 34px; height: 34px; border-radius: 999px; background: var(--violet-50); color: var(--violet-700);
  font-family: var(--font-display); font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }

.mkt-pill { display: inline-flex; align-items: center; gap: 8px; padding: 6px 13px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--border); box-shadow: var(--sh-sm); font-size: 13.5px; font-weight: 600; }
.mkt-cta { position: relative; overflow: hidden; border-radius: var(--r-2xl); background: var(--whoosh); box-shadow: var(--sh-glow); }
.mkt-cta__sheen { position: absolute; inset: 0; width: 40%; transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .18), transparent); animation: wsh-sheen 4s var(--ease-whoosh) infinite; }
.mkt-buy { height: 52px; padding: 0 28px; border-radius: var(--r-md); border: 0; cursor: pointer; background: #fff; color: var(--violet-700);
  font-family: var(--font-display); font-weight: 700; font-size: 17px; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }

@media (prefers-reduced-motion: reduce) { .feature::before { display: none; } .feature:hover .ficon { transform: none; } .mkt-cta__sheen { display: none; } }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--n-300); border-radius: 999px; border: 3px solid var(--background); }
.dark *::-webkit-scrollbar-thumb { background: var(--n-700); }
