@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%; }.trust-row{ display:flex; align-items:center; gap:10px 26px; justify-content:center; flex-wrap:wrap; }.trust-logos{ display:contents; }@media (max-width:640px){ .trust-row{ flex-direction:column; gap:14px; }.trust-logos{ display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:12px 22px; } }@media (max-width:820px){ .r-split{ grid-template-columns:1fr !important; gap:32px !important; } }@media (max-width:680px){ .r-3{ grid-template-columns:1fr !important; } }@media (max-width:980px){ .r-footer{ grid-template-columns:repeat(3,1fr) !important; }.r-footer>:first-child{ grid-column:1 / -1; } }@media (max-width:600px){ .r-footer{ grid-template-columns:1fr 1fr !important; } }@media (max-width:640px){ .hero-cta{ flex-wrap:nowrap !important; }.hero-cta .wsh-btn--lg{ --_px:14px; --_fs:15px; flex:1 1 0; min-width:0; } }.wsh-arrow{ transition:transform var(--d-fast) var(--ease-whoosh); }.wsh-btn:hover .wsh-arrow,.mkt-buy:hover .wsh-arrow,.feature:hover .wsh-arrow,a:hover .wsh-arrow,button:hover .wsh-arrow{ transform:translateX(4px); }@media (prefers-reduced-motion:reduce){.wsh-arrow{ transition:none; }.wsh-btn:hover .wsh-arrow,.mkt-buy:hover .wsh-arrow,.feature:hover .wsh-arrow,a:hover .wsh-arrow,button:hover .wsh-arrow{ transform:none; }}

.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; } .nav-burger{ display:inline-flex !important; } #nav-toggle:checked ~ .nav-drawer{ display:flex; } #nav-toggle:checked ~ .wrap .nav-burger .i-menu{ display:none; } #nav-toggle:checked ~ .wrap .nav-burger .i-close{ display:block; } .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); }
.lang{ position:relative; } .lang summary{ list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:6px; padding:7px 10px; border-radius:var(--r-md); font-size:13.5px; font-weight:600; color:var(--foreground); -webkit-tap-highlight-color:transparent; } .lang summary::-webkit-details-marker{ display:none; } .lang summary:hover, .lang[open] summary{ background:var(--muted); } .lang-menu{ position:absolute; top:calc(100% + 6px); right:0; min-width:150px; display:flex; flex-direction:column; padding:6px; border:1px solid var(--border); border-radius:var(--r-md); background:var(--background); box-shadow:0 16px 30px -14px rgba(20,16,40,.28); z-index:60; } .lang-menu a{ padding:8px 10px; border-radius:8px; font-size:13.5px; color:var(--muted-foreground); text-decoration:none; } .lang-menu a:hover{ background:var(--muted); color:var(--foreground); } .lang-menu a[aria-current='true']{ color:var(--foreground); font-weight:600; }
@media (max-width:640px){ .lang summary span{ display:none; } }
.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); } .nav-toggle{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; } .nav-burger{ display:none; align-items:center; justify-content:center; width:40px; height:40px; margin-right:-6px; border-radius:var(--r-md); cursor:pointer; color:var(--foreground); -webkit-tap-highlight-color:transparent; } .nav-burger .i-close{ display:none; } .nav-burger:active{ background:var(--surface-sunken); } .nav-drawer{ display:none; position:absolute; top:100%; left:0; right:0; flex-direction:column; padding:6px 20px 16px; border-bottom:1px solid var(--border); background:var(--background); box-shadow:0 16px 30px -14px rgba(20,16,40,.2); } .nav .nav-drawer a{ padding:14px 4px; font-size:16px; font-weight:600; color:var(--foreground); text-decoration:none; border-top:1px solid var(--border); }
.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); }

/* The generated SITE_CSS bundle predates these semantic tokens (they exist in
   src/styles/tokens/colors.css but not in the snapshot in ./css.ts), so anything referencing them
   silently resolved to nothing — .step-num lost its tile, .pm-tbl__i never had one. Values mirror
   colors.css exactly; delete this block when css.ts is regenerated. */
:root{ --primary-soft:var(--violet-50); --primary-soft-ink:var(--violet-700);
  --primary-soft-border:var(--violet-100); }
.dark{ --primary-soft:rgba(138,93,244,.15); --primary-soft-ink:var(--violet-200);
  --primary-soft-border:rgba(138,93,244,.28); }

/* Nav: shorter, quieter links, an underline that wipes in on hover, and a real CTA pair
   (ghost "sign in" + solid "start free") instead of a single primary button. */
.lp .nav{ height:62px; background:color-mix(in srgb, var(--background) 76%, transparent); backdrop-filter:saturate(1.4) blur(12px); }
.lp .logo{ font-size:20.5px; }
.lp .nav .navlinks{ gap:20px !important; }
.lp .nav .navlinks a{ font-size:14px; font-weight:500; position:relative; padding:5px 0; }
.lp .nav .navlinks a::after{ content:""; position:absolute; left:0; right:0; bottom:-1px; height:1.5px; border-radius:2px;
  background:var(--foreground); transform:scaleX(0); transform-origin:left center;
  transition:transform var(--d-base) var(--ease-whoosh); }
.lp .nav .navlinks a:hover::after{ transform:scaleX(1); }
.lp .nav-ghost{ display:inline-flex; align-items:center; height:36px; padding:0 12px; border-radius:var(--r-md);
  font-size:14px; font-weight:600; color:var(--foreground) !important; transition:background var(--d-fast) var(--ease-standard); }
.lp .nav-ghost:hover{ background:var(--muted); }
.lp .nav .wsh-btn{ --_h:36px; --_px:15px; --_fs:14px; }
/* One glow on the page is a signature; one on every button is a template. Soften it site-wide. */
.lp .wsh-btn--primary{ box-shadow:0 6px 18px -10px rgba(91,51,240,.55); }
.lp .wsh-btn--primary:hover:not(:disabled){ box-shadow:0 10px 26px -12px rgba(91,51,240,.55); }
/* Firms up once you leave the hero (class toggled by the homepage's scroll handler). */
.lp .nav.is-stuck{ background:color-mix(in srgb, var(--background) 92%, transparent);
  box-shadow:0 1px 0 var(--border), 0 10px 26px -22px rgba(26,11,77,.45); }
@media (max-width:860px){ .lp .nav-ghost{ display:none; } }
/* ---- shared section primitives ----
   Every marketing page (hubs, comparisons, free tools, blog, about, pricing) is built from
   .eyebrow / h2.sec / .lede / .feature, so lifting these lifts the whole site to the homepage's
   type scale and restraint without rewriting each page template. Per-page accent hues are left
   alone on purpose: one accent per page is identity, unlike six side by side. */
.lp .eyebrow{ display:inline-flex; align-items:center; gap:12px; font-size:11px; line-height:1;
  letter-spacing:.18em; }
.lp .eyebrow::before{ content:""; width:24px; height:2px; border-radius:2px; background:var(--whoosh);
  flex-shrink:0; }
/* The rule is a section-level signal. Repeated on every card in a 12-card grid it turns into
   decoration, so it is suppressed inside cards, articles and the proof strip. */
.lp .feature .eyebrow::before, .lp article .eyebrow::before, .lp .wsh-card .eyebrow::before,
.lp .trust-row .eyebrow::before{ display:none; }
.lp h2.sec{ font-size:clamp(30px,4.1vw,48px); letter-spacing:-.035em; line-height:1.03;
  text-wrap:balance; }
.lp .lede{ font-size:18.5px; line-height:1.62; max-width:64ch; text-wrap:pretty; }

/* Cards: the sweeping gradient wipe on hover was the most template-looking thing on the site. */
.lp .feature{ border-radius:16px; box-shadow:none; padding:24px;
  transition:transform var(--d-base) var(--ease-whoosh), box-shadow var(--d-base) var(--ease-whoosh),
             border-color var(--d-base) var(--ease-whoosh); }
.lp .feature::before{ display:none; }
.lp .feature:hover{ transform:translateY(-3px); box-shadow:var(--sh-md); border-color:var(--n-300); }
.lp .feature:hover .ficon{ transform:none; }
.lp .ficon{ border-radius:11px; }

/* Eyebrow pill + numbered steps, aligned with the homepage's versions. */
.lp .mkt-pill{ padding:6px 14px 6px 11px; font-size:13px; letter-spacing:-.005em; }
.lp .step-num{ width:32px; height:32px; font-size:14px; background:var(--primary-soft);
  color:var(--primary-soft-ink); }
.lp .check{ align-items:flex-start; gap:12px; font-size:15.5px; line-height:1.5; }
.lp .check svg{ margin-top:2px; }

/* Proof strip: names should read as quiet evidence, not as headlines. */
.lp .trust-logos span{ font-size:16px !important; color:var(--n-400) !important; }

/* FAQ: same rhythm as the rest of the page. */
.lp .faq-q{ font-size:18px; letter-spacing:-.015em; }

/* ---- shared closing CTA (finalCTA) — every marketing page ends on this ---- */
.hp-closer{ position:relative; overflow:clip; background:var(--n-950); border-top:2px solid transparent;
  border-image:var(--whoosh) 1; padding:124px 0 150px; text-align:center; }
/* Cropped from below on purpose: set in caps so there are no descenders, and the cut lands on a
   flat baseline instead of slicing a single letter's tail. */
.hp-closer__mark{ position:absolute; left:50%; bottom:-8%; transform:translateX(-50%); font-family:var(--font-display);
  font-weight:700; font-size:min(16.5vw,214px); letter-spacing:-.04em; line-height:.8; color:#fff;
  text-transform:uppercase; opacity:.042; pointer-events:none; user-select:none; white-space:nowrap; }
.hp-closer__in{ position:relative; }
.hp-closer h2{ font-family:var(--font-display); font-weight:700; font-size:clamp(34px,5.4vw,66px);
  letter-spacing:-.04em; line-height:1.02; color:#fff; margin:0; }
.hp-closer p{ font-size:19px; line-height:1.55; color:var(--n-400); margin:20px auto 0; max-width:56ch; }
.hp-closer__cta{ display:flex; align-items:center; justify-content:center; gap:20px; margin-top:36px; flex-wrap:wrap; }
.hp-closer__alt{ font-size:14.5px; font-weight:600; color:var(--n-300); display:inline-flex; align-items:center; gap:6px; }
.hp-closer__alt:hover{ color:#fff; }
.hp-closer__fine{ margin-top:30px; font-size:13px; color:var(--n-400); }


/* ============================================================
   Whooshly homepage (.hp-*)
   Two hues only: violet = product, coral = the spark. Neutrals carry
   everything else, and the product UI carries the colour interest.
   ============================================================ */
.hp{ --hp-line:1px solid var(--border); }
.hp-sec{ padding:118px 0; position:relative; }
.hp-sec--rule{ border-top:var(--hp-line); }
.hp-sec--sunken{ background:var(--surface-sunken); }
.hp-sec--tight{ padding:88px 0; }

/* --- section headers --- */
.hp-eye{ display:inline-flex; align-items:center; gap:12px; font-family:var(--font-mono); font-size:11px;
  line-height:1; letter-spacing:.18em; text-transform:uppercase; color:var(--muted-foreground); }
.hp-eye::before{ content:""; width:24px; height:2px; border-radius:2px; background:var(--whoosh); flex-shrink:0; }
.hp-h2{ font-family:var(--font-display); font-weight:700; font-size:clamp(31px,4.3vw,52px); line-height:1.02;
  letter-spacing:-.036em; margin:20px 0 0; color:var(--foreground); text-wrap:balance; }
.hp-h2 span{ color:var(--muted-foreground); }
.hp-lede{ font-size:18.5px; line-height:1.62; color:var(--muted-foreground); margin:20px 0 0; max-width:64ch; text-wrap:pretty; }
.hp-head{ max-width:780px; }
.hp-head--mid{ margin-left:auto; margin-right:auto; text-align:center; }
.hp-head--mid .hp-lede{ margin-left:auto; margin-right:auto; }

/* --- scroll reveal (gated on .hp-js so a no-JS page renders fully visible) --- */
.hp-js .hp-rise{ opacity:0; transform:translateY(20px);
  transition:opacity .75s var(--ease-arrive), transform .75s var(--ease-arrive); }
.hp-js .hp-rise.is-in{ opacity:1; transform:none; }
@media (prefers-reduced-motion:reduce){ .hp-js .hp-rise{ opacity:1; transform:none; transition:none; } }

/* --- lists --- */
.hp-checks{ display:flex; flex-direction:column; gap:14px; margin-top:30px; }
.hp-check{ display:flex; gap:12px; align-items:flex-start; font-size:15.5px; line-height:1.5; color:var(--foreground); }
.hp-check svg{ width:18px; height:18px; margin-top:2px; color:var(--success); flex-shrink:0; }
.hp-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.hp-chip{ font-family:var(--font-mono); font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted-foreground); border:var(--hp-line); border-radius:999px; padding:6px 12px; background:var(--card); }

/* ============================================================ HERO */
.hp-hero{ position:relative; padding:70px 0 78px; overflow:clip; }
.hp-hero::before{ content:""; position:absolute; left:0; right:0; top:-260px; height:760px; pointer-events:none;
  background:radial-gradient(46% 56% at 26% 34%, rgba(91,51,240,.14), transparent 72%),
             radial-gradient(34% 44% at 88% 12%, rgba(255,92,114,.11), transparent 74%); }
.hp-hero__in{ position:relative; }
.hp-pill{ display:inline-flex; align-items:center; gap:9px; padding:6px 14px 6px 11px; border-radius:999px;
  background:var(--card); border:var(--hp-line); box-shadow:var(--sh-sm); font-size:13px; font-weight:600;
  letter-spacing:-.005em; }
.hp-pill i{ width:7px; height:7px; border-radius:999px; background:var(--coral-500); display:block; flex-shrink:0;
  box-shadow:0 0 0 3px rgba(255,92,114,.18); }
.hp-h1{ font-family:var(--font-display); font-weight:700; font-size:clamp(41px,6.1vw,79px); line-height:.99;
  letter-spacing:-.043em; margin:24px 0 0; max-width:19ch; }
.hp-h1 span{ display:block; color:var(--muted-foreground); }
.hp-sub{ font-size:19px; line-height:1.6; color:var(--muted-foreground); margin:26px 0 0; max-width:63ch; text-wrap:pretty; }
.hp-cta{ display:flex; gap:12px; margin-top:34px; flex-wrap:wrap; }
.hp-fine{ margin:16px 0 0; font-size:13.5px; color:var(--muted-foreground); }
.hp-proof{ display:flex; gap:10px 24px; flex-wrap:wrap; margin-top:28px; font-size:13.5px; color:var(--muted-foreground); }
.hp-proof span{ display:inline-flex; align-items:center; gap:7px; }
.hp-proof svg{ width:16px; height:16px; color:var(--success); flex-shrink:0; }

/* --- the product frame (the tour video drops straight into .hp-shot__stage) --- */
.hp-shot{ margin-top:58px; position:relative; }
.hp-shot__frame{ position:relative; border:var(--hp-line); border-radius:18px; background:var(--card); overflow:hidden;
  box-shadow:0 44px 100px -34px rgba(26,11,77,.34), 0 14px 34px -14px rgba(26,11,77,.14); }
.hp-shot__bar{ height:40px; display:flex; align-items:center; gap:10px; padding:0 15px;
  border-bottom:var(--hp-line); background:var(--surface-sunken); }
.hp-shot__dots{ display:flex; gap:6px; flex-shrink:0; }
.hp-shot__dots i{ width:9px; height:9px; border-radius:999px; background:var(--n-300); display:block; }
.hp-shot__url{ margin:0 auto; font-family:var(--font-mono); font-size:11.5px; color:var(--muted-foreground);
  background:var(--card); border:var(--hp-line); border-radius:999px; padding:4px 15px; max-width:70%;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.hp-shot__stage{ position:relative; aspect-ratio:16/9; background:var(--card); overflow:hidden; }
.hp-shot__stage>video,.hp-shot__stage>img{ position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block; }
.hp-shot__caps{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); border-top:var(--hp-line);
  background:var(--surface-sunken); }
.hp-shot__cap{ padding:18px 22px 20px; border-left:var(--hp-line); }
.hp-shot__cap:first-child{ border-left:0; }
.hp-shot__cap b{ display:block; font-family:var(--font-display); font-weight:600; font-size:14.5px;
  letter-spacing:-.01em; color:var(--foreground); }
.hp-shot__cap span{ display:block; margin-top:5px; font-size:13px; line-height:1.5; color:var(--muted-foreground); }

/* ============================================================ product-UI mock kit (.pm-*)
   Shared by the hero stage, the surface panels and the analytics band. These are deliberately
   built from the same tokens as the real app, so a screenshot swap later looks continuous. */
.pm{ font-family:var(--font-sans); color:var(--foreground); }
.pm-row{ display:flex; align-items:center; gap:10px; }
.pm-slug{ font-family:var(--font-mono); font-size:13px; color:var(--muted-foreground); white-space:nowrap; }
.pm-slug b{ color:var(--primary); font-weight:700; }
.pm-live{ display:inline-flex; align-items:center; gap:6px; font-size:10.5px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--success-ink); background:var(--success-soft); border-radius:999px; padding:3px 9px; }
.pm-live i{ width:6px; height:6px; border-radius:999px; background:var(--success); display:block; }
.pm-dest{ font-size:12.5px; color:var(--muted-foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pm-btn{ display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 12px; border-radius:8px;
  font-family:var(--font-display); font-weight:600; font-size:12.5px; border:var(--hp-line); background:var(--card);
  color:var(--foreground); white-space:nowrap; }
.pm-btn--pri{ background:var(--primary); border-color:transparent; color:#fff; }
/* Some .pm-btn instances are now real <a>/<button> elements rather than decorative spans, so they
   need the type resets a span never did — and a pointer, since they actually do something. */
a.pm-btn, button.pm-btn{ cursor:pointer; font-family:var(--font-display); text-decoration:none;
  appearance:none; transition:var(--t-colors); }
a.pm-btn:hover, button.pm-btn:hover{ border-color:var(--primary); color:var(--primary-soft-ink); }
a.pm-btn--pri:hover, button.pm-btn--pri:hover{ background:var(--primary-hover); color:#fff;
  border-color:transparent; }
.pm-btn svg{ width:14px; height:14px; }
.pm-lbl{ font-family:var(--font-mono); font-size:10px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--muted-foreground); }
.pm-num{ font-family:var(--font-display); font-weight:700; letter-spacing:-.03em; line-height:1;
  font-variant-numeric:tabular-nums; }
.pm-delta{ font-size:11.5px; font-weight:700; color:var(--success-ink); }
.pm-card{ border:var(--hp-line); border-radius:12px; background:var(--card); }
.pm-sep{ height:1px; background:var(--border); }

/* metric strip */
.pm-metrics{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1px; background:var(--border);
  border:var(--hp-line); border-radius:12px; overflow:hidden; }
.pm-metric{ background:var(--card); padding:14px 16px; min-width:0; }
.pm-metric .pm-num{ font-size:clamp(20px,2.1vw,30px); margin-top:8px; }
.pm-metric__f{ display:flex; align-items:center; gap:8px; margin-top:7px; }

/* bar chart */
.pm-bars{ display:flex; align-items:flex-end; gap:var(--pm-bg,3px); height:100%; }
.pm-bars>i{ flex:1; min-width:0; display:block; border-radius:3px 3px 1px 1px; background:var(--violet-200);
  transform-origin:bottom; }
.pm-bars>i.a{ background:var(--primary); }
.pm-bars>i.c{ background:var(--coral-400); }
/* Charts draw themselves in only when JS is there to say the section has scrolled into view — with
   JS off they render at full height rather than as an empty axis. */
.hp-js .pm-bars>i{ transform:scaleY(.06); transition:transform .9s var(--ease-arrive) var(--bd,0ms); }
.hp-js .is-in .pm-bars>i, .hp-js .hp-shot .pm-bars>i{ transform:none; }
@keyframes hp-grow{ from{ transform:scaleY(.06); } to{ transform:none; } }
@keyframes hp-fill{ from{ width:0; } to{ width:var(--w); } }
@media (prefers-reduced-motion:no-preference){
  .hp-shot .pm-bars>i{ animation:hp-grow .85s var(--ease-arrive) var(--bd,0ms) both; }
  .hp-shot .pm-rank__t i{ animation:hp-fill .9s var(--ease-arrive) var(--bd,0ms) both; }
}
.dark .pm-bars>i{ background:color-mix(in srgb, var(--violet-400) 34%, var(--n-900)); }
.dark .pm-bars>i.a{ background:var(--violet-400); }
.dark .pm-bars>i.c{ background:var(--coral-500); }
@media (prefers-reduced-motion:reduce){ .hp-js .pm-bars>i{ transform:none !important; transition:none; } }
.pm-axis{ display:flex; justify-content:space-between; margin-top:9px; }

/* rank list (countries / devices / referrers) */
.pm-rank{ display:flex; flex-direction:column; gap:11px; }
.pm-rank__r{ display:grid; grid-template-columns:1fr auto; gap:4px 10px; }
.pm-rank__n{ font-size:12.5px; color:var(--foreground); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pm-rank__v{ font-family:var(--font-mono); font-size:11.5px; color:var(--muted-foreground); }
.pm-rank__t{ grid-column:1 / -1; height:5px; border-radius:999px; background:var(--muted); overflow:hidden; }
.pm-rank__t i{ display:block; height:100%; border-radius:999px; background:var(--primary); width:var(--w); }
.hp-js .pm-rank__t i{ width:0; transition:width 1s var(--ease-arrive) var(--bd,0ms); }
.hp-js .is-in .pm-rank__t i,.hp-js .hp-shot .pm-rank__t i{ width:var(--w); }
@media (prefers-reduced-motion:reduce){ .hp-js .pm-rank__t i{ width:var(--w) !important; transition:none; } }

/* surfaces checklist */
.pm-surfaces{ display:flex; flex-direction:column; gap:1px; background:var(--border); border:var(--hp-line);
  border-radius:12px; overflow:hidden; }
.pm-surface{ display:flex; align-items:center; gap:9px; padding:9px 12px; background:var(--card); font-size:12.5px; }
.pm-surface svg{ width:15px; height:15px; color:var(--muted-foreground); flex-shrink:0; }
.pm-surface b{ font-weight:500; }
.pm-surface span{ margin-left:auto; font-family:var(--font-mono); font-size:11px; color:var(--muted-foreground); }
.pm-surface--on svg{ color:var(--primary); }
.pm-toggle{ width:26px; height:15px; border-radius:999px; background:var(--muted); position:relative;
  display:block; flex-shrink:0; border:var(--hp-line); }
.pm-toggle::after{ content:""; position:absolute; top:1.5px; left:2px; width:10px; height:10px; border-radius:999px;
  background:var(--n-400); }
.pm-toggle--on{ background:var(--primary); border-color:transparent; }
.pm-toggle--on::after{ left:auto; right:2px; background:#fff; }

/* phone + mini-window frames */
.pm-phone{ width:212px; border:1px solid var(--n-800); border-radius:26px; background:var(--n-950); padding:6px;
  box-shadow:var(--sh-lg); flex-shrink:0; }
.pm-phone__scr{ border-radius:21px; overflow:hidden; background:var(--card); position:relative; }
.pm-phone__notch{ position:absolute; top:7px; left:50%; transform:translateX(-50%); width:52px; height:5px;
  border-radius:999px; background:var(--n-800); z-index:2; }
.pm-win{ border:var(--hp-line); border-radius:12px; overflow:hidden; background:var(--card); box-shadow:var(--sh-sm); }
.pm-win__bar{ height:28px; display:flex; align-items:center; gap:7px; padding:0 11px; border-bottom:var(--hp-line);
  background:var(--surface-sunken); }
.pm-win__bar i{ width:7px; height:7px; border-radius:999px; background:var(--n-300); display:block; }
.pm-win__u{ margin-left:6px; font-family:var(--font-mono); font-size:10px; color:var(--muted-foreground);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* ============================================================ HERO STAGE composition */
/* The stage is a fixed 16:9 box, so the two columns must never grow past it — the chart absorbs the
   difference (grid-template-rows caps the row; min-height:0 lets the flex chart actually shrink). */
.hp-ov{ position:absolute; inset:0; display:grid; grid-template-columns:minmax(0,1.62fr) minmax(0,.86fr);
  grid-template-rows:minmax(0,1fr); }
.hp-ov__main{ display:flex; flex-direction:column; padding:clamp(16px,1.9vw,26px); min-width:0; min-height:0;
  overflow:hidden; gap:clamp(12px,1.5vw,20px); }
.hp-ov__side{ border-left:var(--hp-line); background:var(--surface-sunken); padding:clamp(14px,1.6vw,22px);
  display:flex; flex-direction:column; gap:14px; min-width:0; min-height:0; overflow:hidden; }
.hp-ov__head{ display:flex; align-items:center; gap:12px; min-width:0; }
.hp-ov__chart{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.hp-ov__foot{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,1.8vw,26px); }
.hp-ov__engine{ margin-top:auto; border:var(--hp-line); border-radius:12px; background:var(--card); padding:13px 14px; }
.hp-ov__engine p{ font-size:11.5px; line-height:1.5; color:var(--muted-foreground); margin:7px 0 10px; }
.hp-ov__engine .hp-chips{ gap:6px; }
.hp-ov__engine .hp-chip{ font-size:9.5px; padding:4px 8px; }
.pm-surface--add{ color:var(--muted-foreground); }
.hp-ov__chart>div:first-child{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:10px; }
.hp-ov__plot{ flex:1; min-height:56px; }
.hp-ov__side .pm-lbl{ display:block; }
.hp-ov__qr{ background:var(--card); border:var(--hp-line); border-radius:12px; padding:12px;
  display:flex; align-items:center; gap:12px; }
.hp-ov__qrimg{ line-height:0; flex-shrink:0; }
.hp-ov__qrimg svg{ width:clamp(56px,6.4vw,84px) !important; height:auto !important; }
.hp-ov__qr .pm-btn{ height:26px; padding:0 9px; font-size:11px; }

/* Below ~1080px the 16:9 stage is too short for the full dashboard, so the secondary blocks drop
   out in order of importance rather than overflowing the frame. */
@media (max-width:1079px){ .hp-ov__opt{ display:none; } }
@media (min-width:761px) and (max-width:1079px){ .hp-ov__engine{ display:none; } }

/* ============================================================ THE KIT (surface switcher) */
.hp-kit{ display:grid; grid-template-columns:296px minmax(0,1fr); gap:36px; margin-top:56px; align-items:start; }
.hp-kit>input{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
.hp-rail{ display:flex; flex-direction:column; gap:3px; position:relative; }
.hp-rail label{ display:flex; gap:13px; align-items:flex-start; padding:14px 16px; border-radius:12px; cursor:pointer;
  border:1px solid transparent; transition:background var(--d-fast) var(--ease-standard), border-color var(--d-fast) var(--ease-standard); }
.hp-rail label:hover{ background:var(--muted); }
.hp-rail__i{ width:32px; height:32px; border-radius:9px; display:grid; place-items:center; background:var(--muted);
  color:var(--muted-foreground); flex-shrink:0; transition:var(--t-colors); }
.hp-rail__i svg{ width:17px; height:17px; }
.hp-rail__t{ display:block; font-family:var(--font-display); font-weight:600; font-size:15.5px; letter-spacing:-.012em; }
.hp-rail__d{ display:block; font-size:13px; line-height:1.45; color:var(--muted-foreground); margin-top:4px; }
.hp-rail__note{ margin:18px 16px 0; font-size:13px; line-height:1.55; color:var(--muted-foreground); }
.hp-stage{ display:grid; min-height:474px; }
.hp-panel{ grid-area:1/1; min-width:0; opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity var(--d-slow) var(--ease-arrive), transform var(--d-slow) var(--ease-arrive), visibility var(--d-slow); }
.hp-panel.is-on{ opacity:1; visibility:visible; transform:none; }
.hp-kit__foot{ display:flex; align-items:center; gap:12px 20px; flex-wrap:wrap; margin-top:28px; padding:18px 22px;
  border:var(--hp-line); border-radius:14px; background:var(--surface-sunken); }
.hp-kit__foot b{ font-family:var(--font-display); font-weight:600; font-size:14.5px; letter-spacing:-.01em; }
.hp-kit__foot .hp-chip{ background:var(--card); }

/* the panel shell every surface preview sits in */
.hp-pan{ display:flex; flex-direction:column; height:100%; min-width:0; max-width:100%; border:var(--hp-line); border-radius:16px;
  background:var(--card); box-shadow:var(--sh-md); overflow:hidden; }
.hp-pan__top{ display:flex; align-items:center; gap:12px; padding:14px 18px; border-bottom:var(--hp-line);
  background:var(--surface-sunken); flex-shrink:0; }
.hp-pan__path{ margin-left:auto; font-family:var(--font-mono); font-size:11px; color:var(--muted-foreground);
  border:var(--hp-line); border-radius:999px; padding:4px 11px; background:var(--card); white-space:nowrap; }
.hp-pan__t{ font-family:var(--font-display); font-weight:600; font-size:14px; letter-spacing:-.01em; }
.hp-pan__body{ flex:1; min-width:0; padding:20px; }
.hp-pan__split{ display:grid; grid-template-columns:minmax(0,1fr) 232px; gap:22px; }
.hp-pan__note{ display:flex; gap:9px; align-items:flex-start; padding:13px 18px; border-top:var(--hp-line);
  background:var(--surface-sunken); font-size:13px; line-height:1.5; color:var(--muted-foreground); }
.hp-pan__note svg{ width:16px; height:16px; color:var(--primary); flex-shrink:0; margin-top:1px; }
.hp-pan__note b{ color:var(--foreground); font-weight:600; }
.hp-pan__more{ margin-left:auto; align-self:center; white-space:nowrap; font-family:var(--font-display);
  font-weight:600; font-size:12.5px; color:var(--primary); text-decoration:none; }
.hp-pan__more:hover{ text-decoration:underline; }

/* link table */
.pm-bar{ display:flex; align-items:center; gap:9px; margin-bottom:6px; min-width:0; }
.pm-search{ display:inline-flex; align-items:center; gap:8px; height:30px; padding:0 12px; border-radius:8px;
  border:var(--hp-line); background:var(--surface-sunken); font-size:12.5px; color:var(--muted-foreground);
  min-width:0; white-space:nowrap; overflow:hidden; }
.pm-search svg{ width:14px; height:14px; }
.pm-tbl{ display:flex; flex-direction:column; }
.pm-tbl__more{ display:flex; justify-content:space-between; gap:12px; padding-top:14px; font-family:var(--font-mono);
  font-size:11px; color:var(--muted-foreground); }
.hp-ov__qr{ align-items:flex-start; }
.pm-tbl__h,.pm-tbl__r{ display:grid; grid-template-columns:30px minmax(0,1fr) 62px 62px 74px; gap:12px;
  align-items:center; padding:11px 4px; }
.pm-tbl__h{ border-bottom:var(--hp-line); padding-bottom:9px; }
.pm-tbl__r{ border-bottom:var(--hp-line); }
.pm-tbl__r:last-child{ border-bottom:0; }
.pm-tbl__i{ width:30px; height:30px; border-radius:8px; display:grid; place-items:center;
  background:var(--primary-soft); color:var(--primary); }
.pm-tbl__i svg{ width:15px; height:15px; }
.pm-tbl__n{ text-align:right; font-family:var(--font-display); font-weight:600; font-size:13.5px;
  font-variant-numeric:tabular-nums; }
.pm-tbl__n--m{ color:var(--muted-foreground); font-weight:400; }

/* UTM builder */
.pm-utm{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.pm-field label{ display:block; font-size:11.5px; font-weight:600; color:var(--muted-foreground); margin-bottom:5px; }
.pm-field div{ border:var(--hp-line); border-radius:8px; background:var(--card); padding:8px 11px;
  font-family:var(--font-mono); font-size:12px; color:var(--foreground); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.pm-field--on div{ border-color:var(--ring); box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 20%, transparent); }
.pm-url{ font-family:var(--font-mono); font-size:12px; line-height:1.75; word-break:break-all;
  background:var(--surface-sunken); border:var(--hp-line); border-radius:10px; padding:12px 13px; }
.pm-url .k{ color:var(--violet-600); } .pm-url .v{ color:var(--coral-600); } .pm-url .q{ color:var(--muted-foreground); }

/* vcard + bio phone content */
.pm-vc__cover{ height:64px; background:var(--whoosh); }
.pm-vc__av{ width:56px; height:56px; border-radius:999px; border:3px solid var(--card); margin:-28px auto 0;
  background:var(--violet-100); color:var(--violet-700); display:grid; place-items:center;
  font-family:var(--font-display); font-weight:700; font-size:19px; position:relative; }
.pm-vc__b{ padding:10px 16px 16px; text-align:center; }
.pm-bio__l{ display:flex; align-items:center; gap:8px; border:var(--hp-line); border-radius:10px; padding:9px 11px;
  font-size:12px; font-weight:600; background:var(--card); }
.pm-bio__l span{ margin-left:auto; font-family:var(--font-mono); font-size:10.5px; font-weight:400;
  color:var(--muted-foreground); }

/* landing page mock */
.pm-lp__f{ border:var(--hp-line); border-radius:8px; padding:8px 10px; font-size:11.5px;
  color:var(--muted-foreground); background:var(--card); }

/* ============================================================ TRY IT (live QR widget) */
.hp-try{ display:grid; grid-template-columns:minmax(0,1fr) 420px; gap:56px; align-items:center; }
.hp-try__card{ border:var(--hp-line); border-radius:16px; background:var(--card); box-shadow:var(--sh-lg); overflow:hidden; }
.hp-try__top{ display:flex; align-items:center; gap:12px; padding:14px 18px; border-bottom:var(--hp-line);
  background:var(--surface-sunken); }
.hp-try__top .pm-live{ margin-left:auto; }
.hp-try__body{ padding:18px; }
.hp-try__out{ display:flex; gap:18px; margin-top:18px; align-items:flex-start; }
.hp-try__qr{ line-height:0; flex-shrink:0; border:var(--hp-line); border-radius:12px; padding:8px; background:#fff; }
.hp-try__qr svg{ width:126px !important; height:auto !important; border-radius:6px; }
.hp-try__side{ flex:1; min-width:0; display:flex; flex-direction:column; gap:14px; }
.hp-try__sw{ display:flex; gap:9px; }
.hp-try__sw .qr-sw{ width:26px; height:26px; padding:0; border:0; border-radius:999px; cursor:pointer;
  transition:transform var(--d-fast) var(--ease-whoosh); }
.hp-try__sw .qr-sw:hover{ transform:translateY(-2px); }
.hp-try__claim{ text-align:center; font-size:12.5px; font-weight:600; color:var(--primary); text-decoration:none; }
.hp-try__claim:hover{ text-decoration:underline; }

/* ============================================================ CHANGE STORY */
.hp-two{ display:grid; grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); gap:56px; align-items:center; }
.hp-tl{ border:var(--hp-line); border-radius:16px; background:var(--card); box-shadow:var(--sh-md); overflow:hidden; }
.hp-tl__demo,.hp-an__demo{ font-family:var(--font-mono); font-size:9.5px; font-weight:700;
  letter-spacing:.11em; text-transform:uppercase; color:var(--primary); }
.hp-tl__demo{ padding:11px 22px; border-bottom:var(--hp-line); background:var(--violet-50); }
.hp-tl__top{ display:flex; align-items:center; gap:16px; padding:22px; border-bottom:var(--hp-line); }
.hp-tl__top>div{ min-width:0; }
.hp-tl__qr{ padding:9px; border:var(--hp-line); border-radius:12px; background:#fff; line-height:0; flex-shrink:0; }
.hp-tl__list{ padding:6px 20px 8px; }
.hp-tl__r{ display:grid; grid-template-columns:66px 1fr auto; gap:14px; align-items:center; padding:13px 0;
  position:relative; }
.hp-tl__r+.hp-tl__r{ border-top:1px dashed var(--border); }
.hp-tl__d{ font-family:var(--font-mono); font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted-foreground); }
.hp-tl__u{ font-family:var(--font-mono); font-size:13px; color:var(--muted-foreground); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.hp-tl__r--on{ margin-left:-22px; padding-left:22px; box-shadow:inset 3px 0 0 var(--primary); }
.hp-tl__r--on .hp-tl__u{ color:var(--foreground); font-weight:700; }
.hp-tl__tag{ font-family:var(--font-mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted-foreground); }
.hp-tl__foot{ padding:15px 20px; border-top:var(--hp-line); background:var(--surface-sunken); font-size:13.5px;
  color:var(--muted-foreground); }
.hp-tl__foot b{ color:var(--foreground); }

/* ============================================================ ANALYTICS (dark band) */
.hp-dark{ background:var(--n-950); color:var(--foreground); }
.hp-an{ display:grid; grid-template-columns:minmax(0,1fr) 300px; gap:0; margin-top:52px; border:var(--hp-line);
  border-radius:18px; overflow:hidden; background:var(--card); box-shadow:0 40px 90px -40px rgba(0,0,0,.8); }
.hp-an__main{ display:flex; flex-direction:column; padding:22px 24px 24px; min-width:0; }
.hp-an__side{ border-left:var(--hp-line); background:var(--surface-sunken); padding:22px; display:flex;
  flex-direction:column; gap:24px; min-width:0; }
.hp-an__tabs{ display:flex; gap:2px; align-items:center; border-bottom:var(--hp-line); margin:-4px 0 20px; flex-shrink:0; }
.hp-an__demo{ margin-right:8px; color:var(--violet-300); white-space:nowrap; }
.hp-an__cap{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-top:26px; }
.hp-an__tab{ font-size:13px; font-weight:600; color:var(--muted-foreground); padding:11px 13px; position:relative; white-space:nowrap; }
.hp-an__tab--on{ color:var(--foreground); }
.hp-an__tab--on::after{ content:""; position:absolute; left:13px; right:13px; bottom:-1px; height:2px;
  border-radius:2px; background:var(--whoosh); }
.hp-an__range{ margin-left:auto; }
.hp-an__plot{ flex:1; min-height:172px; margin-top:22px; }

/* ============================================================ PAY ONCE */
.hp-cost{ border:var(--hp-line); border-radius:16px; background:var(--card); box-shadow:var(--sh-md); padding:24px; }
.hp-cost__head{ display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.hp-cost__legend{ display:flex; flex-direction:column; gap:7px; }
.hp-cost__legend span{ display:inline-flex; align-items:center; gap:8px; font-size:12.5px; color:var(--muted-foreground); }
.hp-cost__legend i{ width:16px; height:2.5px; border-radius:2px; display:block; }
.hp-cost svg{ display:block; width:100%; height:auto; margin-top:18px; }
.hp-cost__foot{ margin-top:18px; padding-top:16px; border-top:var(--hp-line); font-size:14px;
  color:var(--muted-foreground); }
.hp-cost__foot b{ font-family:var(--font-display); font-size:17px; color:var(--foreground); letter-spacing:-.02em; }
.hp-cost__wipe{ transform-box:fill-box; transform-origin:left center; }
.hp-js .hp-cost__wipe{ transform:scaleX(0); transition:transform 1.4s var(--ease-arrive); }
.hp-js .is-in .hp-cost__wipe{ transform:scaleX(1); }
@media (prefers-reduced-motion:reduce){ .hp-js .hp-cost__wipe{ transform:none !important; transition:none; } }

/* ============================================================ PRICING */
.hp-price{ display:grid; grid-template-columns:1fr 1fr; gap:0; max-width:840px; margin:52px auto 0;
  border:var(--hp-line); border-radius:18px; overflow:hidden; background:var(--card); box-shadow:var(--sh-md); }
.hp-plan{ padding:34px 32px 32px; display:flex; flex-direction:column; }
.hp-plan+.hp-plan{ border-left:var(--hp-line); }
.hp-plan--core{ position:relative;
  background:linear-gradient(180deg, color-mix(in srgb, var(--violet-500) 6%, var(--card)), var(--card) 62%); }
.hp-plan--core::before{ content:""; position:absolute; inset:0 0 auto; height:3px; background:var(--whoosh); }
.hp-plan__n{ display:flex; align-items:center; gap:10px; font-family:var(--font-display); font-weight:600; font-size:19px; }
.hp-plan__tag{ font-family:var(--font-mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--coral-700); background:var(--coral-50); border-radius:999px; padding:4px 9px; }
.hp-plan__p{ display:flex; align-items:baseline; gap:9px; margin-top:16px; }
.hp-plan__p b{ font-family:var(--font-display); font-weight:700; font-size:52px; letter-spacing:-.04em; line-height:1; }
.hp-plan__p span{ color:var(--muted-foreground); font-weight:600; font-size:15px; }
.hp-plan__s{ font-size:14px; color:var(--muted-foreground); margin:10px 0 0; }
.hp-plan .hp-checks{ margin:26px 0 30px; gap:12px; }
.hp-plan .hp-check{ font-size:14.5px; }
.hp-plan__cta{ margin-top:auto; }
.hp-price__foot{ text-align:center; font-size:13.5px; color:var(--muted-foreground); max-width:56ch;
  margin:26px auto 0; line-height:1.6; }

/* ============================================================ RESPONSIVE */
@media (max-width:1080px){
  .hp-kit{ grid-template-columns:264px minmax(0,1fr); gap:26px; }
  .hp-two{ gap:40px; }
  .hp-pan__split{ grid-template-columns:minmax(0,1fr) 200px; gap:18px; }
  .hp-an{ grid-template-columns:minmax(0,1fr) 258px; }
}
@media (max-width:940px){
  .hp-sec{ padding:88px 0; }
  .hp-try{ grid-template-columns:1fr; gap:34px; }
  .hp-ov__foot{ grid-template-columns:1fr; }
  .hp-two{ grid-template-columns:1fr; gap:38px; }
  .hp-an{ grid-template-columns:1fr; }
  .hp-an__side{ border-left:0; border-top:var(--hp-line); flex-direction:row; flex-wrap:wrap; gap:26px 34px; }
  .hp-an__side>*{ flex:1 1 190px; min-width:0; }
  .hp-an__plot{ min-height:150px; }
  /* surface switcher: rail becomes a scrollable chip bar above the stage */
  .hp-kit{ grid-template-columns:minmax(0,1fr); gap:22px; margin-top:40px; }
  .hp-rail{ flex-direction:row; gap:8px; overflow-x:auto; padding-bottom:6px; scrollbar-width:none;
    -webkit-overflow-scrolling:touch; }
  .hp-rail::-webkit-scrollbar{ display:none; }
  .hp-rail label{ flex-direction:column; gap:8px; padding:12px 14px; border:var(--hp-line); border-radius:12px;
    min-width:132px; background:var(--card); }
  .hp-rail__d{ display:none; }
  .hp-rail__note{ display:none; }
  .hp-rail__t{ font-size:13.5px; white-space:nowrap; }
  .hp-stage{ min-height:0; }
  .hp-panel{ position:relative; }
  .hp-pan__split{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width:760px){
  .hp-hero{ padding-top:44px; }
  .hp-h1{ max-width:none; }
  .hp-sub{ font-size:17px; margin-top:20px; }
  .hp-cta{ margin-top:26px; gap:10px; }
  .hp-cta .wsh-btn{ flex:1 1 auto; }
  .hp-shot{ margin-top:40px; }
  .hp-shot__frame{ border-radius:14px; }
  .hp-shot__stage{ aspect-ratio:auto; }
  /* the hero composition reflows to a stack, so it stays legible instead of scaling to 5px type */
  .hp-ov{ position:static; grid-template-columns:1fr; grid-template-rows:none; }
  .hp-ov__main,.hp-ov__side{ overflow:visible; }
  .hp-ov__main{ gap:16px; padding:18px 16px; }
  .hp-ov__side{ border-left:0; border-top:var(--hp-line); gap:14px; padding:16px; }
  .hp-ov__qrimg svg{ width:64px !important; }
  .hp-ov__engine{ margin-top:0; }
  .hp-ov__plot{ height:96px; }
  .hp-shot__caps{ grid-template-columns:1fr; }
  .hp-shot__cap{ border-left:0; border-top:var(--hp-line); padding:15px 18px 16px; }
  .hp-shot__cap:first-child{ border-top:0; }
  .hp-h2{ font-size:clamp(27px,7.6vw,36px); }
  .hp-lede{ font-size:16.5px; }
  .hp-price{ grid-template-columns:1fr; }
  .hp-plan+.hp-plan{ border-left:0; border-top:var(--hp-line); }
  .hp-plan{ padding:28px 22px; }
  .hp-plan__p b{ font-size:44px; }
  .hp-closer{ padding:84px 0 104px; }
  .hp-closer__mark{ font-size:24vw; bottom:-5%; }
  .hp-metrics-2{ grid-template-columns:1fr 1fr !important; }
  .pm-tbl__h,.pm-tbl__r{ grid-template-columns:26px minmax(0,1fr) 54px; gap:9px; }
  .pm-tbl__r .pm-live{ display:none; }
  .pm-tbl__h>:nth-child(4),.pm-tbl__r>:nth-child(4),
  .pm-tbl__h>:nth-child(5),.pm-tbl__r>:nth-child(5){ display:none; }
  .pm-utm{ grid-template-columns:1fr; }
  .hp-tl__top{ flex-wrap:wrap; }
  .hp-try__out{ flex-direction:column; align-items:stretch; }
  .hp-try__qr{ align-self:center; }
  .hp-tl__r{ grid-template-columns:58px 1fr; }
  .hp-tl__tag{ grid-column:2; }
  .hp-an__plot{ height:130px; }
  .hp-an__tabs{ overflow-x:auto; scrollbar-width:none; }
  .hp-an__tabs::-webkit-scrollbar{ display:none; }
  .hp-an__main,.hp-an__side{ padding:18px 16px; }
  .hp-an__side{ flex-direction:column; gap:24px; }
  .hp-an__side>*{ flex:none; }
  .hp-an__cap{ flex-direction:column; gap:4px; margin-top:20px; }
  .hp-pan__body{ padding:16px; }
  /* the panel toolbars/footers stack instead of pushing the panel past the viewport */
  .pm-bar{ flex-wrap:wrap; }
  .pm-bar>.pm-btn:not(.pm-btn--pri){ display:none; }
  .pm-bar>.pm-btn--pri{ margin-left:auto !important; }
  .hp-pan__note{ flex-wrap:wrap; }
  .hp-pan__note>span{ flex:1 1 0; min-width:0; }
  .hp-pan__more{ margin-left:0; margin-top:4px; width:100%; }
  .pm-phone{ width:100%; max-width:212px; margin:0 auto; }
}
@media (max-width:560px){ .hp-ov__edit{ display:none; } }
@media (max-width:480px){
  .pm-metrics{ grid-template-columns:1fr 1fr; }
  .pm-metrics>:last-child{ grid-column:1 / -1; }
  .hp-proof{ gap:8px 16px; font-size:12.5px; }
}

.hp--v2{
  --ink:var(--border);
  --bw:1px;
  --hard:var(--sh-lg);
  --hard-sm:var(--sh-sm);
}
.dark .hp--v2, .hp--v2 .dark{
  --ink:var(--n-700);
  --hard:0 20px 52px -28px rgba(0,0,0,.64);
  --hard-sm:0 8px 24px -18px rgba(0,0,0,.7);
}

/* ---- rhythm: clear sections without poster-like rules ---- */
.hp--v2 .hp-sec{ padding:clamp(72px,8vw,110px) 0; }
.hp--v2 .hp-sec--rule{ border-top:1px solid var(--border); }
.hp--v2 .hp-dark{ border-top:1px solid var(--n-800); }

/* ---- chapter headers: compact overlines, not badges ---- */
.hp--v2 .hp-eye{ gap:9px; font-weight:700; letter-spacing:.13em; }
.hp--v2 .hp-eye::before{ display:none; }
.hp--v2 .hp-eye b{ color:var(--primary); font-size:11px; letter-spacing:.08em; }
.hp--v2 .hp-eye b::after{ content:"/"; margin-left:9px; color:var(--n-300); }
.hp--v2 .hp-h2{ font-size:clamp(30px,4.5vw,54px); letter-spacing:-.042em; line-height:1.01; margin-top:20px; }
.hp--v2 .hp-head{ max-width:820px; }

/* ============================================================ HERO
   Centred and short: an eyebrow, one headline, one line of copy, then the tool. Nothing else
   competes with the field the visitor is meant to type in. */
/* Sized so the whole tool — label, field and submit — clears a 720px-tall viewport. A hero
   headline big enough to push the input below the fold defeats the point of putting the working
   product in the hero at all, so the type here is deliberately smaller than the chapter headings
   further down the page. */
.hp--v2 .hp-hero{ padding:clamp(36px,4vw,58px) 0 clamp(56px,6vw,86px); text-align:center;
  background:linear-gradient(180deg,color-mix(in srgb,var(--violet-50) 54%,var(--background)),var(--background) 72%); }
.hp--v2 .hp-hero::before{ top:-300px; height:820px;
  background:radial-gradient(44% 48% at 50% 28%,rgba(91,51,240,.09),transparent 72%); }
.hp--v2 .hp-h1{ font-size:clamp(40px,5.6vw,68px); letter-spacing:-.052em; line-height:.98;
  margin:22px auto 0; max-width:18ch; }
.hp--v2 .hp-h1 span{ display:block; color:var(--foreground); }
.hp--v2 .hp-sub{ margin:20px auto 0; max-width:62ch; font-size:18px; line-height:1.58; }
.hp--v2 .hp-entity{ margin:18px auto 0; max-width:70ch; color:var(--foreground); font-size:14px;
  line-height:1.55; font-weight:600; }
.hp--v2 .hp-domain-note{ margin:14px auto 0; color:var(--muted-foreground); font-size:12.5px; }
.hp--v2 .hp-domain-note code{ color:inherit; font-family:var(--font-mono); }
.hp--v2 .hp-proof{ justify-content:center; margin-top:26px; }
.hp--v2 .hp-pill{ padding:0; border:0; border-radius:0; box-shadow:none; background:transparent;
  font-family:var(--font-mono); font-size:11px; font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--primary); }

/* ============================================================ HERO TOOL (.ht-*)
   Radios drive both the tab chrome and the panes via `:checked ~`, so the switch survives a page
   with JS disabled — and so does the QR pane, which server-renders a real code. */
.ht{ position:relative; max-width:880px; margin:clamp(24px,2.7vw,34px) auto 0; text-align:left; }
.ht-r{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }

.ht-tabs{ display:flex; gap:8px; justify-content:center; }
.ht-tab{ display:inline-flex; align-items:center; gap:9px; cursor:pointer; position:relative; z-index:1;
  padding:11px 18px 15px; margin-bottom:-4px;
  border:1px solid var(--border); border-bottom:0; border-radius:13px 13px 0 0;
  background:var(--surface-sunken); color:var(--muted-foreground);
  font-family:var(--font-display); font-weight:600; font-size:15px; letter-spacing:-.012em;
  transition:var(--t-colors); }
.ht-tab svg{ width:18px; height:18px; }
.ht-tab:hover{ color:var(--foreground); }
.ht-r:nth-of-type(1):checked ~ .ht-tabs .ht-tab:nth-child(1),
.ht-r:nth-of-type(2):checked ~ .ht-tabs .ht-tab:nth-child(2){ background:var(--card); color:var(--foreground); z-index:3; }
.ht-r:focus-visible:nth-of-type(1) ~ .ht-tabs .ht-tab:nth-child(1),
.ht-r:focus-visible:nth-of-type(2) ~ .ht-tabs .ht-tab:nth-child(2){
  box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 45%, transparent); }

.ht-card{ position:relative; z-index:2; border:1px solid var(--border); border-radius:18px;
  background:var(--card); box-shadow:0 26px 70px -34px rgba(38,20,96,.34),var(--sh-sm);
  padding:clamp(20px,2.3vw,26px); }
.ht-pane{ display:none; }
.ht-r:nth-of-type(1):checked ~ .ht-card .ht-pane--link,
.ht-r:nth-of-type(2):checked ~ .ht-card .ht-pane--qr{ display:block; }
/* No-JS / no-CSS-support fallback is the first pane, which is also the checked one. */

.ht-pane__head{ display:flex; align-items:center; justify-content:space-between; gap:18px;
  margin-bottom:18px; }
.ht-pane__txt{ min-width:0; }
.ht-pane__mark{ flex-shrink:0; line-height:0; display:grid; place-items:center; padding:9px;
  border-radius:13px; background:var(--violet-50); border:1px solid var(--violet-100); }
.ht-pane__mark svg{ display:block; }
.ht-t{ font-family:var(--font-display); font-weight:700; font-size:21px;
  letter-spacing:-.03em; line-height:1.15; margin:0; }
.ht-s{ font-size:13.5px; color:var(--muted-foreground); margin:4px 0 0; }
.ht-lbl{ display:block; font-family:var(--font-mono); font-size:11px; font-weight:700;
  letter-spacing:.13em; text-transform:uppercase; color:var(--muted-foreground); }
.ht-lbl--mini{ margin-bottom:9px; }

.ht-field{ position:relative; display:flex; align-items:center; margin-top:10px; overflow:hidden;
  border:1px solid var(--border); border-radius:12px; background:var(--card);
  transition:box-shadow var(--d-fast) var(--ease-standard); }
.ht-field:focus-within{ box-shadow:0 0 0 4px color-mix(in srgb, var(--primary) 22%, transparent); }
.ht-pre{ align-self:stretch; display:flex; align-items:center; padding:0 14px; flex-shrink:0;
  border-right:1px solid var(--border); background:var(--surface-sunken);
  font-family:var(--font-mono); font-size:13.5px; color:var(--muted-foreground); }
.ht-input{ flex:1; min-width:0; height:58px; border:0; outline:0; background:transparent;
  font-family:var(--font-sans); font-size:16.5px; color:var(--foreground); padding:0 16px;
  transition:opacity var(--d-base) var(--ease-whoosh), transform var(--d-base) var(--ease-whoosh); }
.ht-input::placeholder{ color:var(--muted-foreground); }
.ht-cap{ margin:18px 0 0; }
.ht-err{ margin:12px 0 0; font-size:13.5px; font-weight:600; color:var(--coral-600); }
.dark .ht-err{ color:var(--coral-300); }

.ht-actions{ display:flex; align-items:center; gap:16px 20px; flex-wrap:wrap; margin-top:18px; }
.ht-go{ box-shadow:0 8px 22px -12px rgba(91,51,240,.68) !important; }
.ht-go:hover:not(:disabled){ transform:translateY(-1px); box-shadow:0 12px 28px -14px rgba(91,51,240,.74) !important; }
.ht-go:active:not(:disabled){ transform:translateY(0); box-shadow:0 5px 14px -10px rgba(91,51,240,.62) !important; }
.ht-alt{ font-size:13.5px; color:var(--muted-foreground); }
.ht-alt a{ font-weight:600; color:var(--primary); }

/* ============================================================ THE WHOOSH
   The brand mark carries the motion. Roll (translateX), hop (translateY) and spin (rotate) each
   animate a different nested element: they run on different durations and curves, and a single
   composed `transform` could only have one timing function. `--ht-run` is measured in JS —
   translateX percentages resolve against the element's own width, not its container's. */
@keyframes ht-rollx{ from{ transform:translateX(0); } to{ transform:translateX(var(--ht-run,280px)); } }
@keyframes ht-spin{ from{ transform:rotate(0); } to{ transform:rotate(360deg); } }
/* Fast up, float at the apex, accelerate down — a real bounce rather than a sine wobble. */
@keyframes ht-hop{
  0%{ transform:translateY(0); animation-timing-function:cubic-bezier(.28,0,.2,1); }
  45%{ transform:translateY(-14px); animation-timing-function:cubic-bezier(.7,0,.85,1); }
  100%{ transform:translateY(0); }
}

/* --- the whoosh stage: the form steps aside and the mark performs ---
   Form and stage share one grid cell, so the swap is a crossfade in place. Collapsing the form
   instead would snap every section below the hero up the page mid-request. */
.ht-swap{ display:grid; }
.ht-swap > *{ grid-area:1 / 1; min-width:0; }
.ht-form{ transition:opacity .32s var(--ease-standard), transform .32s var(--ease-whoosh),
  filter .32s var(--ease-standard); }
.ht-card.is-whooshing .ht-form{ opacity:0; transform:translateY(-10px) scale(.985); filter:blur(3px);
  pointer-events:none; }
.ht-stage{ align-self:center; opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .32s var(--ease-standard) .1s, visibility .32s; }
.ht-card.is-whooshing .ht-stage{ opacity:1; visibility:visible; }
.ht-stage__track{ position:relative; height:52px; }
.ht-srl{ position:absolute; left:0; top:50%; margin-top:-17px; width:34px; height:34px; }
.ht-srl-y,.ht-srl-r{ display:block; }
.ht-srl svg{ display:block; }
.ht-stage__cap{ margin:6px 0 0; text-align:center; font-family:var(--font-mono); font-size:11.5px;
  font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:var(--muted-foreground); }
.ht-stage__cap i{ display:inline-block; width:3px; height:3px; border-radius:999px; margin-left:3px;
  background:var(--muted-foreground); vertical-align:middle; opacity:.25; }
@keyframes ht-dot{ 0%,60%,100%{ opacity:.25; } 30%{ opacity:1; } }
@media (prefers-reduced-motion:no-preference){
  .ht-card.is-whooshing .ht-srl{ animation:ht-rollx 1.5s linear infinite; }
  .ht-card.is-whooshing .ht-srl-y{ animation:ht-hop .5s linear infinite; }
  .ht-card.is-whooshing .ht-srl-r{ animation:ht-spin .44s linear infinite; }
  .ht-stage__cap i{ animation:ht-dot 1.4s linear infinite; }
  .ht-stage__cap i:nth-child(2){ animation-delay:.18s; }
  .ht-stage__cap i:nth-child(3){ animation-delay:.36s; }
}

/* --- the arrival: a second W rolls the length of the short link and the link unreveals behind
       it, on the same duration and curve, so the wipe edge tracks the mark exactly --- */
@keyframes ht-arrive{ from{ opacity:0; transform:translateX(-26px); } to{ opacity:1; transform:none; } }
.ht-arrive{ animation:ht-arrive .7s var(--ease-arrive) both; }
@keyframes ht-unreveal{ from{ clip-path:inset(0 100% 0 0); } to{ clip-path:inset(0 0 0 0); } }
@keyframes ht-orl-fade{ 0%{ opacity:0; } 10%{ opacity:1; } 76%{ opacity:1; } 100%{ opacity:0; } }
.ht-reveal{ position:relative; display:inline-block; max-width:100%; }
.ht-orl{ position:absolute; left:-6px; top:50%; margin-top:-15px; width:30px; height:30px;
  z-index:2; pointer-events:none; opacity:0; }
.ht-orl-y,.ht-orl-r{ display:block; }
.ht-orl svg{ display:block; }
/* No fill-mode anywhere here, deliberately. "both" would pin each element to its FIRST keyframe
   whenever the animation is registered but not advancing — a backgrounded tab, a throttled frame
   budget — and the first keyframe of the wipe is a fully-clipped link. The short link the visitor
   came for must be visible unless a wipe is actively running over it, so the base style stays
   unclipped and the animation only borrows it for 720ms. */
@media (prefers-reduced-motion:no-preference){
  .ht-reveal.is-revealing .ht-orl{ animation:ht-rollx 1.05s var(--ease-whoosh), ht-orl-fade 1.05s linear; }
  .ht-reveal.is-revealing .ht-orl-y{ animation:ht-hop .44s linear 2.4; }
  .ht-reveal.is-revealing .ht-orl-r{ animation:ht-spin .38s linear 2.76; }
  .ht-reveal.is-revealing .ht-out__url{ animation:ht-unreveal 1.05s var(--ease-whoosh); }
}
@media (prefers-reduced-motion:reduce){ .ht-arrive{ animation:none; } }
.ht-out{ margin-top:26px; padding-top:24px; border-top:1px dashed var(--border); }
.ht-out__head{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
.ht-eye{ display:inline-flex; align-items:center; gap:8px; font-family:var(--font-mono); font-size:11px;
  font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--muted-foreground); }
.ht-eye svg{ width:14px; height:14px; }
.ht-eye--ok{ color:var(--success-ink); }
.ht-again{ background:none; border:0; padding:0; cursor:pointer; font-family:var(--font-sans);
  font-size:13.5px; font-weight:600; color:var(--muted-foreground); }
.ht-again:hover{ color:var(--foreground); text-decoration:underline; }
.ht-out__row{ display:flex; align-items:center; gap:20px; margin-top:16px; }
.ht-out__qr{ flex-shrink:0; line-height:0; padding:7px; border:1px solid var(--border); border-radius:10px;
  background:#fff; min-width:88px; min-height:88px; }
.ht-out__main{ min-width:0; flex:1; }
.ht-out__url{ display:block; font-family:var(--font-mono); font-weight:700;
  font-size:clamp(19px,2.6vw,26px); letter-spacing:-.02em; color:var(--primary);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ht-out__dest{ margin:5px 0 0; font-size:12.5px; color:var(--muted-foreground);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ht-out__btns{ display:flex; gap:9px; margin-top:14px; flex-wrap:wrap; }
.ht-copy.is-copied{ background:var(--success); }
.ht-claim{ display:block; margin-top:18px; font-size:14px; font-weight:600; color:var(--primary); }
.ht-claim:hover{ text-decoration:underline; }
.ht-claim--tight{ margin-top:12px; font-size:12.5px; text-align:center; }
.ht-fine{ margin:8px 0 0; font-size:12.5px; color:var(--muted-foreground); }

/* ---- QR pane ---- */
.ht-qr{ display:flex; gap:24px; align-items:flex-start; margin-top:22px; }
.ht-qr__img{ position:relative; flex-shrink:0; line-height:0; padding:9px;
  border:1px solid var(--border); border-radius:12px; background:#fff; }
.ht-qr__img svg{ width:150px !important; height:auto !important; }
.ht-qr__code{ line-height:0; transition:opacity var(--d-base) var(--ease-standard),
  filter var(--d-base) var(--ease-standard); }

/* The W hops into the middle of the code while a new one is fetched, then shrinks away. It is a
   loading state, never a permanent centre logo — the downloaded PNG carries no mark, and an
   overlay the encoder never reserved error-correction budget for is an overlay that breaks scans. */
.ht-qr__img.is-gen .ht-qr__code{ opacity:.3; filter:blur(1.5px); }
.ht-qr__mark{ position:absolute; left:50%; top:50%; width:38px; height:38px; margin:-19px 0 0 -19px;
  display:grid; place-items:center; border-radius:11px; background:#fff; z-index:2;
  box-shadow:0 0 0 5px #fff, 0 8px 18px rgba(26,11,77,.20);
  opacity:0; transform:scale(.4); pointer-events:none;
  transition:opacity var(--d-fast) var(--ease-standard), transform var(--d-fast) var(--ease-whoosh); }
.ht-qr__mark svg{ display:block; width:38px !important; height:38px !important; }
/* Flies in from the top-left, lands, hops once, settles dead centre. */
@keyframes ht-qr-hop{
  0%  { opacity:0; transform:translate(-54px,-64px) rotate(-160deg) scale(.45); }
  18% { opacity:1; }
  40% { transform:translate(-14px,6px) rotate(60deg) scale(1.05); }
  58% { transform:translate(-4px,-22px) rotate(200deg) scale(.95); }
  80% { transform:translate(0,4px) rotate(330deg) scale(1.04); }
  100%{ opacity:1; transform:translate(0,0) rotate(360deg) scale(1); }
}
@keyframes ht-qr-in{ from{ opacity:.25; transform:scale(.965); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:no-preference){
  .ht-qr__img.is-gen .ht-qr__mark{ animation:ht-qr-hop .9s cubic-bezier(.3,0,.2,1) both; }
  .ht-qr__img.is-fresh .ht-qr__code{ animation:ht-qr-in .5s var(--ease-arrive) both; }
}
@media (prefers-reduced-motion:reduce){ .ht-qr__img.is-gen .ht-qr__mark{ opacity:1; transform:none; } }
.ht-qr__side{ flex:1; min-width:0; }

/* ---- phone mocks: the screen fills the frame ----
   .pm-phone is a grid item in .hp-pan__split, so it stretches to the row height while
   .pm-phone__scr stayed content-sized — on the digital-cards panel that left ~97px of bare black
   phone body under the card. Making the frame a flex column with the screen as the growing child
   means the screen covers whatever height the grid hands the frame. */
.pm-phone{ display:flex; flex-direction:column; }
.pm-phone__scr{ flex:1; display:flex; flex-direction:column; }
.pm-vc__b, .pm-phone__scr > div:last-child{ flex:1; }

/* The breadcrumb chip is a label, not content: let it shrink and ellipsize rather than push the
   panel 24px past its own edge on a 375px screen. */
.hp-pan__path{ min-width:0; overflow:hidden; text-overflow:ellipsis; }
.ht-sws{ display:flex; gap:10px; margin-bottom:18px; }
.ht-sw{ width:30px; height:30px; padding:0; border:1.5px solid var(--ink); border-radius:999px;
  cursor:pointer; transition:transform var(--d-fast) var(--ease-spring), box-shadow var(--d-fast); }
.ht-sw:hover{ transform:translateY(-2px); }
.ht-sw[data-on]{ box-shadow:0 0 0 3px var(--card),0 0 0 5px var(--ring); }

/* ============================================================ OUTCOME BAND
   A static bridge between the live tool and the rest of the page. */
.hp-outcomes{ border-top:1px solid var(--border); border-bottom:1px solid var(--border);
  background:var(--surface-sunken); }
.hp-outcomes__grid{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); padding-top:0; padding-bottom:0; }
.hp-outcomes__grid>div{ display:grid; grid-template-columns:auto 1fr; gap:13px; align-items:start;
  padding:24px clamp(18px,2.6vw,34px); border-left:1px solid var(--border); }
.hp-outcomes__grid>div:first-child{ border-left:0; }
.hp-outcomes__grid span{ font-family:var(--font-mono); font-size:10.5px; font-weight:700;
  letter-spacing:.08em; color:var(--primary); padding-top:3px; }
.hp-outcomes__grid p{ margin:0; font-size:14.5px; line-height:1.5; color:var(--muted-foreground); }
.hp-outcomes__grid b{ color:var(--foreground); font-weight:700; }

/* ============================================================ FRAMES
   Product frames use the same quiet border and elevation grammar as the app. */
.hp--v2 .hp-tl, .hp--v2 .hp-cost, .hp--v2 .hp-price, .hp--v2 .hp-pan, .hp--v2 .hp-an{
  border:1px solid var(--border); box-shadow:var(--sh-md); }
.hp--v2 .hp-two--tight{ grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr); gap:clamp(30px,4.5vw,56px);
  align-items:center; margin-top:44px; }
.hp--v2 .hp-two--tight .hp-lede{ margin-top:0; }
.hp--v2 .hp-price{ margin-top:clamp(44px,5vw,64px); }
.hp--v2 .hp-plan--core::before{ height:2px; }
.hp--v2 .hp-plan__tag{ border:1px solid var(--border); }
.hp--v2 .hp-chip{ border:1px solid var(--border); }

/* ============================================================ RESPONSIVE */
@media (max-width:940px){
  .hp--v2 .hp-two--tight{ grid-template-columns:1fr; }
}
@media (max-width:720px){
  .ht-tabs{ padding-left:0; gap:6px; }
  .ht-tab{ flex:1; justify-content:center; padding:10px 10px 14px; font-size:14px; }
  .ht-card{ border-radius:14px; box-shadow:var(--hard-sm); }
  .ht-input{ height:52px; font-size:16px; }
  .ht-pane__mark svg{ width:34px; height:34px; }
  .ht-roll{ left:12px; }
  .ht-actions .wsh-btn{ width:100%; }
  .ht-alt{ width:100%; }
  .ht-out__row{ flex-direction:column; align-items:stretch; gap:14px; }
  .ht-out__qr{ align-self:flex-start; }
  .ht-qr{ flex-direction:column; align-items:stretch; }
  .ht-qr__img{ align-self:center; }
  .hp--v2 .hp-h1{ max-width:none; }
  .hp--v2 .hp-proof{ gap:8px 16px; }
  .hp-outcomes__grid{ grid-template-columns:1fr; }
  .hp-outcomes__grid>div{ border-left:0; border-top:1px solid var(--border); padding:19px 0; }
  .hp-outcomes__grid>div:first-child{ border-top:0; }
}
