/* LedgerOS marketing site. "Ledger" theme (v5).
 *
 * Hand-written, zero-framework. Three self-hosted font files are the only
 * requests beyond the page itself, and none of them blocks first paint.
 *
 * Why this direction. v1 was a generic AI blue, v2 green, v3 warm porcelain,
 * v4 harbour navy. Navy was right about seriousness and wrong about warmth:
 * it made a tool for keeping receipts feel like a banking dashboard, and every
 * SaaS page on the internet is already blue.
 *
 * v5 is deep forest on warm cream, with coral used sparingly:
 *
 *   - forest (#0C3B32) is the ink, the dark bands and the footer. It carries
 *     the same authority navy did without the fintech association.
 *   - cream (#F6F0E5) is the canvas. Paper, not screen. It suits a product
 *     whose whole subject is paper receipts, and it is markedly easier on the
 *     eye outdoors than a blue-white.
 *   - coral appears on roughly 2% of the surface: the primary button, links,
 *     and the marks on a chart. Restricted so it still means something.
 *   - a soft sage (#D9E4D5) fills confirmation chips and chart areas.
 *
 * Two values are deliberately NOT the ones from the reference design. Its
 * coral (#F06243) under white text is 3.16:1 and its muted grey-green
 * (#718377) on cream is 3.55:1, both short of the 4.5:1 WCAG AA needs for
 * body text. --sky is the darker #C93C22 (4.97:1) and --ink-soft is #546A5E
 * (5.14:1). The bright coral survives as --accent for marks that carry no
 * words. Someone reading this on a phone in daylight is the normal case here,
 * not the edge case.
 *
 * Every colour below is meant to match Theme.kt and tailwind.config.js. If you
 * change one here, change those too: they are one product.
 *
 * Motion rules unchanged: transform/opacity only, off under reduced motion.
 */

/* ── Self-hosted faces ───────────────────────────────────────────────────────
 *
 * Copied from the @fontsource packages at build time and served from /fonts/.
 * unicode-range is omitted deliberately: these are already latin subsets, and
 * a wrong range silently drops glyphs rather than failing loudly.
 *
 * Fraunces and DM Sans are variable, so one file per family covers the whole
 * weight range and there is no second request when a heading goes bold. */
@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/fraunces-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('/fonts/dm-sans-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 1000;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'DM Mono';
  src: url('/fonts/dm-mono-latin-500-normal.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Canvas. --paper is the page, --paper-2 the alternating tinted band. */
  --paper:     #F6F0E5;
  --paper-2:   #F0E8D8;
  --card:      #FFFDF8;

  /* Ink.
   *
   * --ink is #1E2245 because that is exactly what Theme.kt uses for
   * onBackground and onSurface. Headings on this page and headings inside the
   * app are now the same colour rather than two navies that almost match,
   * which is the kind of near-miss that makes a product feel assembled from
   * parts. --ink-deep (Sky900) is for dark surfaces — the final band, the
   * footer, the primary button — where more depth is wanted than body text
   * should ever have. */
  --ink:       #173C34;   /* Theme.kt onBackground. KEEP IN SYNC */
  --ink-deep:  #0C3B32;   /* Forest. Dark bands and the footer. */
  --ink-2:     #14453A;   /* Forest, one step up */
  --ink-soft:  #546A5E;
  --line:      #DCD4C6;

  /* Interactive blue — Sky600/700, straight from Theme.kt. */
  --sky:       #C93C22;
  --sky-2:     #B32F17;
  --sky-soft:  #FBE3DC;   /* Coral tint. Chips and containers. */
  --sky-50:    #FDF1ED;

  /* Pro only. Gold400 → Gold600 is the Android Pro gradient, unchanged. */
  --gold:      #D89A2A;
  --gold-2:    #B87C12;
  --gold-soft: #F5E6C4;
  --gold-ink:  #6B4A05;

  /* Confirmation only. Never used for decoration. */
  --mint:      #2E7D5A;
  --mint-ink:  #123D2A;
  --mint-soft: #D9E4D5;

  /* The Android dashboard hero gradient, unchanged. Used on the primary
     button, the phone mock and the closing band so the three read as the
     same material. */
  --grad-ink:  linear-gradient(150deg, #1B5044 0%, #0C3B32 100%);
  --grad-gold: linear-gradient(120deg, #F06243 0%, #C93C22 100%);

  --radius:    20px;
  --radius-lg: 28px;

  /* Shadows are tinted with the ink rather than pure black. Neutral-grey
     shadow over a blue-white canvas reads muddy; tinting keeps it clean. */
  --shadow-sm: 0 1px 2px rgba(12,59,50,.05), 0 6px 16px -8px rgba(12,59,50,.10);
  --shadow-md: 0 2px 6px rgba(12,59,50,.06), 0 20px 44px -20px rgba(12,59,50,.22);
  --shadow-lg: 0 10px 24px -10px rgba(12,59,50,.26), 0 36px 76px -30px rgba(12,59,50,.38);
  --shadow-glow: 0 12px 30px -12px rgba(201,60,34,.40);

  --ease-out: cubic-bezier(.16,1,.3,1);

  /* Typefaces.
   *
   * Three self-hosted faces, served from this origin. The previous stack was
   * deliberately webfont-free and the comment here said the upgrade would be
   * "one self-hosted variable woff2, preloaded from this origin". This is that
   * upgrade, taken on purpose rather than slipped in.
   *
   *   Fraunces  display. A soft, slightly wonky old-style serif. It is what
   *             stops the page reading as another framework starter.
   *   DM Sans   body. Geometric humanist, wide apertures, holds up small on a
   *             phone held at arm's length outdoors.
   *   DM Mono   figures only. Tabular by construction, so a column of dollar
   *             amounts lines up on the decimal instead of drifting.
   *
   * Cost: three latin-subset woff2 files, about 88 KB in total, from this
   * domain rather than a third party. Two are variable, so one file covers
   * every weight the page uses. font-display: swap means text paints in the
   * fallback immediately and never blocks, and the fallback stacks below are
   * metric-near so the swap is not a lurch.
   *
   * NOT loaded from fonts.googleapis.com. A third-party font request is a
   * third-party dependency on a page that has to work on regional mobile data,
   * and it hands another party a log of every visitor. */
  --serif: 'Fraunces', Charter, 'Sitka Display', 'Iowan Old Style', Constantia,
           'Palatino Linotype', Georgia, serif;
  --sans: 'DM Sans', 'Avenir Next', Avenir, 'Segoe UI Variable Text', 'Segoe UI',
          -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', Arial, sans-serif;
  --mono: 'DM Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', 'Roboto Mono',
          Menlo, Consolas, monospace;

  /* The decorative coral. Bright enough to signal, too bright to carry text:
     white on it is 3.16:1, short of the 4.5:1 AA needs. So it marks things
     (dots, chart points, rules, big numerals) and --sky (#C93C22, 4.97:1)
     carries anything with words on it. Same family, one passes. */
  --accent:      #F06243;
  --accent-soft: #FBE3DC;

  /* Legacy aliases. The markup and older rules still reference the porcelain
     names in places; mapping them here means one file changes, not five, and
     nothing silently falls back to an unstyled default. */
  --porcelain:   var(--paper);
  --porcelain-2: var(--paper-2);
  --copper:      var(--sky-2);
  --copper-2:    var(--sky);
  --copper-soft: var(--sky-soft);
  --sage:        #2E7D5A;
  --teal-500:    var(--mint);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Proportional lining figures. Default oldstyle numerals in some serifs drop
     the 3, 4, 7 and 9 below the baseline, which looks wrong next to a dollar
     amount — and this page is mostly dollar amounts. */
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: 'kern' 1, 'liga' 1;
}

/* Fine paper grain — present but subliminal. */
body::after {
  content: '';
  position: fixed; inset: 0; z-index: 1000; pointer-events: none; opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

::selection { background: rgba(47,128,237,.28); }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 22px; }
.narrow { max-width: 780px; margin: 0 auto; }

/* Type scale.
 *
 * A 1.25 modular scale, clamped so it interpolates with the viewport instead
 * of stepping at breakpoints. Display sizes get progressively tighter
 * tracking — letter-spacing that looks right at 16px looks loose at 60px,
 * and that looseness is most of what makes a page feel amateur.
 *
 * Line height moves the other way: tight on display, generous on body. */
h1, h2, h3 { margin: 0 0 16px; text-wrap: balance; }
h1, h2 {
  font-family: var(--serif);
  font-weight: 700;
  color: var(--ink);
}
h1 {
  font-size: clamp(40px, 5.8vw, 64px);
  line-height: 1.04;
  letter-spacing: -0.028em;
}
h2 {
  font-size: clamp(29px, 3.6vw, 42px);
  line-height: 1.1;
  letter-spacing: -0.022em;
}
h3 {
  font-size: 19px; font-weight: 700; line-height: 1.3;
  letter-spacing: -0.014em;
}
p  { margin: 0 0 16px; }
.lead {
  font-size: clamp(17px, 1.6vw, 20px);
  color: var(--ink-soft);
  line-height: 1.62;
  /* Measure. Past roughly 70 characters the eye loses the line return, and
     the hero paragraph is the one people actually read. */
  max-width: 62ch;
}
.narrow .lead, .narrow > .lead { margin-left: auto; margin-right: auto; }
.muted { color: var(--ink-soft); }
.small { font-size: 14.5px; line-height: 1.58; }

/* The pitch phrase: italic serif over a blue rule — the ONE place the accent
   speaks loudly. The rule sits on the baseline rather than behind the glyphs
   so descenders stay legible. */
.accent {
  font-style: italic;
  color: var(--ink-2);
  background-image: linear-gradient(to top, rgba(47,128,237,.34) 0 .14em, transparent .14em);
  padding: 0 .04em;
}

/* Vertical rhythm. Sections breathe more at desktop width and tighten on a
   phone, where 88px of padding is most of a screen. */
section { padding: clamp(64px, 8vw, 104px) 0; position: relative; }
section.tint { background: var(--paper-2); }

/* A hairline between a tinted band and the plain canvas. Without it the two
   greys meet in a soft blur that reads as a rendering fault on OLED phones. */
section.tint { box-shadow: inset 0 1px 0 var(--line), inset 0 -1px 0 var(--line); }

/* ── Scroll reveal ────────────────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(26px); }
.reveal.in {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

/* ── Header ───────────────────────────────────────────────────────────── */
header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(245,248,252,.72);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom: 1px solid transparent;
  transition: border-color .3s, background-color .3s, box-shadow .3s;
}
header.scrolled {
  background: rgba(245,248,252,.92);
  border-bottom-color: var(--line);
  box-shadow: 0 8px 26px -16px rgba(11,46,92,.2);
}
.nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 13px 0; }
.brand { display: flex; align-items: center; gap: 9px; font-weight: 800; font-size: 19px; letter-spacing: -0.02em; text-decoration: none; color: var(--ink); }
.brand-mark {
  width: 32px; height: 32px; border-radius: 10px;
  background: var(--grad-ink); color: #FFFFFF;
  font-family: var(--serif); font-size: 17px; font-weight: 700;
  display: grid; place-items: center;
  box-shadow: 0 5px 14px -5px rgba(11,46,92,.5);
}
.nav-links { display: flex; align-items: center; gap: 24px; }
.nav-links a { color: var(--ink-soft); text-decoration: none; font-size: 15px; font-weight: 600; transition: color .2s; }
.nav-links a:hover { color: var(--ink); }
/* The CTA in the nav is a .btn — its light label must win over the plain
   link colour above. (v2 bug: dark text on a dark button, unreadable.) */
.nav-links a.btn, .nav-links a.btn:hover { color: #F5F8FC; }
@media (max-width: 760px) { .nav-links .hide-sm { display: none; } }

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn, .btn-ghost {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 50px; padding: 0 26px; border-radius: 14px;
  font-weight: 700; font-size: 16px; text-decoration: none; cursor: pointer;
  border: 1px solid transparent;
  transition: transform .25s var(--ease-out), box-shadow .25s var(--ease-out),
              background-color .2s, border-color .2s;
  -webkit-tap-highlight-color: transparent;
}
.btn {
  background: var(--grad-ink); color: #F5F8FC;
  box-shadow: var(--shadow-glow);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 18px 44px -14px rgba(11,46,92,.55); }
.btn:active { transform: translateY(0) scale(.98); }
.btn::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -70%; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(47,128,237,.28), transparent);
  transform: skewX(-18deg); transition: left .6s var(--ease-out);
}
.btn:hover::after { left: 130%; }

.btn-ghost {
  background: rgba(255,255,255,.85); color: var(--ink); border-color: var(--line);
  box-shadow: var(--shadow-sm);
}
.btn-ghost:hover { transform: translateY(-2px); border-color: rgba(11,46,92,.35); box-shadow: var(--shadow-md); }
.btn-ghost:active { transform: translateY(0) scale(.98); }
.btn-lg { min-height: 58px; padding: 0 32px; font-size: 17px; border-radius: 16px; }
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* Keyboard focus. The default UA ring disappears against a blue button, and
   this is the primary conversion path — it has to be operable without a
   mouse. Offset so the ring reads as a halo rather than a border. */
.btn:focus-visible, .btn-ghost:focus-visible, .nav-links a:focus-visible,
.toggle button:focus-visible, details summary:focus-visible,
.play-badge:focus-visible, footer a:focus-visible {
  outline: 3px solid var(--sky);
  outline-offset: 3px;
  border-radius: 14px;
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero { padding: clamp(56px, 7vw, 92px) 0 clamp(52px, 6vw, 80px); overflow: hidden; }
.hero-bg { position: absolute; inset: 0; pointer-events: none; }
/* Barely-there warmth — atmosphere, not colour. */
.hero-bg .blob { position: absolute; border-radius: 50%; filter: blur(90px); }
.hero-bg .b1 { width: 540px; height: 540px; right: -130px; top: -170px;
  background: radial-gradient(circle, rgba(47,128,237,.14), transparent 65%); }
.hero-bg .b2 { width: 440px; height: 440px; left: -150px; bottom: -130px;
  background: radial-gradient(circle, rgba(11,46,92,.10), transparent 65%); }
.hero-bg .b3 { width: 380px; height: 380px; left: 36%; top: -130px;
  background: radial-gradient(circle, rgba(47,128,237,.10), transparent 65%); }
@media (prefers-reduced-motion: no-preference) {
  .hero-bg .blob { animation: drift 16s ease-in-out infinite alternate; }
  .hero-bg .b2 { animation-duration: 20s; animation-delay: -6s; }
  .hero-bg .b3 { animation-duration: 24s; animation-delay: -11s; }
  @keyframes drift {
    from { transform: translate(0,0) scale(1); }
    to   { transform: translate(34px, 26px) scale(1.08); }
  }
}

.hero-grid { position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 52px; align-items: center; }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; gap: 40px; } }

.eyebrow {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--card); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  color: var(--ink); font-size: 13px; font-weight: 700;
  padding: 7px 14px; border-radius: 999px; margin-bottom: 20px;
}
.eyebrow::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--copper); box-shadow: 0 0 0 3px rgba(47,128,237,.2);
}
.trust-line { margin-top: 20px; font-size: 14px; color: var(--ink-soft); }

/* ── Phone mock-up ────────────────────────────────────────────────────── */
.phone {
  position: relative;
  width: 292px; margin: 0 auto;
  background: linear-gradient(160deg, #FFFFFF, #E7EEF8);
  border: 1px solid rgba(227,233,242,.95);
  border-radius: 34px; padding: 10px;
  box-shadow: var(--shadow-lg);
}
@media (prefers-reduced-motion: no-preference) {
  .phone { animation: float 7s ease-in-out infinite; }
  @keyframes float {
    0%, 100% { transform: translateY(0) rotate(-.4deg); }
    50%      { transform: translateY(-12px) rotate(.4deg); }
  }
}
.phone::before {
  content: ''; position: absolute; inset: 12% -8% -6% -8%; z-index: -1;
  background: linear-gradient(120deg, rgba(11,46,92,.4), rgba(47,128,237,.3));
  filter: blur(50px); opacity: .35; border-radius: 50%;
}
.phone-inner { position: relative; background: var(--porcelain); border-radius: 26px; overflow: hidden; }
.phone-inner::after {
  content: ''; position: absolute; top: -60%; left: -80%; width: 60%; height: 220%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.55), transparent);
  transform: skewX(-18deg); pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .phone-inner::after { animation: sweep 6s var(--ease-out) infinite; animation-delay: 1.2s; }
  @keyframes sweep { 0% { left: -80%; } 38%, 100% { left: 160%; } }
}
.phone-bar { background: var(--card); border-bottom: 1px solid var(--line); padding: 9px 11px; display: flex; align-items: center; gap: 6px; }
.pill-pro { background: var(--grad-gold); color: #3E2500; font-size: 9px; font-weight: 800; padding: 2px 6px; border-radius: 5px; letter-spacing: .05em; }
.phone-body { padding: 11px; }
/* The mock screen is the real dashboard hero, same gradient as Android. It is
   a sales asset: if it does not match what a visitor sees after signing up,
   the first run of the app feels like a bait and switch. */
.hero-card {
  background: var(--grad-ink);
  border-radius: 18px; padding: 14px; color: #EDF3FA; margin-bottom: 10px;
  box-shadow: 0 12px 26px -12px rgba(11,46,92,.55);
}
.hero-card .amt { font-size: 29px; font-weight: 800; letter-spacing: -.025em; color: #FFFFFF; }
.mini-card { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 11px; margin-bottom: 10px; box-shadow: var(--shadow-sm); }
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.tile-icon { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; font-size: 14px; }

/* ── Cards / grids ────────────────────────────────────────────────────── */
.grid { display: grid; gap: 20px; }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 860px) { .g3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .g3, .g2 { grid-template-columns: 1fr; } }

.card {
  position: relative;
  /* isolate so the sheen below cannot paint over a neighbouring card, and so
     the stacking context is the card itself rather than the section. */
  isolation: isolate;
  overflow: hidden;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 26px; box-shadow: var(--shadow-sm);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), border-color .35s;
}
.card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-md);
  border-color: rgba(47,128,237,.34);
}

/* Card splash — two layers, matching the sweep already used on .btn and the
   phone mock so the whole page moves the same way.
 *
 * ::before is the wash: a soft blue bloom rising out of the bottom-left,
 * which gives the card depth without adding a visible gradient at rest.
 * ::after is the sheen: a narrow skewed highlight that crosses once.
 *
 * Both animate opacity and transform only — no layout, no paint of a property
 * that would force reflow — so this stays cheap on a mid-range Android.
 * z-index -1 keeps them under the text; the card's own background is opaque,
 * so nothing shows through from behind. */
.card::before {
  content: ''; position: absolute; z-index: -1;
  left: -30%; bottom: -60%; width: 160%; height: 160%;
  background:
    radial-gradient(closest-side, rgba(47,128,237,.16), transparent 70%),
    radial-gradient(closest-side, rgba(52,199,123,.10), transparent 70%) 60% 40% / 70% 70% no-repeat;
  opacity: 0;
  transform: translate3d(0, 18px, 0) scale(.9);
  transition: opacity .5s var(--ease-out), transform .6s var(--ease-out);
  pointer-events: none;
}
.card:hover::before,
.card:focus-within::before {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

.card::after {
  content: ''; position: absolute; z-index: -1;
  top: 0; bottom: 0; left: -80%; width: 42%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
  transform: skewX(-18deg);
  transition: left .75s var(--ease-out);
  pointer-events: none;
}
.card:hover::after,
.card:focus-within::after { left: 145%; }

/* The accent card carries a permanent, very faint version of the wash so it
   reads as the recommended one before anybody hovers anything — hover-only
   emphasis is invisible on a phone, which is where most of this traffic is. */
.card-accent::before { opacity: .55; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .card::before, .card::after { transition: none; }
  .card:hover::after, .card:focus-within::after { left: -80%; }
}
.icon-tile {
  width: 46px; height: 46px; border-radius: 14px;
  display: grid; place-items: center; margin-bottom: 14px; font-size: 20px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.5), var(--shadow-sm);
  transition: transform .35s var(--ease-out);
}
.card:hover .icon-tile { transform: scale(1.08) rotate(-3deg); }
.t-sky  { background: var(--sky-soft);  color: var(--ink-2); }
.t-teal { background: var(--mint-soft); color: var(--mint-ink); }
.t-gold { background: var(--gold-soft); color: var(--gold-ink); }

/* The one card per section that should be looked at first. A left rule rather
   than a full border: it marks the card without turning it into a callout box,
   and it survives the card's own hover border-colour change. */
.card-accent {
  border-color: var(--sky-soft);
  box-shadow: var(--shadow-sm), inset 4px 0 0 var(--sky);
}
.card-accent:hover { box-shadow: var(--shadow-md), inset 4px 0 0 var(--sky); }

/* ── Steps ────────────────────────────────────────────────────────────── */
.steps { counter-reset: step; display: grid; gap: 20px; grid-template-columns: repeat(4, 1fr); position: relative; }
@media (max-width: 860px) { .steps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } }
.step { position: relative; padding-top: 56px; }
.step::before {
  counter-increment: step; content: counter(step);
  position: absolute; top: 0; left: 0;
  width: 40px; height: 40px; border-radius: 14px;
  background: var(--grad-ink); color: #FFFFFF;
  font-family: var(--serif); font-weight: 700; font-size: 17px;
  display: grid; place-items: center;
  box-shadow: 0 9px 20px -9px rgba(11,46,92,.5);
}
.step::after {
  content: ''; position: absolute; top: 20px; left: 52px; right: -8px;
  border-top: 2px dashed rgba(78,91,117,.32);
}
.step:last-child::after { display: none; }
@media (max-width: 860px) { .step::after { display: none; } }

/* ── Pricing ──────────────────────────────────────────────────────────── */
.toggle {
  display: inline-flex; background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px; gap: 4px; box-shadow: var(--shadow-sm);
}
.toggle button {
  border: 0; background: transparent; color: var(--ink-soft); font-weight: 700; font-size: 15px;
  padding: 10px 22px; border-radius: 999px; cursor: pointer;
  transition: color .25s, background-color .25s, box-shadow .25s, transform .2s var(--ease-out);
}
.toggle button[aria-pressed="true"] { background: var(--grad-ink); color: #F5F8FC; box-shadow: var(--shadow-glow); }
.toggle button:not([aria-pressed="true"]):hover { color: var(--ink); }

.plans { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; max-width: 840px; margin: 34px auto 0; align-items: stretch; }
@media (max-width: 720px) { .plans { grid-template-columns: 1fr; } }
.plan {
  position: relative;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 30px; display: flex; flex-direction: column; box-shadow: var(--shadow-sm);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.plan:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
.plan.featured {
  border: 0; z-index: 0;
  background: linear-gradient(160deg, #123A6E, #0B2E5C);
  color: #E8F0FB;
  box-shadow: var(--shadow-lg);
}
.plan.featured::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 2px; z-index: -1;
  background: linear-gradient(115deg, var(--copper), var(--copper-2));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.plan.featured h3, .plan.featured .price { color: #F5F8FC; }
.plan.featured .muted, .plan.featured .small { color: rgba(232,240,251,.72); }
.plan.featured .per { color: rgba(232,240,251,.6); }
.plan .badge {
  display: inline-flex; align-self: flex-start;
  background: var(--grad-gold); color: #3E2500;
  font-size: 12px; font-weight: 800; letter-spacing: .02em;
  padding: 5px 12px; border-radius: 999px; margin-bottom: 12px;
}
.price {
  font-size: 46px; font-weight: 700; letter-spacing: -.03em;
  font-family: var(--serif);
  /* Old-style figures are what Fraunces gives by default, and they read as
     prose rather than as data. A price is data. */
  font-variant-numeric: lining-nums tabular-nums;
}
.per { font-size: 15px; color: var(--ink-soft); font-weight: 600; }
.feat { list-style: none; padding: 0; margin: 20px 0 0; display: grid; gap: 10px; flex: 1; }
.feat li { display: flex; gap: 10px; font-size: 15px; align-items: flex-start; }
.feat .tick { color: var(--sage); font-weight: 800; flex-shrink: 0; }
.plan.featured .feat .tick { color: var(--copper-2); }
.feat .cross { color: var(--ink-soft); flex-shrink: 0; }
.feat li.off { color: var(--ink-soft); }
.plan.featured .feat li.off { color: rgba(232,240,251,.55); }
/* The JS-rendered "Save %" note carries an inline colour; remap it. */
.plan .small[style] { color: var(--sage) !important; }
.plan.featured .small[style] { color: var(--copper-2) !important; }

/* ── Android app strip ────────────────────────────────────────────────── */
.play-strip { background: var(--card); }
.play-grid { display: grid; grid-template-columns: 1fr auto; gap: 44px; align-items: center; }
@media (max-width: 720px) { .play-grid { grid-template-columns: 1fr; } }
.play-line { margin-top: 12px; font-size: 14px; color: var(--ink-soft); }
.play-line a, #faq a { color: var(--ink-2); font-weight: 600; }
.play-badge {
  display: inline-flex; align-items: center; gap: 12px;
  background: var(--grad-ink);
  color: #F5F8FC; text-decoration: none;
  border-radius: 14px; padding: 12px 22px; line-height: 1.15;
  box-shadow: var(--shadow-md);
  transition: transform .25s var(--ease-out), box-shadow .25s var(--ease-out);
}
.play-badge:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.play-badge:active { transform: scale(.98); }
.play-badge-icon { font-size: 22px; color: var(--sky); }
.play-badge-top { display: block; font-size: 11px; opacity: .75; }
.play-badge-name { display: block; font-size: 18px; font-weight: 800; }
.play-qr-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px; text-align: center; box-shadow: var(--shadow-md);
}
.play-qr-card img { display: block; margin: 0 auto 8px; }
@media (max-width: 720px) { .play-qr-card { display: none; } }

/* ── FAQ ──────────────────────────────────────────────────────────────── */
details {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px 22px; margin-bottom: 14px; box-shadow: var(--shadow-sm);
  transition: border-color .3s, box-shadow .3s;
}
details:hover { border-color: rgba(11,46,92,.28); }
details[open] { box-shadow: var(--shadow-md); border-color: rgba(11,46,92,.32); }
details summary {
  font-weight: 700; cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; gap: 14px; align-items: center;
}
details summary::-webkit-details-marker { display: none; }
details summary::after {
  content: '+'; font-size: 22px; font-weight: 400; color: var(--ink-2); line-height: 1;
  transition: transform .3s var(--ease-out);
}
details[open] summary::after { transform: rotate(45deg); }
details p { margin: 12px 0 0; color: var(--ink-soft); animation: faq-in .35s var(--ease-out); }
@keyframes faq-in { from { opacity: 0; transform: translateY(-4px); } }

/* ── Final CTA ────────────────────────────────────────────────────────── */
.final {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg, #1D63C7 0%, #0F3E7A 48%, #0B2E5C 100%);
  color: #E8F0FB; border-radius: var(--radius-lg); padding: 64px 32px; text-align: center;
  box-shadow: var(--shadow-lg);
}
.final h2 { color: #F5F8FC; }
.final .lead { color: rgba(232,240,251,.85) !important; }
.final::before, .final::after {
  content: ''; position: absolute; border-radius: 50%; filter: blur(70px); pointer-events: none;
}
.final::before { width: 340px; height: 340px; right: -80px; top: -120px; background: rgba(47,128,237,.18); }
.final::after { width: 280px; height: 280px; left: -70px; bottom: -110px; background: rgba(47,128,237,.12); }
.final .btn { background: var(--grad-gold); color: #3E2500; box-shadow: 0 16px 36px -14px rgba(0,0,0,.55); }
.final .btn:hover { box-shadow: 0 20px 46px -14px rgba(0,0,0,.65); }

/* ── Footer ───────────────────────────────────────────────────────────── */
footer {
  border-top: 1px solid rgba(232,240,251,.1);
  padding: 38px 0; font-size: 14px;
  background: var(--ink-deep); color: rgba(232,240,251,.75);
}
footer a { color: rgba(232,240,251,.72); text-decoration: none; margin-right: 18px; transition: color .2s; }
footer a:hover { color: var(--copper-2); }

:focus-visible { outline: 3px solid var(--copper); outline-offset: 2px; border-radius: 6px; }

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

/* ── Curves and ground ───────────────────────────────────────────────────────
 *
 * The page was a stack of flat rectangles. These add the soft organic shapes
 * the design leans on, and every one of them is CSS: no image requests, no
 * layout cost, and nothing to go stale in a build.
 *
 * All decorative, so all aria-hidden by construction (::before / ::after are
 * not in the accessibility tree) and all pointer-events: none, so none of it
 * can ever swallow a tap.
 */

/* A wide, very soft wash sitting behind the top of the page. Two offset
   radial gradients rather than one: a single gradient reads as a spotlight,
   two overlapping read as light. */
.hero,
.band-soft {
  position: relative;
  isolation: isolate;
}
.hero::before,
.band-soft::before {
  content: '';
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 130%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(60% 55% at 18% 12%, rgba(217, 228, 213, .70) 0%, transparent 62%),
    radial-gradient(52% 48% at 88% 6%, rgba(240, 98, 67, .10) 0%, transparent 60%);
}

/* The curved cut between a cream section and the forest band underneath.
   An ellipse rather than a diagonal: a diagonal is the tell of a 2016 landing
   page, a shallow curve reads as paper. */
.curve-top,
.curve-bottom {
  position: relative;
}
.curve-top::before {
  content: '';
  position: absolute;
  left: -5%; right: -5%; top: -1px;
  height: 64px;
  background: var(--paper);
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  pointer-events: none;
}
.curve-bottom::after {
  content: '';
  position: absolute;
  left: -5%; right: -5%; bottom: -1px;
  height: 64px;
  background: var(--paper);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  pointer-events: none;
}

/* A single coral dot, the same mark the reference uses above its section
   labels. Small enough to be punctuation rather than decoration. */
.dot::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 9px;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
  transform: translateY(-1px);
}

/* Figures. Anywhere a number is doing work, it gets the mono face so columns
   line up and a changing value does not shift the layout around it. */
.figure,
.stat-value,
.metric {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* Cards lift very slightly on hover. 2px, not 8px: the point is that the
   surface is physical, not that it jumps. */
.card-lift {
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out);
}
.card-lift:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

@media (prefers-reduced-motion: reduce) {
  .card-lift { transition: none; }
  .card-lift:hover { transform: none; }
}
