@import url('/sky.css');
/* ── deepkut · shared stylesheet ─────────────────────────────────────────
   One sheet for the whole marketing site (/ and /pricing/). Lifted verbatim
   out of the landing's <style> block when pricing moved to its own page, so
   the two pages cannot drift: same fonts, same vars, same night sky,
   same mascot rig, same reduced-motion catch-all. Font urls are relative to
   THIS file, so they resolve from any depth. Page-specific rules live in a
   marked block at the bottom, not scattered. */

  @font-face { font-family:'Orbit'; src:url('fonts/Orbit.ttf') format('truetype'); font-display:swap; }
  @font-face { font-family:'URWGothic'; src:url('fonts/URWGothic-Book.ttf') format('truetype'); font-display:swap; }

  /* ── MOBILE FIRST ───────────────────────────────────────────────────────
     Every base rule below targets a phone. The only breakpoint is
     `min-width: 720px`, which adds columns and loosens spacing. Do not add
     max-width queries — if a rule needs undoing on desktop, the base rule was
     written for the wrong screen. */

  :root {
    /* ── ink + pink two-tone. --dk-ink is the brand ink; on this dark page it
       flips to its dark-context value (near-white) and the page background
       takes the light-context ink. The inline mascot inherits both vars. */
    --dk-ink: #FFF0F6; --dk-accent: #FFB0FB;
    --c1: #FFB0FB; --c2: #87CEFA; --c5: #FCFF46; --c7: #B2FFFF;
    --bg: #1A1218; --bg-deep: #120C10; --surface: #241820; --border: #3E2B36;
    --text: var(--dk-ink); --muted: #C9ABBC;
    --pink: var(--dk-accent); --pink-hover: #FFC6FC;
    /* functional accent family (mirrors src/app.css) — seasoning by MEANING,
       one accent per element, never headings/CTAs/brand surfaces:
       sun = moon/night-shift moments, sky = info/safekeeping,
       mint = success/growth, peach = warm/physical, lav = special/rare. */
    --dk-sun: #FCFF46; --dk-sky: #87CEFA; --dk-mint: #84E6BD;
    --dk-peach: #FFBEB0; --dk-lav: #DF73FF;
    --sky: var(--dk-sky); --mint: var(--dk-mint); --success: #5ee8a4;
    --glow-pink: 0 0 24px rgba(255, 176, 251,.30);
    --glow-mint: 0 0 24px rgba(132, 230, 189,.28);
    --glow-sky: 0 0 24px rgba(135,206,250,.28);
    --r-full: 9999px; --r-lg: 22px; --r-md: 14px;
    /* everything routes through URW Gothic; Orbit is granted explicitly to
       the hero h1 alone (see .hero h1 below) — keep it that way. */
    --head: 'URWGothic', system-ui, sans-serif; --body: 'URWGothic', system-ui, sans-serif;
  }
  * { box-sizing: border-box; margin: 0; }
  body { font-family: var(--body); background: var(--bg); color: var(--text); line-height: 1.5; overflow-x: clip; }
  h1, h2, h3 { font-family: var(--head); font-stretch: 125%; }
  a { color: inherit; }

  /* ── inline icons ───────────────────────────────────────────────────────
     Curated bimbotech flat-vector set, inlined (no extra requests). Every
     icon is fill-only `currentColor`, so it inherits the text colour of
     whatever it sits in; size is em-relative so it scales with the type. */
  .ico { width: 1em; height: 1em; vertical-align: -0.125em; flex: none; }
  /* the night-shift moment: the moon glows butter, not pink */
  .persona .ico { width: 1.1em; height: 1.1em; vertical-align: -0.2em; margin-left: .05em; color: var(--dk-sun); }
  h2 .ico { width: .8em; height: .8em; vertical-align: -0.06em; margin-left: .12em; color: var(--pink); }
  /* footer heart warms to peach — the CTA heart keeps the brand pink */
  footer .ico { width: .95em; height: .95em; vertical-align: -0.15em; color: var(--dk-peach); }

  /* the brand wordmark (inline SVG, brand/wordmark.svg): Orbit outlines in
     --dk-ink + pink scythe-blade k arm in --dk-accent — both resolve from the
     page vars above, so the ink reads near-white here. 26px tall ≈ the old
     1.25rem text logo's footprint; topbar height is still set by the 44px
     login target, so nothing shifts. */
  .wordmark { height: 26px; width: auto; display: block; }

  .topbar { display: flex; align-items: center; gap: 16px; padding: 16px 20px; max-width: 1000px; margin: 0 auto; }
  /* 44px min touch target — the login link is the only tappable thing up here
     and it sits in the thumb-hostile top corner, so it gets the full box. */
  .navlink, .loginlink { color: var(--muted); font-size: .95rem; text-decoration: none;
    min-height: 44px; display: flex; align-items: center; padding-inline: 8px; }
  /* the auto margin lives on the FIRST link after the wordmark — two autos
     would split the free space and strand "home" mid-bar */
  .navlink, .wordmark + .loginlink { margin-left: auto; }
  .navlink:hover, .loginlink:hover { color: var(--text); }

  /* tonight's moon (moon.js), top right under the content, over the sky */
  .moon { position: fixed; right: 7%; top: 72px; width: 84px; z-index: -1; pointer-events: none; }
  .moon svg { width: 100%; height: auto; display: block; overflow: visible; filter: drop-shadow(0 0 18px #fcff4655); }
  @media (max-width: 640px) { .moon { width: 56px; right: 5%; top: 64px; } }
  .hero { max-width: 1000px; margin: 0 auto; padding: 24px 20px 48px; }
  /* the single hero headline is the one Orbit surface on the page — see spec §2 */
  .hero h1 { font-family: 'Orbit', system-ui, sans-serif; font-size: clamp(2.1rem, 8.5vw, 3.4rem);
    font-weight: 800; line-height: 1.06; }
  .hero h1 i { color: var(--pink); font-style: normal; }
  .hero .persona { margin-top: 14px; font-family: var(--head); font-stretch: 125%; font-weight: 600;
    font-size: 1rem; color: var(--dk-sky); }
  .hero .sub { color: var(--muted); margin-top: 12px; font-size: 1rem; line-height: 1.6; }

  /* Waitlist form. On a phone the pill is two stacked full-width controls —
     an email field and a 48px button. The single-pill treatment only shows up
     at >=720px, where there's room for both without squeezing either. */
  .wl { display: grid; gap: 10px; margin-top: 24px; }
  .wl input { width: 100%; background: var(--surface); border: 2px solid var(--border);
    border-radius: var(--r-full); padding: 14px 20px; outline: none;
    color: var(--text); font-family: var(--body); font-size: 1rem; min-width: 0; }
  .wl input::placeholder { color: var(--muted); }
  .wl input:focus { border-color: var(--pink); box-shadow: var(--glow-pink); }
  .cta { width: 100%; min-height: 48px; background: var(--pink); color: #fff; border: none;
    display: inline-flex; align-items: center; justify-content: center; gap: .45em;
    font-family: var(--body); font-size: 1rem; font-weight: 700; padding: 13px 26px;
    border-radius: var(--r-full); cursor: pointer; transition: all .15s ease;
    box-shadow: var(--glow-pink); }
  .cta:hover { background: var(--pink-hover); }
  .cta:disabled { opacity: .6; transform: none; cursor: default; }
  .wl-done { display: none; color: var(--success); font-weight: 700; margin-top: 14px; }
  .wl-err { display: none; color: #ff6b81; font-size: .9rem; margin-top: 14px; }

  /* ── the mascot ─────────────────────────────────────────────────────────
     Big flat-vector reaper beside the headline. Inlined SVG so the ink body
     and pink scythe pick up --dk-ink / --dk-accent straight from the page —
     on this dark bg the body renders near-white with negative-space eyes.
     Flat and glow-free on purpose: the mark carries itself. */
  .mascotwrap { display: flex; justify-content: center; margin: 36px auto 0; }
  .mascot { width: min(60vw, 230px); height: auto; display: block;
    animation: float 6s ease-in-out infinite; }
  @keyframes float { 50% { transform: translateY(-8px); } }
  /* reduced-motion for the float lives in the snazz catch-all at the bottom
     of the sheet, together with everything else that moves. */

  .sect { max-width: 1000px; margin: 0 auto; padding: 44px 20px; }
  .sect h2 { font-size: 1.35rem; font-weight: 800; text-align: center; }
  .sect > p { text-align: center; }

  .eyebrow { font-family: var(--body); font-size: .72rem; letter-spacing: .09em;
    text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 10px; text-align: center; }


  /* ── the guided tour ────────────────────────────────────────────────────
     The whole pitch as four stops: the problem, what it does, features,
     how it works. BASE (this block) = stacked cards — phones,
     no-JS, reduced-motion and unsupporting browsers all read the tour top
     to bottom, nothing hidden. JS grants .night.flow (motion OK only),
     which adds the entrance reveals + you-are-here furniture; the desktop
     grid + rail live in the media block further down. */
  .night-track { max-width: 640px; margin: 8px auto 0; padding: 0 20px 44px; }
  .beat { padding: 56px 0 6px; }
  .beat-time { font-size: .74rem; letter-spacing: .09em; text-transform: uppercase;
    color: var(--dk-sun); font-weight: 700; }
  .beat h3 { font-size: clamp(1.35rem, 5.8vw, 1.8rem); font-weight: 800; margin-top: 6px; }
  .beat[data-b="problem"] h3, .beat[data-b="does"] h3 { font-size: clamp(1.7rem, 8vw, 2.2rem); }
  .beat .cap { font-size: .92rem; color: var(--muted); margin-top: 12px; line-height: 1.55; }
  .beat .punch { color: var(--text); font-weight: 600; }
  /* prop cards: the want, the rungs, the swap, the miss. same chrome family
     family, so the whole tour reads as one desk. */
  .prop { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--r-md);
    padding: 14px 16px; margin-top: 14px; font-size: .9rem; line-height: 1.5; }
  .prop .t { font-weight: 700; }
  .prop .m { color: var(--muted); font-size: .85rem; }
  /* hunt rungs: the real ladder, one chip per source. the winning rung is
     the one pink moment of the beat. */
  .rungs { list-style: none; display: grid; gap: 8px; margin: 12px 0 0; padding: 0; }
  .rung { display: flex; align-items: baseline; gap: 10px; font-size: .88rem; color: var(--muted); }
  .rung::before { content: ''; flex: none; width: 8px; height: 8px; border-radius: 50%;
    background: var(--border); align-self: flex-start; margin-top: .45em; }
  .rung b { color: var(--text); font-weight: 700; }
  /* each duty gets its meaning-accent dot: files = sun (night work),
     catalogs = sky (order) */
  .rung:nth-child(1)::before { background: var(--dk-sun); }
  .rung:nth-child(2)::before { background: var(--dk-sky); }
  .rung:nth-child(3)::before { background: var(--dk-mint); }
  /* verb / how-it-works rows: the old card grids, condensed to one line
     each so a whole idea fits a single stage panel. icon color = the same
     meaning-accents the cards used. */
  .rows { list-style: none; display: grid; gap: 12px; margin: 16px 0 0; padding: 0; }
  .rows li { display: flex; gap: 12px; align-items: flex-start; font-size: .92rem;
    color: var(--muted); line-height: 1.55; }
  .rows .ico { width: 1.3em; height: 1.3em; margin-top: .15em; }
  .rows b { color: var(--text); font-weight: 700; }
  a.cta { text-decoration: none; margin-top: 18px; }
  /* tour furniture hidden in BASE: the rail (desktop gutter) and the mrail
     strip (phone) only appear once JS grants .flow — no-JS reads the tour
     as plain stacked copy with nothing hidden and nothing missing. */
  .rail, .mrail { display: none; }

  /* ── the flowing tour (.night.flow — JS-granted, motion OK) ─────────────
     One normal page scroll on every screen: each stop plays its entrance as
     it arrives (an IntersectionObserver adds .live once, both directions
     keep the you-are-here marker honest). No sticky stage, no hijacked
     scroll — the sticky rail in the desktop gutter is the only pinned thing,
     and it's 420px of furniture, not the page. Without JS (or with reduced
     motion) .flow never lands, so nothing is ever hidden. */
  .night.flow .beat > * { opacity: 0; transform: translateY(10px);
    transition: opacity .5s ease, transform .5s ease; }
  .night.flow .beat.live > * { opacity: 1; transform: none; }
  .night.flow .beat.live > *:nth-child(2) { transition-delay: .08s; }
  .night.flow .beat.live > *:nth-child(3) { transition-delay: .18s; }
  .night.flow .beat.live > *:nth-child(4) { transition-delay: .3s; }
  .night.flow .beat.live > *:nth-child(5) { transition-delay: .42s; }
  .night.flow .beat.live > *:nth-child(6) { transition-delay: .54s; }
  .night.flow .rung, .night.flow .rows li { opacity: 0; transform: translateY(6px);
    transition: opacity .45s ease, transform .45s ease; }
  .night.flow .beat.live .rung:nth-child(1), .night.flow .beat.live .rows li:nth-child(1) { opacity: 1; transform: none; transition-delay: .45s; }
  .night.flow .beat.live .rung:nth-child(2), .night.flow .beat.live .rows li:nth-child(2) { opacity: 1; transform: none; transition-delay: .95s; }
  .night.flow .beat.live .rung:nth-child(3), .night.flow .beat.live .rows li:nth-child(3) { opacity: 1; transform: none; transition-delay: 1.45s; }

  /* ── desktop tour: rail gutter + generous rhythm ────────────────────────
     The track becomes a two-column grid — the night rail pins itself in the
     left gutter (sticky, mid-viewport) while the beats scroll past it. The
     moon rides the four stops down the rail; structure = information: this is still the night, just walked
     instead of staged. */
  @media (min-width: 720px) {
    .night-track { max-width: 920px; display: grid;
      grid-template-columns: 172px minmax(0, 600px); gap: 56px;
      justify-content: center; align-items: start; padding-bottom: 72px; }
    .beat { padding: 84px 0 20px; }
    .beat h3 { font-size: clamp(1.4rem, 1.9vw, 1.8rem); }
    .beat[data-b="problem"] h3, .beat[data-b="does"] h3 { font-size: clamp(1.8rem, 2.6vw, 2.3rem); }
    .beat .cap { font-size: .98rem; }
    .beat .cta { width: auto; }
    .night.flow .rail { display: block; position: sticky;
      top: calc(50vh - 210px); height: 420px; margin-top: 96px; }
    .rail::before { content: ''; position: absolute; left: 3px; top: 0; bottom: 0; width: 1.5px;
      background: var(--border); }
    .rail ol { list-style: none; margin: 0; padding: 0; position: relative; height: 100%; }
    .rail li { position: absolute; left: 0; display: flex; align-items: center; gap: 12px;
      transform: translateY(-50%); font-size: .74rem; letter-spacing: .06em; color: var(--muted);
      white-space: nowrap; transition: color .4s ease; }
    .rail li::before { content: ''; width: 8px; height: 8px; border-radius: 50%;
      background: var(--border); transition: background .4s ease, box-shadow .4s ease; }
    .rail li.at { color: var(--text); font-weight: 700; }
    .rail li.at::before { background: var(--pink); box-shadow: 0 0 10px rgba(255, 176, 251,.55); }
    .rail li:nth-child(1) { top: 0; } .rail li:nth-child(2) { top: 33.333%; }
    .rail li:nth-child(3) { top: 66.667%; } .rail li:nth-child(4) { top: 100%; }
    /* the moon: top set by JS per stop */
    .rail .orb { position: absolute; left: -7px; top: 0; width: 22px; height: 22px; color: var(--dk-sun);
      transition: top .9s cubic-bezier(.4, .1, .2, 1), filter .9s ease, color .9s ease; }
  }

  /* phone you-are-here strip: four dots under sticky glass, the moon IS the
     marker. Built by JS only under .flow. */
  @media (max-width: 719.9px) {
  .mrail { position: sticky; top: 10px; z-index: 6; display: flex; align-items: center;
    gap: 2px; width: max-content; max-width: calc(100vw - 32px); margin: 0 auto 4px;
    padding: 4px 14px 4px 8px; border-radius: var(--r-full);
    background: rgba(18, 12, 16, .82); border: 1.5px solid var(--border);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
  .mdot { position: relative; width: 26px; height: 26px; flex: none; border: none;
    background: none; padding: 0; cursor: pointer; display: inline-flex;
    align-items: center; justify-content: center; }
  .mdot::before { content: ''; width: 7px; height: 7px; border-radius: 50%;
    background: var(--border); transition: background .3s ease; }
  .mdot .morb { display: none; width: 15px; height: 15px; color: var(--dk-sun); }
  .mdot.at::before { display: none; }
  .mdot.at .morb { display: block; }
  .mlabel { font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
    font-weight: 700; color: var(--dk-sun); margin-left: 8px; white-space: nowrap; }
  } /* end phone-strip media */

  /* how-it-works icons, one accent each by meaning: hardware = peach (warm,
     physical box), interface = pink (the brand-facing bit, default), privacy
     = mint (secure/trusted). headings stay ink. */

  /* ── pricing (its own page now: /pricing/) ──────────────────────────────
     The free-forever row is the HEADLINE, above the plans on purpose: it's
     the promise that makes the three cards honest (BRAND.md — "paywall the
     convenience, never the engine"). Plus isn't on sale yet, so nothing here
     links to a payment page, and there is never a second signup path: every
     CTA is the same waitlist form the landing owns, submitted by the same
     handler in dk.js. Card chrome borrows the .prop family so the page reads
     as the same desk as the tour. */
  .pricing { background: var(--bg-deep); border-top: 1px solid var(--border); }
  .freerow { background: var(--surface); border: 1.5px solid var(--pink);
    border-radius: var(--r-md); box-shadow: var(--glow-pink);
    padding: 16px 18px; margin-top: 18px; text-align: center; }
  .freerow .t { font-family: var(--head); font-stretch: 125%; font-weight: 800; font-size: 1.05rem; }
  .freerow .m { color: var(--muted); font-size: .9rem; line-height: 1.55; margin-top: 8px; }
  .plus-lede { color: var(--muted); font-size: .9rem; line-height: 1.55; margin-top: 18px; }
  .plans { display: grid; gap: 12px; margin-top: 18px; }
  .plan { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--r-md);
    padding: 16px 18px; display: flex; flex-direction: column; }
  /* annual leads — same emphasis the in-app plans page gives it */
  .plan.featured { border-color: var(--pink); }
  .plan h3 { font-size: .95rem; font-weight: 700; }
  .plan .price { font-family: var(--head); font-stretch: 125%; font-weight: 800;
    font-size: 1.9rem; color: var(--pink); line-height: 1.1; margin-top: 6px; }
  .plan .price strong { font-weight: 800; }
  .plan .per { font-family: var(--body); font-stretch: normal; font-weight: 600;
    font-size: .85rem; color: var(--muted); margin-left: 5px; }
  .plan .m { color: var(--muted); font-size: .86rem; line-height: 1.5; margin-top: 8px; flex: 1 1 auto; }
  .plan .cta { margin-top: 14px; }
  .pricing .fine { color: var(--muted); font-size: .82rem; margin-top: 18px; }

  .honest { background: var(--bg-deep); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
  /* the honesty seal reads as a gold seal, not another pink glyph */
  .honest h2 .ico { color: var(--dk-sun); }
  .honest ul { list-style: none; max-width: 560px; margin: 22px auto 0; font-size: .95rem;
    color: var(--muted); line-height: 1.7; padding: 0; }
  .honest li { margin-top: 14px; }
  .honest li b { color: var(--text); }

  footer { text-align: center; padding: 32px 20px; color: var(--muted); font-size: .8rem; }
  footer a { color: var(--muted); min-height: 44px; display: inline-flex; align-items: center; padding-inline: 6px; }
  /* sky's one surviving job: a functional link-hover accent */
  footer a:hover { color: var(--sky); }

  /* ── >= 720px: add the columns back ─────────────────────────────────── */
  @media (min-width: 720px) {
    .topbar { padding: 18px 24px; }
    .loginlink { font-size: .9rem; }

    .hero { display: grid; grid-template-columns: 1fr 380px; gap: 40px; align-items: center;
      padding: 56px 24px 64px;
      /* own the whole first viewport (minus the topbar): the tour starts
         right at the fold instead of leaving a dead band under a short hero
         on tall screens */
      min-height: calc(100vh - 64px); min-height: calc(100svh - 64px);
      box-sizing: border-box; }
    .hero .persona { font-size: 1.05rem; }
    .hero .sub { font-size: 1.05rem; }

    .wl { display: flex; gap: 8px; max-width: 460px; background: var(--surface);
      border: 2px solid var(--border); border-radius: var(--r-full);
      padding: 6px 6px 6px 20px; margin-top: 26px; transition: all .15s; }
    .wl:focus-within { border-color: var(--pink); box-shadow: var(--glow-pink); }
    .wl input { flex: 1; background: none; border: none; padding: 0; border-radius: 0; }
    .wl input:focus { box-shadow: none; }
    .cta { width: auto; flex: none; }
    .cta:hover { transform: translateY(-1px); }

    .mascotwrap { margin-top: 0; }
    .mascot { width: 330px; }

    .sect { padding: 56px 24px; }
    .sect h2 { font-size: 1.5rem; }
    .navlink { font-size: .9rem; }
    .plans { grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 22px; }
    /* .cta goes width:auto up here — inside a card it should fill the card */
    .plan .cta { width: 100%; }
    .engine .lede { font-size: 1.05rem; }
    .honest ul { line-height: 2.1; }
    .honest li { margin-top: 0; }
    footer { padding: 36px 24px; }
  }

  /* ── snazz: scroll life ─────────────────────────────────────────────────
     Three systems, all compositor-only (transform/opacity — nothing here can
     thrash layout):
       1. parallax — CSS scroll-driven animations behind @supports; browsers
          without them keep the static page, which is the correct fallback.
       2. scroll-reveal — a tiny IntersectionObserver script (bottom of the
          page) adds .rv at boot and .in on entry. No JS ⇒ no .rv ⇒ nothing
          is ever hidden.
       3. micro-moments — moon pulse, scythe swing on mascot hover, verb
          icon lift.
     Phones (<720px): parallax OFF — scroll-linked transforms
     jank on low-end hardware. Reveals
     and micro-moments stay; they're event-driven and cheap.
     prefers-reduced-motion: the catch-all at the very bottom flattens ALL of
     it (including the pre-existing hero float) to a static page. */

  /* 1 · the night sky is sky.css / sky.js (shared with the app). Here: the
     motion itself, desktop + motion-OK + scroll-driven animations; everyone
     else keeps the static page. */
  @supports (animation-timeline: scroll()) {
    @media (min-width: 720px) and (prefers-reduced-motion: no-preference) {
      /* hero mascot drifts slower than the page over the first 1000px */
      .mascotwrap { animation: drift linear both; animation-timeline: scroll(root); animation-range: 0px 1000px; }
    }
  }
  /* per-stop depth: each beat drifts a few px against its own view timeline,
     so content moves at a third speed between the pinned rail (sticky) and
     the sky. On
     the beat wrapper, not its children: the .flow entrance transitions own
     child transforms and must never be fought. */
  @supports (animation-timeline: view()) {
    @media (min-width: 720px) and (prefers-reduced-motion: no-preference) {
      .beat { animation: beatdrift linear both; animation-timeline: view();
        animation-range: entry 0% exit 100%; }
    }
  }
  @keyframes beatdrift { from { transform: translateY(28px); } to { transform: translateY(-28px); } }
  @keyframes drift { to { transform: translateY(110px); } }

  /* 2 · scroll-reveal — the ramp is an animation, not a transition, so it
     can't fight the .18s hover transitions the cards already have.
     `backwards` keeps staggered cards hidden through their delay; no
     `forwards`, so after the ramp the element returns to plain styles and
     hover transforms behave. */
  .rv { opacity: 0; }
  .rv.in { opacity: 1; animation: rise .6s cubic-bezier(.22, .9, .35, 1) backwards; animation-delay: var(--rvd, 0s); }
  @keyframes rise { from { opacity: 0; transform: translateY(20px); } }
  .honest li:nth-child(2) { --rvd: .12s; }
  .honest li:nth-child(3) { --rvd: .24s; }

  /* 3 · micro-moments */
  .dk-scythe { transform-box: fill-box; transform-origin: 35% 75%; }
  @media (prefers-reduced-motion: no-preference) {
    .persona .ico { animation: moonpulse 5s ease-in-out infinite; }
    .mascot:hover .dk-scythe { animation: reap .9s ease-in-out; }
  }
  @keyframes moonpulse { 50% { opacity: .6; transform: scale(.93); } }
  @keyframes reap { 35% { transform: rotate(-8deg); } 70% { transform: rotate(3deg); } }
  /* 5 · mascot eye-tracking — the glint sparkles ARE the pupils: always
     visible (the mark's resting face wears them), they ease a few px toward
     the pointer when it comes within ~300px, desktop pointer-fine only
     (JS re-checks). The watermark <use> clone mirrors the motion — fine. */
  .mascot .dk-glints { pointer-events: none;
    transition: transform .3s cubic-bezier(.2, .7, .3, 1); }

  /* 6 · waitlist celebration — THE REAP, ported verbatim from cc's Procreate
     animation (deepkut_scythe_animation.mov; grammar doc in the app's
     ScytheReap.svelte): slow +35° backswing, a 168° whip over the crown with
     a streak arc (r=1020 about the slash pivot 732,1532 — solved from her
     mov, ≠ the resting grip), pink dust at the blade's landing, then the hop
     and the sparkle pops as the bow. Triggered only from the form's success
     path, JS + motion gated; errors never celebrate. */
  .mascotwrap { position: relative; }
  .mascot { overflow: visible; }
  /* slash pivot (183,383 art units) as fill-box % of the scythe's own bbox
     (193.5..439.75 × 234.5..411) — px origins misresolve inside scale(4) */
  .mascot.celebrate .dk-scythe { transform-box: fill-box; transform-origin: -4.3% 84.1%;
    animation: reapslash 1.35s cubic-bezier(.45, 0, .3, 1) .1s both; }
  @keyframes reapslash {
    0% { transform: rotate(0deg); }
    26%, 30% { transform: rotate(35deg); animation-timing-function: cubic-bezier(.5, 0, .2, 1); }
    43%, 58% { transform: rotate(-143deg); }
    82% { transform: rotate(3deg); }
    100% { transform: rotate(0deg); }
  }
  .dk-streak { fill: none; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100;
    opacity: 0; pointer-events: none; }
  .dk-streak.soft { stroke: #fbc7dd; stroke-width: 104; filter: blur(24px); }
  .dk-streak.hot { stroke: #fff0f6; stroke-width: 28; }
  .mascot.celebrate .dk-streak { animation: streaksweep .22s cubic-bezier(.5, 0, .2, 1) .5s forwards,
    streakfade .3s ease-out .72s forwards; }
  @keyframes streaksweep { from { stroke-dashoffset: 100; opacity: .9; } to { stroke-dashoffset: 0; opacity: .9; } }
  @keyframes streakfade { to { stroke-dashoffset: -100; opacity: 0; } }
  /* the bow comes after the stroke: hop waits for the swing to hand back */
  .mascot.celebrate .dk-rig { animation: hop .95s cubic-bezier(.36, .07, .19, .97) 1.4s; }
  /* svg user units: ~100 ≈ 16px at the 330px desktop render */
  @keyframes hop { 26% { transform: translateY(-100px); } 52% { transform: translateY(0); }
    72% { transform: translateY(-38px); } 100% { transform: translateY(0); } }
  .burst { position: absolute; inset: -16px; pointer-events: none; }
  .burst .s { position: absolute; opacity: 0; animation: pop .8s ease-out var(--bd, 0s) forwards; }
  @keyframes pop { 0% { opacity: 0; transform: scale(0); } 40% { opacity: 1; transform: scale(1.15); }
    100% { opacity: 0; transform: scale(.5) translateY(-14px); } }
  /* impact dust: tiny dots thrown from where the blade lands (left of the
     body, mid-height), radial + a little lift, same fills as the app's DUST */
  .burst .p { position: absolute; border-radius: 50%; opacity: 0;
    animation: dustfly .7s cubic-bezier(.2, .7, .4, 1) var(--bd, 0s) forwards; }
  @keyframes dustfly { 0% { opacity: 0; transform: translate(0, 0) scale(.4); }
    12% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1); } }

  /* ── /pricing/ only ─────────────────────────────────────────────────────
     Everything above is shared. These rules are the furniture the pricing
     page needs and the landing doesn't: its own headline block (the ONE
     Orbit surface on that page, same rule the landing's hero h1 follows), a
     free-vs-plus comparison, the question list, and the closing waitlist.
     All of it reuses the .prop/.plan card chrome and the meaning-accents, so
     the page reads as the same desk with more room. */
  .band { background: var(--bg-deep); border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border); }

  /* the wordmark is the way home on every page that isn't home */
  .homelink { display: flex; align-items: center; text-decoration: none; }

  .phead { text-align: center; padding-top: 8px; padding-bottom: 12px; }
  .phead h1 { font-family: 'Orbit', system-ui, sans-serif;
    font-size: clamp(2rem, 8vw, 3rem); font-weight: 800; line-height: 1.06; }
  .phead h1 i { color: var(--pink); font-style: normal; }
  .phead .sub { color: var(--muted); margin: 14px auto 0; max-width: 560px;
    font-size: 1rem; line-height: 1.6; }

  /* free vs plus: two tiers side by side. mint dots = what you already have
     for nothing, pink dots = what money is for. one accent each, by meaning. */
  .compare { display: grid; gap: 12px; margin-top: 20px; text-align: left; }
  .tier { background: var(--surface); border: 1.5px solid var(--border);
    border-radius: var(--r-md); padding: 16px 18px; }
  .tier.now { border-color: var(--dk-mint); }
  .tier h3 { font-size: .95rem; font-weight: 700; }
  .tier .tag { color: var(--muted); font-size: .82rem; margin-top: 5px; }
  .tier ul { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 10px; }
  .tier li { display: flex; gap: 10px; align-items: flex-start;
    font-size: .88rem; color: var(--muted); line-height: 1.5; }
  .tier li::before { content: ''; flex: none; width: 8px; height: 8px;
    border-radius: 50%; margin-top: .45em; background: var(--border); }
  .tier.now li::before { background: var(--dk-mint); }
  .tier.next li::before { background: var(--pink); }
  .tier li b { color: var(--text); font-weight: 700; }

  /* the questions a stranger has before paying. plain blocks, no accordion —
     nothing about money should need a click to read. */
  .faq { display: grid; gap: 10px; margin-top: 20px; text-align: left; }
  .qa { background: var(--surface); border: 1.5px solid var(--border);
    border-radius: var(--r-md); padding: 14px 16px; }
  .qa .q { font-family: var(--head); font-stretch: 125%; font-weight: 800; font-size: .98rem; }
  .qa .a { color: var(--muted); font-size: .88rem; line-height: 1.6; margin-top: 8px; }
  .qa .a a { color: var(--text); }

  /* the close: the same waitlist form, the same reaper, the same celebration */
  .endcta { text-align: center; scroll-margin-top: 12px; }
  /* the hero mascot rides the scroll parallax; this one sits inside a block
     of copy near the page bottom, where a 110px drift would just shove it
     into the paragraph under it. Park it. */
  .endcta .mascotwrap { margin: 4px auto 2px; animation: none; }
  .endcta .mascot { width: min(44vw, 160px); }
  .endcta .sub { color: var(--muted); margin: 6px auto 0; max-width: 480px;
    font-size: .95rem; line-height: 1.6; }
  .endcta .wl { margin-inline: auto; text-align: left; }
  .endcta .fine { color: var(--muted); font-size: .82rem; margin-top: 18px; }

  @media (min-width: 720px) {
    .phead { padding-top: 18px; padding-bottom: 16px; }
    /* stretch, not start: two money columns of different heights read as
       one being an afterthought */
    .compare { grid-template-columns: 1fr 1fr; gap: 14px; }
    .faq { grid-template-columns: 1fr 1fr; gap: 12px; }
    .endcta .mascot { width: 190px; }
  }

  /* reduced-motion catch-all: the whole page goes static (hard requirement) */
  @media (prefers-reduced-motion: reduce) {
    .mascot, .mascotwrap, .persona .ico, .dk-scythe,
    .rv, .rv.in,
    .beat,
    .dk-rig, .dk-glints, .dk-streak, .burst .s, .burst .p { animation: none !important; transition: none !important; }
    .rv { opacity: 1 !important; }
  }
