/* ==========================================================================
   Splitiva marketing site
   Art direction extends the app splash: deep purple fields, drifting ambient
   glow, gold accent. Tokens mirror lib/ui/theme.dart so web and app match.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('fonts/plus-jakarta-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('fonts/plus-jakarta-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   2. Registered properties (enable animation of custom properties)
   -------------------------------------------------------------------------- */

@property --shimmer-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@property --count {
  syntax: '<integer>';
  initial-value: 0;
  inherits: false;
}

@property --card-x {
  syntax: '<percentage>';
  initial-value: 50%;
  inherits: false;
}

@property --card-y {
  syntax: '<percentage>';
  initial-value: 50%;
  inherits: false;
}

/* Pointer offsets for magnetic buttons and tilt stages. Registered so they
   interpolate smoothly instead of snapping between rAF updates. */
@property --mx {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

@property --my {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

@property --rx {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@property --ry {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* Drives the conic ring on featured/premium panels. */
@property --ring-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* --------------------------------------------------------------------------
   3. Tokens
   Each token declares a plain fallback first, then the light-dark() form.
   Browsers without light-dark() keep the light value and stay fully usable.
   -------------------------------------------------------------------------- */

:root {
  color-scheme: light dark;

  /* Brand — single source of truth, every tint derives via color-mix() */
  --brand: #5848c2;
  --brand-deep: #3d2f96;
  --brand-bright: #7b6ae0;
  --accent: #f1c442;
  --accent-deep: #d4a520;

  /* Semantic money colours, mirrored from lib/ui/theme.dart */
  --pos: #1e9e6d;
  --neg: #ff5656;
  --lent: #1e8e76;
  --owe: #f16522;

  /* Surfaces */
  --bg: #f7f8fc;
  --bg: light-dark(#f7f8fc, #090a12);
  --surface: #ffffff;
  --surface: light-dark(#ffffff, #151724);
  --surface-2: #edeff6;
  --surface-2: light-dark(#edeff6, #1c1f30);
  --surface-glass: rgba(255, 255, 255, 0.72);
  --surface-glass: light-dark(rgba(255, 255, 255, 0.72), rgba(28, 31, 48, 0.6));

  /* Text */
  --text: #141421;
  --text: light-dark(#141421, #f2f3f9);
  --text-dim: #5b6076;
  --text-dim: light-dark(#5b6076, #a0a5bd);
  /* Both values verified at >= 4.5:1 against their own surface. The lighter
     greys that read nicely in a mockup fail WCAG AA at these sizes. */
  --text-faint: #656b82;
  --text-faint: light-dark(#656b82, #7d83a0);

  /* Lines */
  --line: #d8dce8;
  --line: light-dark(#d8dce8, #262a3d);
  --line-soft: color-mix(in srgb, var(--line) 55%, transparent);

  /* On-brand (always dark purple sections) */
  --on-brand: #ffffff;
  --on-brand-dim: rgba(255, 255, 255, 0.68);
  --on-brand-faint: rgba(255, 255, 255, 0.42);
  --on-brand-line: rgba(255, 255, 255, 0.14);

  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(15, 17, 32, 0.06), 0 2px 6px rgba(15, 17, 32, 0.04);
  --shadow-md: 0 2px 4px rgba(15, 17, 32, 0.05), 0 10px 24px rgba(15, 17, 32, 0.07);
  --shadow-lg: 0 4px 8px rgba(15, 17, 32, 0.06), 0 24px 56px rgba(15, 17, 32, 0.1);
  --shadow-brand: 0 12px 32px color-mix(in srgb, var(--brand) 28%, transparent);
  --shadow-accent: 0 10px 28px color-mix(in srgb, var(--accent) 34%, transparent);

  /* Radii */
  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-xl: 30px;
  --r-full: 999px;

  /* Spacing — 4px base */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  /* Fluid type scale */
  --t-xs: clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --t-sm: clamp(0.875rem, 0.85rem + 0.15vw, 0.9375rem);
  --t-base: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  --t-lg: clamp(1.125rem, 1.06rem + 0.32vw, 1.3125rem);
  --t-xl: clamp(1.375rem, 1.25rem + 0.6vw, 1.75rem);
  --t-2xl: clamp(1.75rem, 1.5rem + 1.15vw, 2.5rem);
  --t-3xl: clamp(2.125rem, 1.7rem + 2vw, 3.5rem);
  --t-4xl: clamp(2.5rem, 1.85rem + 3.1vw, 4.75rem);

  /* Layout */
  --container: 1200px;
  --container-narrow: 760px;
  --gutter: clamp(1.125rem, 4vw, 2.5rem);
  --header-h: 68px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --header-offset: calc(var(--header-h) + var(--safe-top));

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 160ms;
  --dur: 260ms;
  --dur-slow: 520ms;
}

:root[data-theme='light'] {
  color-scheme: light;
}

:root[data-theme='dark'] {
  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   4. Reset & base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-offset) + var(--space-4));
}

a,
button {
  -webkit-tap-highlight-color: color-mix(in srgb, var(--brand) 22%, transparent);
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, sans-serif;
  font-size: var(--t-base);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

h1,
h2,
h3,
h4 {
  line-height: 1.12;
  letter-spacing: -0.025em;
  font-weight: 800;
  text-wrap: balance;
}

h1 {
  font-size: var(--t-4xl);
  letter-spacing: -0.035em;
}
h2 {
  font-size: var(--t-3xl);
  letter-spacing: -0.03em;
}
h3 {
  font-size: var(--t-xl);
}
h4 {
  font-size: var(--t-lg);
}

p {
  text-wrap: pretty;
}

a {
  color: var(--brand);
  text-decoration-color: color-mix(in srgb, var(--brand) 35%, transparent);
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease-out),
    text-decoration-color var(--dur-fast) var(--ease-out);
}

a:hover {
  text-decoration-color: currentColor;
}

ul,
ol {
  padding-inline-start: 1.15em;
}

:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

::selection {
  background: color-mix(in srgb, var(--brand) 24%, transparent);
}

/* Screen reader only */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 200;
  padding: var(--space-2) var(--space-4);
  background: var(--brand);
  color: #fff;
  border-radius: var(--r-sm);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--dur) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
   5. Layout
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container-narrow {
  max-width: var(--container-narrow);
}

.section {
  padding-block: clamp(3.5rem, 8vw, 7rem);
  position: relative;
}

.section-tight {
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

/* Skip render work for offscreen sections */
.section-defer {
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}

.grid {
  display: grid;
  gap: var(--space-5);
}

.grid-2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.grid-3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}

.grid-4 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.center {
  text-align: center;
}

.center .lead,
.center p {
  margin-inline: auto;
}

.lead {
  font-size: var(--t-lg);
  color: var(--text-dim);
  max-width: 62ch;
  line-height: 1.6;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: var(--space-3);
}

.eyebrow::before {
  content: '';
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.55;
}

.center .eyebrow {
  justify-content: center;
}

/* --------------------------------------------------------------------------
   6. Surfaces & decoration
   -------------------------------------------------------------------------- */

/* Deep purple section — the splash look */
.on-brand {
  --text: var(--on-brand);
  --text-dim: var(--on-brand-dim);
  --text-faint: var(--on-brand-faint);
  --line: var(--on-brand-line);
  --surface: rgba(255, 255, 255, 0.055);
  --surface-2: rgba(255, 255, 255, 0.085);
  position: relative;
  isolation: isolate;
  color: var(--on-brand);
  background:
    radial-gradient(120% 90% at 12% 0%, #6b58d8 0%, transparent 55%),
    radial-gradient(110% 80% at 92% 8%, #4a3aa8 0%, transparent 58%),
    linear-gradient(168deg, #5848c2 0%, #3a2d8f 62%, #2a2170 100%);
  overflow: hidden;
}

/* Prose links only. Without the exclusions this rule outranks `.btn`
   (0,1,1 vs 0,1,0) and repaints button labels gold — which made the gold
   CTA render gold-on-gold. */
.on-brand a:not(.btn):not(.store-badge):not(.brand) {
  color: var(--accent);
}

.on-brand .eyebrow {
  color: var(--accent);
}

/* Ambient drifting glow, inherited from web/index.html splash */
.glow {
  position: absolute;
  inset-block-start: -18%;
  inset-inline-end: -12%;
  width: min(56vw, 620px);
  aspect-ratio: 1;
  border-radius: 50%;
  filter: blur(110px);
  background: rgba(255, 255, 255, 0.16);
  z-index: -1;
  pointer-events: none;
  animation: glow-float 9s ease-in-out infinite alternate;
}

.glow-gold {
  inset-block-start: auto;
  inset-block-end: -22%;
  inset-inline-end: auto;
  inset-inline-start: -14%;
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  animation-delay: -4.5s;
}

/* Fine grain stops large purple fields banding */
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.4;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

/* Soft tinted band for alternating light sections */
.section-alt {
  background: linear-gradient(
    180deg,
    transparent,
    color-mix(in srgb, var(--brand) 4%, transparent) 30%,
    color-mix(in srgb, var(--brand) 4%, transparent) 70%,
    transparent
  );
}

/* ---------------------------------------------------------------- cinematic
   Depth is built from three stacked layers rather than one flat fill:
   a colour field, a soft mesh of offset radial gradients, and grain.
   All of it is decorative, behind content, and never takes pointer events. */

.on-brand-deep {
  background:
    radial-gradient(100% 80% at 15% -10%, #7565e6 0%, transparent 52%),
    radial-gradient(90% 70% at 88% 0%, #4536a4 0%, transparent 55%),
    radial-gradient(120% 90% at 50% 110%, #1d1656 0%, transparent 60%),
    linear-gradient(172deg, #4b3cae 0%, #2f2580 55%, #1b1550 100%);
}

/* Aurora mesh — slow, large, low-contrast. Reads as atmosphere, not motion. */
.mesh {
  position: absolute;
  inset: -30% -10%;
  z-index: -1;
  pointer-events: none;
  opacity: 0.55;
  background:
    radial-gradient(38% 44% at 22% 28%, color-mix(in srgb, var(--brand-bright) 62%, transparent) 0%, transparent 70%),
    radial-gradient(32% 40% at 78% 22%, color-mix(in srgb, var(--accent) 34%, transparent) 0%, transparent 72%),
    radial-gradient(44% 46% at 62% 76%, color-mix(in srgb, #6f5cf0 55%, transparent) 0%, transparent 70%);
  filter: blur(28px);
  animation: mesh-drift 26s var(--ease-in-out) infinite alternate;
}

/* Faint ruled grid, masked to fade out before the section edges. */
.rule-grid {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  background-image:
    linear-gradient(to right, var(--on-brand-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--on-brand-line) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(72% 62% at 50% 42%, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(72% 62% at 50% 42%, #000 0%, transparent 78%);
}

/* Spotlight behind a centered subject. */
.spotlight {
  position: absolute;
  left: 50%;
  top: 8%;
  width: min(120vw, 1100px);
  aspect-ratio: 1.6;
  translate: -50% 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    50% 50% at 50% 50%,
    color-mix(in srgb, var(--accent) 22%, transparent) 0%,
    transparent 70%
  );
  filter: blur(50px);
}

/* Curved seam between a dark section and the light one after it. Purely
   decorative, so it is hidden from assistive tech by the markup. */
.seam {
  position: absolute;
  inset-inline: -2%;
  bottom: -1px;
  height: clamp(48px, 7vw, 104px);
  z-index: 1;
  pointer-events: none;
  background: var(--bg);
  border-start-start-radius: 50% 100%;
  border-start-end-radius: 50% 100%;
}

.seam-alt {
  background: color-mix(in srgb, var(--brand) 4%, var(--bg));
}

/* A band that ends in a `.seam` needs room for it, or the curve eats into
   the last line of content. */
.hero-band {
  padding-block-end: calc(clamp(3.5rem, 8vw, 7rem) + clamp(48px, 7vw, 104px) * 0.6);
}

/* Compact opening for long-form documents. The seam and mesh used elsewhere
   are too theatrical above a privacy policy; a flat band with a lit lower
   edge sets the tone without competing with the text. */
.hero-doc {
  position: relative;
  isolation: isolate;
}

.hero-doc::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--accent) 55%, transparent),
    transparent
  );
}

.hero-doc .rule-grid {
  opacity: 0.32;
}

/* Hairline that fades in from both ends — used to separate stacked bands. */
.hairline {
  height: 1px;
  border: 0;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}

/* --------------------------------------------------------------- typography
   Display treatments for hero headlines. Kept as opt-in classes so the
   default h1/h2 scale still governs the long-form pages. */

/* The tight line-height these use makes the default heading margin read as
   almost no gap, so the spacing is restated here rather than per page. */
.display {
  font-size: var(--t-4xl);
  letter-spacing: -0.04em;
  line-height: 1.03;
  margin-bottom: var(--space-4);
}

.display-sm {
  font-size: var(--t-3xl);
  letter-spacing: -0.035em;
  line-height: 1.06;
  margin-bottom: var(--space-4);
}

/* Gradient headline fill. A solid colour is declared first so browsers
   without background-clip still render readable text. */
.text-grad {
  color: var(--accent);
  background: linear-gradient(96deg, var(--accent) 8%, #ffe9a8 46%, var(--accent) 88%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .text-grad {
    -webkit-text-fill-color: currentColor;
  }
}

/* Understated label above a headline, on dark fields. */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.375rem 0.875rem;
  border-radius: var(--r-full);
  border: 1px solid var(--on-brand-line);
  background: rgba(255, 255, 255, 0.07);
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-brand-dim);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.kicker-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 26%, transparent);
}

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */

.btn {
  --btn-bg: var(--brand);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.875rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--t-sm);
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.btn:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-brand);
}

.btn:active {
  transform: translateY(0) scale(0.985);
}

.btn svg {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}

.btn-lg {
  padding: 1.0625rem 2rem;
  font-size: var(--t-base);
}

/* Gold CTA — mirrors the splash "OPEN" button, for use on purple */
.btn-accent {
  --btn-bg: var(--accent);
  --btn-fg: #1b1505;
  position: relative;
  overflow: hidden;
  /* Own stacking context so the sheen can sit above the background but
     below the label — a negative z-index child paints after the element's
     own background and before its inline content. */
  isolation: isolate;
}

.btn-accent:hover {
  box-shadow: var(--shadow-accent);
}

/* Slow ambient sheen so the primary CTA reads as the focal point */
.btn-accent::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    var(--shimmer-angle),
    transparent 44%,
    rgba(255, 255, 255, 0.38) 50%,
    transparent 56%
  );
  animation: shimmer 5.5s linear infinite;
  pointer-events: none;
}

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  border-color: var(--line);
}

.btn-ghost:hover {
  --btn-bg: var(--surface-2);
  box-shadow: var(--shadow-sm);
}

.on-brand .btn-ghost {
  --btn-fg: #fff;
  border-color: rgba(255, 255, 255, 0.28);
}

.on-brand .btn-ghost:hover {
  --btn-bg: rgba(255, 255, 255, 0.1);
  box-shadow: none;
}

/* Store badges */
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0.6875rem 1.25rem 0.6875rem 1rem;
  border-radius: var(--r-md);
  background: #101018;
  color: #fff;
  text-decoration: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
  transition: transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur) var(--ease-out);
}

.store-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
  color: #fff;
}

.store-badge svg {
  width: 26px;
  height: 26px;
  flex: none;
}

.store-badge span {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.7;
  line-height: 1.3;
}

.store-badge strong {
  display: block;
  font-size: 0.9375rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

/* --------------------------------------------------------------------------
   8. Cards
   -------------------------------------------------------------------------- */

.card {
  container-type: inline-size;
  position: relative;
  padding: var(--space-5);
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

.card-hover:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--brand) 30%, var(--line));
}

/* Pointer-tracked highlight, fed by two custom props from site.js */
.card-glow::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(
    340px circle at var(--card-x) var(--card-y),
    color-mix(in srgb, var(--brand) 12%, transparent),
    transparent 70%
  );
  transition: opacity var(--dur) var(--ease-out);
}

.card-glow:hover::before {
  opacity: 1;
}

.on-brand .card {
  background: var(--surface-glass);
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: none;
}

.on-brand .card-hover:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.22);
}

.card h3 {
  margin-bottom: var(--space-2);
}

.card p {
  color: var(--text-dim);
  font-size: var(--t-sm);
}

/* Card reflows itself based on its own width, not the viewport */
@container (min-width: 420px) {
  .card-wide-row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-4);
    align-items: start;
  }
}

.card-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: var(--space-4);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  color: var(--brand);
  flex: none;
}

.on-brand .card-icon {
  background: rgba(255, 255, 255, 0.1);
  color: var(--accent);
}

.card-icon svg {
  width: 22px;
  height: 22px;
}

/* --------------------------------------------------------------------------
   9. Pills, chips, badges
   -------------------------------------------------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.4375rem 0.875rem;
  border-radius: var(--r-full);
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--text-dim);
}

.on-brand .pill {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.85);
}

.pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pos);
  flex: none;
}

/* Text colours are darkened in light mode so the label clears AA against its
   own tinted background; dark mode needs the opposite treatment. */
.tag-free {
  color: #0f6f4a;
  color: light-dark(#0f6f4a, #4fd1a0);
  background: color-mix(in srgb, var(--pos) 12%, transparent);
  border-color: color-mix(in srgb, var(--pos) 30%, transparent);
}

.tag-pro {
  color: #8a6a00;
  color: light-dark(#8a6a00, #f3cd63);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--accent) 42%, transparent);
}

/* --------------------------------------------------------------------------
   10. Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  padding-top: var(--safe-top);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease-out),
    background var(--dur) var(--ease-out);
}

.site-header[data-stuck='true'] {
  border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
}

.site-header .container {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  flex: none;
}

.brand img {
  width: 32px;
  height: 32px;
  border-radius: 9px;
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-inline-start: auto;
}

.nav a:not(.btn) {
  padding: 0.5rem 0.8125rem;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  font-size: var(--t-sm);
  font-weight: 700;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out);
}

.nav a:not(.btn):hover,
.nav a:not(.btn)[aria-current='page'] {
  color: var(--text);
  background: var(--surface-2);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    background var(--dur-fast) var(--ease-out);
}

.icon-btn:hover {
  color: var(--text);
  border-color: color-mix(in srgb, var(--brand) 40%, var(--line));
}

.icon-btn svg {
  width: 18px;
  height: 18px;
}

/* Theme toggle swaps icons based on resolved scheme */
.icon-sun {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .icon-sun {
    display: block;
  }
  :root:not([data-theme='light']) .icon-moon {
    display: none;
  }
}

:root[data-theme='dark'] .icon-sun {
  display: block;
}
:root[data-theme='dark'] .icon-moon {
  display: none;
}
:root[data-theme='light'] .icon-sun {
  display: none;
}
:root[data-theme='light'] .icon-moon {
  display: block;
}

.nav-toggle {
  display: none;
}

.nav-toggle .icon-close {
  display: none;
}

.nav-cta {
  display: none;
}

@media (max-width: 900px) {
  .nav-toggle {
    display: grid;
  }

  .nav-toggle[aria-expanded='true'] .icon-menu {
    display: none;
  }

  .nav-toggle[aria-expanded='true'] .icon-close {
    display: block;
  }

  /* .nav becomes position:fixed below, so it can no longer push the
     actions right with its auto margin. */
  .header-actions {
    margin-inline-start: auto;
    gap: var(--space-2);
  }

  .site-header .container {
    gap: var(--space-3);
  }

  .nav {
    position: fixed;
    top: 100%;
    right: 0;
    left: 0;
    bottom: auto;
    z-index: 101;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    height: calc(100dvh - var(--header-offset));
    overflow: auto;
    padding: var(--space-5) var(--gutter) calc(var(--space-6) + var(--safe-bottom));
    background: var(--bg);
    border-bottom: 0;
    box-shadow: none;
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: transform var(--dur) var(--ease-out),
      opacity var(--dur) var(--ease-out), visibility var(--dur);
  }

  .nav[data-open='true'] {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
  }

  .nav a:not(.btn) {
    padding: 0.875rem 0.75rem;
    font-size: var(--t-lg);
    border-radius: var(--r-md);
  }

  .nav-cta {
    display: inline-flex;
    margin-top: auto;
    justify-content: center;
  }

  .header-cta-desktop {
    padding: 0.5rem 0.85rem;
    font-size: var(--t-xs);
  }

  .icon-btn,
  .nav-toggle {
    width: 36px;
    height: 36px;
  }

  body:has(.nav[data-open='true']) {
    overflow: hidden;
  }

  body:has(.nav[data-open='true']) .header-cta-desktop {
    visibility: hidden;
  }
}

/* Very narrow phones: drop the duplicate header CTA — the sheet already
   has "Get the app", and three controls + wordmark was crushing the brand. */
@media (max-width: 400px) {
  .header-cta-desktop {
    display: none;
  }

  .brand img {
    width: 28px;
    height: 28px;
  }
}

/* --------------------------------------------------------------------------
   11. Hero
   -------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(3.5rem, 9vw, 7rem) clamp(4rem, 10vw, 8rem);
}

.hero-grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 940px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
}

.hero h1 {
  margin-bottom: var(--space-4);
}

.hero .lead {
  margin-bottom: var(--space-6);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem);
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

.hero-note {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-size: var(--t-sm);
  color: var(--on-brand-dim);
}

.hero-note span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.hero-note svg {
  width: 15px;
  height: 15px;
  color: var(--accent);
  flex: none;
}

/* Gold accent on the second half of the headline, matching store slides */
.hl {
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   12. Phone mockup
   -------------------------------------------------------------------------- */

.phone {
  position: relative;
  width: min(300px, 78vw);
  margin-inline: auto;
  aspect-ratio: 9 / 19.5;
  border-radius: 42px;
  padding: 9px;
  background: linear-gradient(160deg, #2a2c3d, #14151f 42%, #33354a);
  box-shadow: 0 32px 70px rgba(8, 6, 30, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08) inset;
}

.phone-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 34px;
  overflow: hidden;
  background: var(--bg);
}

.phone-screen img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* Dynamic Island */
.phone::before {
  content: '';
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: 31%;
  height: 26px;
  border-radius: var(--r-full);
  background: #06060a;
  z-index: 3;
}

.phone-float {
  animation: float-y 7s ease-in-out infinite alternate;
}

/* --------------------------------------------------------------------------
   13. Sticky feature showcase
   -------------------------------------------------------------------------- */

.showcase {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}

@media (min-width: 940px) {
  .showcase {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(3rem, 6vw, 6rem);
  }

  .showcase-sticky {
    position: sticky;
    top: calc(var(--header-offset) + var(--space-6));
    height: fit-content;
  }
}

.showcase-steps {
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 6vw, 5rem);
}

.showcase-step {
  padding-block: var(--space-2);
}

@media (min-width: 940px) {
  /* Each chapter needs roughly a viewport of scroll so the sticky phone
     can stay put while that chapter is the one in the middle of the screen.
     Without this the last chapter activates after the sticky containing
     block has already begun to scroll the phone away. */
  .showcase-steps {
    gap: 0;
    /* Extra runway after the final chapter — same idea as the per-step
       height, but for the release that would otherwise start as soon as
       the last article's bottom edge reaches the phone's bottom edge. */
    padding-block-end: 35vh;
  }

  .showcase-step {
    min-height: 70vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--space-6);
  }
}

.showcase-step h3 {
  margin-bottom: var(--space-3);
}

.showcase-step p {
  color: var(--text-dim);
}

.step-num {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-bottom: var(--space-3);
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  color: var(--brand);
  font-size: var(--t-sm);
  font-weight: 800;
}

/* Cross-fading screenshot stack inside the sticky phone */
.shot-stack {
  position: relative;
  width: 100%;
  height: 100%;
}

.shot-stack img {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 600ms var(--ease-out);
}

.shot-stack img[data-active='true'] {
  opacity: 1;
}

/* Depth on the outgoing screenshot so the swap reads as a stack, not a fade */
.shot-stack img {
  transform: scale(1.04);
  transition: opacity 620ms var(--ease-out), transform 900ms var(--ease-out);
}

.shot-stack img[data-active='true'] {
  transform: scale(1);
}

/* --------------------------------------------------------------------------
   13b. Cinematic components
   Magnetic CTAs, tilt stages, luminous panels and the chapter rail. Every
   effect here degrades to a plain static element without JS.
   -------------------------------------------------------------------------- */

/* Magnetic button — site.js writes --mx/--my, CSS owns the easing back. */
.magnetic {
  translate: var(--mx, 0) var(--my, 0);
  transition: translate 420ms var(--ease-out), transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.magnetic[data-magnet='active'] {
  /* While tracking the pointer the position must follow immediately;
     the transition above only handles the release. */
  transition: transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

/* Tilt stage — perspective wrapper plus the element that actually rotates. */
.tilt {
  perspective: 1200px;
  transform-style: preserve-3d;
}

.tilt-inner {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 600ms var(--ease-out);
  will-change: transform;
}

.tilt[data-tilt='active'] .tilt-inner {
  transition: transform 120ms linear;
}

/* Luminous panel — a rotating conic ring sitting just outside the border. */
.lume {
  position: relative;
  isolation: isolate;
}

.lume::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(
    from var(--ring-angle),
    transparent 0%,
    color-mix(in srgb, var(--brand) 65%, transparent) 12%,
    color-mix(in srgb, var(--accent) 78%, transparent) 26%,
    transparent 42%,
    transparent 100%
  );
  /* Mask to a hairline ring so only the border glows, not the fill. */
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  -webkit-mask-composite: xor;
  animation: ring-spin 8s linear infinite;
}

/* Asymmetric editorial layout: a lead column that stays with the reader on
   wide screens, and a content column that scrolls past it. */
.split {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 940px) {
  .split {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  }

  .split-lead {
    position: sticky;
    top: calc(var(--header-offset) + var(--space-6));
  }
}

/* Positioning context for the hero phone and its floating chips. Width is
   pinned to the phone so the chips anchor to its edges rather than to the
   much wider grid column. */
.hero-stage {
  position: relative;
}

.hero-stage .tilt-inner {
  position: relative;
  width: min(300px, 78vw);
  margin-inline: auto;
}

/* Offsets are a share of the phone width, so the chips keep the same
   relationship to the device as it scales down. */
.chip-tl {
  inset-block-start: 14%;
  inset-inline-start: -42%;
}

.chip-br {
  inset-block-end: 30%;
  inset-inline-end: -38%;
}

.chip-bl {
  inset-block-end: 11%;
  inset-inline-start: -34%;
}

/* Floating transaction chips around the hero phone */
.chip {
  position: absolute;
  /* Above the phone bezel, which sits at 3 for the dynamic island */
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.5rem 0.8125rem;
  border-radius: var(--r-full);
  /* Opaque enough to stay legible where a chip overlaps the light
     screenshot behind it, not just the purple field. */
  background: color-mix(in srgb, #17114a 82%, transparent);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 14px 30px rgba(10, 8, 36, 0.32);
  font-size: var(--t-xs);
  font-weight: 800;
  color: #fff;
  white-space: nowrap;
  animation: chip-float 6s var(--ease-in-out) infinite alternate;
  animation-delay: calc(var(--c, 0) * -1.7s);
}

.chip-ico {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 0.6875rem;
  flex: none;
}

.chip-amt {
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Chips are decoration layered over a photo; below the hero breakpoint the
   phone shrinks and they would collide with the screenshot. */
@media (max-width: 939px) {
  .chip {
    display: none;
  }
}

/* Chapter rail for the sticky showcase.
   Dimming is opt-in: it only starts once JS has confirmed it is syncing the
   chapters to the sticky visual. Without JS every chapter stays fully
   legible and the rail reads as a plain progress spine. */
.chapter {
  position: relative;
  padding-inline-start: var(--space-6);
  padding-block: var(--space-2);
  transition: opacity 460ms var(--ease-out);
}

/* The rail itself */
.chapter::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 2px;
  border-radius: 2px;
  background: var(--line);
}

/* Progress fill that grows while the chapter is the active one */
.chapter::after {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: 2px;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--brand), var(--accent));
  transition: height 620ms var(--ease-out);
}

[data-chapters='synced'] .chapter {
  opacity: 0.42;
}

[data-chapters='synced'] .chapter::after {
  height: 0;
}

[data-chapters='synced'] .chapter[data-active='true'] {
  opacity: 1;
}

[data-chapters='synced'] .chapter[data-active='true']::after {
  height: 100%;
}

/* Stat / metric strip used across pages */
.metric {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface);
}

.metric b {
  font-size: var(--t-2xl);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--brand);
}

.on-brand .metric {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.13);
}

.on-brand .metric b {
  color: var(--accent);
}

.metric span {
  font-size: var(--t-sm);
  color: var(--text-dim);
}

/* Metrics are short enough to sit in narrower tracks than a normal card
   grid, which keeps a row of three from breaking into 2 + 1. */
.metric-row {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}

/* --------------------------------------------------------------------------
   14. Marquee (bank / UPI trust row)
   -------------------------------------------------------------------------- */

.marquee {
  --marquee-dur: 42s;
  position: relative;
  display: flex;
  overflow: hidden;
  gap: var(--space-3);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 12%,
    #000 88%,
    transparent
  );
}

.marquee:hover .marquee-track {
  animation-play-state: paused;
}

.marquee-track {
  display: flex;
  gap: var(--space-3);
  flex: none;
  min-width: 100%;
  padding-inline-end: var(--space-3);
  animation: marquee var(--marquee-dur) linear infinite;
}

.marquee-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.5rem 1rem;
  border-radius: var(--r-full);
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}

.on-brand .marquee-item {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.82);
}

/* --------------------------------------------------------------------------
   15. Stats
   -------------------------------------------------------------------------- */

.stat {
  text-align: center;
}

.stat-value {
  display: block;
  font-size: var(--t-3xl);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--brand);
}

.on-brand .stat-value {
  color: var(--accent);
}

.stat-label {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--t-sm);
  color: var(--text-dim);
}

/* Pure-CSS count-up via registered custom property */
.count {
  counter-reset: c var(--count);
}

.count::after {
  content: counter(c);
}

.count[data-run='true'] {
  animation: count-up 1.8s var(--ease-out) forwards;
}

/* --------------------------------------------------------------------------
   16. FAQ accordion
   -------------------------------------------------------------------------- */

.faq {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.faq-item {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.faq-item:has(> details[open]) {
  border-color: color-mix(in srgb, var(--brand) 32%, var(--line));
  box-shadow: var(--shadow-sm);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  min-height: 3.25rem;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: '';
  width: 10px;
  height: 10px;
  flex: none;
  border-right: 2px solid var(--text-faint);
  border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur) var(--ease-out);
}

.faq-item details[open] summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

/* Genuinely smooth height animation */
.faq-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-out);
}

.faq-item details[open] .faq-body {
  grid-template-rows: 1fr;
}

.faq-body > div {
  overflow: hidden;
}

.faq-body p {
  padding: 0 var(--space-5) var(--space-5);
  color: var(--text-dim);
  margin: 0;
}

/* --------------------------------------------------------------------------
   17. Comparison table
   -------------------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

table.cmp {
  width: 100%;
  border-collapse: collapse;
  min-width: 520px;
}

table.cmp th,
table.cmp td {
  padding: var(--space-4) var(--space-5);
  text-align: left;
  border-bottom: 1px solid var(--line);
  font-size: var(--t-sm);
}

table.cmp thead th {
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 800;
}

table.cmp tbody tr:last-child th,
table.cmp tbody tr:last-child td {
  border-bottom: 0;
}

table.cmp tbody th {
  font-weight: 700;
  color: var(--text);
}

table.cmp .yes {
  color: var(--pos);
  font-weight: 800;
}

table.cmp .no {
  color: var(--text-faint);
}

table.cmp col.hl-col,
table.cmp .col-hl {
  background: color-mix(in srgb, var(--brand) 6%, transparent);
}

/* The Splitiva column is the point of the table, so it gets a cap and a
   stronger tint rather than reading as one of three equal columns. */
table.cmp thead th.col-hl {
  position: relative;
  color: var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}

table.cmp thead th.col-hl::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
}

/* Row emphasis: the whole row lifts, and the Splitiva cell brightens with it,
   so scanning across stays easy on a wide table. */
table.cmp tbody tr {
  transition: background var(--dur-fast) var(--ease-out);
}

table.cmp tbody tr:hover {
  background: color-mix(in srgb, var(--brand) 5%, transparent);
}

table.cmp tbody tr:hover .col-hl {
  background: color-mix(in srgb, var(--brand) 13%, transparent);
}

/* Horizontal scroll on narrow screens is easy to miss. Fade the trailing
   edge so there is a visible cue that the table continues. */
.table-wrap {
  position: relative;
  mask-image: linear-gradient(90deg, #000 0, #000 94%, transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 94%, transparent 100%);
}

@media (min-width: 720px) {
  .table-wrap {
    mask-image: none;
    -webkit-mask-image: none;
  }
}

/* --------------------------------------------------------------------------
   18. Pricing
   -------------------------------------------------------------------------- */

.plan {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
}

.plan-featured {
  border-color: color-mix(in srgb, var(--brand) 40%, var(--line));
  box-shadow: var(--shadow-lg);
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--brand) 7%, var(--surface)),
    var(--surface) 60%
  );
}

/* Free vs Pro is a hierarchy, not a pair of equals: Pro gets the wider
   column and sits slightly proud of the free plan on desktop. */
.plan-duo {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
  max-width: 940px;
  margin-inline: auto;
}

@media (min-width: 820px) {
  .plan-duo {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    align-items: center;
  }

  .plan-duo .plan-featured {
    padding-block: calc(var(--space-6) + var(--space-3));
  }
}

.plan-price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.plan-price b {
  font-size: var(--t-3xl);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
}

.plan-price span {
  color: var(--text-dim);
  font-size: var(--t-sm);
}

.check-list {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: var(--t-sm);
}

.check-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  color: var(--text-dim);
}

.check-list svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 2px;
  color: var(--pos);
}

/* --------------------------------------------------------------------------
   19. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--surface);
  padding-block: var(--space-8) var(--space-6);
  margin-top: var(--space-8);
}

.footer-grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 168px), 1fr));
  margin-bottom: var(--space-7);
}

.footer-grid > div:first-child {
  grid-column: 1 / -1;
}

@media (min-width: 720px) {
  .footer-grid {
    grid-template-columns: 1.6fr repeat(3, 1fr);
  }

  .footer-grid > div:first-child {
    grid-column: auto;
  }
}

/* Rendered as h2 so the document never skips a heading level; the visual
   weight comes from the class, not the tag. */
.footer-heading {
  font-size: var(--t-xs);
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--space-4);
}

.footer-links {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.footer-links a {
  color: var(--text-dim);
  font-size: var(--t-sm);
  font-weight: 600;
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--brand);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
  justify-content: space-between;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
  font-size: var(--t-sm);
  color: var(--text-faint);
}

/* --------------------------------------------------------------------------
   20. Motion
   -------------------------------------------------------------------------- */

@keyframes glow-float {
  from {
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    transform: translate3d(4%, 5%, 0) scale(1.12);
  }
}

@keyframes float-y {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(0, -14px, 0);
  }
}

@keyframes marquee {
  to {
    transform: translate3d(-100%, 0, 0);
  }
}

/* Aurora mesh drift — large and slow enough to read as light, not movement */
@keyframes mesh-drift {
  from {
    transform: translate3d(-2%, -1%, 0) scale(1);
  }
  to {
    transform: translate3d(3%, 2%, 0) scale(1.1);
  }
}

@keyframes ring-spin {
  to {
    --ring-angle: 360deg;
  }
}

@keyframes chip-float {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(0, -12px, 0);
  }
}

@keyframes shimmer {
  to {
    --shimmer-angle: 360deg;
  }
}

@keyframes count-up {
  to {
    --count: var(--count-to, 100);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes rise-scale {
  from {
    opacity: 0;
    transform: translate3d(0, 26px, 0) scale(0.965);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

/* Hero entrance — runs with zero JS via @starting-style */
.enter {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}

@starting-style {
  .enter {
    opacity: 0;
    transform: translate3d(0, 20px, 0);
  }
}

/* Word-by-word headline stagger */
.word {
  display: inline-block;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-spring);
  transition-delay: calc(var(--w, 0) * 40ms);
}

@starting-style {
  .word {
    opacity: 0;
    transform: translate3d(0, 26px, 0);
  }
}

/* Scroll reveals — native scroll timeline where available, IO fallback below */
.reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity 640ms var(--ease-out), transform 640ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 80ms);
}

.reveal.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal:not(.is-visible) {
      opacity: 1;
      transform: none;
      animation: rise-scale linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 22%;
    }
  }
}

/* Cross-document view transitions — SPA-like navigation, no JS */
@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: vt-out 180ms var(--ease-in-out) both;
}

::view-transition-new(root) {
  animation: vt-in 300ms var(--ease-out) both;
}

@keyframes vt-out {
  to {
    opacity: 0;
  }
}

@keyframes vt-in {
  from {
    opacity: 0;
    transform: translate3d(0, 8px, 0);
  }
}

/* Header keeps its identity across navigations */
.site-header {
  view-transition-name: site-header;
}

/* --------------------------------------------------------------------------
   21. Document pages — privacy policy, terms, support, delete account
   Long-form prose with a sticky table of contents. Deliberately narrower
   measure than the marketing sections: these pages are read, not scanned.
   -------------------------------------------------------------------------- */

.doc {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

@media (max-width: 900px) {
  .doc {
    grid-template-columns: minmax(0, 1fr);
  }
}

.doc-toc {
  position: sticky;
  top: calc(var(--header-offset) + var(--space-5));
}

/* The TOC duplicates links that already exist as headings below, so it is
   redundant for a screen reader walking the document in order. */
@media (max-width: 900px) {
  .doc-toc {
    display: none;
  }
}

.doc-toc-title {
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--space-4);
}

.doc-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  border-inline-start: 2px solid var(--line);
}

.doc-toc a {
  display: block;
  padding: 0.4rem var(--space-4);
  margin-inline-start: -2px;
  border-inline-start: 2px solid transparent;
  font-size: var(--t-sm);
  font-weight: 600;
  line-height: 1.45;
  color: var(--text-dim);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.doc-toc a:hover {
  color: var(--text);
}

.doc-toc a[aria-current='true'] {
  color: var(--brand);
  color: light-dark(var(--brand), var(--brand-bright));
  border-inline-start-color: var(--brand);
}

.doc-section + .doc-section {
  margin-top: var(--space-7);
}

/* Anchored headings must clear the sticky header when jumped to. */
.doc-section {
  scroll-margin-top: calc(var(--header-offset) + var(--space-5));
}

.doc-section > h2 {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font-size: var(--t-xl);
  margin-bottom: var(--space-4);
}

.doc-num {
  flex: none;
  font-size: var(--t-sm);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--brand);
  color: light-dark(var(--brand), var(--brand-bright));
}

.doc-section h3 {
  font-size: var(--t-lg);
  margin-top: var(--space-5);
  margin-bottom: var(--space-2);
}

.doc-section h3:first-child {
  margin-top: 0;
}

.doc-section p,
.doc-section li {
  color: var(--text-dim);
}

.doc-section p + p {
  margin-top: var(--space-3);
}

.doc-section ul,
.doc-section ol {
  margin: var(--space-3) 0 0;
  padding-inline-start: 1.25rem;
}

.doc-section li + li {
  margin-top: var(--space-2);
}

.doc-section strong {
  color: var(--text);
}

/* Callout for the privacy claims that matter most */
.note {
  --note: var(--brand);
  margin-top: var(--space-4);
  padding: var(--space-4);
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--note) 32%, transparent);
  background: color-mix(in srgb, var(--note) 9%, transparent);
}

.note > :first-child {
  margin-top: 0;
}

.note-pos {
  --note: var(--pos);
}

/* The mix is deliberately dark: at 78% the green variant lands on 4.49:1
   against its own tinted panel, one hundredth short of AA. */
.note-label {
  font-weight: 800;
  color: var(--note);
  color: light-dark(
    color-mix(in srgb, var(--note) 66%, #000),
    color-mix(in srgb, var(--note) 62%, #fff)
  );
}

.doc-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-4);
  font-size: var(--t-sm);
  color: var(--on-brand-dim);
}

.doc-updated {
  font-size: var(--t-sm);
  color: var(--text-faint);
  margin-bottom: var(--space-6);
}

/* --------------------------------------------------------------------------
   22. Mobile composition
   Desktop is a two-column stage. On a phone the same markup has to become a
   single-column story: cropped product peeks, full-width taps, and a sticky
   screenshot that stays with the chapters instead of scrolling away first.
   -------------------------------------------------------------------------- */

@media (max-width: 939px) {
  /* Roomier side padding — ~18px felt edge-hugging on phones. */
  :root {
    --gutter: clamp(1.35rem, 5.5vw, 2rem);
    --header-h: 60px;
  }

  .section {
    padding-block: clamp(2.5rem, 7vw, 4.5rem);
  }

  .hero {
    /* Keep room under the bank marquee — the curved .seam is absolute and
       will cover the last content if bottom padding is zeroed. */
    padding-block: clamp(1.5rem, 5vw, 2.5rem)
      calc(var(--space-7) + clamp(48px, 8vw, 72px));
  }

  .hero h1 {
    font-size: clamp(2rem, 1.55rem + 4.2vw, 2.75rem);
    text-wrap: balance;
  }

  .hero .lead {
    font-size: 1.0625rem;
    line-height: 1.55;
  }

  .hero-grid {
    gap: var(--space-5);
  }

  .hero-cta {
    flex-direction: column;
    align-items: stretch;
  }

  .hero-cta .btn {
    width: 100%;
  }

  .hero-note {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }

  .kicker {
    max-width: 100%;
    text-wrap: balance;
  }

  .seam {
    height: clamp(48px, 10vw, 72px);
    border-start-start-radius: 50% 70%;
    border-start-end-radius: 50% 70%;
  }

  .hero-band {
    padding-block-end: calc(clamp(2.5rem, 7vw, 4.5rem) + 48px);
  }

  /* Phone must shrink with its stage — width:min(300px,78vw) on .phone was
     overflowing the crop and looking half-cut on mobile. */
  .hero-stage {
    height: min(72vw, 380px);
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    mask-image: linear-gradient(#000 78%, transparent 100%);
    -webkit-mask-image: linear-gradient(#000 78%, transparent 100%);
  }

  .hero-stage .tilt-inner {
    width: min(240px, 62vw);
  }

  .hero-stage .phone {
    width: 100%;
    border-radius: 34px;
    padding: 7px;
  }

  .phone-float {
    animation: none;
  }

  /* Scrolling marquee clips pills on a 390px screen — wrap the labels instead. */
  .marquee {
    flex-wrap: wrap;
    justify-content: center;
    overflow: visible;
    gap: var(--space-2);
    mask-image: none;
    -webkit-mask-image: none;
  }

  .marquee-track {
    animation: none;
    flex-wrap: wrap;
    justify-content: center;
    min-width: 0;
    width: 100%;
    padding-inline-end: 0;
    gap: var(--space-2);
  }

  .marquee-track[aria-hidden='true'] {
    display: none;
  }

  .on-brand .marquee-item {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.28);
    color: #fff;
    font-size: var(--t-xs);
    padding: 0.45rem 0.85rem;
  }

  /* On phones, sticky eats the viewport and clips chapter copy under the
     header. Keep the phone as a static peek that scrolls away with the intro. */
  .showcase-sticky {
    position: relative;
    top: auto;
    z-index: 1;
    height: auto;
    max-height: min(42vw, 260px);
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    margin-block: var(--space-2) var(--space-5);
    padding-top: 0;
    background: transparent;
    box-shadow: none;
    pointer-events: none;
    mask-image: linear-gradient(#000 55%, transparent 100%);
    -webkit-mask-image: linear-gradient(#000 55%, transparent 100%);
  }

  .section-alt .showcase-sticky {
    background: transparent;
  }

  .showcase-sticky::after {
    display: none;
  }

  .showcase-sticky .phone {
    width: min(168px, 46vw);
    border-radius: 28px;
    padding: 6px;
  }

  .showcase-sticky .phone::before {
    top: 14px;
    height: 18px;
  }

  .showcase-steps {
    gap: var(--space-7);
    padding-block: var(--space-2) var(--space-6);
  }

  .showcase-step {
    min-height: 0;
    padding-block: var(--space-5);
  }

  .showcase-step h3,
  .showcase-step p {
    max-width: 36rem;
    overflow-wrap: anywhere;
  }

  .chapter {
    padding-inline-start: var(--space-5);
    min-width: 0;
  }

  /* Intro above the phone needs room under the sticky header when scrolled to. */
  .showcase {
    gap: var(--space-2);
  }

  .metric-row {
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: var(--space-2);
  }

  .metric {
    padding: var(--space-3);
  }

  .metric b {
    font-size: var(--t-xl);
  }

  .metric span {
    font-size: var(--t-xs);
    line-height: 1.35;
  }

  .demo-frame {
    max-width: none;
    padding: var(--space-4);
  }

  .store-badge {
    flex: 1 1 100%;
    justify-content: center;
  }

  .site-footer {
    padding-bottom: calc(var(--space-6) + var(--safe-bottom));
  }

  .lead {
    font-size: 1.0625rem;
  }
}

@media (max-width: 719px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }

  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
  }

  /* Turn the comparison table into stacked cards so nothing has to be
     swiped sideways to be read. */
  .table-wrap {
    overflow: visible;
    border: 0;
    background: transparent;
    mask-image: none;
    -webkit-mask-image: none;
  }

  table.cmp {
    min-width: 0;
    display: block;
  }

  table.cmp thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  table.cmp tbody {
    display: grid;
    gap: var(--space-3);
  }

  table.cmp tbody tr {
    display: grid;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
  }

  table.cmp tbody tr:hover {
    background: var(--surface);
  }

  table.cmp th,
  table.cmp td {
    border: 0;
    padding: 0;
  }

  table.cmp tbody th {
    font-size: var(--t-base);
    padding-bottom: var(--space-1);
  }

  table.cmp tbody td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-3);
    padding: 0.4rem 0.7rem;
    border-radius: var(--r-sm);
    background: var(--surface-2);
  }

  table.cmp tbody td::before {
    content: attr(data-label);
    color: var(--text-faint);
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: var(--t-xs);
  }

  table.cmp tbody td.col-hl {
    background: color-mix(in srgb, var(--brand) 10%, transparent);
  }
}

/* --------------------------------------------------------------------------
   23. Reduced motion — one switch turns all of it off
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* Critical: reveals must not leave content invisible when motion is off */
  .reveal,
  .enter,
  .word {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Pointer-driven effects: neutralise the offsets site.js would write, so a
     stale custom property can never leave an element visibly displaced. */
  .magnetic {
    translate: none !important;
  }

  .tilt-inner {
    transform: none !important;
  }

  /* Chapters must all stay legible when the sticky sync is not animating. */
  [data-chapters='synced'] .chapter {
    opacity: 1 !important;
  }

  [data-chapters='synced'] .chapter::after {
    height: 100% !important;
  }

  /* Ambient decoration holds a single frame rather than freezing mid-drift. */
  .mesh {
    transform: none !important;
  }

  /* Marquee: global animation kill leaves the track stuck off-screen. */
  .marquee {
    flex-wrap: wrap;
    justify-content: center;
    mask-image: none !important;
    -webkit-mask-image: none !important;
    row-gap: var(--space-2);
  }

  .marquee-track {
    animation: none !important;
    transform: none !important;
    min-width: 0;
    flex-wrap: wrap;
    justify-content: center;
  }

  .marquee-track[aria-hidden='true'] {
    display: none !important;
  }

  @view-transition {
    navigation: none;
  }
}
