/*
  Cha-Ching — marketing site.

  Binding rules from BRAND.md, restated so they don't get lost in a refactor:
    · One accent. Gold is punctuation, never a wash — one gold element per
      viewport, two at the absolute ceiling.
    · No decorative gradients. A linear-gradient appears exactly twice below,
      both times as a mask-image affordance on a scroll edge.
    · Elevation is a hairline plus one soft shadow. Never a glow.
    · `transition` always names its properties.
    · Never transition a property whose value resolves through a CSS variable —
      Chromium freezes it at the first computed value. Where a colour has to
      animate (the pay ticket's rail switch) JS writes a literal hex, so the
      transition is on a real value and not a var.

  Theme: the complete light palette lives on bare :root. The dark block below
  redefines tokens only — no colour anywhere in this file has its sole
  definition inside a media query.
*/

/* ══ Tokens ═══════════════════════════════════════════════════════════ */

:root {
  color-scheme: light dark;

  /* Text and surfaces */
  --ink: #0b0b0c;
  --ink-2: #55555e;
  --ink-3: #8a8a94;
  --paper: #ffffff;
  --paper-2: #fafafb;
  --line: #e6e6ea;
  --line-2: #f1f1f4;

  /* Dark bands. Deliberately the same in both themes: a dark section is dark. */
  --stage: #0e0e10;
  --stage-2: #16161a;
  --stage-line: #26262b;
  --stage-line-2: #1c1c21;
  --stage-ink: #ffffff;
  --stage-ink-2: #9a9aa4;
  --stage-ink-3: #6e6e78;

  /* Accent and status */
  --gold: #ffaa00;
  --gold-ink: #1a1000;
  --good: #167a4a;
  --warn: #9a3412;

  /* Opaque enough that a gold CTA passing underneath doesn't bloom through the
     blur and read as a glow. */
  --nav-bg: rgb(255 255 255 / 0.93);
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.06);
  --shadow-2: 0 12px 32px -14px rgb(0 0 0 / 0.28);
  --focus: var(--ink);

  /* Type */
  --display: "Bricolage Grotesque", "Inter", -apple-system, BlinkMacSystemFont,
    "Segoe UI", Helvetica, Arial, sans-serif;
  --ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Space — BRAND.md's scale, nothing between the steps. */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --s8: 4.5rem;
  --s9: 7rem;

  --gutter: clamp(1.25rem, 5vw, 4.5rem);
  --measure: 76rem;
  --measure-wide: 88rem;
  --bay: clamp(var(--s8), 9vw, var(--s9));

  --ease: cubic-bezier(0.2, 0, 0, 1);
  --spring: cubic-bezier(0.16, 1.1, 0.3, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f4f4f6;
    --ink-2: #a2a2ac;
    --ink-3: #7b7b85;
    --paper: #0b0b0c;
    --paper-2: #121215;
    --line: #26262b;
    --line-2: #1a1a1e;

    --stage: #131317;
    --stage-2: #1b1b20;
    --stage-line: #2e2e35;
    --stage-line-2: #232329;

    --good: #34c07d;
    --warn: #e08a4f;

    --nav-bg: rgb(11 11 12 / 0.93);
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.5);
    --shadow-2: 0 12px 32px -14px rgb(0 0 0 / 0.7);
    --focus: var(--gold);
  }
}

/*
  Any block that sits on the dark stage re-points the surface tokens at their
  stage equivalents, so every component reused inside one is correct without a
  single `.band .thing` override.
*/
.on-stage {
  --ink: var(--stage-ink);
  --ink-2: var(--stage-ink-2);
  --ink-3: var(--stage-ink-3);
  --paper: var(--stage);
  --paper-2: var(--stage-2);
  --line: var(--stage-line);
  --line-2: var(--stage-line-2);
  --focus: var(--gold);
  --good: #34c07d;
  background: var(--stage);
  color: var(--stage-ink);
}

/* ══ Base ═════════════════════════════════════════════════════════════ */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

img,
svg {
  max-width: 100%;
}

::selection {
  background: var(--gold);
  color: var(--gold-ink);
}

.mono {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* text-wrap: balance will happily break the name at its hyphen. */
.nb {
  white-space: nowrap;
}

.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: -9999px;
  z-index: 50;
}

.skip:focus {
  left: var(--s4);
  top: var(--s4);
  padding: var(--s3) var(--s4);
  border-radius: 8px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 600;
  text-decoration: none;
}

/* One focus treatment, everywhere. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

/* The sticky nav is ~4.5rem, so anchors have to clear it. */
[id] {
  scroll-margin-top: 5.5rem;
}

/* ══ Brand mark ═══════════════════════════════════════════════════════ */

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  text-decoration: none;
}

/* The coin is fixed gold; the two sound arcs take currentColor, so one file
   works on the white nav and on the dark footer. */
.mark {
  display: inline-flex;
  color: var(--ink);
}

.mark svg {
  display: block;
  overflow: visible;
}

/*
  The arcs arriving a beat late IS the "ching". Fired once, timed to land with
  the pay ticket at the end of the load sequence. Never looped.
*/
.nav .mark .ping {
  animation: ching 420ms var(--spring) 560ms both;
  transform-origin: 40px 30px;
}

@keyframes ching {
  0% {
    opacity: 0;
    transform: translateX(-5px) scale(0.55);
  }
  62% {
    opacity: 1;
    transform: translateX(0) scale(1.1);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

.wordmark {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.125rem;
  letter-spacing: -0.03em;
}

/* ══ Nav ══════════════════════════════════════════════════════════════ */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  max-width: 100%;
  padding: var(--s4) var(--gutter);
  background: var(--nav-bg);
  border-bottom: 1px solid transparent;
  backdrop-filter: saturate(120%) blur(10px);
  -webkit-backdrop-filter: saturate(120%) blur(10px);
  transition:
    border-color 200ms var(--ease),
    box-shadow 200ms var(--ease);
}

.nav.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-1);
}

/*
  The bar compacts once the hero is behind you. Done as a transform on an inner
  wrapper rather than a padding change: the nav is in flow, so animating its
  height would reflow the page under the scroll position on every frame.
*/
.nav-inner {
  display: flex;
  align-items: center;
  gap: var(--s6);
  transition: transform 320ms var(--ease);
}

.nav.is-stuck .nav-inner {
  transform: scale(0.955);
}

/* Scroll progress. Ink rather than gold — the nav already spends its gold on
   the mark and the CTA, and BRAND.md caps a viewport at two. */
.progress {
  position: absolute;
  inset: auto 0 -1px 0;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
}

.progress i {
  display: block;
  height: 100%;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left center;
}

.nav-links {
  display: flex;
  gap: var(--s5);
  margin-left: auto;
  font-size: 0.9375rem;
  font-weight: 500;
}

.nav-links a {
  position: relative;
  padding: var(--s1) 0;
  color: var(--ink-2);
  text-decoration: none;
}

/* Underline grows from the left instead of transitioning a var-driven colour. */
.nav-links a::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 220ms var(--ease);
}

.nav-links a:hover {
  color: var(--ink);
}

.nav-links a:hover::after {
  transform: scaleX(1);
}

.nav-cta {
  flex: 0 0 auto;
}

@media (max-width: 62rem) {
  .nav-links {
    display: none;
  }

  .nav-cta {
    margin-left: auto;
  }
}

/* ══ Buttons ══════════════════════════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--s3) var(--s5);
  border: 1.5px solid transparent;
  border-radius: 8px;
  font: inherit;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    transform 140ms var(--ease),
    box-shadow 180ms var(--ease);
}

.btn-primary {
  background: var(--gold);
  color: var(--gold-ink);
  border-color: var(--gold);
  box-shadow: 0 1px 0 rgb(0 0 0 / 0.06);
}

.btn-primary:hover {
  transform: translateY(-1.5px);
  box-shadow: 0 8px 20px -10px rgb(0 0 0 / 0.55);
}

.btn-primary:active {
  transform: translateY(0.5px);
  box-shadow: 0 1px 0 rgb(0 0 0 / 0.06);
}

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}

.btn-ghost:hover {
  border-color: var(--ink-3);
  transform: translateY(-1.5px);
}

.btn-ghost:active {
  transform: translateY(0.5px);
}

.btn-sm {
  padding: var(--s2) var(--s4);
  font-size: 0.875rem;
}

.btn-lg {
  padding: var(--s4) var(--s6);
  font-size: 1.0625rem;
  border-radius: 8px;
}

.btn-block {
  display: flex;
  width: 100%;
}

/* ══ Section furniture ════════════════════════════════════════════════ */

.section {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--bay) var(--gutter);
}

.section-wide {
  max-width: var(--measure-wide);
}

.section-head {
  max-width: 44rem;
  margin-bottom: clamp(var(--s6), 5vw, var(--s7));
}

.section-head-wide {
  max-width: 52rem;
}

.eyebrow {
  margin-bottom: var(--s4);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

h2 {
  font-size: clamp(2.125rem, 5.2vw, 3.75rem);
  margin-bottom: var(--s4);
}

.section-lede {
  max-width: 40rem;
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  line-height: 1.55;
  color: var(--ink-2);
}

.microcopy {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-3);
}

.br-lg {
  display: none;
}

@media (min-width: 56rem) {
  .br-lg {
    display: inline;
  }
}

/* Full-bleed dark band with a contained interior. */
.band {
  padding: var(--bay) var(--gutter);
}

.band-inner {
  max-width: var(--measure-wide);
  margin: 0 auto;
}

/* ══ Hero ═════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  align-items: center;
  gap: clamp(var(--s6), 6vw, var(--s8));
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: clamp(var(--s7), 7vw, var(--s9)) var(--gutter) var(--bay);
}

/* Hairline arcs only — no fill, no gradient, no glow. Sits behind everything
   in the hero and never intercepts a pointer. */
.hero-ambient {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.hero-copy,
.hero-art {
  position: relative;
  z-index: 1;
  min-width: 0;
}

.hero h1 {
  font-size: clamp(3.25rem, 8.4vw, 6.25rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 0.94;
  margin-bottom: var(--s5);
}

.hero .lede {
  max-width: 34rem;
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  line-height: 1.5;
  color: var(--ink-2);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  margin: var(--s6) 0 var(--s4);
}

@media (max-width: 62rem) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s7);
  }
}

/* Two ragged inline buttons look like an accident at phone width. */
@media (max-width: 30rem) {
  .hero-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
  }

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

/* ══ The pay ticket, reproduced ═══════════════════════════════════════ */

.preview {
  margin: 0;
}

.preview-stage {
  display: flex;
  justify-content: center;
  padding: clamp(var(--s5), 4vw, var(--s7));
  background: var(--stage);
  border: 1px solid var(--stage-line);
  border-radius: 16px;
}

.preview figcaption {
  margin-top: var(--s3);
  font-size: 0.8125rem;
  color: var(--ink-3);
  text-align: center;
}

/*
  The ticket keeps its own palette in both themes. The real pay page is one
  committed look — a white card on a dark stage — because it gets scanned in a
  car, at a counter, on a cracked screen. Flipping it to dark here would show
  merchants something the product never does.
*/
.ticket {
  --ink: #0b0b0c;
  --ink-2: #55555e;
  --ink-3: #8a8a94;
  --paper: #ffffff;
  --line: #e6e6ea;
  --line-2: #f1f1f4;
  --focus: #0b0b0c;

  isolation: isolate;
  width: min(100%, 21.5rem);
  background: var(--paper);
  color: var(--ink);
  border-radius: 16px;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.3),
    0 18px 44px -18px rgb(0 0 0 / 0.6);
}

.t-slab {
  height: 6px;
  background: var(--line);
}

/* The one band of rail colour that anchors the card. JS writes a literal hex
   here, so this transition is on a real value, not on a variable. */
.t-slab-fill {
  display: block;
  height: 100%;
  background: #00d54b;
  transition: background-color 300ms var(--ease);
}

.t-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s4) var(--s5) 0;
  font-size: 0.875rem;
}

.t-merchant {
  font-weight: 600;
}

.t-order {
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--ink-3);
}

.t-amount {
  padding: var(--s1) var(--s5) var(--s3);
  font-family: var(--display);
  font-size: 3.5rem;
  font-weight: 700;
  letter-spacing: -0.05em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.t-rails {
  position: relative;
  display: flex;
  gap: var(--s1);
  padding: 0 var(--s5) var(--s4);
  overflow-x: auto;
  scrollbar-width: none;
  /* mask-image affordance, not decoration: the row scrolls, so both edges fade
     to say so. The left fade sits over the container's own padding at
     scrollLeft 0, so nothing is clipped until it has actually scrolled. */
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 1.5rem,
    #000 calc(100% - 1.75rem),
    transparent
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 1.5rem,
    #000 calc(100% - 1.75rem),
    transparent
  );
}

.t-rails::-webkit-scrollbar {
  display: none;
}

/* The selection pill slides between chips — the same move the real pay page
   makes. Position and size come from JS measuring the active chip. */
.t-pill {
  position: absolute;
  top: 0;
  left: 0;
  height: 1.875rem;
  border-radius: 999px;
  background: #00d54b;
  transform: translateX(0);
  transition:
    transform 320ms var(--spring),
    width 320ms var(--spring),
    background-color 300ms var(--ease);
  pointer-events: none;
}

.t-chip {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  padding: 0 0.6875rem;
  height: 1.875rem;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  transition:
    border-color 180ms var(--ease),
    color 120ms var(--ease);
}

.t-chip:hover {
  border-color: var(--ink-3);
}

.t-chip.is-on {
  border-color: transparent;
  /*
    The label waits for the pill to arrive before it turns to the rail's ink.
    Flipping it at the same instant the pill leaves would leave white text on
    the white card for the length of the slide.
  */
  transition:
    border-color 180ms var(--ease),
    color 120ms var(--ease) 210ms;
}

/* Without JS the chips can't do anything, so don't offer a pointer. */
html:not(.js) .t-chip {
  cursor: default;
}

.t-qr {
  position: relative;
  width: 10.5rem;
  height: 10.5rem;
  margin: 0 auto var(--s3);
  padding: var(--s3);
  border: 1px solid var(--line-2);
  border-radius: 12px;
}

/* The codes are stacked and cross-fade, so the swap never shows an empty
   plate. Only the active one is visible, which is also the no-JS state. */
.t-code {
  position: absolute;
  inset: var(--s3);
  opacity: 0;
  visibility: hidden;
  transform: scale(0.97);
  transition:
    opacity 300ms var(--ease),
    transform 300ms var(--ease),
    visibility 0s linear 300ms;
}

.t-code.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity 300ms var(--ease),
    transform 300ms var(--ease),
    visibility 0s linear 0s;
}

.t-code svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Viewfinder corners. JS recolours them to the active rail. */
.t-vf {
  position: absolute;
  width: 13px;
  height: 13px;
  border: 2px solid #00d54b;
  transition: border-color 300ms var(--ease);
}

.t-vf.tl {
  top: -1px;
  left: -1px;
  border-right: 0;
  border-bottom: 0;
  border-top-left-radius: 5px;
}

.t-vf.tr {
  top: -1px;
  right: -1px;
  border-left: 0;
  border-bottom: 0;
  border-top-right-radius: 5px;
}

.t-vf.bl {
  bottom: -1px;
  left: -1px;
  border-right: 0;
  border-top: 0;
  border-bottom-left-radius: 5px;
}

.t-vf.br {
  bottom: -1px;
  right: -1px;
  border-left: 0;
  border-top: 0;
  border-bottom-right-radius: 5px;
}

.t-hint {
  min-height: 2.5rem;
  padding: 0 var(--s5) var(--s3);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ink-2);
  text-align: center;
}

.t-facts {
  display: grid;
  gap: var(--s2);
  margin: 0;
  padding: 0 var(--s5) var(--s4);
}

.t-facts div {
  padding-top: var(--s2);
  border-top: 1px solid var(--line-2);
}

.t-facts dt {
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.t-facts dd {
  margin: 2px 0 0;
  font-size: 0.875rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.t-facts .ref {
  letter-spacing: 0.14em;
}

/* Copy-to-clipboard, the same affordance the real pay page gives a customer. */
.copyable {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s2);
  max-width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.copyable .mono {
  font-family: var(--mono);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.copyhint {
  flex: 0 0 auto;
  font-family: var(--ui);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
  opacity: 0;
  transform: translateX(-3px);
  transition:
    opacity 180ms var(--ease),
    transform 180ms var(--ease);
}

.copyable:hover .copyhint,
.copyable:focus-visible .copyhint,
.copyable.is-copied .copyhint {
  opacity: 1;
  transform: none;
}

.copyable.is-copied .copyhint {
  color: var(--good);
}

@media (hover: none) {
  .copyhint {
    opacity: 0.7;
    transform: none;
  }
}

/* A depiction of the pay page's button, not a button — it has nowhere to go. */
.t-cta {
  margin: 0 var(--s5) var(--s5);
  padding: var(--s3);
  border-radius: 8px;
  background: #00d54b;
  color: #03170b;
  font-size: 0.9375rem;
  font-weight: 600;
  text-align: center;
  transition:
    background-color 300ms var(--ease),
    color 300ms var(--ease);
}

/* ══ At a glance ══════════════════════════════════════════════════════ */

.strip {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.strip-inner {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: var(--measure-wide);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.strip-inner div {
  padding: var(--s6) var(--s4) var(--s6) 0;
}

.strip-inner div + div {
  padding-left: var(--s5);
  border-left: 1px solid var(--line);
}

.strip strong {
  display: block;
  font-family: var(--display);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1;
  margin-bottom: var(--s2);
  font-variant-numeric: tabular-nums;
}

.strip span {
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ink-3);
}

@media (max-width: 48rem) {
  .strip-inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .strip-inner div:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }

  .strip-inner div:nth-child(n + 3) {
    border-top: 1px solid var(--line);
  }
}

/* ══ Calculator ═══════════════════════════════════════════════════════ */

.calc {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  gap: clamp(var(--s6), 5vw, var(--s8));
  align-items: start;
  padding-top: var(--s6);
  border-top: 1px solid var(--line);
}

@media (max-width: 56rem) {
  .calc {
    grid-template-columns: minmax(0, 1fr);
  }
}

.calc-inputs {
  display: grid;
  gap: var(--s6);
}

.field {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s2) var(--s4);
}

.field-label {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink-2);
}

.field-value {
  font-family: var(--display);
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.field-rail {
  position: relative;
  grid-column: 1 / -1;
  display: block;
  height: 22px;
  margin-top: var(--s1);
}

.field-track {
  position: absolute;
  inset: 50% 0 auto 0;
  height: 3px;
  margin-top: -1.5px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.field-track i {
  display: block;
  height: 100%;
  background: var(--ink);
  border-radius: 999px;
  transition: width 90ms linear;
}

.field-rail input[type="range"] {
  position: relative;
  width: 100%;
  height: 22px;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}

.field-rail input[type="range"]::-webkit-slider-runnable-track {
  height: 22px;
  background: transparent;
}

.field-rail input[type="range"]::-moz-range-track {
  height: 22px;
  background: transparent;
}

.field-rail input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--ink);
  border: 4px solid var(--paper);
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.4);
  transition: transform 140ms var(--ease);
}

.field-rail input[type="range"]::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--ink);
  border: 4px solid var(--paper);
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.4);
}

.field-rail input[type="range"]:hover::-webkit-slider-thumb,
.field-rail input[type="range"]:focus-visible::-webkit-slider-thumb {
  transform: scale(1.14);
}

.field-rail input[type="range"]:active::-webkit-slider-thumb {
  transform: scale(0.94);
}

.field-ends {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--ink-3);
}

.calc-orders {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

.calc-orders strong {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.calc-out {
  padding: clamp(var(--s5), 3vw, var(--s6));
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--paper-2);
}

.calc-bars {
  display: grid;
  gap: var(--s2);
  margin-bottom: var(--s5);
}

.calc-bar {
  height: 10px;
  background: var(--line-2);
  border-radius: 999px;
  overflow: hidden;
}

.calc-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 220ms var(--ease);
}

.calc-bar-fill.is-card {
  background: var(--ink-3);
}

/* The one gold thing in this section. */
.calc-bar-fill.is-cc {
  background: var(--gold);
}

.calc-rows {
  margin: 0;
}

.calc-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--line);
}

.calc-row dt {
  font-weight: 600;
}

.calc-row dt em {
  display: block;
  font-style: normal;
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--ink-3);
}

.calc-row dd {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.calc-keep {
  padding: var(--s5) 0 var(--s4);
}

.calc-keep-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s2);
}

.calc-keep-num {
  font-family: var(--display);
  font-size: clamp(3rem, 8vw, 5.5rem);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 0.95;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.calc-keep-sub {
  margin-top: var(--s2);
  font-size: 1rem;
  color: var(--ink-2);
}

.calc-note {
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-3);
}

/* ══ Comparison table ═════════════════════════════════════════════════ */

/*
  Kept as a real table at every width — stacking it into blocks would mean
  display:block on the table elements, which drops the table semantics screen
  readers rely on. It scrolls inside its own container instead, which is
  focusable and labelled, with a mask affordance on the right edge.
*/
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 16px;
}

.table-scroll:focus-visible {
  outline-offset: -2px;
}

.cmp {
  width: 100%;
  min-width: 36rem;
  border-collapse: collapse;
  text-align: left;
}

.table-hint {
  display: none;
  margin-top: var(--s3);
  font-size: 0.8125rem;
  color: var(--ink-3);
}

@media (max-width: 44rem) {
  .table-scroll {
    mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
  }

  .cmp th,
  .cmp td {
    padding: var(--s4);
  }

  .table-hint {
    display: block;
  }
}

.cmp th,
.cmp td {
  padding: var(--s4) var(--s5);
  vertical-align: top;
  border-bottom: 1px solid var(--line-2);
}

.cmp thead th {
  padding-top: var(--s5);
  padding-bottom: var(--s3);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}

.cmp tbody th {
  width: 26%;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
}

.cmp td {
  width: 37%;
  font-size: 0.9375rem;
  color: var(--ink-2);
}

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

/* Our column is the emphasised one — by weight and a hairline, not a fill. */
.cmp .is-us {
  color: var(--ink);
  font-weight: 500;
  border-left: 1px solid var(--line);
  background: var(--paper-2);
}

.cmp thead .is-us {
  color: var(--ink);
}

.cmp tbody tr {
  transition: background-color 160ms var(--ease);
}

.cmp tbody tr:hover {
  background: var(--paper-2);
}

.table-note {
  margin-top: var(--s3);
  font-size: 0.8125rem;
  color: var(--ink-3);
}

/* ══ Steps ════════════════════════════════════════════════════════════ */

.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s5), 3vw, var(--s6));
  margin: 0;
  padding: 0;
  list-style: none;
}

.steps li {
  padding-top: var(--s4);
  border-top: 2px solid var(--ink);
}

.step-n {
  display: block;
  margin-bottom: var(--s3);
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.steps h3 {
  font-size: 1.375rem;
  margin-bottom: var(--s2);
}

.steps p {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@media (max-width: 52rem) {
  .steps {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ══ Platforms ════════════════════════════════════════════════════════ */

.platforms {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s5), 3vw, var(--s6));
  margin: 0;
  padding: 0;
  list-style: none;
}

.platforms li {
  display: flex;
  flex-direction: column;
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
}

/* The one that ships gets the ink border. Status is stated in words too — the
   distinction can never rest on a colour alone. */
.platforms li:first-child {
  border-color: var(--ink);
}

.pf-status {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: var(--s2);
  margin-bottom: var(--s4);
  padding: var(--s1) var(--s3);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.pf-status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-3);
}

.pf-status.is-live {
  border-color: var(--good);
  color: var(--good);
}

.pf-status.is-live::before {
  background: var(--good);
}

.platforms h3 {
  font-size: 1.25rem;
  margin-bottom: var(--s3);
}

.pf-line {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

.pf-line .mono {
  font-family: var(--mono);
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

@media (max-width: 56rem) {
  .platforms {
    grid-template-columns: minmax(0, 1fr);
  }
}

.notify {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s5);
  margin-top: clamp(var(--s5), 3vw, var(--s6));
  padding: clamp(var(--s5), 3vw, var(--s6));
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper-2);
}

.notify-title {
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.notify-sub {
  max-width: 34rem;
  margin-top: var(--s2);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-3);
}

.notify-field {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.notify-field input {
  min-width: 0;
  width: 15rem;
  padding: var(--s2) var(--s3);
  border: 1.5px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
  transition: border-color 180ms var(--ease);
}

.notify-field input::placeholder {
  color: var(--ink-3);
}

.notify-field input:hover {
  border-color: var(--ink-3);
}

.notify-status {
  grid-column: 1 / -1;
  font-size: 0.8125rem;
  color: var(--good);
}

.notify-status:empty {
  display: none;
}

@media (max-width: 52rem) {
  .notify {
    grid-template-columns: minmax(0, 1fr);
  }

  .notify-field input {
    flex: 1 1 12rem;
    width: auto;
  }
}

/* ══ Methods wall ═════════════════════════════════════════════════════ */

.methods {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
}

/* Child combinator throughout: each card contains its own <ul> of capability
   lines, and a descendant selector here would style those as cards too. */
.methods > li {
  display: flex;
  flex-direction: column;
  padding: var(--s5);
  background: var(--paper);
  transition: background-color 200ms var(--ease);
}

.methods > li:hover {
  background: var(--paper-2);
}

/* The fifth card takes the wide cell — it has the most to say. */
.methods > li:nth-child(5) {
  grid-column: span 2;
}

/*
  Each rail's own brand colour, straight from app/lib/rails/index.ts. Kept in
  the stylesheet rather than inline so the one that needs a dark-theme variant
  can have one — Apple Cash's near-black identifier would vanish against a dark
  page. The light value is still the only definition on bare :root terms; the
  media query below only overrides it.
*/
.m-cashapp {
  --dot: #00d54b;
}
.m-venmo {
  --dot: #008cff;
}
.m-zelle {
  --dot: #6d1ed4;
}
.m-apple {
  --dot: #111113;
}
.m-crypto {
  --dot: #2775ca;
}

@media (prefers-color-scheme: dark) {
  .m-apple {
    --dot: #f4f4f6;
  }
}

/* The brand colour as a precise identifier, not decoration. It extends on
   hover, which is the whole tile's reaction — a transform on the tile itself
   would tear the 1px seams of the wall apart. */
.m-rule {
  display: block;
  width: 2.25rem;
  height: 4px;
  margin-bottom: var(--s4);
  border-radius: 999px;
  background: var(--dot);
  transform-origin: left center;
  transition: transform 340ms var(--ease);
}

.methods > li:hover .m-rule,
.methods > li:focus-within .m-rule {
  transform: scaleX(2.1);
}

.methods h3 {
  font-size: 1.25rem;
  margin-bottom: var(--s3);
}

.m-line {
  font-size: 0.9375rem;
  color: var(--ink-2);
  margin-bottom: var(--s4);
}

.caps {
  display: grid;
  gap: var(--s2);
  margin: auto 0 0;
  padding: var(--s4) 0 0;
  border-top: 1px solid var(--line-2);
  list-style: none;
  font-size: 0.8125rem;
}

/* Hanging indent rather than a grid: a grid would make the trailing <em> its
   own cell and break "Confirms itself — stablecoins" onto two rows. */
.caps li {
  position: relative;
  padding-left: 1.375rem;
  color: var(--ink-2);
}

.caps li::before {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--mono);
  font-weight: 600;
}

.caps li.yes::before {
  content: "✓";
  color: var(--good);
}

.caps li.no::before {
  content: "–";
  color: var(--ink-3);
}

.caps em {
  font-style: normal;
  color: var(--ink-3);
}

@media (max-width: 60rem) {
  .methods {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 40rem) {
  .methods {
    grid-template-columns: minmax(0, 1fr);
  }

  .methods > li:nth-child(5) {
    grid-column: span 1;
  }
}

/* ══ The bundle argument ══════════════════════════════════════════════ */

.args {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s5), 3vw, var(--s7));
}

.arg {
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
}

.arg-n {
  display: block;
  margin-bottom: var(--s4);
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.arg h3 {
  font-size: 1.375rem;
  line-height: 1.12;
  margin-bottom: var(--s3);
}

.arg p {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@media (max-width: 60rem) {
  .args {
    grid-template-columns: minmax(0, 1fr);
  }
}

.ladder {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(var(--s5), 4vw, var(--s7));
  margin-top: clamp(var(--s6), 5vw, var(--s8));
  padding: clamp(var(--s5), 3vw, var(--s6));
  border: 1px solid var(--line);
  border-radius: 16px;
}

.ladder-chart {
  display: flex;
  align-items: flex-end;
  gap: var(--s3);
  height: 9rem;
}

.rung {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto auto;
  align-items: end;
  justify-items: center;
  gap: var(--s1);
  width: 2.75rem;
  height: 100%;
}

.rung-bar {
  width: 100%;
  height: var(--h);
  background: var(--line);
  border-radius: 4px 4px 0 0;
  transform-origin: bottom center;
  transition: transform 700ms var(--spring);
}

/* The rungs grow when the block arrives. Scoped to html.js so that without
   JavaScript the chart is simply drawn, at full height, straight away. */
html.js .ladder:not(.is-in) .rung-bar {
  transform: scaleY(0);
}

.rung:nth-child(1) .rung-bar {
  transition-delay: 40ms;
}
.rung:nth-child(2) .rung-bar {
  transition-delay: 120ms;
}
.rung:nth-child(3) .rung-bar {
  transition-delay: 200ms;
}
.rung:nth-child(4) .rung-bar {
  transition-delay: 280ms;
}
.rung:nth-child(5) .rung-bar {
  transition-delay: 400ms;
}

.rung.is-free .rung-bar {
  background: var(--gold);
}

.rung-n {
  font-size: 0.75rem;
  color: var(--ink-3);
}

.rung-p {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.rung.is-free .rung-p {
  color: var(--ink);
}

.ladder-copy {
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  line-height: 1.5;
  color: var(--ink-2);
}

.ladder-copy strong {
  color: var(--ink);
}

@media (max-width: 46rem) {
  .ladder {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ══ Routing ══════════════════════════════════════════════════════════ */

.split {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(var(--s6), 5vw, var(--s8));
  align-items: start;
}

@media (max-width: 60rem) {
  .split {
    grid-template-columns: minmax(0, 1fr);
  }
}

.lede-sub {
  margin-bottom: var(--s4);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* A merchant's actual setup, spelled out method by method. */
.setup {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}

.setup li {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--line);
}

.setup-k {
  font-size: 0.9375rem;
  font-weight: 600;
}

.setup-v {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@media (max-width: 30rem) {
  .setup li {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s1);
  }
}

.reasons {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s5), 3vw, var(--s7));
  margin-top: clamp(var(--s6), 5vw, var(--s8));
}

.reason {
  padding-top: var(--s4);
  border-top: 2px solid var(--ink);
}

.reason h3 {
  font-size: 1.1875rem;
  line-height: 1.14;
  margin-bottom: var(--s3);
}

.reason p {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@media (max-width: 60rem) {
  .reasons {
    grid-template-columns: minmax(0, 1fr);
  }
}

.modes-wrap {
  margin-top: clamp(var(--s6), 5vw, var(--s8));
  padding-top: var(--s6);
  border-top: 1px solid var(--line);
}

.modes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s5);
  margin: 0 0 var(--s5);
  padding: 0;
  list-style: none;
  font-size: 0.9375rem;
  color: var(--ink-2);
}

.modes li {
  padding-left: var(--s4);
  border-left: 2px solid var(--gold);
}

.modes strong {
  color: var(--ink);
}

@media (max-width: 52rem) {
  .modes {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s4);
  }
}

.panel {
  padding: clamp(var(--s5), 3vw, var(--s6));
  border: 1px solid var(--stage-line);
  border-radius: 16px;
}

.panel-title {
  margin-bottom: var(--s5);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.rot {
  display: grid;
  gap: var(--s5);
}

.rot-row {
  display: grid;
  gap: var(--s2);
}

.rot-name {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s2);
  font-size: 0.9375rem;
  font-weight: 600;
}

.rot-handle {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

.rot-name em {
  font-style: normal;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold);
}

.rot-bar {
  display: block;
  height: 6px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.rot-bar i {
  display: block;
  height: 100%;
  background: var(--ink-3);
  border-radius: 999px;
  transform-origin: left center;
  transition: transform 760ms var(--ease);
}

html.js .split-art:not(.is-in) .rot-bar i {
  transform: scaleX(0);
}

.rot-row:nth-child(2) .rot-bar i {
  transition-delay: 110ms;
}
.rot-row:nth-child(3) .rot-bar i {
  transition-delay: 220ms;
}

.rot-row.is-next .rot-bar i {
  background: var(--gold);
}

.rot-val {
  font-family: var(--mono);
  font-size: 0.8125rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.panel-foot {
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: 0.875rem;
  color: var(--ink-2);
}

.panel-foot strong {
  color: var(--ink);
}

.art-caption {
  margin-top: var(--s3);
  font-size: 0.8125rem;
  color: var(--ink-3);
  text-align: center;
}

/* ══ What it doesn't do ═══════════════════════════════════════════════ */

.limits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: clamp(var(--s5), 3vw, var(--s6)) clamp(var(--s5), 4vw, var(--s7));
  margin: 0;
  padding: 0;
  list-style: none;
}

.limits li {
  padding-left: var(--s5);
  border-left: 2px solid var(--gold);
}

.limits h3 {
  font-size: 1.125rem;
  margin-bottom: var(--s2);
}

.limits p {
  font-size: 0.9375rem;
  color: var(--ink-2);
}

/* ══ Pricing ══════════════════════════════════════════════════════════ */

.price {
  display: grid;
  grid-template-columns: 23rem minmax(0, 1fr);
  gap: clamp(var(--s6), 5vw, var(--s8));
  align-items: start;
}

@media (max-width: 56rem) {
  .price {
    grid-template-columns: minmax(0, 1fr);
  }
}

.price-card {
  padding: clamp(var(--s5), 3vw, var(--s6));
  border: 2px solid var(--ink);
  border-radius: 16px;
  background: var(--paper);
  box-shadow: var(--shadow-2);
  transition:
    transform 300ms var(--ease),
    box-shadow 300ms var(--ease);
}

.price-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 22px 46px -20px rgb(0 0 0 / 0.36);
}

.price-eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.price-tag {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin-bottom: var(--s5);
  font-size: 0.9375rem;
  color: var(--ink-2);
}

.price-num {
  font-family: var(--display);
  font-size: 4.5rem;
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.price-list {
  display: grid;
  gap: var(--s2);
  margin: 0 0 var(--s6);
  padding: var(--s4) 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
  font-size: 0.9375rem;
}

.price-list li::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: var(--s3);
  border-radius: 50%;
  background: var(--gold);
  vertical-align: middle;
}

.price-list em {
  font-style: normal;
  color: var(--ink-3);
}

.price-card .microcopy {
  margin-top: var(--s3);
}

.price-notes {
  display: grid;
  gap: var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 1rem;
  color: var(--ink-2);
}

.price-notes li {
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--line);
}

.price-notes li:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.price-notes strong {
  color: var(--ink);
}

/* ══ FAQ ══════════════════════════════════════════════════════════════ */

.faq {
  max-width: 48rem;
  border-top: 1px solid var(--line);
}

.faq details {
  border-bottom: 1px solid var(--line);
}

.faq summary {
  position: relative;
  padding: var(--s5) var(--s7) var(--s5) 0;
  font-family: var(--display);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  cursor: pointer;
  list-style: none;
}

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

.faq summary::after,
.faq summary::before {
  content: "";
  position: absolute;
  right: var(--s2);
  top: 50%;
  width: 14px;
  height: 1.5px;
  background: var(--ink-3);
  transition: transform 240ms var(--ease);
}

.faq summary::before {
  transform: rotate(90deg);
}

.faq details[open] summary::before {
  transform: rotate(0deg);
}

.faq summary:hover::after,
.faq summary:hover::before {
  background: var(--ink);
}

.faq-body {
  padding-bottom: var(--s5);
  animation: faq-open 260ms var(--ease) both;
}

.faq-body p {
  max-width: 44rem;
  font-size: 0.9375rem;
  color: var(--ink-2);
}

@keyframes faq-open {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ══ Close + footer ═══════════════════════════════════════════════════ */

.close {
  padding: clamp(var(--s8), 10vw, 9rem) var(--gutter);
  text-align: center;
}

.close-inner {
  max-width: 44rem;
  margin: 0 auto;
}

.close h2 {
  font-size: clamp(2.5rem, 7vw, 5rem);
  letter-spacing: -0.045em;
  margin-bottom: var(--s5);
}

.close-lede {
  margin-bottom: var(--s6);
  font-size: clamp(1rem, 1.4vw, 1.1875rem);
  color: var(--ink-2);
}

.foot {
  padding: var(--s7) var(--gutter) var(--s8);
  border-top: 1px solid var(--stage-line);
}

.foot-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s6);
  align-items: start;
  max-width: var(--measure-wide);
  margin: 0 auto;
}

.foot-line {
  max-width: 40rem;
  margin-top: var(--s4);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--ink-3);
}

.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s5);
  font-size: 0.875rem;
}

.foot-links a {
  color: var(--ink-2);
  text-decoration: none;
}

.foot-links a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 46rem) {
  .foot-inner {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ══ Sticky CTA ═══════════════════════════════════════════════════════ */

.dock {
  position: fixed;
  z-index: 30;
  right: var(--s5);
  bottom: var(--s5);
  display: flex;
  align-items: center;
  gap: var(--s4);
  max-width: calc(100vw - var(--s5) * 2);
  padding: var(--s3) var(--s3) var(--s3) var(--s5);
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  box-shadow: var(--shadow-2);
  transform: translateY(140%);
  opacity: 0;
  transition:
    transform 420ms var(--spring),
    opacity 240ms var(--ease);
}

.dock.is-in {
  transform: translateY(0);
  opacity: 1;
}

.dock[hidden] {
  display: none;
}

.dock-line {
  font-size: 0.875rem;
  color: var(--ink-2);
  white-space: nowrap;
}

.dock-line strong {
  color: var(--ink);
}

@media (max-width: 40rem) {
  .dock {
    left: var(--s4);
    right: var(--s4);
    bottom: var(--s4);
    max-width: none;
    justify-content: space-between;
    padding-left: var(--s4);
  }

  .dock-line {
    font-size: 0.8125rem;
    white-space: normal;
  }
}

/* ══ Motion ═══════════════════════════════════════════════════════════ */

/*
  Load sequence. Pure CSS with `both`, so it runs identically whether or not
  app.js ever arrives, and always ends on the settled state.
*/
[data-seq] {
  animation: rise 720ms var(--ease) both;
  animation-delay: calc(var(--i, 0) * 80ms + 60ms);
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* The ticket is the last thing to arrive, and it lands rather than fades. */
.hero-art[data-seq] {
  animation-name: land;
  animation-duration: 880ms;
  animation-timing-function: var(--spring);
}

@keyframes land {
  from {
    opacity: 0;
    transform: translateY(26px) scale(0.965);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/*
  Scroll reveals. The start state is scoped to html.js, so with JavaScript off
  nothing is ever hidden and the page is complete on arrival.
*/
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(16px);
}

html.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity 640ms var(--ease),
    transform 640ms var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}

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

  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }

  html.js [data-reveal] {
    opacity: 1;
    transform: none;
  }

  /* Anything whose resting state is drawn by a reveal transition is simply
     drawn, whether or not the observer ever got to it. */
  .rung-bar,
  .rot-bar i,
  .m-rule {
    transform: none !important;
  }

  .btn:hover,
  .btn:active {
    transform: none;
  }

  .dock {
    transform: none;
  }
}


/* ── Beta bar ──────────────────────────────────────────────────────────────
   Sits above the nav rather than floating over content: a banner that can be
   scrolled past and missed is worse than none, because the person who missed it
   is the one who signs up expecting to install today. */
.beta-bar {
  position: relative;
  z-index: 20;
  padding: 10px clamp(1rem, 4vw, 3rem);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-align: center;
}

.beta-bar strong {
  color: var(--gold);
  font-weight: 600;
}


/* ── Wordmark ──────────────────────────────────────────────────────────────
   The sound arcs are the hyphen. They already mean "the sound" in the mark, so
   putting them between the two syllables makes the word say what the name says.
   The coin in a lockup therefore drops its own arcs — one idea, said once. */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  letter-spacing: -0.045em;
  white-space: nowrap;
}

.wm-arcs {
  flex: 0 0 auto;
  margin: 0 0.04em;
  align-self: center;
  overflow: visible;
}
