/*  riveroledger.com — the promotional site's stylesheet.

    The :root token block below is lifted VERBATIM from ../../app.css (which lifts it
    from Jonathan's Claude Design project). Never hand-edit a token here: when the app's
    block changes, re-run `node test/site.test.mjs` — it fails if the two drift — and copy
    the block again. Every rule under "site rules" is written in terms of those tokens.  */

@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ─── design tokens — from the design system, do not edit by hand ─────── */

:root{
  /* ─────────── GROUND & SURFACES ─────────── */
  --paper:               #FBF9F5;   /* app background — warm off-white, kinder than pure white at 1am */
  --surface:             #FFFFFF;   /* cards, sheets, anything floating above the paper */
  --surface-sunken:      #F3F0E9;   /* input wells, empty states, segmented-control track */
  --surface-inverse:     #1B1A17;   /* settle-up bar, toasts, "Settled" chip */
  --hairline:            #E9E4DA;   /* default 1px divider between list rows */
  --hairline-strong:     #D8D1C3;   /* input and secondary-button borders */

  /* ─────────── INK ─────────── */
  --ink:                 #1B1A17;   /* all money and all primary labels */
  --ink-secondary:       #6A665E;   /* venue, stakes, timestamps, helper copy */
  --ink-quiet:           #9B958B;   /* eyebrows, units, placeholder text */
  --ink-disabled:        #B7B1A6;   /* text inside anything switched off */
  --ink-on-accent:       #FFFFFF;   /* label on a filled accent surface */
  --ink-on-inverse:      #FBF9F5;   /* label on the dark surface */

  /* ─────────── ACCENT — never confusable with profit or loss ─────────── */
  /* Each choice supplies a light-ground and a dark-ground value; the theme
     picks which. Every hue sits between blue and magenta, well clear of both
     money colors. `--accent-*` are derived from --surface/--ink rather than
     hard white/black so they follow the theme instead of fighting it. */
  --accent-l:            #47566B;   /* slate — the default since 2026-08-27 (was violet #4A3AFF) */
  --accent-d:            #A9B6CB;
  --accent:              var(--accent-l);
  --accent-hover:        color-mix(in oklab, var(--accent) 86%, var(--ink));
  --accent-press:        color-mix(in oklab, var(--accent) 72%, var(--ink));
  --accent-wash:         color-mix(in oklab, var(--accent) 11%, var(--surface));
  --accent-edge:         color-mix(in oklab, var(--accent) 30%, var(--surface));
  --focus-halo:          color-mix(in oklab, var(--accent) 30%, transparent);
  --focus-ring:          0 0 0 3px var(--focus-halo);

  /* ─────────── MONEY — the only place green and red are permitted ─────────── */
  --profit:              #0A8A50;   /* a positive figure. Never a button, never a border, never decoration */
  --profit-wash:         color-mix(in oklab, var(--profit) 13%, var(--surface));
  --loss:                #D2301D;   /* a negative figure, and money you owe someone */
  --loss-wash:           color-mix(in oklab, var(--loss) 13%, var(--surface));
  --even:                #6A665E;   /* exactly break-even gets no color at all */

  /* ─────────── SHADOW ─────────── */
  --shadow-card:         0 1px 1px rgba(27,26,23,.04), 0 3px 10px -2px rgba(27,26,23,.07);
  --shadow-raised:       0 2px 4px rgba(27,26,23,.06), 0 12px 28px -8px rgba(27,26,23,.14);
  --shadow-sheet:        0 -8px 44px -10px rgba(27,26,23,.24);

  /* ─────────── TYPE ─────────── */
  --font-money: "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI Variable Display", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-ui:    ui-sans-serif, system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-code:  ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --text-jumbo:   56px;  /* the amount you are typing into a money field */
  --text-hero:    40px;  /* the one number that answers the screen */
  --text-display: 30px;  /* stat-tile figures and screen titles */
  --text-title:   23px;  /* sheet titles, headline money on a card */
  --text-heading: 18px;  /* section headings, money on a list row */
  --text-body:    16px;  /* the smallest size money is ever set at */
  --text-label:   14px;  /* buttons, list labels, field labels */
  --text-caption: 13px;  /* venue, stakes, timestamps */
  --text-micro:   11px;  /* uppercase eyebrows only, never running copy */

  --leading-tight: 1.02;  /* jumbo and hero money */
  --leading-snug:  1.22;  /* titles */
  --leading-body:  1.45;  /* labels and list rows */
  --leading-loose: 1.6;   /* paragraphs */

  --track-money:  -0.022em;  /* pulls big figures together so a column reads as one shape */
  --track-tight:  -0.014em;  /* headings */
  --track-normal:  0em;
  --track-caps:    0.09em;   /* uppercase eyebrows */

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;   /* every money figure */
  --weight-bold:     700;   /* hero money only */

  /* ─────────── SPACE ─────────── */
  --space-hair:   2px;
  --space-tiny:   4px;
  --space-small:  8px;
  --space-medium: 12px;
  --space-base:   16px;   /* the default gap and the screen gutter on a phone */
  --space-large:  24px;
  --space-xlarge: 32px;
  --space-huge:   48px;
  --space-giant:  72px;   /* gap between major sections on desktop */

  /* ─────────── TOUCH ─────────── */
  --tap-minimum:     44px;  /* nothing interactive is ever smaller than this */
  --tap-comfortable: 52px;  /* standard button and list-row height */
  --tap-thumb:       60px;  /* the one-handed, one-eye-open primary action */

  /* ─────────── SHAPE ─────────── */
  --radius-small:  8px;    /* chips and small buttons */
  --radius-medium: 12px;   /* buttons and text inputs */
  --radius-large:  16px;   /* cards and money inputs */
  --radius-xlarge: 22px;   /* stat tiles */
  --radius-sheet:  28px;   /* top corners of a bottom sheet */
  --radius-pill:   999px;
  --border-hair:   1px;
  --border-thick:  1.5px;  /* inputs and secondary buttons, so they hold up in bad light */

  /* ─────────── MOTION ─────────── */
  --ease-out:   cubic-bezier(.2,.8,.3,1);
  --speed-fast: 110ms;   /* color and shadow changes */
  --speed-base: 190ms;   /* things that move */

  /* ─────────── LAYOUT ─────────── */
  --page-max:       1680px;  /* desktop content column, incl. the sidebar */
  --phone-max:      390px;   /* the phone we design to first */
  --sign-display:   inline;  /* set to none to hide the leading + on profits */
}

/* ─── accents & themes (added on top of the design system) ────────────── */

/* The accent never colors a figure — money is the only thing that gets green
   or red — so these only have to avoid *being* green or red themselves. Teal is
   pushed to cyan and amber to yellow-gold for exactly that reason. Each supplies
   a value for a light ground and one for a dark; the theme picks. Mirrored in
   js/theme.js, which the picker reads so the swatches can't go stale. */
:root[data-accent='slate']    { --accent-l: #47566B; --accent-d: #A9B6CB; }
:root[data-accent='violet']   { --accent-l: #4A3AFF; --accent-d: #9A8CFF; }
:root[data-accent='blue']     { --accent-l: #1668D6; --accent-d: #6FB1F5; }
:root[data-accent='teal']     { --accent-l: #067A8E; --accent-d: #45C3DA; }
:root[data-accent='purple']   { --accent-l: #7A2ED6; --accent-d: #C094F7; }
:root[data-accent='magenta']  { --accent-l: #C81E8C; --accent-d: #F275C0; }
:root[data-accent='amber']    { --accent-l: #9A6B00; --accent-d: #E8B84B; }
:root[data-accent='ink']      { --accent-l: #1B1A17; --accent-d: #F2EFE9; }

/* Dark: warm charcoal, because the light theme is a warm off-white — a blue
   black next to it would read as a different product. Money colors lift so
   they stay legible on a dark ground. */
:root[data-theme='dark'] {
  color-scheme: dark;
  --paper:           #14120F;
  --surface:         #1C1A16;
  --surface-sunken:  #24211B;
  --surface-inverse: #F2EFE9;
  --hairline:        #2E2A23;
  --hairline-strong: #423B31;
  --ink:             #F2EFE9;
  --ink-secondary:   #ABA396;
  --ink-quiet:       #7E776B;
  --ink-disabled:    #5B554C;
  --ink-on-accent:   #14120F;
  --ink-on-inverse:  #1B1A17;
  --accent:          var(--accent-d);
  --profit:          #35C97F;
  --loss:            #FF6F5B;
  --even:            #ABA396;
  --shadow-card:     0 1px 1px rgba(0, 0, 0, .3), 0 3px 10px -2px rgba(0, 0, 0, .4);
  --shadow-raised:   0 2px 4px rgba(0, 0, 0, .35), 0 12px 28px -8px rgba(0, 0, 0, .55);
  --shadow-sheet:    0 -8px 44px -10px rgba(0, 0, 0, .6);
}

/* Follow the system only when the person hasn't chosen for themselves. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --paper:           #14120F;
    --surface:         #1C1A16;
    --surface-sunken:  #24211B;
    --surface-inverse: #F2EFE9;
    --hairline:        #2E2A23;
    --hairline-strong: #423B31;
    --ink:             #F2EFE9;
    --ink-secondary:   #ABA396;
    --ink-quiet:       #7E776B;
    --ink-disabled:    #5B554C;
    --ink-on-accent:   #14120F;
    --ink-on-inverse:  #1B1A17;
    --accent:          var(--accent-d);
    --profit:          #35C97F;
    --loss:            #FF6F5B;
    --even:            #ABA396;
    --shadow-card:     0 1px 1px rgba(0, 0, 0, .3), 0 3px 10px -2px rgba(0, 0, 0, .4);
    --shadow-raised:   0 2px 4px rgba(0, 0, 0, .35), 0 12px 28px -8px rgba(0, 0, 0, .55);
    --shadow-sheet:    0 -8px 44px -10px rgba(0, 0, 0, .6);
  }
}

/* ─── site-only tokens (not part of the app's design system) ───────────── */
:root {
  --badge-black: block;   /* Apple's black badge on paper, the white one on charcoal */
  --badge-white: none;
  --bezel: #1B1A17;       /* a phone's bezel is an object: dark in both themes */
  --rise: 28px;           /* reveal travel — 18px under flick scroll (below) */
  --ease-reveal: cubic-bezier(0.22, 1, 0.36, 1);
}
:root[data-theme='dark'] { --badge-black: none; --badge-white: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) { --badge-black: none; --badge-white: block; }
}
@media (max-width: 768px) { :root { --rise: 18px; } }

/* ─── site rules ───────────────────────────────────────────────────────── */
*, *::before, *::after { 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: 17px/1.55 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, video, svg { display: block; max-width: 100%; }
a { color: inherit; }
p { margin: 0; }
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-small); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.wrap { max-width: 1120px; margin: 0 auto; padding-inline: var(--space-base); }
@media (min-width: 769px) { .wrap { padding-inline: var(--space-xlarge); } }

/* type */
h1, h2, h3 { font-family: var(--font-money); font-weight: var(--weight-semibold); letter-spacing: var(--track-tight); line-height: var(--leading-snug); margin: 0; text-wrap: balance; }
h1 { font-size: clamp(36px, 7vw, 60px); line-height: 1.04; letter-spacing: var(--track-money); }
h2 { font-size: clamp(27px, 3.6vw, 38px); }
h3 { font-size: var(--text-heading); }
.lede { font-size: clamp(17px, 1.6vw, 20px); color: var(--ink-secondary); max-width: 52ch; margin-top: var(--space-large); line-height: var(--leading-loose); }
.money { font-family: var(--font-money); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; letter-spacing: var(--track-money); }
.money.up   { color: var(--profit); }
.money.down { color: var(--loss); }
.money.even { color: var(--even); }

/* header */
.top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-base); padding: var(--space-base) 0; }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; font: var(--weight-semibold) 19px/1 var(--font-money); letter-spacing: var(--track-tight); color: var(--ink); }
.brand svg { width: 28px; height: 28px; color: var(--ink); flex: none; }

/* Apple's badge — official artwork, two versions, the theme picks */
.badge { display: inline-block; line-height: 0; border-radius: 8px; }
.badge img { height: 44px; width: auto; }
.badge.big img { height: 56px; }
.badge .black { display: var(--badge-black); }
.badge .white { display: var(--badge-white); }

/* buttons — tactile press: down-stroke 60ms, everything else 180ms */
.btn { appearance: none; border: 0; cursor: pointer; font: var(--weight-semibold) var(--text-label)/1 var(--font-ui); padding: 0 var(--space-large); height: var(--tap-comfortable); border-radius: var(--radius-medium); touch-action: manipulation; display: inline-flex; align-items: center; justify-content: center; gap: 8px; text-decoration: none;
  transition: transform .18s ease-out, box-shadow .18s ease-out, background-color .18s ease-out, color .18s ease-out; }
.btn:active { transition-duration: .06s; transform: scale(.97); }
.btn-primary { background: var(--accent); color: var(--ink-on-accent); }
.btn-quiet { background: transparent; color: var(--ink); border: var(--border-thick) solid var(--hairline-strong); }
@media (hover: hover) {
  .btn-primary:hover { background: var(--accent-hover); }
  .btn-quiet:hover { border-color: var(--ink-quiet); }
}

/* links (footer) — underline slides through; static accent underline on touch */
.lk { color: var(--ink); text-decoration: none; font-weight: var(--weight-medium); position: relative; display: inline-block; }
.lk::after { content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px; background: var(--accent); transform: scaleX(0); transform-origin: right; transition: transform .3s var(--ease-reveal); }
@media (hover: hover) { .lk:hover::after { transform: scaleX(1); transform-origin: left; } }
.lk:focus-visible::after { transform: scaleX(1); transform-origin: left; }
@media (hover: none) { .lk { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--accent); } .lk::after { display: none; } }

/* hero */
.hero { padding: var(--space-xlarge) 0 var(--space-giant); display: grid; gap: var(--space-huge); align-items: center; }
@media (min-width: 900px) { .hero { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); padding-top: var(--space-huge); min-height: 78svh; } }
.cta { display: flex; align-items: center; gap: var(--space-base); flex-wrap: wrap; margin-top: var(--space-xlarge); }
.fine { color: var(--ink-quiet); font-size: var(--text-label); }
.hero .pitch[hidden], .hero .invite[hidden] { display: none; }

/* the invite state of the hero (?t=CODE) */
.invite .code-label { color: var(--ink-secondary); margin-top: var(--space-large); font-size: var(--text-label); }
.invite .code { font: var(--weight-semibold) clamp(44px, 11vw, 66px)/1 var(--font-money); letter-spacing: .05em; font-variant-numeric: tabular-nums; margin: var(--space-small) 0 var(--space-base); display: flex; gap: .45em; }
.invite .how { margin-top: var(--space-large); }

/* ordered steps — a real sequence, so the numbers mean something */
.steps { list-style: none; counter-reset: step; padding: 0; margin: var(--space-large) 0 0; display: grid; gap: var(--space-medium); max-width: 56ch; }
.steps li { counter-increment: step; display: grid; grid-template-columns: 30px 1fr; gap: var(--space-medium); color: var(--ink-secondary); line-height: var(--leading-body); align-items: start; }
.steps li::before { content: counter(step); font: var(--weight-semibold) var(--text-label)/1 var(--font-money); color: var(--ink); border: var(--border-thick) solid var(--hairline-strong); border-radius: 50%; width: 30px; height: 30px; display: grid; place-items: center; }
.steps b { color: var(--ink); font-weight: var(--weight-semibold); }

/* ledger card — the app's Tonight screen, authored in its FINISHED state */
.ledger { background: var(--surface); border: var(--border-hair) solid var(--hairline); border-radius: var(--radius-large); box-shadow: var(--shadow-card); padding: var(--space-base); display: grid; gap: var(--space-medium); width: 100%; max-width: 420px; margin-inline: auto; font-size: var(--text-label); }
.lg-head { display: flex; justify-content: space-between; align-items: center; }
.lg-date { font: var(--weight-semibold) var(--text-title)/1.1 var(--font-money); letter-spacing: var(--track-tight); }
.chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border-radius: var(--radius-pill); font-size: var(--text-micro); font-weight: var(--weight-semibold); letter-spacing: var(--track-caps); text-transform: uppercase; white-space: nowrap; }
.chip.live { background: var(--accent-wash); color: var(--accent); }
.chip.live i { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.chip.settled { background: var(--surface-inverse); color: var(--ink-on-inverse); }
.stack { display: grid; }
.stack > * { grid-area: 1 / 1; }
.pre { visibility: hidden; }                                   /* every non-final state */
.lg-totals { display: grid; grid-template-columns: 1fr auto; row-gap: 6px; padding: var(--space-medium); background: var(--surface-sunken); border-radius: var(--radius-medium); color: var(--ink-secondary); }
.lg-totals .money { color: var(--ink); text-align: right; font-size: var(--text-body); }
.lg-rows { list-style: none; margin: 0; padding: 0; }
.row { display: grid; grid-template-columns: 1fr auto; grid-template-areas: "name net" "in net"; padding: 10px 0; border-top: var(--border-hair) solid var(--hairline); align-items: center; column-gap: var(--space-medium); }
.row .name { grid-area: name; font: var(--weight-semibold) var(--text-body)/1.2 var(--font-money); letter-spacing: var(--track-tight); }
.row .in { grid-area: in; color: var(--ink-secondary); font-size: var(--text-caption); display: flex; gap: .35em; white-space: nowrap; }
.row .net { grid-area: net; font-size: var(--text-heading); text-align: right; }
.row .net .stack > * { text-align: right; }
.lg-settle { display: grid; gap: var(--space-small); }
.bar { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-small); background: var(--surface-inverse); color: var(--ink-on-inverse); border-radius: var(--radius-medium); padding: var(--space-medium) var(--space-base); font-weight: var(--weight-semibold); }
.bar span { font-weight: var(--weight-regular); opacity: .8; font-size: var(--text-caption); }
.pays { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.pays li { display: flex; justify-content: space-between; align-items: center; background: var(--surface-sunken); border-radius: var(--radius-small); padding: 8px 12px; font-weight: var(--weight-medium); }
.pays em { font-style: normal; color: var(--ink-quiet); margin: 0 .4em; font-weight: var(--weight-regular); }
.lg-count { color: var(--ink-secondary); font-size: var(--text-caption); text-align: center; }
.replay { justify-self: center; margin-top: var(--space-medium); visibility: hidden; opacity: 0; transition: opacity .3s ease-out; }
.ledger-wrap { display: grid; }
.ledger-wrap.done .replay { visibility: visible; opacity: 1; }
html:not(.anim) .replay { display: none; }                      /* reduced motion or no JS: nothing to replay */

/* The beat sheet. Only under html.anim (JS present, motion allowed). Every state
   change is an OPACITY step: WebKit finishes a `visibility` keyframe on the wrong
   value (reproduced 2026-09-05), opacity it gets right. Everything is paused at time
   zero until .play arrives, so the card opens on its first frame with no flash of the
   finished state; fill-mode "both" holds each end state. */
html.anim .ledger .pre { visibility: visible; }                 /* under the beat sheet, opacity does the hiding */
@keyframes lg-rise   { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes lg-vanish { from { opacity: 1; } to { opacity: 0; } }
@keyframes lg-appear { 0% { opacity: 0; transform: scale(1); } 1% { opacity: 1; transform: scale(1.08); } 100% { opacity: 1; transform: scale(1); } }
/* three-state figures run the whole 8s and switch on percentages */
@keyframes lg-tot-mid  { 0%, 22.4% { opacity: 0; } 22.5%, 28.7% { opacity: 1; } 28.75%, 100% { opacity: 0; } }   /* 1.8s → 2.3s */
@keyframes lg-cash-mid { 0%, 52.4% { opacity: 0; } 52.5%, 72.4% { opacity: 1; } 72.5%, 100% { opacity: 0; } }   /* 4.2s → 5.8s */
@keyframes lg-sam-bad  { 0%, 49.4% { opacity: 0; } 49.5%, 72.4% { opacity: 1; } 72.5%, 100% { opacity: 0; } }   /* 3.96s → 5.8s */
@keyframes lg-bar-off  { 0%, 54.9% { opacity: 0; transform: translateY(12px); } 55% { opacity: 0; transform: translateY(12px); } 61% { opacity: 1; transform: none; } 73.6% { opacity: 1; transform: none; } 73.75%, 100% { opacity: 0; transform: none; } }   /* rises at 4.4s, gone at 5.9s */

html.anim .ledger .r1 { animation: lg-rise .5s var(--ease-reveal) .20s both; }
html.anim .ledger .r2 { animation: lg-rise .5s var(--ease-reveal) .34s both; }
html.anim .ledger .r3 { animation: lg-rise .5s var(--ease-reveal) .48s both; }
html.anim .ledger .r4 { animation: lg-rise .5s var(--ease-reveal) .62s both; }
html.anim .ledger .r5 { animation: lg-rise .5s var(--ease-reveal) .76s both; }
html.anim .ledger .lg-totals { animation: lg-rise .5s var(--ease-reveal) 1.15s both; }
html.anim .ledger .tot-0  { animation: lg-vanish 1ms linear 1.8s both; }
html.anim .ledger .tot-1  { animation: lg-tot-mid 8s linear both; }
html.anim .ledger .tot-2  { animation: lg-appear .3s var(--ease-out) 2.3s both; }
html.anim .ledger .cash-0 { animation: lg-vanish 1ms linear 4.2s both; }
html.anim .ledger .cash-1 { animation: lg-cash-mid 8s linear both; }
html.anim .ledger .cash-2 { animation: lg-appear .3s var(--ease-out) 5.8s both; }
html.anim .ledger .r1 .in-0 { animation: lg-vanish 1ms linear 1.8s both; }
html.anim .ledger .r1 .in-1 { animation: lg-appear .3s var(--ease-out) 1.8s both; }
html.anim .ledger .r3 .in-0 { animation: lg-vanish 1ms linear 2.3s both; }
html.anim .ledger .r3 .in-1 { animation: lg-appear .3s var(--ease-out) 2.3s both; }
html.anim .ledger .r1 .out-0 { animation: lg-vanish 1ms linear 3.00s both; }
html.anim .ledger .r2 .out-0 { animation: lg-vanish 1ms linear 3.24s both; }
html.anim .ledger .r3 .out-0 { animation: lg-vanish 1ms linear 3.48s both; }
html.anim .ledger .r4 .out-0 { animation: lg-vanish 1ms linear 3.72s both; }
html.anim .ledger .r5 .out-0 { animation: lg-vanish 1ms linear 3.96s both; }
html.anim .ledger .r1 .out-1, html.anim .ledger .r1 .net-1 { animation: lg-appear .3s var(--ease-out) 3.00s both; }
html.anim .ledger .r2 .out-1, html.anim .ledger .r2 .net-1 { animation: lg-appear .3s var(--ease-out) 3.24s both; }
html.anim .ledger .r3 .out-1, html.anim .ledger .r3 .net-1 { animation: lg-appear .3s var(--ease-out) 3.48s both; }
html.anim .ledger .r4 .out-1, html.anim .ledger .r4 .net-1 { animation: lg-appear .3s var(--ease-out) 3.72s both; }
html.anim .ledger .r5 .out-1, html.anim .ledger .r5 .net-1 { animation: lg-sam-bad 8s linear both; }               /* Sam's first, wrong cash-out */
html.anim .ledger .r5 .out-2, html.anim .ledger .r5 .net-2 { animation: lg-appear .3s var(--ease-out) 5.8s both; }  /* corrected */
html.anim .ledger .bar.off { animation: lg-bar-off 8s linear both; }
html.anim .ledger .bar.ok  { animation: lg-rise .5s var(--ease-reveal) 6.0s both; }
html.anim .ledger .chip.live    { animation: lg-vanish 1ms linear 6.4s both; }
html.anim .ledger .chip.settled { animation: lg-appear .3s var(--ease-out) 6.4s both; }
html.anim .ledger .pays li:nth-child(1) { animation: lg-rise .5s var(--ease-reveal) 6.5s both; }
html.anim .ledger .pays li:nth-child(2) { animation: lg-rise .5s var(--ease-reveal) 6.7s both; }
html.anim .ledger .lg-count { animation: lg-rise .5s var(--ease-reveal) 7.2s both; }
/* !important so it beats every shorthand above whatever their specificity: paused until .play */
html.anim .ledger:not(.play) * { animation-play-state: paused !important; }
html.anim .ledger.reset * { animation: none !important; }

/* sections */
.sec { padding: var(--space-giant) 0; border-top: var(--border-hair) solid var(--hairline); }
.sec .grid { display: grid; gap: var(--space-xlarge); align-items: center; }
@media (min-width: 900px) {
  .sec .grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-giant); }
  .sec.flip .grid > .shot { order: -1; }
}
.copy p { margin-top: var(--space-base); color: var(--ink-secondary); max-width: 56ch; line-height: var(--leading-loose); }
.copy p b { color: var(--ink); font-weight: var(--weight-semibold); }

/* a phone, holding a real screenshot */
.shot { display: flex; justify-content: center; }
.phone { width: min(100%, 300px); border-radius: 38px; padding: 9px; background: var(--bezel); box-shadow: var(--shadow-raised); }
.phone img { border-radius: 30px; width: 100%; height: auto; aspect-ratio: 1284 / 2778; background: var(--paper); }   /* height:auto — the height attribute is a presentational hint that would otherwise win */

/* plans */
.plans { display: grid; gap: var(--space-base); margin-top: var(--space-xlarge); }
@media (min-width: 640px) { .plans { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .plans { grid-template-columns: repeat(4, 1fr); } }
.plan { border: var(--border-hair) solid var(--hairline); border-radius: var(--radius-large); padding: var(--space-large); background: var(--surface); display: grid; gap: var(--space-small); align-content: start; }
.plan.free { background: var(--surface-sunken); border-color: transparent; }
.plan .price { font: var(--weight-semibold) var(--text-display)/1 var(--font-money); letter-spacing: var(--track-money); font-variant-numeric: tabular-nums; margin-top: var(--space-small); }
.plan .price small { font: var(--weight-regular) var(--text-label)/1 var(--font-ui); color: var(--ink-secondary); letter-spacing: 0; }
.plan .yr { color: var(--ink-secondary); font-size: var(--text-label); }
.plan ul { margin: var(--space-medium) 0 0; padding: 0; list-style: none; color: var(--ink-secondary); font-size: var(--text-label); display: grid; gap: 6px; line-height: var(--leading-body); }

/* two phones side by side */
.shot.pair { gap: var(--space-base); align-items: flex-start; }
.shot.pair .phone { width: min(47%, 230px); }

/* questions — a definition list, question left, answer right */
.qa { margin: var(--space-xlarge) 0 0; }
.qa > div { display: grid; gap: var(--space-small); padding: var(--space-large) 0; border-top: var(--border-hair) solid var(--hairline); }
.qa dt { font: var(--weight-semibold) var(--text-heading)/1.3 var(--font-money); letter-spacing: var(--track-tight); }
.qa dd { margin: 0; color: var(--ink-secondary); line-height: var(--leading-loose); max-width: 60ch; }
@media (min-width: 769px) { .qa > div { grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr); column-gap: var(--space-giant); } }

/* get it */
.get { text-align: center; display: grid; justify-items: center; gap: var(--space-large); }

/* footer */
.site-foot { border-top: var(--border-hair) solid var(--hairline); padding: var(--space-xlarge) 0 var(--space-huge); color: var(--ink-secondary); font-size: var(--text-label); display: grid; gap: var(--space-base); }
.foot-links { display: flex; gap: var(--space-large); flex-wrap: wrap; }
.legal { color: var(--ink-quiet); font-size: var(--text-caption); max-width: 72ch; line-height: var(--leading-body); }

/* documents: Support, Privacy, Terms, 404 */
.doc { max-width: 62ch; margin: 0 auto; padding: var(--space-xlarge) 0 var(--space-giant); }
.doc h1 { font-size: clamp(32px, 5vw, 44px); }
.doc h2 { font-size: var(--text-title); margin-top: var(--space-xlarge); }
.doc p, .doc li { color: var(--ink-secondary); line-height: var(--leading-loose); }
.doc p { margin-top: var(--space-medium); }
.doc ul { padding-left: 1.2em; margin: var(--space-medium) 0 0; }
.doc li { margin-top: 6px; }
.doc b, .doc strong { color: var(--ink); font-weight: var(--weight-semibold); }
.doc .stamp { color: var(--ink-quiet); font-size: var(--text-caption); margin-top: var(--space-small); }
.doc a { color: var(--accent); }

/* reveal choreography — hidden state ONLY under html.js (added by script) */
html.js .reveal { opacity: 0; transform: translateY(var(--rise)); transition: opacity .6s var(--ease-reveal), transform .6s var(--ease-reveal); }
html.js .reveal.is-in { opacity: 1; transform: none; }
html.js .reveal.fast { transition-duration: .15s; }

/* copy-the-code — button-to-success morph, footprint reserved by .slot */
.slot { height: var(--tap-comfortable); display: grid; justify-items: start; }
.morph { position: relative; width: 190px; height: var(--tap-comfortable); overflow: hidden; padding: 0;
  transition: width .3s ease-in-out, border-radius .3s ease-in-out, background-color .25s ease-out, color .25s ease-out, transform .18s ease-out; }
.morph .lbl { position: relative; z-index: 1; transition: opacity .15s ease-out; }
.morph .spin { position: absolute; inset: 0; margin: auto; width: 22px; height: 22px; border-radius: 50%; border: 3px solid color-mix(in oklab, var(--ink-on-accent) 30%, transparent); border-top-color: var(--ink-on-accent); opacity: 0; }
.morph .mark { position: absolute; inset: 0; margin: auto; width: 26px; height: 26px; fill: none; stroke: var(--ink-on-accent); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
.morph .mark path { transition: stroke-dashoffset .35s ease-out .1s; }
.morph.pending .lbl, .morph.success .lbl, .morph.error .lbl { opacity: 0; }
.morph.pending .spin { opacity: 1; animation: rot .9s linear infinite; }
@keyframes rot { to { transform: rotate(360deg); } }
.morph.success .mark, .morph.error .mark { opacity: 1; }
.morph.pending, .morph.success, .morph.error { width: var(--tap-comfortable); border-radius: var(--radius-pill); }
.morph.success { background: var(--surface-inverse); color: var(--ink-on-inverse); }
.morph.success .mark { stroke: var(--ink-on-inverse); }
.morph.error { animation: shake .3s cubic-bezier(.36, .07, .19, .97); }
@keyframes shake { 10%, 50%, 90% { transform: translateX(-6px); } 30%, 70% { transform: translateX(6px); } }

/* reduced motion — designed static states */
@media (prefers-reduced-motion: reduce) {
  html.js .reveal { transform: none; transition: opacity .2s linear; }
  .btn, .lk::after, .morph, .morph .lbl, .morph .mark path { transition-duration: .01ms !important; }
  .btn:active { transform: none !important; }
  .morph.error { animation: none; }
  .morph.pending, .morph.success, .morph.error { width: 190px; border-radius: var(--radius-medium); }
  .morph.pending .lbl, .morph.success .lbl, .morph.error .lbl { opacity: 1; }
  .morph.pending .spin, .morph.success .mark, .morph.error .mark { display: none; }
}
