:root {
  --bg: #07080a;
  --ink: #e9ecf1;
  --muted: rgba(233, 236, 241, 0.62);
  --edge: rgba(233, 236, 241, 0.12);
  --chrome-gradient: linear-gradient(180deg, #f2f4f8, #b9bec7 45%, #7e838c 55%, #d9dce2);
  /* Same metal, diluted for hover states that shouldn't compete with the
     active nav item's full chrome treatment. */
  --chrome-gradient-soft: linear-gradient(180deg, rgba(242, 244, 248, 0.16), rgba(185, 190, 199, 0.1) 45%, rgba(126, 131, 140, 0.07) 55%, rgba(217, 220, 226, 0.12));
  --nav-height: 76px;
  --mono: "Fragment Mono", ui-monospace, monospace;
  --display: "Switzer", -apple-system, BlinkMacSystemFont, sans-serif;

  /* Semantic status colors, desaturated to sit inside the chrome/mono palette.
     Used only on status chips and signed amounts, never decoratively. */
  --good: #8fe3b0;
  --amber: #e9c46a;
  --bad: #e8867a;

  /* Paper surfaces. Two sections (product details, spec) invert to a light
     "printed document" ground, which is the page's own thesis made literal.
     That surface had no token layer: the same two text roles the dark side
     names once each (--ink, --muted) had been re-derived by hand as four
     alphas, .40 / .48 / .52 / .58, which failed WCAG AA at every step and put
     the light sections a full tier weaker than the dark ones they mirror.

     Derived rather than tuned. On the dark ground --muted sits 33.8% of the
     way from --ink toward --bg, keeping the ink's own hue rather than the
     background's. --paper-muted is that same 33.8% from --paper-ink toward
     --paper at the same hue (oklch 0.436 0.009 264), so both grounds express
     one relationship instead of two opinions: 6.36:1 here against 6.68:1
     there. Explicit values, not alpha, because these sections float
     translucent white cards over the paper and an alpha would make every
     ratio depend on what happened to be underneath. */
  --paper: #e7e7e2;
  --paper-ink: #111317;
  --paper-muted: #4f5156;
  --paper-edge: rgba(17, 19, 23, 0.12);
  --paper-edge-strong: rgba(17, 19, 23, 0.25);
  --paper-good: #27623e;
  --paper-amber: #6e571e;

  /* Ink on chrome and other light surfaces: the counterpart to --ink, which
     names only the light-on-dark direction. Because this one had no name it
     was respelled per component, so #0a0b0d (8 uses, every one a color) sits
     beside near-identical #090a0c and #090b0e doing the same job. Naming it is
     what stops a fourth spelling being invented. Values are not merged here;
     that is a colour decision, not an extraction. */
  --ink-on-light: #0a0b0d;

  /* Translucent surface tints for components raised off the dark ground, the
     counterpart to the opaque --panel-bg-* section grounds. Two steps, each
     used five times and always as a background. The .12 white that appears
     just as often is deliberately not here: it is split across border,
     background and box-shadow, so it is three intents wearing one value. */
  --surface-1: rgba(255, 255, 255, 0.025);
  --surface-2: rgba(255, 255, 255, 0.035);

  /* Two panel background tints used across the sticky stacks so the second
     and third panel visibly differ from the base bg as they cover the one
     beneath, per the Nova/Habitline stacked-panel reference. */
  --panel-bg-1: #07080a;
  --panel-bg-2: #0c0e12;
  --panel-bg-3: #101318;

  /* The uppercase mono label is the most repeated role on the site: section
     eyebrows, figure captions, form labels, panel keys. It had drifted to eight
     definitions across four tracking values (.05 / .07 / .08 / .1em) and two
     sizes, so the same job read slightly differently in every section. Two
     sizes only, and tracking that opens as the size drops, because uppercase
     mono at 11px needs more room between letters than at 12px, not less.

     11px is the floor for any label the visitor is expected to read. The only
     type allowed below it is inside the phone mockup, where the UI is depicted
     at roughly 0.7 scale rather than read. */
  --t-label: 12px;
  --t-label-sm: 11px;
  --t-label-track: 0.1em;
  --t-label-track-sm: 0.12em;
}

html,
body {
  overflow-x: clip;
}

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

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ---------- nav ---------- */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--nav-height);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition:
    background 0.3s ease,
    border-color 0.3s ease;
}

.nav--stuck {
  background: rgba(7, 8, 10, 0.62);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border-bottom: 1px solid var(--edge);
}

.nav-inner {
  height: 100%;
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav-logo {
  display: flex;
  align-items: center;
  text-decoration: none;
  /* Line the wordmark up with the "H" of "Hold" in the hero below it.
     Two separate offsets are being cancelled here, both measured off rendered
     pixels rather than the source art:

     1. The mark's own inset. wordmark.png carries a symmetric 103px bleed on
        its 1129px canvas, object-fit: contain letterboxes it again, and
        LiquidMetal's own scale={0.7} insets it further, so the first lit pixel
        of the V sat ~48px inside this box. That is --nav-logo-nudge, which
        shrinks with the mark at the breakpoints below.
     2. The rail gap. .nav-inner caps at 1360px and .hero-inner at 1600px, so
        above 1360px the headline starts up to 120px left of this nav, and a
        fixed nudge would only ever be right at one viewport width. The second
        term reproduces the hero's own centring maths so the mark tracks the
        headline at every width, and collapses to zero at 1360px and below
        where the two caps converge.

     Uses 100vw, which counts a classic scrollbar the containers exclude; that
     costs up to ~8px on platforms without overlay scrollbars, against the
     120px it removes. Transform, not margin: nothing about the nav's flex
     layout should shift for an optical nudge, and this element is an
     overflow: hidden clipping box under 900px, so moving the box keeps the
     mark whole where moving a child inside it would crop. */
  transform: translateX(
    calc(var(--nav-logo-nudge, -48.4px) - (min(100vw, 1600px) - min(100vw, 1360px)) / 2)
  );
}

.nav-logo-scale {
  display: block;
  transform-origin: left center;
  transform: scale(var(--nav-logo-scale, 1));
}

.nav-logo-image {
  display:block;
  width:240px;
  height:56px;
  object-fit:contain;
  filter:contrast(1.25) brightness(1.15);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 2.5rem;
}

/* Hamburger: hidden on desktop, shown below 900px (see responsive section).
   A real 44x44 hit target, three bars, no icon font. */
.nav-hamburger {
  display: none;
  width: 44px;
  height: 44px;
  padding: 0;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
}

.nav-hamburger span {
  display: block;
  width: 18px;
  height: 1.5px;
  border-radius: 1px;
  background: var(--ink);
  transition: transform 0.25s ease, opacity 0.2s ease;
}

.nav-hamburger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}

.nav-hamburger[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav-hamburger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

/* ---------- mobile nav drawer ---------- */

/* visibility (not pointer-events) gates interaction: hidden elements are
   already unclickable, and GSAP's autoAlpha flips visibility with the fade.
   Portaled to <body> (see Nav.tsx), so these z-indexes are compared against
   the whole document, not just .nav's local stack; set well above .nav's
   own z-index: 100. */
.nav-mobile-backdrop {
  position: fixed;
  top: var(--nav-height);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 998;
  background: rgba(7, 8, 10, 0.6);
  opacity: 0;
  visibility: hidden;
}

.nav-mobile-menu {
  position: fixed;
  top: var(--nav-height);
  right: 0;
  bottom: 0;
  z-index: 999;
  width: min(360px, 86vw);
  overflow-y: auto;
  background: rgba(7, 8, 10, 0.92);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border-left: 1px solid var(--edge);
  padding: 24px 28px 40px;
  visibility: hidden;
  transform: translateX(100%);
}

.nav-mobile-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0 0 8px auto;
  padding: 0;
  background: none;
  border: none;
  color: var(--ink);
  cursor: pointer;
}

.nav-mobile-sections {
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin-bottom: 28px;
}

.nav-mobile-section .nav-col-heading {
  margin-bottom: 6px;
}

.nav-mobile-link {
  min-height: 44px;
  display: flex;
  align-items: center;
  font-size: 16px;
  padding: 0;
  border-bottom: 1px solid var(--edge);
}

.nav-mobile-section .nav-mobile-link:last-child {
  border-bottom: none;
}

.nav-mobile-cta {
  width: 100%;
  min-height: 44px;
}

.nav-menu {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.nav-menu-item {
  position: relative;
}

.nav-trigger {
  background: none;
  border: none;
  color: var(--ink);
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  padding: 10px 14px;
  cursor: pointer;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .nav-trigger:hover {
    color: var(--ink);
    opacity: 0.85;
  }
}

.nav-panel {
  position: fixed;
  top: var(--nav-height);
  left: 0;
  right: 0;
  background: rgba(7, 8, 10, 0.85);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.nav-menu-item:has(.nav-trigger[aria-expanded="true"]) .nav-panel {
  pointer-events: auto;
}

.nav-panel-inner {
  max-width: 1360px;
  margin: 0 auto;
  padding: 28px 32px 36px;
  display: flex;
  gap: 64px;
}

.nav-col-heading {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

.menu-link {
  display: block;
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
  padding: 6px 0;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .menu-link:hover {
    opacity: 0.75;
  }
}

.menu-link.inert {
  color: var(--muted);
  cursor: default;
}

/* ---------- chrome buttons ---------- */

@keyframes btn-chrome-glow {
  0%,
  100% {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      0 0 8px rgba(233, 236, 241, 0.18),
      0 0 2px rgba(233, 236, 241, 0.25);
  }
  50% {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.8),
      0 0 26px rgba(233, 236, 241, 0.6),
      0 0 8px rgba(233, 236, 241, 0.55);
  }
}

.btn-chrome {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px 22px;
  border-radius: 999px;
  background: var(--chrome-gradient);
  color: var(--ink-on-light);
  font-family: var(--display);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  border: none;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  /* Same shimmering-metal idea as the nav wordmark's LiquidMetal shader,
     just as an ordinary box-shadow pulse rather than a shader — a button
     doesn't need its own WebGL canvas — and noticeably slower: the
     wordmark's own animation runs at speed=1 (roughly a 2-3s character),
     this is a 6s breathing cycle. */
  animation: btn-chrome-glow 6s ease-in-out infinite;
  transition:
    transform 0.2s ease,
    filter 0.2s ease;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .btn-chrome:hover {
    transform: translateY(-1px);
    filter: brightness(1.05);
  }
}

.btn-chrome--lg {
  padding: 16px 30px;
  font-size: 16px;
}

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 16px 30px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 600;
  font-size: 16px;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .btn-ghost:hover {
    border-color: rgba(233, 236, 241, 0.4);
  }
}

/* ---------- hero ---------- */

.hero {
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: var(--nav-height);
}

.hero-inner {
  /* Widened from 1360px: at the old cap, wide viewports left only ~688px for
     the copy column once the 560px card and 48px gap were subtracted, less
     than the ~742px the headline needs at its 112px font-size ceiling, so the
     line collided with the card. At 1600px there is consistently >=740px of
     margin for the copy column (see Hero.tsx / this file's collision-fix
     comment for the arithmetic at 1440 and 1920). */
  max-width: 1600px;
  margin: 0 auto;
  width: 100%;
  padding: 48px 32px;
  display: flex;
  align-items: center;
  /* justify-content: space-between distributes any leftover free space on
     TOP of `gap`; gap itself is the guaranteed minimum between the two flex
     items, so the copy column and card column are never closer than 48px. */
  justify-content: space-between;
  gap: 48px;
}

.hero-copy {
  max-width: 680px;
  /* Flex items accept z-index directly (no position:relative needed). If the
     escaped headline ever does touch the card, the copy column paints over
     it rather than disappearing behind it. */
  z-index: 2;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 28px;
}

.eyebrow-dash {
  display: inline-block;
  width: 18px;
  height: 2px;
  background: var(--chrome-gradient);
  flex-shrink: 0;
}

.hero-headline {
  margin: 0 0 28px;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(56px, 7vw, 112px);
  line-height: 0.98;
  letter-spacing: -0.03em;
  color: var(--ink);
}

/* Lines size to their own text (not the 680px copy column) and clip vertically
   only, so the mask-reveal never crops the glyphs horizontally. overflow-x:
   visible paired with overflow-y: clip is the documented escape hatch for a
   one-axis mask: unlike hidden/auto, clip does not force the visible axis to
   auto, so the line can bleed past its box with no scroll container forming.
   At 1280-1920px viewport widths the longest line ("Tap anywhere.") measures
   well under (viewport - 64px hero padding) even at the 112px ceiling, so the
   vw term does not need to shrink to stay inside the viewport. */
.headline-line {
  display: block;
  width: max-content;
  overflow-x: visible;
  overflow-y: clip;
  white-space: nowrap;
}

.headline-inner {
  display: block;
  transform: translateY(0%);
  white-space: nowrap;
  will-change: transform;
}

.hero-lead {
  max-width: 560px;
  color: var(--muted);
  font-size: 17px;
  line-height: 1.55;
  margin: 0 0 36px;
}

.hero-ctas {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 56px;
}

.hero-figures {
  display: flex;
  align-items: stretch;
}

.figure {
  padding: 0 32px;
  border-left: 1px solid var(--edge);
}

.figure:first-child {
  padding-left: 0;
  border-left: none;
}

.figure-label {
  font-family: var(--mono);
  font-size: var(--t-label-sm);
  letter-spacing: var(--t-label-track-sm);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}

.figure-value {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(28px, 3vw, 40px);
  color: var(--ink);
  white-space: nowrap;
}

.figure-value--static {
  font-size: clamp(20px, 2vw, 26px);
}

.odo-affix {
  font-family: var(--mono);
  /* Proportional to the figure it trails, but never below the 11px floor:
     at the 19px hero-satellite scale a bare 0.45em computes to 8.5px. */
  font-size: max(11px, 0.45em);
  font-weight: 400;
  color: var(--muted);
}

/* ---------- odometer ---------- */

.odometer {
  display: inline-flex;
  align-items: baseline;
  font-variant-numeric: tabular-nums;
}

.odo-static {
  display: inline-block;
}

.odo-digit {
  display: inline-block;
  overflow: hidden;
  height: 1em;
  line-height: 1;
  width: 0.62em;
}

.odo-digit-stack {
  display: flex;
  flex-direction: column;
  will-change: transform;
}

.odo-digit-stack span {
  display: block;
  height: 1em;
  line-height: 1;
  text-align: center;
}

/* ---------- chrome card ---------- */

.hero-card-wrap {
  position: relative;
  flex-shrink: 0;
  z-index: 1;
}

.hero-card-stage {
  position: relative;
  width: min(560px, 42vw);
  aspect-ratio: 1 / 1;
}

.hero-card-poster {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 86%;
  aspect-ratio: 3.4 / 2.14;
  height: fit-content;
  border-radius: 8%;
  background: var(--chrome-gradient);
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.5);
  transition: opacity 0.4s ease;
}

.hero-card-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.4s ease;
}

.hero-satellite {
  position:absolute; z-index:3; display:grid; gap:5px; padding:14px 16px;
  border:1px solid rgba(255,255,255,.2); border-radius:15px;
  background:rgba(13,15,19,.68); backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
  box-shadow:0 22px 60px rgba(0,0,0,.48),inset 0 1px rgba(255,255,255,.12);
  transition:transform .45s cubic-bezier(.2,.8,.2,1),border-color .3s;
}
.hero-satellite span,.hero-satellite small { font:var(--t-label-sm)/1.3 var(--mono); color:var(--muted); text-transform:uppercase; letter-spacing:var(--t-label-track-sm); }
.hero-satellite strong { font:600 19px var(--display); color:var(--ink); }
.hero-satellite--balance { left:-8%;top:12%;min-width:150px; }
.hero-satellite--auth { right:-5%;bottom:17%;grid-template-columns:auto 1fr;align-items:center;transform:rotate(2deg); }
.hero-satellite--auth i { grid-row:1/3;width:8px;height:8px;border-radius:50%;background:var(--good);box-shadow:0 3px 10px rgba(143,227,176,.65);margin-right:5px; }
.hero-satellite--auth strong { font-size:14px; }
.hero-satellite--wallet { left:10%;bottom:5%;grid-template-columns:58px auto;align-items:center;transform:rotate(-2deg); }
.hero-satellite--wallet .brand-mark { width:58px;height:28px;grid-row:1; }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .hero-card-wrap:hover .hero-satellite--balance { transform:translate(-8px,-8px) rotate(-2deg); }
  .hero-card-wrap:hover .hero-satellite--auth { transform:translate(8px,-7px) rotate(3deg); }
  .hero-card-wrap:hover .hero-satellite--wallet { transform:translate(-4px,8px) rotate(-3deg); }
}

/* ---------- marquee ---------- */

.marquee {
  overflow: hidden;
  border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
  padding: 22px 0;
}

.marquee-track {
  display: flex;
  width: max-content;
  will-change: transform;
}

.marquee-seq {
  display: flex;
  flex-shrink: 0;
}

.marquee-item {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0 22px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.marquee-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--chrome-gradient);
  flex-shrink: 0;
}

/* ---------- brand marks (Apple Pay / Google Pay) ---------- */

.brand-mark {
  display: block;
  flex-shrink: 0;
  width: auto;
  /* fill="currentColor" on the underlying SVG (BrandMarks.tsx) — this is
     the default for every dark-background usage; .wallet-stage overrides
     it to a dark color for its own white card context. */
  color: #ffffff;
}

.brand-mark--marquee {
  height: 26px;
}

.brand-mark--spec {
  height: 30px;
}

.wallets-value {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
  /* This reuses .figure-value--static (font-size clamp(20px,2vw,26px)) for
     its line-box, sized for secondary text elsewhere — but here it holds
     icons, not text, so that smaller allocation read as visibly shorter
     than the Top tier/Chains odometer figures beside it in the same row.
     Pin the icon height to match their cap-height instead of the
     inherited (irrelevant) font-size.
     Both marks are bare wordmarks now (see BrandMarks.tsx): each one's own
     cropped bbox is taller than its "Pay" text alone, since Apple Pay's box
     also carries the apple glyph above cap-height and Google Pay's box
     carries the full "G" circle. 39px (up from a plain 34px) is what makes
     the "Pay" cap-height in each mark land at the same size as the Top
     tier/Chains odometer digits beside it; margin-top nudges the whole pair
     down so their shared text baseline lands on the odometer baseline
     instead of just top-aligning the boxes (measured against a baseline
     probe span, not eyeballed). */
  height: 39px;
  margin-top: 8px;
}

.wallets-value .brand-mark--spec {
  height: 39px;
}

/* ---------- shared section scaffolding ---------- */

.section-inner {
  max-width: 1360px;
  margin: 0 auto;
  padding: 120px 32px;
  position: relative;
}

.chapter-eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: var(--t-label-track);
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 24px;
}

.section-heading {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(32px, 4vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 20px;
}

.section-heading em {
  font-style: normal;
  color: var(--muted);
}

/* A single, sparing typographic accent for headline emphasis: one italic
   serif word breaking the sans display rhythm, used on 2-3 headlines only
   (never a new default). System serif stack, no extra font load. Separate
   from the standard muted-color em convention above and in
   .details-head h2 em / .control-intro h2 em / .card-mobile h2 em, which
   stays untouched everywhere else. */
.accent-serif {
  font-family: ui-serif, Georgia, serif;
  font-style: italic;
  font-weight: 400;
  color: inherit;
}

.section-lead {
  max-width: 560px;
  color: var(--muted);
  font-size: 17px;
  line-height: 1.6;
  margin: 0 0 56px;
}

.inert {
  color: var(--muted);
  cursor: default;
}

/* ambient radial glow, reused behind the card stages */
.ambient-glow {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(233, 236, 241, 0.07), transparent);
}

/* ---------- sticky stacked panels (section 02, reduced-motion section 03) ---------- */

.stack-group {
  position: relative;
}

.stack-item {
  height: 100svh;
}

.stack-panel {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  background: var(--panel-bg-1);
  border-top: 1px solid transparent;
  overflow: hidden;
}

.stack-panel--2 {
  background: var(--panel-bg-2);
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
  border-top-color: var(--edge);
}

.stack-panel--3 {
  background: var(--panel-bg-3);
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
  border-top-color: var(--edge);
}

.stack-inner {
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 32px;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 64px;
  align-items: center;
}

.stack-copy {
  max-width: 480px;
}

.stack-ghost-n {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(64px, 8vw, 120px);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--edge);
  margin-bottom: 8px;
}

.stack-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(28px, 3vw, 40px);
  color: var(--ink);
  margin: 0 0 16px;
}

.stack-body {
  color: var(--muted);
  font-size: 16px;
  line-height: 1.6;
  margin: 0;
}

/* ---------- product panels (real DOM UI inside section 02) ---------- */

.product-panel {
  border: 1px solid var(--edge);
  border-radius: 16px;
  background: rgba(233, 236, 241, 0.03);
  padding: 24px;
}

.product-panel-label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 18px;
}

.chain-list {
  display: flex;
  flex-direction: column;
  margin-bottom: 20px;
}

.chain-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: 13px;
}

.chain-row:last-child {
  border-bottom: none;
}

.chain-glyph {
  display: flex;
  color: var(--muted);
}

.chain-name {
  color: var(--ink);
  flex: 1;
}

.chain-asset {
  color: var(--muted);
  letter-spacing: 0.04em;
}

.stepper {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--edge);
}

.stepper-row {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
}

.stepper-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--edge);
  flex-shrink: 0;
}

.stepper-row--current {
  color: var(--ink);
}

.stepper-row--current .stepper-dot {
  background: var(--good);
  box-shadow: 0 2px 7px rgba(143, 227, 176, 0.6);
}

.stepper-index {
  font-size: 11px;
  color: var(--muted);
  width: 18px;
  flex-shrink: 0;
}

.stepper--identity .stepper-row {
  color: var(--ink);
}

.verify-pending {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--edge);
}

.verify-pending-top {
  margin-bottom: 14px;
}

.progress-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--edge);
  overflow: hidden;
  margin-bottom: 12px;
}

.progress-bar-fill {
  width: 62%;
  height: 100%;
  background: var(--amber);
}

.verify-pending-note {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 10px;
}

.verify-support {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-decoration: underline;
  text-decoration-color: var(--edge);
}

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  white-space: nowrap;
}

.status-chip--pending {
  color: var(--amber);
  border-color: rgba(233, 196, 106, 0.35);
}

.status-chip--authorized {
  color: var(--amber);
  border-color: rgba(233, 196, 106, 0.35);
}

.status-chip--cleared {
  color: var(--good);
  border-color: rgba(143, 227, 176, 0.35);
}

.status-chip--declined {
  color: var(--bad);
  border-color: rgba(232, 134, 122, 0.35);
}

.tx-list {
  display: flex;
  flex-direction: column;
}

.tx-row {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--edge);
}

.tx-row:last-child {
  border-bottom: none;
}

.tx-row--declined {
  opacity: 0.55;
}

.tx-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--edge);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  flex-shrink: 0;
}

.tx-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.tx-merchant {
  color: var(--ink);
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tx-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.chip {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.chip--category {
  padding: 2px 8px;
  border: 1px solid var(--edge);
  border-radius: 999px;
}

.tx-date {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
}

.tx-amount {
  font-family: var(--mono);
  font-size: 14px;
  white-space: nowrap;
}

.tx-amount--pos {
  color: var(--good);
}

.tx-amount--neg {
  color: var(--ink);
}

.tx-status {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}

.tx-status-note {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
}

/* ---------- section 03: scroll-scrubbed card ---------- */

.card-scroll-wrap {
  position: relative;
  height: 240vh;
}

.card-scroll-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.card-eyebrow {
  position: absolute;
  top: 120px;
  left: 32px;
  margin: 0;
}

.card-glow {
  position: absolute;
  width: min(900px, 90vw);
  height: min(900px, 90vw);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(233, 236, 241, 0.08), transparent);
  pointer-events: none;
}

.card-stage-canvas-wrap {
  position: relative;
  width: min(620px, 60vw);
  aspect-ratio: 1 / 1;
}

.card-stage-poster {
  position: absolute;
}

.card-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: rgba(7, 8, 10, 0.7);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  font-family: var(--display);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
  pointer-events: none;
}

.card-chip--active {
  opacity: 1;
  transform: translateY(0);
}

.card-chip--a {
  bottom: 18%;
  left: 50%;
  translate: -50% 0;
}

.card-chip--b {
  top: 30%;
  right: 8%;
}

.card-chip--c {
  bottom: 22%;
  right: 12%;
}

/* reduced-motion static fallback: three posed panels, no canvas */
.card-static-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 32px;
  width: 100%;
  position: relative;
}

.card-static-poster {
  width: min(420px, 70vw);
  aspect-ratio: 3.4 / 2.14;
  border-radius: 8%;
  background: var(--chrome-gradient);
  box-shadow: 0 40px 80px rgba(0, 0, 0, 0.5);
}

.card-static-poster--wallet {
  transform: rotateY(35deg);
}

.card-static-poster--approved {
  transform: rotateX(28deg);
}

.card-static .card-chip {
  position: static;
  opacity: 1;
  transform: none;
}

.card-mobile { display:none; }

/* ---------- section 04: the app (phone mockup, reuses stack-group/stack-item/
   stack-panel from section 02; only .app-preview-* rules below are new) ---------- */

.app-preview-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 520px;
  perspective: 1400px;
}

.app-preview-glow {
  position: absolute;
  width: min(620px, 72vw);
  height: min(620px, 72vw);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(233, 236, 241, 0.1), transparent);
  pointer-events: none;
  z-index: 0;
}

.app-preview-phone {
  position: relative;
  z-index: 1;
}

/* Real iPhone 17 Pro shell (public/iphone-17-pro.png), supplied by toka and
   keyed out of its source screenshot: the checkerboard was baked in as real
   pixels, so it was removed by colour-keying the two checker greys, and the
   art was cropped to the device. The shell is a transparent-screen overlay
   sitting ABOVE the live UI, so the real Dynamic Island and bezel occlude the
   screen content and the opaque bezel masks the screen's rounded corners for
   free. Its own aspect (2.06) and its screen aperture's aspect (2.168) match
   the real device's 71.9x150mm body and 402x874pt display, which is how the
   frame was confirmed genuine rather than a lookalike.

   The screen aperture was measured from the asset's alpha channel by
   flood-filling the exterior and taking the remaining interior transparent
   region, hence the odd-looking percentages: they are the aperture's real
   position in the artwork, not round numbers. */
.app-preview-phone-frame {
  position: relative;
  width: min(280px, 62vw);
  aspect-ratio: 416 / 857;
  filter:
    drop-shadow(0 60px 90px rgba(0, 0, 0, 0.6))
    drop-shadow(0 20px 34px rgba(0, 0, 0, 0.45));
  transform: perspective(1400px) rotateY(-14deg) rotateX(4deg) rotateZ(-1deg);
  transform-style: preserve-3d;
}

.app-preview-phone-shell {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.app-preview-screen {
  position: absolute;
  left: 4.327%;
  top: 1.75%;
  width: 91.587%;
  height: 96.383%;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 30px 12px 14px;
  border-radius: 7.5% / 3.6%;
  overflow: hidden;
  background: linear-gradient(180deg, var(--panel-bg-1), #050607 130%);
}

.app-preview-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font: 10px var(--mono);
  letter-spacing: 0.04em;
  color: var(--muted);
}

.app-preview-status-icons {
  display: flex;
  gap: 3px;
}

.app-preview-status-icons i {
  display: block;
  width: 3px;
  height: 8px;
  border-radius: 1px;
  background: var(--muted);
}

.app-preview-label {
  font: 10px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.app-preview-balance {
  display: grid;
  gap: 4px;
  padding: 14px;
  border: 1px solid var(--edge);
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.06), transparent 60%), var(--panel-bg-2);
}

.app-preview-figure {
  font: 700 26px var(--display);
  letter-spacing: -0.03em;
  color: var(--ink);
}

.app-preview-sub {
  font: 10px var(--mono);
  color: var(--muted);
}

.app-preview-quick-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.app-preview-quick {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 8px;
  border: 1px solid var(--edge);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink);
}

.app-preview-quick span {
  font: 10px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.app-preview-card {
  position: relative;
  aspect-ratio: 1.586 / 1;
  padding: 16px;
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: var(--ink-on-light);
  background: var(--chrome-gradient);
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.6);
}

.app-preview-card-top,
.app-preview-card-bottom {
  display: flex;
  justify-content: space-between;
}

.app-preview-card-top {
  font: 700 11px var(--display);
  letter-spacing: 0.06em;
}

.app-preview-card-bottom {
  font: 600 11px var(--mono);
  letter-spacing: 0.02em;
}

.app-preview-card-chip {
  width: 28px;
  height: 20px;
  border-radius: 4px;
  background: linear-gradient(135deg, #dfe3ea, #9aa0aa);
}

.app-preview-wallet-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--edge);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
}

.app-preview-wallet-mark {
  width: 34px;
  height: 14px;
  color: var(--ink);
}

.app-preview-wallet-chip span {
  font: 10px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--good);
}

.app-preview-tx-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.app-preview-tx-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.025);
}

.app-preview-tx-row--authorized .app-preview-tx-avatar { background: rgba(233, 196, 106, 0.18); color: var(--amber); }
.app-preview-tx-row--cleared .app-preview-tx-avatar { background: rgba(143, 227, 176, 0.18); color: var(--good); }
.app-preview-tx-row--declined .app-preview-tx-avatar { background: rgba(232, 134, 122, 0.18); color: var(--bad); }

.app-preview-tx-avatar {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font: 11px var(--mono);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.08);
}

.app-preview-tx-main {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.app-preview-tx-main > span:first-child {
  overflow: hidden;
  font: 11px var(--display);
  color: var(--ink);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.app-preview-tx-meta {
  font: 10px var(--mono);
  color: var(--muted);
  text-transform: uppercase;
}

.app-preview-tx-amount {
  flex-shrink: 0;
  font: 600 11px var(--mono);
  color: var(--ink);
}

.app-preview-tx-amount--pos {
  color: var(--good);
}

.app-preview-tabbar {
  display: flex;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--edge);
}

.app-preview-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  color: var(--muted);
}

.app-preview-tab--active {
  color: var(--ink-on-light);
  background: var(--chrome-gradient);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

/* Stage 2: the card pulled out of the phone chrome, a closer/steeper 3D
   float rather than a second phone screenshot. */
.app-preview-card-stage {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  perspective: 1400px;
}

.app-preview-card-float {
  position: relative;
  width: min(340px, 74vw);
  aspect-ratio: 1.586 / 1;
  padding: 26px;
  border-radius: 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: var(--ink-on-light);
  background: var(--chrome-gradient);
  box-shadow:
    0 60px 120px rgba(0, 0, 0, 0.55),
    0 24px 48px rgba(0, 0, 0, 0.4),
    inset 0 1px 1px rgba(255, 255, 255, 0.7);
  transform: perspective(1400px) rotateY(-26deg) rotateX(9deg) rotateZ(-3deg);
  transform-style: preserve-3d;
}

.app-preview-card-float .app-preview-card-top {
  font: 700 15px var(--display);
  letter-spacing: 0.06em;
}

.app-preview-card-float .app-preview-card-bottom {
  font: 600 17px var(--mono);
  letter-spacing: 0.02em;
}

.app-preview-card-float .app-preview-card-chip {
  width: 42px;
  height: 30px;
  border-radius: 6px;
  background: linear-gradient(135deg, #dfe3ea, #9aa0aa);
}

.app-preview-card-stage-wallet {
  transform: perspective(1400px) rotateY(-18deg) rotateX(5deg);
}

/* Stage 3: pulled back from the phone into a cropped, close-up ledger strip,
   no notch or status bar, tilted the opposite way from stage 2's card so the
   three panels never share a silhouette. */
.app-preview-list-stage {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  perspective: 1400px;
}

.app-preview-list-float {
  position: relative;
  width: min(300px, 78vw);
  padding: 24px 20px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.01) 40%, rgba(0, 0, 0, 0.45)), var(--panel-bg-2);
  box-shadow:
    0 50px 100px rgba(0, 0, 0, 0.5),
    0 18px 36px rgba(0, 0, 0, 0.35),
    inset 0 1px 1px rgba(255, 255, 255, 0.35);
  transform: perspective(1400px) rotateY(14deg) rotateX(-5deg) rotateZ(2deg);
  transform-style: preserve-3d;
}

.app-preview-list-float .app-preview-label {
  display: block;
  margin-bottom: 14px;
}

.app-preview-list-float .app-preview-tx-row {
  padding: 10px;
}

.app-preview-list-float .app-preview-tx-main > span:first-child {
  font-size: 12px;
}

.app-preview-list-float .app-preview-tx-amount {
  font-size: 12px;
}

@media (max-width: 900px) {
  .app-preview-stage {
    min-height: 0;
    padding: 24px 0 8px;
  }

  .app-preview-glow {
    width: 380px;
    height: 380px;
  }

  .app-preview-phone-frame {
    width: min(240px, 70vw);
    transform: none;
  }

  .app-preview-card-float {
    width: min(260px, 74vw);
    padding: 20px;
    transform: perspective(1000px) rotateY(-14deg) rotateX(5deg);
  }

  .app-preview-card-stage-wallet {
    transform: perspective(1000px) rotateY(-14deg) rotateX(5deg);
  }

  .app-preview-list-float {
    width: min(280px, 82vw);
    padding: 18px 16px;
    transform: perspective(1000px) rotateY(8deg) rotateX(-3deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-preview-row {
    opacity: 1 !important;
    transform: none !important;
  }

  .app-preview-phone-frame {
    transform: none;
  }

  .app-preview-card-float,
  .app-preview-card-stage-wallet,
  .app-preview-list-float {
    transform: none;
  }
}

/* ---------- section 05: manifesto + statement strip ---------- */

.manifesto-section {
  position: sticky;
  top: 0;
  min-height: 100svh;
  display: flex;
  align-items: center;
  background: var(--bg);
}

/* everything after the pinned manifesto scrolls OVER it (stacked-panel reveal):
   opaque bg + higher paint order, and the incoming panel gets rounded top corners */
.statement-strip,
.spec-section,
.custody-section,
.numbers-section,
.faq-section,
.close-section,
.site-footer {
  position: relative;
  z-index: 1;
  background: var(--bg);
}

.statement-strip {
  border-top-left-radius: 24px;
  border-top-right-radius: 24px;
}

.manifesto-inner {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 32px;
  text-align: center;
}

.manifesto-inner .chapter-eyebrow {
  justify-content: center;
}

.manifesto-sentence {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(28px, 3.2vw, 44px);
  line-height: 1.35;
  color: var(--ink);
  margin: 0;
}

.mask-word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  margin: 0 0.15em 0 0;
}

.mask-word-inner {
  display: inline-block;
  will-change: transform;
}

.mask-word--chip {
  vertical-align: middle;
  margin: 0 0.2em;
}

.pill-chip {
  display: inline-flex;
  align-items: baseline;
  padding: 4px 14px;
  border-radius: 999px;
  background: var(--chrome-gradient);
  color: var(--ink-on-light);
  font-family: var(--mono);
  font-size: 0.6em;
  font-weight: 600;
  vertical-align: middle;
}

.statement-strip {
  position: relative;
  overflow: hidden;
  padding: 40px 0;
  border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
}

.statement-track {
  display: flex;
  width: max-content;
  will-change: transform;
}

.statement-text {
  font-family: var(--display);
  font-weight: 800;
  font-size: 9vw;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(233, 236, 241, 0.5);
  white-space: nowrap;
}

.statement-glass-chip {
  position: absolute;
  top: 50%;
  left: 55%;
  transform: translateY(-50%);
  padding: 20px 26px;
  border-radius: 16px;
  border: 1px solid var(--edge);
  background: rgba(7, 8, 10, 0.5);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.statement-glass-value {
  font-family: var(--display);
  font-weight: 700;
  font-size: 28px;
  color: var(--ink);
  white-space: nowrap;
}

.statement-glass-caption {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 6px;
}

/* ---------- section 07: spec ---------- */

.tier-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  margin-bottom: 64px;
}

.tier-card {
  position: relative;
  border: 1px solid var(--edge);
  border-radius: 20px;
  padding: 32px 28px;
  background: rgba(233, 236, 241, 0.03);
}

.tier-card--featured {
  border-color: rgba(233, 236, 241, 0.28);
  background: rgba(233, 236, 241, 0.05);
}

.tier-flag {
  position: absolute;
  top: -13px;
  left: 28px;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--chrome-gradient);
  color: var(--ink-on-light);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.tier-name {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

.tier-price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 32px;
  color: var(--ink);
  margin-bottom: 8px;
}

.tier-price-suffix {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 400;
  color: var(--muted);
}

.tier-cap {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--muted);
  padding-bottom: 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--edge);
}

.tier-bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 14px;
  color: var(--ink);
}

.fee-table {
  margin-bottom: 64px;
}

.fee-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) repeat(3, 90px);
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--edge);
}

.fee-row--head {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.fee-label {
  color: var(--ink);
  font-size: 14px;
}

.fee-row--head .fee-label {
  color: var(--muted);
}

.fee-col {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  text-align: right;
}

.fee-note {
  max-width: 68ch;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  margin-top: 20px;
  line-height: 1.6;
}

.worked-example {
  border: 1px solid var(--edge);
  border-radius: 16px;
  padding: 28px;
  max-width: 560px;
}

.worked-header {
  font-family: var(--display);
  font-weight: 600;
  font-size: 16px;
  color: var(--ink);
  margin-bottom: 18px;
}

.worked-row {
  display: grid;
  grid-template-columns: 70px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: 13px;
}

.worked-row-label {
  color: var(--muted);
}

.worked-row-note {
  color: var(--muted);
}

.worked-row-value {
  text-align: right;
  color: var(--ink);
}

.worked-row-value--pos {
  color: var(--good);
}

.worked-row--total {
  border-bottom: none;
  padding-top: 16px;
}

.worked-row--total .worked-row-label,
.worked-row--total .worked-row-value {
  color: var(--ink);
  font-weight: 700;
  font-size: 16px;
}

/* ---------- section 08: custody ---------- */

.custody-map {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.custody-map-item {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.custody-node {
  flex: 1;
  border: 1px solid var(--edge);
  border-radius: 16px;
  padding: 24px;
  transition: transform 0.2s ease;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .custody-node:hover {
    transform: translateY(-4px);
  }
}

.custody-node-k {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.custody-node-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  color: var(--ink);
  margin: 0 0 10px;
}

.custody-node-body {
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
  margin: 0 0 16px;
}

.custody-node-who {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
  padding-top: 14px;
  border-top: 1px solid var(--edge);
}

.custody-node-who b {
  color: var(--ink);
  font-weight: 600;
}

.custody-arrow {
  color: var(--muted);
  flex-shrink: 0;
  margin: 0 6px;
}

/* ---------- section 09: numbers ---------- */

.numbers-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}

.numbers-tile {
  border: 1px solid var(--edge);
  border-radius: 16px;
  padding: 32px 28px;
}

.numbers-tile-label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 20px;
}

.numbers-tile-value {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(48px, 5vw, 60px);
  color: var(--ink);
  opacity: 0.18;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin-bottom: 14px;
}

.numbers-tile-caption {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--muted);
}

/* ---------- section 10: faq ---------- */

.faq-list {
  max-width: 760px;
  border-top: 1px solid var(--edge);
}

.faq-row {
  border-bottom: 1px solid var(--edge);
}

.faq-question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 0;
  background: none;
  border: none;
  color: var(--ink);
  font-family: var(--display);
  font-size: 17px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.faq-plus {
  flex-shrink: 0;
  color: var(--muted);
  transform-origin: center;
}

.faq-panel {
  height: 0;
  overflow: hidden;
}

.faq-answer {
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
  margin: 0 0 22px;
  max-width: 640px;
}

/* ---------- section 11: close ---------- */

.close-section {
  min-height: 100svh;
  display: flex;
  align-items: center;
}

.close-inner {
  padding-top: 100px;
  padding-bottom: 100px;
}

.close-stack {
  margin: 0 0 40px;
  display: flex;
  flex-direction: column;
}

.close-word {
  display: block;
  overflow: hidden;
  line-height: 1;
}

.close-word-inner {
  display: block;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(48px, 7vw, 108px);
  letter-spacing: -0.02em;
  color: var(--ink);
  /* This headline sits directly on a photographic chrome texture whose
     bright highlight bands move depending on crop/viewport; the section's
     own scrim gradient handles most of it, but a highlight can still sweep
     under a single word at some widths. A soft dark shadow is cheap
     insurance that guarantees legibility regardless of what's behind it,
     without flattening the letterforms into a hard outline. */
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.55);
  will-change: transform;
}

.close-headline {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(24px, 2.6vw, 34px);
  line-height: 1.3;
  color: var(--ink);
  margin: 0 0 20px;
}

.close-lead {
  max-width: 520px;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.6;
  margin: 0 0 36px;
}

/* ---------- section 12: footer ---------- */

.site-footer {
  border-top: 1px solid var(--edge);
  padding-top: 0;
  overflow: hidden;
}

.site-footer .section-inner {
  padding-bottom: 60px;
}

.footer-columns {
  display: flex;
  gap: 80px;
  margin: 40px 0 60px;
}

.footer-legal {
  display: flex;
  gap: 20px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  padding-top: 24px;
  border-top: 1px solid var(--edge);
}

.footer-wordmark {
  font-family: var(--display);
  font-weight: 800;
  font-size: 18vw;
  line-height: 0.8;
  letter-spacing: -0.02em;
  color: var(--ink);
  opacity: 0.95;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  padding-bottom: 0.04em;
}

/* ---------- reference-led craft pass ---------- */

.btn-chrome,
.btn-ghost {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, 0.26);
  background:
    linear-gradient(135deg, rgba(255,255,255,.22), rgba(255,255,255,.04) 42%, rgba(255,255,255,.12)),
    rgba(20, 23, 28, 0.58);
  backdrop-filter: blur(18px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.42),
    inset 0 -1px 0 rgba(255,255,255,.08),
    0 12px 36px rgba(0,0,0,.32);
}

.btn-chrome::before,
.btn-ghost::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -2px;
  background: linear-gradient(105deg, transparent 18%, rgba(255,255,255,.48) 42%, transparent 66%);
  transform: translateX(-110%);
  transition: transform .65s cubic-bezier(.2,.8,.2,1);
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .btn-chrome:hover,
  .btn-ghost:hover {
    color: #fff;
    border-color: rgba(255,255,255,.46);
    filter: none;
    transform: translateY(-2px);
  }
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .btn-chrome:hover::before,
  .btn-ghost:hover::before { transform: translateX(110%); }
}

.wallets-value .brand-mark { display: inline-block; vertical-align: middle; }

.stack-panel { isolation: isolate; }
.stack-panel::before {
  content: "";
  position: absolute;
  inset: 10% 0 auto 44%;
  width: 56vw;
  height: 56vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(107, 121, 255, .1), transparent 62%);
  filter: blur(10px);
  z-index: -1;
}
.stack-panel--2::before { background: radial-gradient(circle, rgba(233,196,106,.09), transparent 62%); }
.stack-panel--3::before { background: radial-gradient(circle, rgba(143,227,176,.1), transparent 62%); }

.stack-inner { grid-template-columns: .72fr 1.28fr; gap: clamp(48px, 7vw, 120px); }
.stack-copy { align-self: end; padding-bottom: 10vh; }
.stack-ghost-n {
  position: absolute;
  top: 9vh;
  left: 32px;
  font-size: clamp(100px, 18vw, 280px);
  opacity: .55;
  z-index: -1;
}
.stack-title { font-size: clamp(48px, 6vw, 92px); letter-spacing: -.045em; line-height: .9; }
.stack-body { max-width: 430px; font-size: 17px; }

.product-stage { position: relative; padding: 54px 38px; }
.product-orbit {
  position: absolute;
  border: 1px solid rgba(233,236,241,.1);
  border-radius: 50%;
  pointer-events: none;
}
.product-orbit--a { inset: 0 5%; }
.product-orbit--b { inset: 12% -3%; opacity:.45; }

.product-panel {
  position: relative;
  z-index: 2;
  padding: 0;
  border-color: rgba(255,255,255,.17);
  border-radius: 28px;
  background:
    linear-gradient(145deg, rgba(255,255,255,.09), rgba(255,255,255,.018) 42%),
    rgba(8,10,13,.76);
  backdrop-filter: blur(24px) saturate(1.35);
  -webkit-backdrop-filter: blur(24px) saturate(1.35);
  box-shadow: 0 40px 100px rgba(0,0,0,.46), inset 0 1px 0 rgba(255,255,255,.13);
  overflow: visible;
  transform: perspective(1000px) rotateY(-3deg);
}
.product-panel--verify { transform: perspective(1000px) rotateY(3deg); }
.product-panel-top {
  height: 58px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--edge);
}
.product-panel-label { margin: 0; color: var(--ink); }
.live-indicator, .secure-mark {
  font: 11px/1 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.live-indicator i {
  display: inline-block; width: 6px; height: 6px; margin-right: 7px;
  border-radius: 50%; background: var(--good); box-shadow: 0 2px 8px rgba(143,227,176,.65);
}
.panel-balance { padding: 26px 24px 20px; display: grid; gap: 2px; }
.panel-balance span, .panel-balance small { font: var(--t-label-sm)/1.5 var(--mono); letter-spacing: var(--t-label-track-sm); color: var(--muted); }
/* -.04em collided at this specific size/weight: "8", "4" and "0" overlapped
   ("$12,840" read as smeared ink at the 700-weight/54px ceiling). Tabular
   digits at this display weight need less negative tracking than letterforms
   do; -.015em keeps the tight display feel without the digits touching. */
.panel-balance strong { font: 700 clamp(34px,4vw,54px)/1 var(--display); letter-spacing: -.015em; }
.chain-list, .stepper, .stepper--identity, .verify-pending, .tx-list { margin-left: 24px; margin-right: 24px; }
.chain-list { display:grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-bottom: 20px; }
.chain-row {
  min-height: 76px; padding: 12px 8px; border: 1px solid var(--edge)!important; border-radius: 12px;
  flex-direction: column; align-items: flex-start; gap: 6px; background: var(--surface-1);
}
.chain-name { font-size: 11px; }
.chain-asset { font-size: 11px; }
.stepper { margin-bottom: 24px; }
.identity-card {
  display: grid; grid-template-columns: 48px 1fr auto; align-items:center; gap: 14px;
  margin: 24px; padding: 16px; border-radius: 16px; background: rgba(255,255,255,.05);
}
.identity-avatar {
  width:48px; height:48px; border-radius: 50%; display:grid; place-items:center;
  font: 12px var(--mono); background: linear-gradient(135deg,#dce0e7,#5d626c); color:#090a0c;
}
.identity-card div:nth-child(2) { display:grid; gap:4px; }
.identity-card strong { font-size: 14px; }
.identity-card span { font: 11px var(--mono); color: var(--muted); }
.identity-card i { font: 12px var(--mono); color: var(--amber); font-style: normal; }
.verify-pending { padding-bottom: 24px; }
.spend-summary { display:grid; grid-template-columns:1fr 1fr; gap:1px; margin: 0 24px; background:var(--edge); }
.spend-summary div { display:grid; gap:5px; padding:18px; background:#0b0d11; }
.spend-summary span { font:11px var(--mono); color:var(--muted); text-transform:uppercase; }
.spend-summary strong { font:700 25px var(--display); }
.tx-list { margin-top: 12px; padding-bottom: 16px; }
.floating-receipt {
  position:relative;z-index:4;display:grid;grid-template-columns:1fr auto;align-items:center;gap:16px;
  min-width:0;margin:0 24px 22px;padding:15px 18px;overflow:hidden;
  border:1px solid rgba(255,255,255,.58);border-radius:16px;
  color:#090b0e;
  background:
    radial-gradient(circle at 78% 10%,rgba(171,181,255,.82),transparent 27%),
    radial-gradient(circle at 14% 118%,rgba(255,255,255,.98),transparent 42%),
    linear-gradient(120deg,#6c727d 0%,#f6f8fb 18%,#838a96 37%,#e9edf2 55%,#5c626d 76%,#f6f7f9 100%);
  box-shadow:
    0 22px 52px rgba(0,0,0,.38),
    inset 0 1px 1px rgba(255,255,255,.92),
    inset 0 -1px 1px rgba(29,32,38,.35);
  transition:transform .4s cubic-bezier(.2,.8,.2,1),box-shadow .4s;
}
.floating-receipt::before {
  content:"";position:absolute;inset:-80% -12%;pointer-events:none;
  background:linear-gradient(108deg,transparent 36%,rgba(255,255,255,.75) 48%,transparent 61%);
  transform:translateX(-48%) rotate(-7deg);transition:transform .8s cubic-bezier(.2,.8,.2,1);
}
.floating-receipt::after {
  content:"";position:absolute;inset:1px;border-radius:15px;pointer-events:none;
  box-shadow:inset 0 0 22px rgba(255,255,255,.28);
}
.floating-receipt span,.floating-receipt strong { position:relative;z-index:1; }
.floating-receipt span { font:11px var(--mono);color:rgba(9,11,14,.62);text-transform:uppercase;letter-spacing:.1em; }
.floating-receipt strong { font:700 15px var(--display);color:#090b0e;text-align:right; }
.floating-receipt--deposit,.floating-receipt--verify,.floating-receipt--spend { inset:auto; }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .product-stage:hover .floating-receipt { transform:translateY(-4px);box-shadow:0 28px 62px rgba(0,0,0,.46),inset 0 1px 1px rgba(255,255,255,.92); }
  .product-stage:hover .floating-receipt::before { transform:translateX(48%) rotate(-7deg); }
}

.card-stage-canvas-wrap { width: min(760px, 68vw); }
.card-stage-copy { position:absolute; left:7vw; top:50%; transform:translateY(-50%); display:grid; z-index:2; pointer-events:none; }
.card-stage-copy span { font:11px var(--mono); color:var(--muted); text-transform:uppercase; letter-spacing:.12em; }
.card-stage-copy strong { margin-top:12px; font:700 clamp(34px,4vw,64px)/.95 var(--display); letter-spacing:-.04em; }
.card-progress { position:absolute; right:32px; top:50%; display:grid; gap:8px; }
.card-progress i { width:3px; height:38px; border-radius:4px; background:var(--edge); transition:background .3s, box-shadow .3s; }
.card-progress i.active { background:var(--ink); box-shadow:0 0 18px rgba(233,236,241,.45); }
.card-stories { position:absolute; right:7vw; top:50%; width:min(300px,24vw); height:180px; transform:translateY(-50%); z-index:3; }
.card-story { position:absolute; inset:0; display:grid; align-content:center; opacity:0; transform:translateY(28px); transition:opacity .5s,transform .65s cubic-bezier(.2,.8,.2,1); pointer-events:none; }
.card-story--active { opacity:1; transform:translateY(0); }
.card-story>span { font:11px var(--mono); color:var(--muted); letter-spacing:.12em; }
.card-story h3 { margin:12px 0 10px; font:700 clamp(28px,3.2vw,52px)/.95 var(--display); letter-spacing:-.04em; }
.card-story p { margin:0; color:var(--muted); font-size:14px; line-height:1.55; }
.card-chip { border-color:rgba(255,255,255,.2); background:rgba(18,21,26,.68); box-shadow:0 14px 45px rgba(0,0,0,.38), inset 0 1px rgba(255,255,255,.1); }

.manifesto-section { overflow:hidden; }
.manifesto-section::before {
  content:""; position:absolute; width:72vw; height:72vw; border-radius:50%;
  background:radial-gradient(circle,rgba(114,129,255,.12),transparent 64%);
  filter:blur(18px);
}
.manifesto-inner { max-width:1180px; width:100%; }
.manifesto-kicker { margin-bottom:36px; font:600 clamp(18px,2vw,26px) var(--display); color:var(--muted); }
.manifesto-sentence { font-size:clamp(38px,5vw,76px); line-height:1.08; letter-spacing:-.045em; }
.pill-chip {
  color:var(--ink); background:rgba(255,255,255,.09); border:1px solid rgba(255,255,255,.24);
  box-shadow:inset 0 1px rgba(255,255,255,.24),0 12px 30px rgba(0,0,0,.35);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
}
.manifesto-values { display:grid; grid-template-columns:.72fr 1.28fr; gap:12px; max-width:760px; margin:48px auto 0; text-align:left; }
.manifesto-value-card { display:grid; gap:8px; padding:20px 22px; border:1px solid var(--edge); border-radius:18px; background:var(--surface-2); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); box-shadow:inset 0 1px rgba(255,255,255,.1); }
.manifesto-value-card span,.manifesto-value-card small { font:var(--t-label-sm)/1.4 var(--mono); color:var(--muted); text-transform:uppercase; letter-spacing:var(--t-label-track-sm); }
.manifesto-value-card strong { font:700 clamp(24px,3vw,38px)/1 var(--display); letter-spacing:-.035em; }
.manifesto-value-card--cap { background:linear-gradient(130deg,rgba(255,255,255,.12),var(--surface-1)); }
.manifesto-proof { display:grid; grid-template-columns:repeat(3,1fr); margin-top:64px; border-top:1px solid var(--edge); text-align:left; }
.manifesto-proof div { display:grid; grid-template-columns:auto 1fr; gap:4px 16px; padding:20px; border-right:1px solid var(--edge); }
.manifesto-proof div:last-child { border-right:0; }
.manifesto-proof span { grid-row:1/3; font:11px var(--mono); color:var(--muted); }
.manifesto-proof strong { font-size:14px; }
.manifesto-proof small { font:11px var(--mono); color:var(--muted); }
.statement-glass-chip { overflow:hidden; min-width:270px; border-color:rgba(255,255,255,.26); background:linear-gradient(135deg,rgba(255,255,255,.18),rgba(255,255,255,.03)),rgba(7,8,10,.58); }
.statement-glass-chip {
  left:50%;transform:translate(-50%,-50%);min-width:330px;padding:24px 30px;text-align:center;
  border-color:rgba(255,255,255,.64);
  background:
    radial-gradient(circle at 78% 12%,rgba(173,181,255,.9),transparent 28%),
    radial-gradient(circle at 18% 120%,rgba(255,255,255,1),transparent 42%),
    linear-gradient(120deg,#5c626d 0%,#f7f9fb 17%,#7c838f 36%,#eef1f4 55%,#515762 77%,#f5f6f8 100%);
  box-shadow:0 26px 70px rgba(0,0,0,.55),inset 0 1px 1px rgba(255,255,255,.95),inset 0 -1px 1px rgba(18,20,24,.4);
}
.statement-glass-chip::before { content:"";position:absolute;inset:1px;border-radius:15px;box-shadow:inset 0 0 30px rgba(255,255,255,.28);pointer-events:none; }
.statement-glass-chip::after { content:""; position:absolute; inset:-60%; background:linear-gradient(110deg,transparent 42%,rgba(255,255,255,.8),transparent 58%); transform:translateX(-42%); transition:transform .85s cubic-bezier(.2,.8,.2,1); }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .statement-strip:hover .statement-glass-chip::after { transform:translateX(42%); }
}
.statement-glass-index { position:relative; z-index:1; font:11px var(--mono); letter-spacing:.16em; color:rgba(9,11,14,.58); }
.statement-glass-value,.statement-glass-caption { position:relative; z-index:1; }
.statement-glass-value { color:#090b0e; }
.statement-glass-caption { color:rgba(9,11,14,.62); }

/* ---------- dimensional glass system ---------- */

.product-panel,
.control-device,
.manifesto-value-card,
.custody-map,
.custody-node {
  border-color:rgba(255,255,255,.18);
  box-shadow:
    0 34px 90px rgba(0,0,0,.34),
    inset 0 1px 0 rgba(255,255,255,.18),
    inset 0 -1px 0 rgba(255,255,255,.035);
}
.control-device {
  background:
    radial-gradient(circle at 78% 5%,rgba(160,169,255,.11),transparent 28%),
    linear-gradient(145deg,rgba(255,255,255,.12),rgba(255,255,255,.018) 38%),
    rgba(12,14,18,.92);
}
.manifesto-value-card,
.custody-node {
  background:
    radial-gradient(circle at 82% 0,rgba(146,158,255,.11),transparent 38%),
    linear-gradient(145deg,rgba(255,255,255,.075),rgba(255,255,255,.018) 52%),
    rgba(8,10,13,.76)!important;
}
.control-actions>div,
.card-controls button,
.card-controls>div,
.wallet-provisioned,
.deposit-route,
.activity-receipt {
  border-color:rgba(255,255,255,.14);
  background:linear-gradient(145deg,rgba(255,255,255,.075),rgba(255,255,255,.018));
  box-shadow:inset 0 1px rgba(255,255,255,.1),0 13px 28px rgba(0,0,0,.18);
}
.detail-card,
.spec-section .tier-card,
.spec-section .worked-example,
.spec-section .fee-table {
  border:1px solid var(--paper-edge);
  box-shadow:
    0 34px 80px rgba(31,35,41,.1),
    inset 0 1px 0 rgba(255,255,255,.82),
    inset 0 -1px 0 rgba(17,19,23,.06);
}
.detail-card {
  background-image:
    radial-gradient(circle at 84% -5%,rgba(255,255,255,.72),transparent 33%),
    linear-gradient(145deg,rgba(255,255,255,.24),rgba(255,255,255,.015) 55%);
  background-blend-mode:soft-light,normal;
}
.detail-card--hold {
  background:
    radial-gradient(circle at 85% 0,rgba(145,158,255,.13),transparent 34%),
    linear-gradient(145deg,#171a20,#0e1014 62%);
}
.detail-card--funding {
  background:
    radial-gradient(circle at 82% 2%,rgba(255,255,255,.72),transparent 32%),
    linear-gradient(145deg,#d9dcff,#aeb5ff 58%,#ececff);
}
.detail-card--wallet { background:linear-gradient(145deg,rgba(255,255,255,.94),rgba(232,232,226,.82)); }
.detail-card--receipt {
  background:
    radial-gradient(circle at 82% 0,rgba(255,255,255,.48),transparent 34%),
    linear-gradient(140deg,#f2dfab,#c69e55);
}
.spec-section .tier-card {
  background:
    radial-gradient(circle at 82% 0,rgba(255,255,255,.88),transparent 35%),
    linear-gradient(145deg,rgba(255,255,255,.68),rgba(255,255,255,.24));
}
.spec-section .tier-card--featured {
  background:
    radial-gradient(circle at 80% 0,rgba(151,162,255,.14),transparent 34%),
    linear-gradient(145deg,#1a1d23,#0d0f13 62%);
  box-shadow:0 42px 90px rgba(30,32,37,.22),inset 0 1px rgba(255,255,255,.17);
}
.spec-section .worked-example,
.spec-section .fee-table {
  border-radius:26px;background:linear-gradient(145deg,rgba(255,255,255,.72),rgba(255,255,255,.3));
}
.spec-section .fee-table { padding:10px 24px 2px; }
.faq-list { display:grid;gap:10px;border-top:0; }
.faq-row {
  padding:0 22px;border:1px solid rgba(255,255,255,.13);border-radius:18px;
  background:
    radial-gradient(circle at 88% 0,rgba(145,158,255,.08),transparent 32%),
    linear-gradient(145deg,rgba(255,255,255,.055),rgba(255,255,255,.014));
  box-shadow:0 18px 45px rgba(0,0,0,.18),inset 0 1px rgba(255,255,255,.09);
  transition:border-color .25s,background-color .25s;
}
/* The FAQ rows were the one card-shaped control on the page with no hover at
   all. Quieter than .detail-card's -8px lift, which is right for a list: the
   edge catches light and the plus brightens, no movement, so a row does not
   jump under the cursor while the reader is scanning down the stack. */
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .faq-row:hover { border-color:rgba(255,255,255,.26);background-color:rgba(255,255,255,.03); }
}
.faq-plus { transition:color .25s; }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .faq-row:hover .faq-plus { color:var(--ink); }
}
.details-section,.spec-section,.custody-section,.numbers-section,.faq-section { overflow:clip; }

/* ---------- interactive product control center ---------- */

.control-section {
  position:relative; z-index:2; height:300svh;
  overflow:visible;
  background:radial-gradient(circle at 72% 48%,rgba(120,135,255,.12),transparent 32%),#090a0d;
}
.control-sticky {
  position:sticky;top:0;height:100svh;display:grid;
  grid-template-columns:minmax(320px,.72fr) minmax(500px,1.28fr);
  gap:clamp(54px,8vw,130px);align-items:center;
  /* +32px on the wide-viewport term: .section-inner/.stack-inner (the
     sections directly above and below this one) center a 1360px box via
     margin:auto and THEN add their own 32px padding on top, landing content
     at 72px from the viewport edge at 1440px. This formula only did the
     centering half (40px at 1440), so this section's heading sat 32px to
     the left of Spec's heading right below it. The +32px makes the two
     match at every width above the 1360px content cap; below it, both
     still floor out at the same 32px. */
  padding:clamp(70px,8vw,110px) max(32px,calc((100vw - 1360px)/2 + 32px));
  overflow:hidden;
}
.control-sticky::after {
  content:"";position:absolute;z-index:-1;right:-12vw;top:4%;width:66vw;height:66vw;border-radius:50%;
  border:1px solid rgba(255,255,255,.06);
  box-shadow:0 0 0 8vw rgba(255,255,255,.012),0 0 0 16vw rgba(255,255,255,.008);
}
.control-intro h2 { margin:0 0 24px;font:800 clamp(50px,6.2vw,96px)/.9 var(--display);letter-spacing:-.055em; }
.control-intro h2 em { font-style:normal;color:var(--muted); }
.control-intro>p:not(.chapter-eyebrow) { max-width:510px;margin:0 0 44px;color:var(--muted);font-size:17px;line-height:1.6; }
.control-tabs { display:grid;border-top:1px solid var(--edge); }
.control-tabs::after {
  content:"";height:1px;width:var(--control-progress,0%);margin-top:-1px;
  background:linear-gradient(90deg,#fff,rgba(143,152,255,.7));
  box-shadow:0 0 14px rgba(143,152,255,.45);
}
/* The active tab's 18px indent is reserved permanently rather than animated
   via padding: animating padding relayouts the row on every tab change, and
   animating a transform instead would carry the button's own border-bottom
   out of alignment with its siblings. Reserving the space means only the
   accent bar animates (transform: scaleX, compositor-only) and the label
   text no longer jumps sideways when a tab is selected. */
.control-tabs button {
  position:relative;display:grid;grid-template-columns:1fr auto;align-items:center;gap:16px;
  min-height:72px;padding:0 4px 0 18px;border:0;border-bottom:1px solid var(--edge);background:none;color:var(--muted);
  text-align:left;cursor:pointer;transition:color .25s;
}
.control-tabs button::before { content:"";position:absolute;left:0;top:50%;width:8px;height:2px;margin-top:-1px;background:var(--ink);transform:scaleX(0);transform-origin:left;transition:transform .35s cubic-bezier(.2,.8,.2,1); }
.control-tabs button.active { color:var(--ink); }
.control-tabs button.active::before { transform:scaleX(1); }
/* Hover previews the selected state rather than inventing a second language:
   the same ink colour the active tab takes, and the same accent bar at part
   extension. Both properties already carry their transitions above, so this
   costs no new animation. */
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .control-tabs button:hover:not(.active) { color:var(--ink); }
  .control-tabs button:hover:not(.active)::before { transform:scaleX(.45); }
}
.control-tabs button span { font:600 19px var(--display); }
.control-tabs button small { font:11px var(--mono);color:var(--muted); }
.control-device {
  position:relative;width:100%;min-height:680px;border:1px solid rgba(255,255,255,.17);
  border-radius:42px;padding:20px;background:linear-gradient(150deg,rgba(255,255,255,.11),rgba(255,255,255,.02) 28%),#0d0f13;
  box-shadow:0 70px 140px rgba(0,0,0,.6),inset 0 1px rgba(255,255,255,.15);
  transform:perspective(1400px) rotateX(var(--device-rx,0deg)) rotateY(var(--device-ry,0deg));
  transition:transform .18s ease-out;
}
.control-device-shell { justify-self:center;width:min(640px,100%);perspective:1400px; }
.control-device-bar { height:42px;display:flex;align-items:center;justify-content:space-between;padding:0 10px;font:11px var(--mono);color:var(--muted); }
.control-device-bar strong { color:var(--ink);letter-spacing:.08em; }
.control-view-wrap { min-height:566px;border:1px solid var(--edge);border-radius:28px;background:#090b0e;overflow:hidden;animation:view-in .55s cubic-bezier(.2,.8,.2,1); }
@keyframes view-in { from { opacity:0;transform:translateY(16px) scale(.985); } }
.control-view { min-height:566px;padding:30px; }
.control-balance { display:grid;gap:6px;padding:14px 2px 28px; }
.control-balance span,.control-balance small { font:var(--t-label-sm)/1.4 var(--mono);color:var(--muted);text-transform:uppercase;letter-spacing:var(--t-label-track-sm); }
.control-balance strong { font:700 clamp(48px,6vw,72px)/1 var(--display);letter-spacing:-.055em; }
.control-actions { display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:24px; }
.control-actions>div,.card-controls button,.card-controls>div {
  min-height:76px;border:1px solid var(--edge);border-radius:16px;background:var(--surface-2);color:var(--ink);
  display:grid;place-items:center;gap:6px;font:11px var(--mono);transition:background .25s,transform .25s;
}
.card-controls button { cursor:pointer; }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .card-controls button:hover { background:rgba(255,255,255,.09);transform:translateY(-2px); }
}
.control-actions i,.card-controls i { font:normal 20px var(--display); }
.deposit-route { padding:20px;border:1px solid var(--edge);border-radius:18px;background:var(--surface-1); }
.deposit-route-head,.deposit-route-foot { display:flex;align-items:center;justify-content:space-between;gap:16px; }
.deposit-route-head>div { display:grid;gap:4px; }
.deposit-route-head span,.deposit-route-foot span { font:11px var(--mono);color:var(--muted); }
.deposit-route-head strong,.deposit-route-foot strong { font-size:14px; }
.confirmation-track { display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin:24px 0; }
.confirmation-track i { height:4px;border-radius:4px;background:var(--good);box-shadow:0 3px 10px rgba(143,227,176,.3); }
.confirmation-track i.pending { background:var(--edge);box-shadow:none; }
.account-mini-grid { display:grid;grid-template-columns:repeat(3,1fr);gap:1px;margin-top:22px;background:var(--edge); }
.account-mini-grid div { display:grid;gap:6px;padding:17px;background:#0a0c0f; }
.account-mini-grid span { font:11px var(--mono);color:var(--muted);text-transform:uppercase; }
.account-mini-grid strong { font:600 13px var(--display); }
.control-view--card { display:grid;grid-template-columns:1.05fr .95fr;gap:18px;align-content:center; }
.control-card-visual {
  position:relative;grid-row:span 2;aspect-ratio:1.58;border-radius:22px;padding:24px;color:#090a0c;
  background:linear-gradient(145deg,#f4f5f7,#777d87 48%,#d8dce2);box-shadow:0 30px 60px rgba(0,0,0,.48);overflow:hidden;
}
.control-card-visual::before { content:"";position:absolute;inset:-60% 28%;background:rgba(255,255,255,.45);transform:rotate(28deg);filter:blur(15px); }
.control-card-visual.frozen { filter:saturate(.15) brightness(.7); }
.control-card-visual.frozen .control-card-state i { background:var(--bad); }
.control-card-brand,.control-card-number,.control-card-state,.control-card-chip { position:absolute;z-index:1; }
.control-card-brand { top:24px;right:24px;font:700 12px var(--display); }
.control-card-chip { top:42%;left:24px;width:42px;height:31px;border-radius:7px;background:linear-gradient(135deg,#eee3be,#907b42); }
.control-card-number { left:24px;bottom:24px;font:13px var(--mono);letter-spacing:.12em; }
.control-card-state { right:24px;bottom:24px;font:11px var(--mono); }
.control-card-state i { display:inline-block;width:6px;height:6px;margin-right:6px;border-radius:50%;background:#246b40; }
.wallet-provisioned { display:grid;grid-template-columns:68px 1fr auto;align-items:center;gap:12px;padding:18px;border:1px solid var(--edge);border-radius:17px;background:var(--surface-2); }
.wallet-provisioned .brand-mark { width:68px;height:28px; }
.wallet-provisioned>div { display:grid;gap:4px; }
.wallet-provisioned strong { font-size:13px; }
.wallet-provisioned span { font:11px var(--mono);color:var(--muted); }
.wallet-provisioned>i { font-style:normal;color:var(--good); }
.card-controls { display:grid;grid-template-columns:repeat(3,1fr);gap:9px;grid-column:1/-1; }
.card-controls button,.card-controls>div { min-height:92px; }
.card-controls span { font:11px var(--mono); }
.control-note { grid-column:1/-1;font:12px/1.5 var(--mono);color:var(--muted);padding:4px; }
.activity-merchant { display:grid;grid-template-columns:54px 1fr auto;align-items:center;gap:14px;padding-bottom:24px;border-bottom:1px solid var(--edge); }
.activity-mark { width:54px;height:54px;border-radius:17px;display:grid;place-items:center;background:linear-gradient(145deg,#dfd1ac,#665a3d);color:#111;font:700 15px var(--display); }
.activity-merchant>div:nth-child(2) { display:grid;gap:5px; }
.activity-merchant span { font:11px var(--mono);color:var(--muted); }
.activity-merchant>strong { font:700 20px var(--display); }
.lifecycle { position:relative;margin:26px 0; }
.lifecycle::before { content:"";position:absolute;left:6px;top:20px;bottom:20px;width:1px;background:var(--edge); }
.lifecycle-row { position:relative;display:grid;grid-template-columns:14px 1fr auto;gap:15px;align-items:center;padding:16px 0; }
.lifecycle-row>i { z-index:1;width:13px;height:13px;border:3px solid #090b0e;border-radius:50%;background:var(--good);box-shadow:0 0 0 1px var(--good); }
.lifecycle-row>div { display:grid;gap:4px; }
.lifecycle-row strong { font-size:14px; }
.lifecycle-row span { font:11px var(--mono);color:var(--muted); }
.lifecycle-row>span { font-size:12px;color:var(--ink); }
.lifecycle-row>span.positive { color:var(--good); }
.activity-receipt { display:grid;grid-template-columns:1fr auto;gap:13px;padding:20px;border-radius:16px;background:var(--surface-2);font:11px var(--mono); }
.activity-receipt span { color:var(--muted); }
.activity-receipt strong { text-align:right; }
.control-device-nav { height:48px;display:flex;align-items:center;justify-content:center;gap:16px; }
.control-device-nav i { width:5px;height:5px;border-radius:50%;background:var(--edge); }
.control-device-nav i.active { width:20px;border-radius:5px;background:var(--ink); }

/* ---------- product-detail bento ---------- */

.details-section {
  position:relative;z-index:3;
  /* Same +32px correction as .control-sticky above: this section's
     immediate neighbours (the stack sections above, .section-inner below)
     both land content 72px from the viewport edge at 1440px; this formula
     was missing the extra 32px padding those containers add on top of
     their centering margin, so "The states other cards leave unexplained."
     sat 32px left of every heading around it. */
  padding:clamp(110px,11vw,170px) max(32px,calc((100vw - 1360px)/2 + 32px));
  color:var(--paper-ink);background:var(--paper);overflow:hidden;
}
.details-head { display:grid;grid-template-columns:1.2fr .55fr;column-gap:clamp(40px,9vw,140px);align-items:end;margin-bottom:70px; }
.details-head .chapter-eyebrow { grid-column:1/-1;color:var(--paper-muted); }
.details-head h2 { margin:0;font:800 clamp(54px,7vw,108px)/.86 var(--display);letter-spacing:-.06em; }
.details-head h2 em { color:var(--paper-muted);font-style:normal; }
.details-head>p:last-child { max-width:400px;margin:0 0 8px;color:var(--paper-muted);font-size:17px;line-height:1.58; }
.details-grid { display:grid;grid-template-columns:repeat(12,1fr);gap:14px; }
.details-grid,.tier-grid,.custody-map,.product-stage,.control-sticky { perspective:1400px; }
.detail-card,.tier-card,.custody-node,.product-stage,.control-device-shell { transform-style:preserve-3d; }
.detail-card {
  position:relative;min-height:520px;padding:34px;border:1px solid var(--paper-edge);
  border-radius:30px;background:rgba(255,255,255,.52);overflow:hidden;
  box-shadow:0 25px 80px rgba(24,28,34,.07);
  transition:transform .5s cubic-bezier(.2,.8,.2,1),box-shadow .5s,border-color .35s;
}
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .detail-card:hover { transform:translateY(-8px);box-shadow:0 40px 90px rgba(24,28,34,.12);border-color:var(--paper-edge-strong); }
}
.detail-card-copy { position:relative;z-index:2;max-width:560px; }
.detail-card-copy>span { font:11px var(--mono);text-transform:uppercase;letter-spacing:.1em;color:var(--paper-muted); }
.detail-card-copy h3 { margin:13px 0 12px;font:700 clamp(30px,3vw,48px)/.96 var(--display);letter-spacing:-.045em; }
.detail-card-copy p { max-width:470px;margin:0;color:var(--paper-muted);font-size:15px;line-height:1.55; }
.detail-card--hold { grid-column:span 7;background:var(--paper-ink);color:var(--ink);border-color:var(--paper-ink); }
.detail-card--funding { grid-column:span 5;background:linear-gradient(145deg,#d9dcff,#b3b9ff 58%,#ebebff); }
.detail-card--wallet { grid-column:span 5;min-height:520px;background:#f3f3ef; }
.detail-card--receipt { grid-column:span 7;min-height:520px;background:linear-gradient(140deg,#f2dfab,#c69e55); }
.detail-card--hold .detail-card-copy>span,.detail-card--hold .detail-card-copy p { color:rgba(240,241,243,.52); }
.hold-ui {
  position:absolute;left:34px;right:34px;bottom:34px;display:grid;grid-template-columns:1fr 1fr;
  border:1px solid rgba(255,255,255,.12);border-radius:20px;background:var(--surface-2);overflow:hidden;
}
.hold-ui>div:not(.hold-merchant) { display:grid;gap:8px;padding:22px;border-right:1px solid rgba(255,255,255,.1); }
.hold-ui>div:nth-child(2) { border-right:0; }
.hold-ui span,.hold-ui small { font:var(--t-label-sm)/1.4 var(--mono);letter-spacing:var(--t-label-track-sm);color:var(--muted); }
.hold-ui>div>strong { font:700 28px var(--display); }
.hold-merchant { grid-column:1/-1;display:grid;grid-template-columns:48px 1fr auto;align-items:center;gap:14px;padding:18px 22px;border-top:1px solid rgba(255,255,255,.1); }
.hold-merchant i { width:48px;height:48px;display:grid;place-items:center;border-radius:15px;background:#d9c9a3;color:#161719;font:700 13px var(--display);font-style:normal; }
.hold-merchant>span { display:grid;gap:5px;color:#f0f1f3;font:600 14px var(--display); }
.hold-merchant small { display:block; }
.hold-merchant>strong { font:700 18px var(--display); }
.network-orbit {
  position:absolute;left:50%;top:59%;width:260px;aspect-ratio:1;transform:translate(-50%,-50%);
  border:1px solid var(--paper-edge);border-radius:50%;
  box-shadow:0 0 0 46px rgba(255,255,255,.14),0 0 0 47px rgba(17,19,23,.07);
}
.network-orbit>strong { position:absolute;inset:50% auto auto 50%;transform:translate(-50%,-50%);display:grid;place-items:center;width:96px;aspect-ratio:1;border-radius:50%;background:var(--paper-ink);color:#fff;font:700 18px var(--display);box-shadow:0 18px 35px rgba(34,36,55,.25); }
.network-orbit>i {
  --angle:calc(var(--i) * 72deg);position:absolute;left:calc(50% + cos(var(--angle)) * 130px);top:calc(50% + sin(var(--angle)) * 130px);
  width:42px;aspect-ratio:1;display:grid;place-items:center;transform:translate(-50%,-50%);border-radius:50%;
  background:rgba(255,255,255,.82);border:1px solid var(--paper-edge);font:700 12px var(--display);font-style:normal;
}
.funding-failure { position:absolute;z-index:2;left:26px;right:26px;bottom:24px;display:grid;gap:4px;padding:16px 18px;border:1px solid var(--paper-edge);border-radius:15px;background:rgba(255,255,255,.78);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px); }
.funding-failure span,.funding-failure small { font:11px/1.4 var(--mono);color:var(--paper-muted); }
.funding-failure strong { font-size:13px; }
.wallet-stage { position:absolute;left:34px;right:34px;bottom:34px;display:grid;gap:10px; }
.wallet-stage>div { min-height:76px;display:grid;grid-template-columns:112px 1fr;align-items:center;padding:0 22px;border:1px solid var(--paper-edge);border-radius:19px;background:#fff;box-shadow:0 14px 30px rgba(20,22,26,.06); }
.wallet-stage .brand-mark { width:96px;height:32px;color:var(--paper-ink); }
.wallet-stage span { justify-self:end;font:11px var(--mono);color:#247342; }
.receipt-lines { position:absolute;left:34px;right:34px;bottom:34px;display:grid;grid-template-columns:1fr auto;gap:0;padding:8px 22px;border-radius:20px;background:rgba(30,25,15,.9);color:#f5ecd8;box-shadow:0 25px 45px rgba(73,50,14,.22); }
.receipt-lines>div { display:contents; }
.receipt-lines span,.receipt-lines strong { padding:14px 0;border-bottom:1px solid rgba(255,255,255,.1);font:11px var(--mono); }
.receipt-lines strong { text-align:right; }
.receipt-lines>div:last-child span,.receipt-lines>div:last-child strong { border-bottom:0;font-size:14px;color:#fff; }
.receipt-lines strong.positive { color:#9ee0ae; }

.tier-grid { gap:12px; }
.tier-card { min-height:520px; padding:0 30px 34px; overflow:hidden; border-radius:28px; transition:transform .45s cubic-bezier(.2,.8,.2,1),border-color .3s; }
/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .tier-card:hover { transform:translateY(-10px); border-color:rgba(255,255,255,.28); }
}
.tier-art { height:180px; margin:0 -30px 28px; position:relative; overflow:hidden; border-bottom:1px solid var(--edge); background:radial-gradient(circle at 50% 120%,rgba(255,255,255,.18),transparent 64%); }
.tier-art span { position:absolute; top:18px; left:22px; font:11px var(--mono); color:var(--muted); }
.tier-art i { position:absolute; width:190px; aspect-ratio:1.58; left:50%; top:50%; border-radius:14px; transform:translate(-50%,-34%) rotate(-8deg); background:linear-gradient(145deg,#252931,#090a0d 52%,#3d424c); box-shadow:0 28px 50px rgba(0,0,0,.55),inset 0 1px rgba(255,255,255,.22); }
.tier-card--metal .tier-art i { transform:translate(-50%,-34%) rotate(4deg); background:var(--chrome-gradient); }
.tier-card--private .tier-art i { transform:translate(-50%,-34%) rotate(-4deg); background:linear-gradient(145deg,#17191e,#000 58%,#747982); box-shadow:0 0 45px rgba(233,236,241,.12); }
.tier-name { font-size:12px; }
.tier-price { font-size:42px; letter-spacing:-.04em; }
.tier-flag { top:154px; left:auto; right:22px; z-index:2; }
.worked-example { max-width:none; padding:0; display:grid; grid-template-columns:.8fr 1.2fr; overflow:hidden; border-radius:24px; background:var(--surface-1); }
.worked-visual { position:relative; padding:40px; min-height:390px; border-right:1px solid var(--edge); background:radial-gradient(circle at 20% 20%,rgba(233,196,106,.12),transparent 50%); }
.worked-kicker { font:11px var(--mono); color:var(--muted); text-transform:uppercase; letter-spacing:.1em; }
.worked-merchant-mark { width:74px;height:74px;margin:54px 0 24px;border-radius:22px;display:grid;place-items:center;font:600 22px var(--display);background:linear-gradient(145deg,#d9c9a2,#695c3d);color:#111;box-shadow:0 18px 40px rgba(0,0,0,.4); }
.worked-visual h3 { margin:0 0 10px;font:700 clamp(26px,3vw,42px)/1 var(--display);letter-spacing:-.035em; }
.worked-visual p { max-width:340px;margin:0;color:var(--muted);line-height:1.55; }
.worked-total { position:absolute;left:40px;right:40px;bottom:34px;display:flex;align-items:end;justify-content:space-between;padding-top:18px;border-top:1px solid var(--edge); }
.worked-total span { font:var(--t-label-sm)/1.4 var(--mono);color:var(--muted);text-transform:uppercase;letter-spacing:var(--t-label-track-sm); }
.worked-total strong { font:700 30px var(--display); }
.worked-ledger { padding:40px; display:flex; flex-direction:column; justify-content:center; }

/* A deliberate light editorial world breaks the repeated dark-outline rhythm,
   borrowing the hard composition changes in Habitline, Nova and MVN. */
.spec-section {
  color:var(--paper-ink);
  background:var(--paper);
  border-radius:32px 32px 0 0;
}
.spec-section .chapter-eyebrow,.spec-section .section-lead,.spec-section .tier-name,
.spec-section .tier-price-suffix,.spec-section .tier-cap,.spec-section .fee-note,
.spec-section .worked-kicker,.spec-section .worked-visual p,.spec-section .worked-total span,
.spec-section .worked-row-label,.spec-section .worked-row-note { color:var(--paper-muted); }
.spec-section .section-heading,.spec-section .section-heading em,.spec-section .tier-price,
.spec-section .tier-bullets,.spec-section .fee-label,.spec-section .fee-col,
.spec-section .worked-visual h3,.spec-section .worked-total strong,.spec-section .worked-header,
.spec-section .worked-row-value { color:var(--paper-ink); }
.spec-section .tier-card {
  border-color:var(--paper-edge); background:rgba(255,255,255,.42);
  box-shadow:0 24px 70px rgba(30,32,37,.07);
}
/* The tier index sits on the card art with no ground of its own, so on the two
   paper cards it was --muted (the dark ground's near-white) on near-white and
   read as blank. aria-hidden, so the contrast tooling skipped it; only looking
   at the page caught it. The featured card keeps the dark roles below. */
.spec-section .tier-art span { color:var(--paper-muted); }
.spec-section .tier-card--featured { background:var(--paper-ink); color:var(--ink); transform:translateY(-18px); }
.spec-section .tier-card--featured .tier-name,.spec-section .tier-card--featured .tier-cap,
.spec-section .tier-card--featured .tier-art span { color:var(--muted); }
.spec-section .tier-card--featured .tier-price,.spec-section .tier-card--featured .tier-bullets { color:var(--ink); }
.spec-section .tier-art,.spec-section .tier-cap,.spec-section .fee-row,
.spec-section .worked-example,.spec-section .worked-visual,.spec-section .worked-total { border-color:var(--paper-edge); }
.spec-section .worked-example { background:rgba(255,255,255,.5); }
.spec-section .worked-ledger .status-chip { color:var(--paper-amber); }
.spec-section .worked-ledger .status-chip--cleared { color:var(--paper-good); }

.numbers-section { min-height:90svh; display:flex; align-items:center; overflow:hidden; }
.numbers-section .section-inner { width:100%; }
.numbers-editorial { position:relative; }
.numbers-word { font:800 clamp(72px,14vw,220px)/.72 var(--display); letter-spacing:-.065em; color:var(--ink); white-space:nowrap; }
.numbers-word--outline { color:transparent;-webkit-text-stroke:1px rgba(233,236,241,.42); transform:translateX(8vw); }
.numbers-note { display:grid;grid-template-columns:repeat(3,auto);gap:10px 30px;align-items:center;margin:70px 0 0 auto;width:max-content;max-width:100%;font:11px var(--mono);color:var(--muted);text-transform:uppercase;letter-spacing:.06em; }
.numbers-note strong { grid-column:1/-1;color:var(--ink);font:600 clamp(20px,3vw,38px) var(--display);text-transform:none;letter-spacing:-.03em; }

.custody-map { position:relative;padding:44px;border-radius:28px;background:radial-gradient(circle at 50% 0,rgba(116,131,255,.12),transparent 55%),var(--surface-1); }
.custody-node { min-height:300px;border-radius:22px!important;background:rgba(9,11,14,.72)!important;backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 24px 60px rgba(0,0,0,.28); }

.close-section {
  min-height:100svh;
  /* Scrim is heaviest where the headline/lead/CTA actually sit (left side of
     this layout) and lightest over the card-fan graphic on the right, so the
     chrome photo's bright highlight bands can never land behind text at full
     brightness regardless of where they fall in the image. Previously this
     gradient ran the other direction (light scrim under the text, heavy
     scrim under the card art with no text), which is why some crops of the
     chrome image left "Get the card" and the lead paragraph nearly unreadable. */
  /* Declared twice on purpose. The JPEG line is the floor for anything without
     image-set(); the second line overrides it where image-set() parses, and a
     browser that cannot parse it drops that declaration and keeps the first
     rather than losing the background entirely. 246KB -> 57KB on AVIF, which
     is the single largest asset on the page. Quality kept deliberately high
     for the format (68, not the 58 that measured visually identical here)
     because brushed metal is the one subject where banding would show, and
     chrome is the brand. */
  background:
    linear-gradient(90deg,rgba(5,6,8,.82),rgba(5,6,8,.5) 45%,rgba(5,6,8,.16)),
    url("/chrome-ribbons-v1.jpg") center/cover no-repeat;
  background:
    linear-gradient(90deg,rgba(5,6,8,.82),rgba(5,6,8,.5) 45%,rgba(5,6,8,.16)),
    image-set(url("/chrome-ribbons-v1.avif") type("image/avif"), url("/chrome-ribbons-v1.webp") type("image/webp"), url("/chrome-ribbons-v1.jpg") type("image/jpeg")) center/cover no-repeat;
  overflow:hidden;
}
.close-inner { z-index:2; }
.close-card-fan { position:absolute;right:5vw;bottom:-7vw;width:46vw;height:30vw;z-index:1;filter:drop-shadow(0 35px 45px rgba(0,0,0,.5)); }
.close-card-fan i { position:absolute;left:50%;bottom:0;width:42%;aspect-ratio:1.58;border-radius:10%;transform-origin:50% 120%;background:linear-gradient(145deg,#242833,#050608 55%,#9da3ad);border:1px solid rgba(255,255,255,.22); }
.close-card-fan i:nth-child(1){transform:translateX(-50%) rotate(-34deg)}
.close-card-fan i:nth-child(2){transform:translateX(-50%) rotate(-17deg)}
.close-card-fan i:nth-child(3){transform:translateX(-50%) rotate(0)}
.close-card-fan i:nth-child(4){transform:translateX(-50%) rotate(17deg)}
.close-card-fan i:nth-child(5){transform:translateX(-50%) rotate(34deg)}

/* Material overrides live after the component rules so each surface keeps its
   own color world while sharing the same depth, rim light and glass response. */
.control-device {
  border-color:rgba(255,255,255,.2);
  background:
    radial-gradient(circle at 78% 5%,rgba(160,169,255,.11),transparent 28%),
    linear-gradient(145deg,rgba(255,255,255,.12),rgba(255,255,255,.018) 38%),
    rgba(12,14,18,.92);
  box-shadow:0 70px 140px rgba(0,0,0,.6),inset 0 1px rgba(255,255,255,.19),inset 0 -1px rgba(255,255,255,.04);
}
.detail-card {
  border-color:var(--paper-edge);
  box-shadow:0 34px 80px rgba(31,35,41,.1),inset 0 1px rgba(255,255,255,.82),inset 0 -1px rgba(17,19,23,.06);
}
.detail-card--hold {
  background:radial-gradient(circle at 85% 0,rgba(145,158,255,.13),transparent 34%),linear-gradient(145deg,#171a20,#0e1014 62%);
}
.detail-card--funding {
  background:radial-gradient(circle at 82% 2%,rgba(255,255,255,.72),transparent 32%),linear-gradient(145deg,#d9dcff,#aeb5ff 58%,#ececff);
}
.detail-card--wallet { background:linear-gradient(145deg,rgba(255,255,255,.94),rgba(232,232,226,.82)); }
.detail-card--receipt {
  background:radial-gradient(circle at 82% 0,rgba(255,255,255,.48),transparent 34%),linear-gradient(140deg,#f2dfab,#c69e55);
}
.spec-section .tier-card {
  background:radial-gradient(circle at 82% 0,rgba(255,255,255,.88),transparent 35%),linear-gradient(145deg,rgba(255,255,255,.68),rgba(255,255,255,.24));
  box-shadow:0 34px 80px rgba(31,35,41,.1),inset 0 1px rgba(255,255,255,.82),inset 0 -1px rgba(17,19,23,.06);
}
.spec-section .tier-card--featured {
  background:radial-gradient(circle at 80% 0,rgba(151,162,255,.14),transparent 34%),linear-gradient(145deg,#1a1d23,#0d0f13 62%);
  box-shadow:0 42px 90px rgba(30,32,37,.22),inset 0 1px rgba(255,255,255,.17);
}
.spec-section .worked-example,
.spec-section .fee-table {
  background:linear-gradient(145deg,rgba(255,255,255,.72),rgba(255,255,255,.3));
}

/* Defer layout/paint work for long off-screen, non-sticky sections. */
.spec-section,.custody-section,.numbers-section,.faq-section,.close-section,.site-footer {
  content-visibility:auto;
  contain-intrinsic-size:auto 900px;
}

.nav-mobile-menu::before {
  content:""; position:fixed; inset:0; z-index:-1;
  background:radial-gradient(circle at 80% 15%,rgba(117,133,255,.18),transparent 36%);
}

@supports (animation-timeline: scroll()) {
  .nav::after {
    content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
    background:linear-gradient(90deg,#fff,#8f98ff);
    transform:scaleX(0);transform-origin:left;
    animation:page-progress linear both;animation-timeline:scroll(root);
  }
  @keyframes page-progress { to { transform:scaleX(1); } }
}
.nav-mobile-section .nav-col-heading { display:flex;gap:12px;margin-bottom:4px; }
.nav-mobile-section .nav-col-heading span { color:var(--ink); }
.nav-mobile-link { min-height:58px;font-size:clamp(24px,7vw,34px);font-weight:600;letter-spacing:-.03em; }

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  .hero-inner {
    flex-direction: column;
    align-items: flex-start;
    padding-top: 100px;
    /* Hero deliberately runs a wider content area than .section-inner on
       desktop (32 vs 72), but the two converge at phone width (both 20), so
       leaving it at 32 here made the gutter ramp jump 32 -> 32 -> 20 while
       every other section went 72 -> 24 -> 20. Below 900px the hero is a
       single column, so the headline/card collision constraint that governs
       its desktop padding no longer applies. */
    padding-left: 24px;
    padding-right: 24px;
  }

  /* The clamp/max padding formulas on these two bottom out at 32px, which is
     the desktop gutter, so below 900px they stayed 8px inboard of
     .section-inner and .stack-inner (both 24px here). Same wandering-left-edge
     problem, same fix. */
  .details-section {
    padding-left: 24px;
    padding-right: 24px;
  }

  .hero-card-wrap {
    align-self: center;
  }
  .hero-satellite--balance { left:-6%;top:8%; }
  .hero-satellite--auth { right:-9%;bottom:15%; }
  .hero-satellite--wallet { left:4%;bottom:0; }

  .hero-card-stage {
    width: min(360px, 70vw);
  }

  .nav-inner {
    padding: 0 20px;
  }

  .nav-right {
    gap: 1rem;
  }

  .nav-menu {
    display: none;
  }

  .nav-logo {
    width: 186px;
    height: 43px;
    overflow: hidden;
    flex-shrink: 0;
    /* Scaled with the mark: the inset it corrects is a proportion of the
       artwork, so it shrinks as .nav-logo-scale does. */
    --nav-logo-nudge: -34.8px;
  }

  .nav-logo-scale {
    --nav-logo-scale: 0.776;
  }

  .nav-cta {
    padding: 10px 16px;
    font-size: 13px;
    min-height: 44px;
  }

  .nav-hamburger {
    display: flex;
  }

  /* Touch targets: chrome/ghost CTAs sit a hair under 44px on desktop
     (11px padding + 14px text); grow the hit area on touch viewports
     without touching the visual padding rhythm elsewhere. */
  .btn-chrome,
  .btn-ghost {
    min-height: 44px;
  }

  .section-inner {
    padding: 80px 24px;
  }

  .control-section {
    height:auto;min-height:auto;
  }
  .control-sticky { position:relative;height:auto;grid-template-columns:1fr;padding:100px 24px;gap:54px; }
  .control-intro h2 { font-size:clamp(52px,12vw,78px); }
  .control-device-shell { width:min(640px,100%); }
  .control-device { min-height:0; }
  .details-head { grid-template-columns:1fr;gap:26px;margin-bottom:48px; }
  .details-head h2 { font-size:clamp(52px,12vw,78px); }
  .details-grid { grid-template-columns:1fr; }
  .detail-card,.detail-card--hold,.detail-card--funding,.detail-card--wallet,.detail-card--receipt { grid-column:1; }
  .detail-card { min-height:520px; }

  .nav-mobile-menu {
    width: 100vw;
    border-left: 0;
    padding: 28px 24px 44px;
  }

  .nav-mobile-sections { gap: 18px; }

  .stack-inner { gap: 42px; }
  .stack-copy { padding-bottom: 0; }
  .stack-ghost-n { position:static; font-size:72px; margin-bottom:-8px; }
  .stack-title { font-size:clamp(44px,13vw,68px); }
  .product-stage { padding:20px 12px 36px; }
  .product-panel,.product-panel--verify { transform:none; }
  .floating-receipt--deposit,.floating-receipt--spend,.floating-receipt--verify { left:auto;right:auto; }

  /* The value chip in the statement marquee is positioned at a fixed
     left:55% + fixed padding, sized for wide viewports; below 900px it can
     run past the right edge of the (overflow:hidden) strip. Re-center it. */
  .statement-glass-chip {
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 14px 18px;
  }

  .statement-glass-value {
    font-size: 20px;
  }

  /* toka: card first, then the headline, then Top tier/Chains/Wallets on
     one line — moving the whole card block ahead of the copy column is a
     plain flex reorder since they're already siblings of .hero-inner. */
  .hero-card-wrap {
    order: -1;
  }

  /* The three hero figures were sized for desktop (28-40px odometer values,
     32px padding between columns) — too wide to ever fit three across on a
     phone. Compressed sizing here, rather than letting the row wrap, is
     what actually gets "Top tier / Chains / Wallets" on one line. */
  .hero-figures {
    flex-wrap: nowrap;
    width: 100%;
  }

  .figure {
    padding: 0 12px;
    min-width: 0;
  }

  .figure-label {
    font-size: 11px;
    margin-bottom: 5px;
  }

  .figure-value {
    font-size: 16px;
  }

  .figure-value--static {
    font-size: 14px;
  }

  .figure .brand-mark--spec {
    height: 18px;
  }

  /* Sticky stacks degrade to normal flow: each panel keeps its own height
     but no longer pins, so the page just scrolls past them in order. */
  .stack-item {
    height: auto;
  }

  .stack-panel {
    position: relative;
    top: auto;
    height: auto;
    padding: 60px 0;
  }

  .stack-inner {
    /* minmax(0, 1fr), not a bare 1fr: a bare 1fr resolves to
       minmax(auto, 1fr), whose auto minimum is the column's min-content
       width, so a wide child (the product-stage device mockup) refuses to
       shrink and blows the column past the viewport. .stack-panel is
       overflow:hidden, so that overflow was silently clipping ~51px off the
       right edge of every panel's copy and visual at 390px. The desktop
       rule above already uses minmax(0, 1fr) for exactly this reason. */
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    /* Match .section-inner's narrow-viewport gutter. .stack-inner's base
       32px is never overridden below 900px, so the stacked "how it works"
       and app-preview panels sat 8px inboard of every other section at
       tablet width (and 12px at phone width, where .section-inner goes to
       20px), which reads as a wandering left edge while scrolling. */
    padding: 0 24px;
  }

  .card-scroll-wrap {
    height: auto;
  }

  .card-static { display:none; }
  .card-mobile {
    position:relative;display:block;padding:100px 24px;background:#08090c;overflow:hidden;
  }
  .card-mobile h2 { position:relative;z-index:2;margin:0;font:800 clamp(48px,12vw,76px)/.92 var(--display);letter-spacing:-.055em; }
  .card-mobile h2 em { color:var(--muted);font-style:normal; }
  .card-mobile-stage { position:relative;height:370px;display:grid;place-items:center; }
  .card-mobile-stage .card-glow { width:440px;height:440px; }
  /* This wrapper is the actual sizing reference createCardScene's resize()
     reads (via the containerRef passed to it in CardSection.tsx) — it MUST
     match the canvas/poster's own box exactly. It previously read the
     ancestor .card-mobile-stage's box instead (full stage width, fixed
     370px height, a totally different aspect ratio from the card), so
     Three.js rendered at the wrong aspect and the browser then stretched
     that image non-uniformly into the narrower CSS-sized canvas box —
     confirmed by screenshot: the card ran off both edges of the viewport
     and looked visibly squashed. */
  .card-mobile-canvas-wrap {
    position: relative;
    z-index: 1;
    width: min(430px, 86vw);
    aspect-ratio: 3.4 / 2.14;
  }
  .card-mobile-canvas-wrap .card-static-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-7deg);
    transition: opacity 0.4s ease;
  }
  .card-mobile-canvas { position:absolute;inset:0;width:100%;height:100%;transition:opacity .4s ease; }
  .card-mobile-wallet {
    position:absolute;z-index:2;right:4%;bottom:15%;display:flex;align-items:center;gap:10px;padding:12px 15px;
    border:1px solid var(--edge);border-radius:14px;background:rgba(16,18,23,.82);box-shadow:0 16px 40px rgba(0,0,0,.45);
  }
  .card-mobile-wallet .brand-mark { width:60px;height:25px; }
  .card-mobile-wallet span { font:11px var(--mono);color:var(--good);text-transform:uppercase; }
  .card-mobile-steps { position:relative;z-index:2;display:grid;border-top:1px solid var(--edge); }
  .card-mobile-steps>div { display:grid;grid-template-columns:34px 1fr;gap:6px 12px;padding:24px 0;border-bottom:1px solid var(--edge); }
  .card-mobile-steps span { grid-row:1/3;font:11px var(--mono);color:var(--muted); }
  .card-mobile-steps strong { font:600 22px var(--display); }
  .card-mobile-steps p { max-width:460px;margin:0;color:var(--muted);font-size:13px;line-height:1.5; }

  .card-scroll-stage {
    position: relative;
    height: auto;
    padding: 80px 0;
  }

  .card-stage-canvas-wrap {
    width: min(520px, 110vw);
  }

  .card-eyebrow {
    top:32px;left:20px;
  }
  .card-stage-copy { left:20px;top:auto;bottom:38px;transform:none;z-index:3; }
  .card-stage-copy strong { font-size:30px; }
  .card-progress { right:20px; }
  .card-stories { left:20px;right:20px;top:90px;width:auto;height:120px;transform:none; }
  .card-story { align-content:start; }
  .card-story h3 { font-size:34px; }
  .card-story p { max-width:270px;font-size:12px; }
  .card-chip--a { bottom:25%; }
  .card-chip--b { top:22%;right:4%; }
  .card-chip--c { bottom:25%;right:4%; }

  .manifesto-section {
    position: relative;
    padding: 80px 0;
  }
  .manifesto-proof { grid-template-columns:1fr; margin-top:42px; }
  .manifesto-values { grid-template-columns:1fr; }
  .manifesto-proof div { border-right:0;border-bottom:1px solid var(--edge); }
  .manifesto-proof div:last-child { border-bottom:0; }

  .statement-text {
    font-size: 14vw;
  }

  .tier-grid,
  .numbers-grid {
    grid-template-columns: 1fr;
  }
  .tier-card { min-height:0; }
  .spec-section .tier-card--featured { transform:none; }
  .worked-example { grid-template-columns:1fr; }
  .worked-visual { border-right:0;border-bottom:1px solid var(--edge); }

  .fee-row {
    grid-template-columns: minmax(0, 1fr) repeat(3, 64px);
    font-size: 12px;
  }

  .custody-map {
    flex-direction: column;
    align-items: stretch;
  }

  .custody-map-item {
    flex-direction: column;
  }

  .custody-arrow {
    transform: rotate(90deg);
    margin: 6px 0;
  }

  .footer-columns {
    flex-wrap: wrap;
    gap: 40px;
  }

  .footer-wordmark {
    font-size: 22vw;
  }
  .numbers-section { min-height:70svh; }
  .numbers-word { font-size:clamp(58px,17vw,130px); }
  .numbers-word--outline { transform:none; }
  .numbers-note { width:100%;grid-template-columns:1fr; }
  .numbers-note strong { grid-column:auto; }
  .custody-map { padding:20px; }
  .close-card-fan { right:-16vw;bottom:3vh;width:85vw;height:50vw;opacity:.65; }
}

/* Small-phone tier (iPhone SE/mini down to 320px). The 900px breakpoint above
   is a straight desktop-layout retrofit; this tier tunes type scale, nav
   footprint and a few fixed-width grids that only break under ~480px. */
@media (max-width: 480px) {
  .nav-inner {
    padding: 0 16px;
  }

  .nav-right {
    gap: 0.6rem;
  }

  .nav-logo {
    width: 152px;
    height: 36px;
    --nav-logo-nudge: -28.2px;
  }

  .nav-logo-scale {
    --nav-logo-scale: 0.635;
  }

  .nav-cta {
    padding: 10px 13px;
    font-size: 12px;
    white-space: nowrap;
  }

  .nav-right {
    gap: 0.4rem;
  }

  /* Leaves a tappable sliver of backdrop even on the narrowest phones,
     rather than going edge to edge, so "close on backdrop click" always
     has somewhere to land. */
  .nav-mobile-menu {
    width: 100vw;
    padding: 20px 20px 32px;
  }

  .hero-inner {
    padding-left: 20px;
    padding-right: 20px;
  }
  .control-sticky { padding:78px 20px; }
  .details-section { padding:90px 20px; }
  .detail-card { min-height:500px;padding:24px;border-radius:24px; }
  .hold-ui,.wallet-stage,.receipt-lines { left:24px;right:24px;bottom:24px; }
  .hold-ui>div:not(.hold-merchant) { padding:17px; }
  .hold-merchant { grid-template-columns:42px 1fr auto;padding:15px 17px; }
  .hold-merchant i { width:42px;height:42px; }
  .network-orbit { width:210px; }
  .network-orbit>i { left:calc(50% + cos(var(--angle)) * 105px);top:calc(50% + sin(var(--angle)) * 105px); }
  .wallet-stage>div { grid-template-columns:92px 1fr;padding:0 17px; }
  .wallet-stage .brand-mark { width:84px; }
  .control-tabs button { grid-template-columns:1fr;gap:3px;padding:12px 4px; }
  .control-device { padding:10px;border-radius:28px; }
  .control-view-wrap { min-height:0;border-radius:20px; }
  .control-view { min-height:520px;padding:20px 16px; }
  .control-balance strong { font-size:48px; }
  .control-actions>div { min-height:68px; }
  .account-mini-grid { grid-template-columns:1fr; }
  .control-view--card { grid-template-columns:1fr;align-content:start; }
  .control-card-visual { grid-row:auto;margin-bottom:4px; }
  .wallet-provisioned { grid-template-columns:44px 1fr auto; }
  .card-controls { grid-template-columns:repeat(3,1fr); }
  .card-controls button,.card-controls>div { min-height:78px; }
  .activity-merchant { grid-template-columns:48px 1fr auto; }
  .hero-satellite { padding:10px 11px; }
  .hero-satellite--balance { left:-2%;top:4%;min-width:118px; }
  .hero-satellite--auth { right:-5%;bottom:12%; }
  .hero-satellite--wallet { display:none; }

  .hero-headline {
    font-size: clamp(30px, 10vw, 52px);
  }

  .hero-ctas {
    flex-wrap: wrap;
    row-gap: 12px;
  }

  .hero-figures {
    flex-direction: row;
    flex-wrap: nowrap;
  }

  .figure {
    padding: 0 8px;
    border-left: 1px solid var(--edge);
  }

  .figure:first-child {
    padding-left: 0;
    border-left: none;
  }

  .figure-label {
    font-size: 11px;
  }

  .figure-value {
    font-size: 13px;
  }

  .figure-value--static {
    font-size: 12px;
  }

  .figure .brand-mark--spec {
    height: 15px;
  }

  .section-inner {
    padding: 64px 20px;
  }

  /* Keep the stacked panels on the same left edge as .section-inner at
     phone width too, see the note in the 900px block. */
  .stack-inner {
    padding: 0 20px;
  }

  .close-word-inner {
    font-size: clamp(34px, 11vw, 48px);
  }

  .statement-text {
    font-size: 12vw;
  }

  .manifesto-inner { padding:0 20px; }
  .manifesto-sentence { font-size:clamp(34px,10vw,48px); }
  .mask-word--chip { display:inline-block;margin:.12em .08em; }
  .statement-glass-chip { min-width:220px; }

  .chain-list { grid-template-columns:repeat(3,1fr); }
  .chain-row:nth-child(n+4) { grid-column:span 1; }
  .product-panel-top { padding:0 18px; }
  .panel-balance,.identity-card { margin-left:18px;margin-right:18px; }
  .panel-balance { padding-left:0;padding-right:0; }
  .chain-list,.stepper,.stepper--identity,.verify-pending,.tx-list { margin-left:18px;margin-right:18px; }
  .floating-receipt { min-width:126px;margin:0 18px 18px;padding:12px 13px; }
  .spend-summary { margin:0 18px; }

  .tier-card,
  .numbers-tile {
    padding: 24px 20px;
  }
  .tier-art { margin:-24px -20px 24px; }
  .tier-flag { top:132px; }
  .spec-section .fee-table { padding:8px 12px 2px; }
  .worked-visual,.worked-ledger { padding:26px 20px; }
  .worked-visual { min-height:390px; }
  .worked-total { left:20px;right:20px; }

  /* The header row prints tier names ("Standard"/"Premium"/"Private"), not
     just short numeric fee values, so the column needs to fit that longest
     word. .fee-col/.fee-label set their own font-size in the base rules
     (13px/14px), which wins over font-size set on the .fee-row container,
     so the size has to be overridden on the cells themselves, not just the
     row (measured: row-level font-size alone left "Standard" at 13px,
     68px wide, colliding into the next 60px column). */
  .fee-row {
    grid-template-columns: minmax(0, 1fr) repeat(3, 60px);
    gap: 8px;
  }

  .fee-label {
    font-size: 12px;
  }

  .fee-col {
    font-size: 12px;
  }

  /* Four columns (avatar / merchant / amount / status) do not fit a phone.
     The two `auto` columns take their content width first, squeezing the
     merchant column toward zero, and .tx-main's content then painted over
     the amount instead of staying in its own cell (the amount was drawn
     on top of the date). Drop to three columns and give the status chip
     its own second row, the standard mobile transaction-row shape, so
     every value keeps its own cell at any width. */
  .tx-row {
    grid-template-columns: 28px minmax(0, 1fr) auto;
    grid-template-areas:
      "avatar main   amount"
      "avatar status .";
    column-gap: 10px;
    row-gap: 6px;
  }

  .tx-avatar {
    grid-area: avatar;
    align-self: start;
  }

  .tx-main {
    grid-area: main;
  }

  .tx-amount {
    grid-area: amount;
    align-self: start;
  }

  /* Status sits in the flexible middle column only, never spanning into the
     `auto` amount column: an auto track absorbs a spanning item's intrinsic
     width, which starved the merchant column to 0px and left the first row
     with no visible merchant name at all. */
  .tx-status {
    grid-area: status;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: wrap;
    min-width: 0;
    gap: 8px;
  }

  .tx-meta {
    flex-wrap: wrap;
    row-gap: 4px;
  }

  /* The "Clear" row's status chip carries a compound label ("Cleared
     (incl. 0.9% conversion)") that's plain text at 900px and up; in the
     narrow middle grid column on a phone that nowrap text runs out of its
     column and visually collides with the value to its right. Letting it
     wrap keeps it inside its own cell instead. */
  .worked-row {
    grid-template-columns: 56px minmax(0, 1fr) auto;
    gap: 8px;
    font-size: 12px;
  }

  .worked-row .status-chip {
    /* .status-chip is display:inline-flex (needed elsewhere for icon+text
       chips with align-items/gap) — but flexbox doesn't wrap mixed
       text-and-element children the way normal inline text does; its plain
       text runs and the embedded FeeBadge each become separate flex items
       and wrap independently, producing a jumbled, out-of-order layout
       ("0.9%" landing above "(incl." and "conversion)" on separate lines
       in no readable order). Confirmed by inspecting the computed style
       and re-screenshotting well past any entrance-animation settle time
       so it wasn't just an odometer mid-count-up artifact. Switching back
       to plain inline flow for this specific compound-text chip fixes the
       reading order; the single-word chips elsewhere never hit this since
       they have no wrapping text to break.
     */
    display: inline;
    white-space: normal;
    text-align: left;
    line-height: 1.4;
  }

  .worked-row .status-chip .odometer {
    display: inline;
  }

  .tx-amount {
    font-size: 12px;
  }

  .status-chip {
    font-size: 11px;
    padding: 3px 8px;
  }

  .custody-node {
    padding: 20px;
  }

  .footer-columns {
    flex-direction: column;
    gap: 32px;
  }

  .footer-wordmark {
    font-size: 15vw;
  }
}

/* ---------- mobile one-shot reveal (attachMobileReveal in scroll.ts) ----------
   Cheap CSS-only stand-in for the GSAP scroll-entrance that every section
   above skips on mobile. Default state (no class) is the plain visible
   layout, so no-JS and reduced-motion both render correctly with zero extra
   rules; JS only adds .reveal-pending immediately before observing. */
@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  .reveal-pending {
    opacity: 0;
    transform: translateY(18px);
    transition:
      opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1),
      transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .reveal-pending.reveal-visible {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal-pending {
    opacity: 1 !important;
    transform: none !important;
  }

  .btn-chrome {
    animation: none;
  }

  .headline-inner {
    transform: translateY(0);
  }

  .marquee-track {
    transform: none !important;
  }

  .mask-word-inner,
  .close-word-inner {
    transform: translateY(0) !important;
  }

  .statement-track {
    transform: none !important;
  }

  .close-reveal {
    opacity: 1 !important;
    transform: none !important;
  }

  .stack-copy > *,
  .product-panel > *,
  .tier-card,
  .fee-row,
  .worked-row,
  .custody-node,
  .numbers-tile,
  .faq-row {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------- local demo application ---------- */

.bank-app {
  --app-bg: #080a0d;
  --app-panel: #101319;
  --app-panel-soft: #0d1015;
  --app-line: rgba(238, 241, 246, 0.1);
  --app-ink: #f0f2f5;
  --app-muted: #8f96a3;
  min-height: 100vh;
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  background:
    radial-gradient(circle at 68% -10%, rgba(117, 130, 156, 0.14), transparent 31rem),
    var(--app-bg);
  color: var(--app-ink);
  font-family: var(--display);
}

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

.bank-app--centered {
  display: grid;
  grid-template-columns: 1fr;
  place-items: center;
  padding: 32px;
}

.app-eyebrow {
  margin: 0 0 8px;
  color: var(--app-muted);
  font: var(--t-label-sm)/1.2 var(--mono);
  letter-spacing: var(--t-label-track-sm);
  text-transform: uppercase;
}

/* ---------- mobile app shell (Phase 1) ---------- */

.app-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(480px, 100%);
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
}

/* Wraps the header + scrollable content pair. Below 1024px this is the
   only element in .app-shell's normal flow (the sidebar is display: none
   and the tab bar is position: fixed, out of flow either way), so giving
   it the flex: 1 1 auto that .app-shell-header/.app-shell-content used to
   get directly from .app-shell reproduces the mobile shell's sticky
   header + scrolling content exactly. At 1024px+ it becomes the content
   column next to the sidebar. */
.app-shell-main {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.app-shell-header {
  position: sticky;
  z-index: 10;
  top: 0;
  display: flex;
  flex: 0 0 52px;
  align-items: center;
  gap: 12px;
  height: 52px;
  padding: 0 16px;
  border-bottom: 1px solid var(--app-line);
  background: rgba(8, 10, 13, 0.86);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.app-shell-avatar {
  display: flex;
  flex: 0 0 34px;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--chrome-gradient);
  color: var(--ink-on-light);
  cursor: pointer;
  font: 600 14px/1 var(--display);
}

/* The title names where you are, so it never truncates: at 390px "Refer a
   friend" was being clipped to "Refer …" while the ambient environment chip
   kept its width. The chip absorbs the shrink instead, and margin-left:auto
   keeps it pinned right now that the title no longer grows. */
.app-shell-title {
  flex: 0 0 auto;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  color: var(--app-ink);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The shared .status-chip is white-space: nowrap, which is right for the short
   marketing chips it was built for ("Confirming", "Cleared"). In this header it
   carries the long environment string, and with no min-width: 0 it refused to
   shrink and ran off the right edge of a 390px screen, cut with no ellipsis.
   Given the same shrink treatment the title next to it already has. Truncating
   costs nothing here: the banner directly above states the same status in full
   sentences, and the desktop sidebar shows the untruncated chip. */
.app-shell-header > .status-chip {
  flex: 0 1 auto;
  min-width: 0;
  /* The title stopped growing (see above), so the chip has to claim the gap
     itself to stay pinned to the right edge. */
  margin-left: auto;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-shell-content {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 20px 16px calc(88px + env(safe-area-inset-bottom));
}

.app-tab-placeholder {
  padding: 40px 4px;
  text-align: center;
}

.app-tab-placeholder h1 {
  margin: 0 0 8px;
  font-size: clamp(24px, 6vw, 30px);
  font-weight: 600;
  letter-spacing: -0.03em;
}

.app-tab-placeholder p:not(.app-eyebrow) {
  margin: 0;
  color: var(--app-muted);
  font-size: 13px;
  line-height: 1.6;
}

.tab-bar {
  position: fixed;
  left: 50%;
  z-index: 30;
  bottom: 0;
  display: flex;
  width: min(480px, 100%);
  transform: translateX(-50%);
  padding-bottom: env(safe-area-inset-bottom);
  border-top: 1px solid var(--app-line);
  background: rgba(8, 10, 13, 0.92);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.tab-bar-item {
  display: flex;
  flex: 1 1 0;
  min-height: 56px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  background: none;
  color: var(--app-muted);
  cursor: pointer;
  font-family: inherit;
}

.tab-bar-icon {
  width: 24px;
  height: 24px;
}

.tab-bar-item span {
  font-size: 11px;
  letter-spacing: 0.01em;
}

.tab-bar-item[aria-current="page"] {
  color: var(--app-ink);
}

/* ---------- desktop app shell (>=1024px) ----------
   Both nav components stay mounted at all times (main.tsx client-renders
   the /app route rather than hydrating it, but the rule holds regardless:
   no matchMedia/innerWidth in the render path, CSS alone decides which
   nav is visible). .app-sidebar is display: none below 1024px, which
   drops it from the accessibility tree and tab order entirely, not just
   hidden visually. */
.app-sidebar {
  display: none;
}

@media (min-width: 1024px) {
  .app-shell {
    flex-direction: row;
    width: 100%;
    max-width: none;
    margin: 0;
    align-items: stretch;
  }

  .app-sidebar {
    position: relative;
    display: flex;
    /* min-width: 0 is doing real work. A flex item defaults to min-width: auto,
       which refuses to shrink below its own min-content width, and the widest
       unbreakable thing in this rail is the environment chip: 54 characters of
       nowrap mono. That set a 414px floor and the rail rendered 455px against
       the 260px declared right here, taking 195px from the content column. The
       chip is a footnote; it does not get to size the chrome. */
    flex: 0 0 260px;
    min-width: 0;
    flex-direction: column;
    padding: 28px 20px 24px;
    border-right: 1px solid var(--app-line);
    background: rgba(12, 14, 18, 0.5);
  }

  /* Not a pill here. .status-chip is a pill because the marketing surface uses
     it for one or two words; this instance carries a 54-character environment
     string, and a pill that has to wrap three times is no longer a pill: the
     inline-flex box sizes to its first line and the rest spills past the
     border. In a 260px rail the honest form is a plain status line, so the
     chrome comes off and the dot plus the text is the whole design. */
  .app-sidebar .status-chip {
    /* Block, not grid or flex. The label is a bare text node beside the dot
       span, and as an anonymous flex/grid item it would not grow the box: the
       measured result was a 26px chip holding three lines of text, spilling
       past its own border. As inline content in a block box it simply wraps. */
    display: block;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    white-space: normal;
    text-align: left;
    line-height: 1.5;
  }

  .app-sidebar .status-chip-dot {
    display: inline-block;
    margin-right: 8px;
  }

  .app-sidebar-wordmark {
    display: flex;
    align-items: center;
    padding: 6px 10px 32px;
    text-decoration: none;
  }

  .app-sidebar-wordmark-scale {
    display: block;
    width: 104px;
    height: 24px;
  }

  .app-sidebar-wordmark-image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .app-sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  /* Rest, hover and selected are three steps of one idea: how much of the row
     is lit. Nothing, a faint wash, a raised surface. 15px because 13 was lost
     in the rail, and 48px rows because this is a desktop pointer target with
     room, not the 44px floor. */
  .app-sidebar-item {
    display: flex;
    width: 100%;
    min-height: 48px;
    align-items: center;
    gap: 12px;
    padding: 0 12px;
    border: 0;
    border-radius: 10px;
    background: none;
    color: var(--app-muted);
    cursor: pointer;
    font: 500 15px/1 var(--display);
    letter-spacing: -0.01em;
    transition: background-color 0.15s ease, color 0.15s ease;
  }

  /* Hover is a capability, not a screen size. Without this guard every rule below
     also fires on touch, where :hover latches after a tap and leaves cards raised
     and rows highlighted until the user taps somewhere else. */
  @media (hover: hover) {
    .app-sidebar-item:hover {
      background: var(--surface-1);
      color: var(--app-ink);
    }
  }

  .app-sidebar-item:active {
    background: rgba(233, 236, 241, 0.1);
  }

  .app-sidebar-icon {
    width: 19px;
    height: 19px;
    flex: 0 0 auto;
  }

  /* Was --chrome-gradient: the material the card itself is made of, and the
     primary CTA. Spending it on a menu row made the loudest element on the
     dashboard a navigation item, brighter than the balance, and read as a
     button rather than a location. A selected row is not an action.

     Selection is now carried the way it should be: the row lifts one surface
     step, the label and icon go to full contrast, and the weight steps up.
     Quieter than the balance it sits beside, and unmistakable. */
  .app-sidebar-item[aria-current="page"] {
    background: var(--surface-2);
    color: var(--app-ink);
    font-weight: 600;
  }

  .app-sidebar-item[aria-current="page"] .app-sidebar-icon {
    opacity: 1;
  }

  /* The icon carries the same three steps as the label, via currentColor plus
     one opacity step, so a resting row reads as one muted object rather than a
     grey label beside a brighter glyph. */
  .app-sidebar-icon {
    opacity: 0.75;
    transition: opacity 0.15s ease;
  }

  .app-sidebar-item:hover .app-sidebar-icon {
    opacity: 1;
  }

  .app-sidebar-footer {
    margin-top: auto;
    padding-top: 16px;
    border-top: 1px solid var(--app-line);
  }

  .app-sidebar-footer .status-chip {
    width: 100%;
    justify-content: center;
  }

  .app-shell-main {
    min-width: 0;
  }

  .app-shell-header {
    position: static;
    z-index: auto;
    flex: 0 0 auto;
    height: auto;
    padding: 44px 56px 28px;
    border-bottom: 0;
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .app-shell-avatar,
  .app-shell-header > .status-chip {
    display: none;
  }

  .app-shell-title {
    font-size: 28px;
    font-weight: 600;
    letter-spacing: -0.025em;
    white-space: normal;
  }

  .app-shell-content {
    padding: 0 56px 64px;
  }

  .app-shell-content > .app-stack {
    max-width: 1180px;
  }

  /* The USD deposit form is the only section on its screen when the
     segmented control is on USD (the crypto method pairs two panels via
     .app-grid instead), stretching a single short form edge to edge at
     1180px reads as an unstyled phone form rather than a composition
     built for the width, so it keeps its own comfortable measure. */
  .app-fund-panel {
    max-width: 640px;
  }

  .tab-bar {
    display: none;
  }
}

/* Content-sized, not height: 26px. The fixed height made this component work
   in exactly one context: put it anywhere its label is longer than a line and
   the box stayed 26px while the text hung out of the bottom, which reads as a
   flex sizing quirk and is not one. Vertical padding reproduces the same 26px
   for every label it was designed for, and lets it grow for the ones it was
   not. min-height rather than repadding, so every existing chip keeps the
   exact 26px it had. This is the second of two .status-chip definitions in
   this file, which is its own problem, noted rather than merged here. */
.status-chip {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 0 10px;
  border: 1px solid var(--app-line);
  border-radius: 999px;
  font: 11px/1 var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.status-chip-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.status-chip--good {
  border-color: rgba(143, 227, 176, 0.28);
  background: rgba(143, 227, 176, 0.08);
  color: var(--good);
}

.status-chip--good .status-chip-dot {
  background: var(--good);
  box-shadow: 0 0 6px rgba(143, 227, 176, 0.6);
}

.status-chip--amber {
  border-color: rgba(233, 196, 106, 0.28);
  background: rgba(233, 196, 106, 0.08);
  color: var(--amber);
}

.status-chip--amber .status-chip-dot {
  background: var(--amber);
  box-shadow: 0 0 6px rgba(233, 196, 106, 0.6);
}

.status-chip--bad {
  border-color: rgba(232, 134, 122, 0.28);
  background: rgba(232, 134, 122, 0.08);
  color: var(--bad);
}

.status-chip--bad .status-chip-dot {
  background: var(--bad);
  box-shadow: 0 0 6px rgba(232, 134, 122, 0.6);
}

.list-row {
  display: flex;
  width: 100%;
  min-height: 56px;
  align-items: center;
  gap: 12px;
  padding: 8px 4px;
  border: 0;
  border-bottom: 1px solid var(--app-line);
  background: none;
  color: var(--app-ink);
  font-family: inherit;
  text-align: left;
}

button.list-row {
  cursor: pointer;
}

.list-row:last-child {
  border-bottom: 0;
}

.list-row-leading {
  display: flex;
  flex: 0 0 36px;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--app-panel-soft);
  color: var(--app-muted);
}

.list-row-leading svg {
  width: 18px;
  height: 18px;
}

.list-row-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 14px;
}

.list-row-trailing {
  flex: 0 0 auto;
  color: var(--app-muted);
  font-size: 13px;
}

.list-row-chevron {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--app-muted);
}

.list-row--destructive .list-row-label,
.list-row--destructive .list-row-leading {
  color: var(--bad);
}

.segmented {
  display: flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--app-line);
  border-radius: 12px;
  background: var(--app-panel-soft);
}

.segmented-item {
  flex: 1 1 0;
  min-height: 38px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--app-muted);
  cursor: pointer;
  font: 500 13px/1 var(--display);
  letter-spacing: -0.01em;
}

.segmented-item[aria-selected="true"] {
  background: var(--app-panel);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 1px 6px rgba(0, 0, 0, 0.3);
  color: var(--app-ink);
}

.sheet-backdrop {
  position: fixed;
  z-index: 40;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(4, 5, 7, 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.sheet-panel {
  width: min(480px, 100%);
  max-height: 86vh;
  overflow-y: auto;
  padding: 10px 20px calc(24px + env(safe-area-inset-bottom));
  border: 1px solid var(--app-line);
  border-bottom: 0;
  border-radius: 20px 20px 0 0;
  background: var(--app-panel);
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.4);
}

.sheet-handle {
  display: block;
  width: 36px;
  height: 4px;
  margin: 0 auto 14px;
  border-radius: 999px;
  background: var(--app-line);
}

.sheet-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.sheet-title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.sheet-close {
  display: flex;
  flex: 0 0 32px;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--app-line);
  border-radius: 50%;
  background: none;
  color: var(--app-muted);
  cursor: pointer;
}

.sheet-close svg {
  width: 16px;
  height: 16px;
}

.tx-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--app-line);
}

.tx-row:last-child {
  border-bottom: 0;
}

.tx-row--authorized .tx-row-avatar {
  background: rgba(233, 196, 106, 0.18);
  color: var(--amber);
}

.tx-row--cleared .tx-row-avatar {
  background: rgba(143, 227, 176, 0.18);
  color: var(--good);
}

.tx-row--declined .tx-row-avatar {
  background: rgba(232, 134, 122, 0.18);
  color: var(--bad);
}

.tx-row-avatar {
  display: grid;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 50%;
  background: var(--app-panel-soft);
  color: var(--app-ink);
  font: 12px var(--mono);
}

.tx-row-main {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.tx-row-merchant {
  overflow: hidden;
  color: var(--app-ink);
  font-size: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tx-row-category {
  color: var(--app-muted);
  font-size: 12px;
}

.tx-row-amount {
  flex: 0 0 auto;
  font: 600 13px/1 var(--mono);
}

.tx-row-amount--pos {
  color: var(--good);
}

.tx-row-amount--neg {
  color: var(--app-ink);
}

.app-balance-panel {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  min-height: 236px;
  padding: clamp(28px, 4vw, 48px);
  border: 1px solid rgba(236, 239, 245, 0.16);
  border-radius: 20px;
  background:
    linear-gradient(120deg, rgba(255, 255, 255, 0.055), transparent 40%),
    linear-gradient(135deg, #171b22, #0b0e13 68%);
  box-shadow: 0 26px 90px rgba(0, 0, 0, 0.25);
}

.app-balance-panel::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -80% -15% auto auto;
  width: 500px;
  height: 500px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 44%;
  transform: rotate(32deg);
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.09), transparent 55%);
}

.app-balance-panel p {
  margin: 0 0 15px;
  color: #a6adba;
  font-size: 13px;
}

.app-balance-panel strong {
  display: block;
  margin-bottom: 12px;
  font-size: clamp(42px, 6vw, 68px);
  font-weight: 500;
  letter-spacing: -0.055em;
}

.app-balance-panel > div > span {
  color: var(--app-muted);
  font: 11px/1.4 var(--mono);
}

/* ---------- desktop tab reflow (>=1024px only) ----------
   These pair two sibling .app-panel sections into a two-column layout on
   wide screens. display: contents below 1024px removes the wrapper from
   the box model entirely, so its children fall back to being direct
   .app-stack items with .app-stack's own 18px gap between them, pixel
   identical to the mobile shell's plain vertical stack. */
.app-grid,
.app-grid--lower,
.app-grid--hero {
  display: contents;
}

@media (min-width: 1024px) {
  .app-grid,
  .app-grid--lower,
  .app-grid--hero {
    display: grid;
    align-items: start;
    gap: 28px;
  }

  .app-grid {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  }

  .app-grid--lower {
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  }

  .app-grid--hero {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  }
}

.app-panel {
  min-width: 0;
  padding: 26px;
  border: 1px solid var(--app-line);
  border-radius: 16px;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.018), transparent 45%), var(--app-panel);
}

.app-panel-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}

.app-panel h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.app-safe-chip,
.app-status-chip,
.app-source-label {
  padding: 6px 9px;
  border: 1px solid var(--app-line);
  border-radius: 999px;
  color: #b7beca;
  font: 11px/1 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.app-safe-chip {
  border-color: rgba(143, 227, 176, 0.18);
  color: var(--good);
}

.app-status-chip {
  color: var(--good);
}

.app-panel-copy {
  max-width: 50ch;
  margin: -7px 0 22px;
  color: var(--app-muted);
  font-size: 13px;
  line-height: 1.65;
}

.app-fund-panel form label {
  display: block;
  margin-bottom: 8px;
  color: #c3c8d1;
  font: var(--t-label-sm)/1.2 var(--mono);
  letter-spacing: var(--t-label-track-sm);
  text-transform: uppercase;
}

.app-amount-field {
  display: flex;
  align-items: center;
  height: 52px;
  border: 1px solid rgba(239, 242, 247, 0.16);
  border-radius: 10px;
  background: #090b0f;
}

.app-amount-field:focus-within {
  border-color: rgba(239, 242, 247, 0.55);
}

.app-amount-field span {
  padding-left: 16px;
  color: var(--app-muted);
  font-size: 17px;
}

.app-amount-field input {
  width: 100%;
  height: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--app-ink);
  font: 18px/1 var(--mono);
}

.app-field-help {
  margin: 8px 0 17px;
  color: #737a86;
  font: 12px/1.4 var(--mono);
}

.app-button {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid #dde1e7;
  border-radius: 9px;
  background: #e6e9ee;
  color: #0a0c0f;
  cursor: pointer;
  font: 600 12px/1 var(--display);
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .app-button:hover {
    background: #fff;
  }
}

.app-button:disabled {
  cursor: wait;
  opacity: 0.55;
}

.app-button--wide {
  width: 100%;
}

.app-form-note {
  margin: 14px 0 0;
  color: var(--app-muted);
  font-size: 11px;
  line-height: 1.5;
}

.app-form-note--good {
  color: var(--good);
}

.app-form-note--success {
  color: var(--good);
}

.app-form-note--pending,
.app-form-note--unknown {
  color: var(--amber);
}

.app-form-note--error {
  color: var(--bad);
}

.app-card-visual {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1.62;
  padding: 23px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 18px;
  background:
    linear-gradient(135deg, transparent 10%, rgba(255, 255, 255, 0.28) 42%, transparent 43%),
    linear-gradient(145deg, #343941, #9da2a9 42%, #3e434b 52%, #bec2c8 81%, #555a62);
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.28);
  color: #090a0c;
  text-shadow: 0 1px rgba(255, 255, 255, 0.25);
}

.app-card-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(100deg, transparent 0 12px, rgba(255, 255, 255, 0.035) 13px 14px);
  pointer-events: none;
}

.app-card-topline,
.app-card-bottom {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: space-between;
  font: 700 12px/1 var(--mono);
  letter-spacing: 0.13em;
}

.app-card-chip {
  position: relative;
  z-index: 1;
  width: 37px;
  height: 29px;
  margin-top: 14%;
  border: 1px solid rgba(0, 0, 0, 0.35);
  border-radius: 6px;
  background: linear-gradient(145deg, #d1c6a7, #8f856a);
}

.app-card-bottom {
  position: absolute;
  right: 23px;
  bottom: 22px;
  left: 23px;
}

.app-card-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 18px 0 0;
}

.app-card-facts div {
  padding: 12px 14px;
  border: 1px solid var(--app-line);
  border-radius: 9px;
}

.app-card-facts dt {
  margin-bottom: 5px;
  color: var(--app-muted);
  font: 11px/1.3 var(--mono);
  text-transform: uppercase;
}

.app-card-facts dd {
  margin: 0;
  font-size: 13px;
}

.app-privacy-note {
  margin: 14px 0 0;
  color: #777e8a;
  font-size: 12px;
  line-height: 1.5;
}

.app-product-list,
.app-activity-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-product-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--app-line);
}

.app-product-list li:last-child {
  border-bottom: 1px solid var(--app-line);
}

.app-product-list div {
  display: grid;
  gap: 5px;
}

.app-product-list strong {
  font-size: 13px;
  font-weight: 600;
}

.app-product-list span {
  color: var(--app-muted);
  font: 11px/1 var(--mono);
}

.app-product-list b {
  color: #c9ced7;
  font: 11px/1 var(--mono);
  text-transform: uppercase;
}

.app-minimum {
  margin: 17px 0 0;
  color: var(--app-muted);
  font-size: 11px;
}

.app-minimum strong {
  color: var(--app-ink);
  font-weight: 500;
}

.app-activity-list li {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--app-line);
}

.app-activity-icon {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 1px solid var(--app-line);
  border-radius: 50%;
  color: var(--good);
}

.app-activity-list li > div {
  display: grid;
  gap: 5px;
}

.app-activity-list strong {
  font-size: 12px;
  font-weight: 600;
}

.app-activity-list span {
  color: var(--app-muted);
  font: 11px/1.2 var(--mono);
}

.app-activity-value {
  justify-items: end;
}

.app-activity-value span[data-state="succeeded"] {
  color: var(--good);
}

.app-activity-value span[data-state="pending"],
.app-activity-value span[data-state="unknown"] {
  color: var(--amber);
}

.app-activity-value span[data-state="failed"] {
  color: var(--bad);
}

.app-empty {
  margin: 0;
  padding: 30px 18px;
  border: 1px dashed var(--app-line);
  border-radius: 10px;
  color: var(--app-muted);
  font-size: 12px;
  text-align: center;
}

.app-empty--activity {
  display: grid;
  place-items: center;
}

.app-empty--activity > span {
  display: grid;
  width: 38px;
  height: 38px;
  margin-bottom: 10px;
  place-items: center;
  border: 1px solid var(--app-line);
  border-radius: 50%;
}

.app-empty--activity p {
  margin: 0 0 5px;
  color: #c0c5cf;
}

.app-empty--activity small {
  font-size: 11px;
}

.app-loader,
.app-load-error {
  max-width: 430px;
  text-align: center;
}

.app-loader {
  color: var(--app-muted);
  font: 11px/1.5 var(--mono);
}

.app-loader-mark {
  display: block;
  width: 30px;
  height: 30px;
  margin: 0 auto 18px;
  border: 1px solid #9097a2;
  border-top-color: transparent;
  border-radius: 50%;
  animation: app-spin 0.9s linear infinite;
}

.app-load-error h1 {
  margin: 0 0 12px;
  font-size: 30px;
  font-weight: 600;
}

.app-load-error > p:not(.app-eyebrow) {
  margin: 0 0 22px;
  color: var(--app-muted);
  line-height: 1.6;
}

.app-text-link {
  display: block;
  margin-top: 18px;
  color: #b8bec8;
  font-size: 12px;
}

.app-link-button {
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.bank-app--centered {
  position: relative;
}

/* Ambient depth behind the auth card, same idea as .card-glow on the
   marketing hero: a soft radial halo in the chrome tint, not a color,
   so the panel reads as lifted off the field rather than floating alone
   in empty space. */
.app-auth-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(820px, 92vw);
  height: min(820px, 92vw);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(233, 236, 241, 0.1), transparent 70%);
  pointer-events: none;
}

.app-auth-mark {
  display: flex;
  justify-content: center;
  margin: 0 0 28px;
}

.app-auth-mark-scale {
  display: block;
  width: 148px;
  height: 34px;
}

.app-auth-mark-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.app-auth-panel {
  position: relative;
  width: min(460px, 100%);
  padding: 34px;
  text-align: left;
  box-shadow:
    0 40px 70px -34px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(255, 255, 255, 0.02) inset;
}

.app-auth-panel h1 {
  margin: 6px 0 22px;
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.app-auth-panel .app-choice-form {
  margin-bottom: 4px;
}

/* Auth CTA gets its own explicit surface rather than inheriting
   .app-button as-is: keeps this button's contrast pinned regardless of
   any future change to the shared app-shell button (used across the
   dashboard funding/checklist flows too), and gives it a hair more
   margin above the 4.5:1 floor. Measured: #05070a on #f4f5f7 = 18.5:1. */
.app-auth-panel .app-button {
  background: #f4f5f7;
  color: #05070a;
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .app-auth-panel .app-button:hover {
    background: #ffffff;
  }
}

.app-status-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 10px 16px;
  border-bottom: 1px solid rgba(233, 196, 106, 0.22);
  background: rgba(233, 196, 106, 0.07);
  color: #e9d69a;
  font: 11px/1.4 var(--mono);
  letter-spacing: 0.01em;
  text-align: center;
}

.app-stack {
  display: grid;
  gap: 18px;
}

.app-intro-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  min-height: 120px;
  background:
    radial-gradient(circle at 95% 0%, rgba(157, 168, 190, 0.12), transparent 18rem),
    var(--app-panel);
}

.app-intro-panel h2 {
  font-size: clamp(24px, 3vw, 34px);
}

.app-intro-panel > p {
  max-width: 52ch;
  margin: 0;
  color: var(--app-muted);
  font-size: 13px;
  line-height: 1.65;
}

.app-progress {
  overflow: hidden;
  height: 5px;
  margin: -8px 0 18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
}

.app-progress span {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #6e7788, #e6e9ee);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}

.app-checklist {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-checklist li {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--app-line);
}

.app-checklist button {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 1px solid rgba(238, 241, 246, 0.18);
  border-radius: 50%;
  background: transparent;
  color: var(--app-muted);
  cursor: pointer;
  font: 11px/1 var(--mono);
}

.app-checklist li[data-complete="true"] button {
  border-color: rgba(143, 227, 176, 0.3);
  background: rgba(143, 227, 176, 0.08);
  color: var(--good);
}

.app-checklist div {
  display: grid;
  gap: 4px;
}

.app-checklist strong {
  font-size: 12px;
  font-weight: 600;
}

.app-checklist span {
  color: var(--app-muted);
  font-size: 12px;
  line-height: 1.45;
}

.app-choice-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.app-choice-list {
  display: grid;
  gap: 8px;
  margin-bottom: 8px;
}

.app-choice-list label {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 12px 14px;
  border: 1px solid var(--app-line);
  border-radius: 10px;
  cursor: pointer;
}

.app-choice-list label[data-selected="true"] {
  border-color: rgba(238, 241, 246, 0.32);
  background: rgba(255, 255, 255, 0.04);
}

.app-choice-list label span {
  display: grid;
  gap: 5px;
}

.app-choice-list label strong {
  font-size: 12px;
  font-weight: 600;
}

.app-choice-list label small {
  color: var(--app-muted);
  font: 11px/1 var(--mono);
}

.app-choice-list label b {
  color: #c8ced8;
  font: 11px/1 var(--mono);
  text-transform: uppercase;
}

.app-field-label {
  display: block;
  margin: 5px 0 -4px;
  color: #c3c8d1;
  font: var(--t-label-sm)/1.2 var(--mono);
  letter-spacing: var(--t-label-track-sm);
  text-transform: uppercase;
}

.app-choice-form > input,
.app-choice-form > select,
/* The stepped sign-up wraps each input with its label, help and error, so the
   direct-child selector above stops matching and the field falls back to the
   browser's white default. Same treatment, one level deeper. */
.app-choice-form .app-field > input,
.app-choice-form .app-field > select,
.app-panel > select {
  width: 100%;
  min-height: 46px;
  padding: 0 13px;
  border: 1px solid rgba(239, 242, 247, 0.16);
  border-radius: 9px;
  outline: 0;
  background: #090b0f;
  color: var(--app-ink);
  font: 12px/1 var(--display);
}

.app-choice-form > input:focus,
.app-choice-form > select:focus,
.app-choice-form .app-field > input:focus,
.app-panel > select:focus {
  border-color: rgba(239, 242, 247, 0.55);
}

.app-card-carousel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 245px), 1fr));
  gap: 16px;
}

.app-card-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.app-card-summary span {
  padding: 5px 7px;
  border: 1px solid var(--app-line);
  border-radius: 999px;
  color: var(--app-muted);
  font: 11px/1 var(--mono);
  text-transform: uppercase;
}

.app-button--secondary {
  border-color: var(--app-line);
  background: transparent;
  color: var(--app-ink);
}

/* Hover is a capability, not a screen size. Without this guard every rule below
   also fires on touch, where :hover latches after a tap and leaves cards raised
   and rows highlighted until the user taps somewhere else. */
@media (hover: hover) {
  .app-button--secondary:hover {
    background: rgba(255, 255, 255, 0.05);
  }
}

.app-warning {
  padding: 14px;
  border: 1px solid rgba(233, 196, 106, 0.2);
  border-radius: 10px;
  background: rgba(233, 196, 106, 0.055);
}

.app-warning strong {
  color: #e9d69a;
  font: 11px/1 var(--mono);
  letter-spacing: 0.05em;
}

.app-warning p {
  margin: 7px 0 0;
  color: var(--app-muted);
  font-size: 12px;
  line-height: 1.5;
}

.app-instructions {
  display: grid;
  gap: 17px;
}

.app-instructions dl {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin: 0;
}

.app-instructions dl div {
  padding: 12px;
  border: 1px solid var(--app-line);
  border-radius: 9px;
}

.app-instructions dt {
  color: var(--app-muted);
  font: 11px/1 var(--mono);
  text-transform: uppercase;
}

.app-instructions dd {
  margin: 7px 0 0;
  font-size: 12px;
}

.app-instructions code {
  overflow-wrap: anywhere;
  padding: 16px;
  border: 1px solid rgba(143, 227, 176, 0.17);
  border-radius: 9px;
  background: rgba(143, 227, 176, 0.04);
  color: var(--good);
  font: 11px/1.6 var(--mono);
  user-select: all;
}

.app-warning-list {
  margin: 0;
  padding: 14px 14px 14px 28px;
  border: 1px solid rgba(233, 196, 106, 0.15);
  border-radius: 9px;
  color: #b6a878;
  font-size: 12px;
  line-height: 1.55;
}

.app-status-chip[data-state="pending"],
.app-status-chip[data-state="active"] {
  color: var(--amber);
}

.app-status-chip[data-state="confirmed"],
.app-status-chip[data-state="consumed"] {
  color: var(--good);
}

.app-status-chip[data-state="expired"],
.app-status-chip[data-state="locked"] {
  color: var(--bad);
}

/* Progressive-disclosure divider: the verify step reveals below the create
   form inside the same panel, so it gets a hairline top rule instead of a
   second nested bordered card. */
.app-challenge-reveal {
  margin-top: 22px;
  padding-top: 22px;
  border-top: 1px solid var(--app-line);
}

.app-demo-code {
  display: grid;
  place-items: center;
  gap: 10px;
  margin-bottom: 18px;
  padding: 22px;
  border: 1px solid rgba(233, 196, 106, 0.2);
  border-radius: 12px;
  background: rgba(233, 196, 106, 0.045);
}

.app-demo-code span,
.app-demo-code small {
  color: var(--app-muted);
  font: 11px/1.3 var(--mono);
  text-transform: uppercase;
}

.app-demo-code strong {
  color: #f0dd9d;
  font: 19px/1 var(--mono);
  letter-spacing: 0.08em;
}

.app-result-line {
  margin: 14px 0 0;
  color: var(--app-muted);
  font-size: 12px;
}

.app-result-line b {
  color: var(--app-ink);
}

.app-challenge-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.app-challenge-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--app-line);
}

.app-challenge-list li > div {
  display: grid;
  gap: 5px;
}

.app-challenge-list li > div:last-child {
  justify-items: end;
}

.app-challenge-list strong {
  font-size: 12px;
  font-weight: 600;
}

.app-challenge-list span,
.app-challenge-list small {
  color: var(--app-muted);
  font: 11px/1.3 var(--mono);
}

.app-challenge-list span[data-state="active"] {
  color: var(--amber);
}

.app-challenge-list span[data-state="consumed"] {
  color: var(--good);
}

.app-challenge-list span[data-state="expired"],
.app-challenge-list span[data-state="locked"] {
  color: var(--bad);
}

@keyframes app-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (max-width: 720px) {
  .app-intro-panel {
    align-items: flex-start;
    flex-direction: column;
  }
}

@media (max-width: 480px) {
  .app-panel {
    padding: 21px 18px;
  }

  .app-card-visual {
    padding: 18px;
  }

  .app-card-bottom {
    right: 18px;
    bottom: 17px;
    left: 18px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-loader-mark {
    animation: none;
    border-top-color: #9097a2;
  }

  .app-button {
    transition: none;
  }
}

/* Home "Your card" panel. The CardFace primitive has no intrinsic width, so
   it is capped here rather than allowed to scale with the desktop column
   (the Apple Pay preview elsewhere hit exactly that, rendering a ~700px-tall
   card before it was capped). */
.app-home-card-face {
  max-width: 320px;
}

/* ---------- figure inheritance ----------

   A figure (<strong><LimitBadge/></strong>) is rendered by <span class="odometer">.
   Every label rule on this site is written as `.panel span, .panel small`, and a
   descendant rule on the span always beats the size the parent <strong> inherits
   down. That silently collapsed eleven headline figures to the 11px label size,
   uppercased the "/ mo" affix, and tinted them --muted: the 72px account balance,
   the 54px card balance, the 38px fee and cap values, the 30px settled total, and
   the 28/19px hold and satellite figures all rendered at label scale.

   Scoped to <strong> on purpose. Odometers that legitimately sit inside a label
   (the "Pending $412" caption under the balance) keep the label's type. Longhands
   rather than `font: inherit`, because the shorthand would reset the
   font-variant-numeric: tabular-nums the odometer needs to stop digits jittering
   as they count. Last in the file so it wins the specificity tie with the label
   rules by source order. */
strong > .odometer {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  font-style: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  text-transform: none;
  color: inherit;
}

/* ---------- coarse-pointer targets ----------

   The 44px target minimum is WCAG 2.5.5 (AAA), not 2.5.8 (AA, which asks for
   24px and every one of these already clears). So this is scoped to coarse
   pointers rather than applied everywhere: a finger needs the 44px, a mouse
   does not, and forcing it at every width would stretch the mega-menu and the
   nav out of the density they were composed at.

   Keyed on pointer, not width, because the cases that actually failed were an
   iPad in landscape at 1024px and a phone at 320px. Width would have caught
   neither correctly. */
@media (pointer: coarse) {
  /* Padding rather than min-height: these are inline/block text links, so
     growing the box keeps the label optically where it was instead of
     re-centring it inside a taller row. */
  .menu-link {
    padding: 12px 0;
  }

  .nav-trigger {
    padding: 13px 14px;
  }

  .nav-logo,
  .nav-cta,
  .app-text-link {
    min-height: 44px;
  }

  .nav-logo,
  .nav-cta {
    align-items: center;
  }

  /* Both variants are text links sitting under the auth forms: a real <a> and
     a <button> styled to match. Centring keeps the underline on the text
     rather than floating it in a 44px box. */
  .app-text-link {
    display: flex;
    align-items: center;
  }

  .app-link-button {
    justify-content: flex-start;
  }

  /* The checklist step marker is a 32px circle in a 36px grid column, and the
     circle is the design. Growing the box would either overflow the column or
     force a 44px ring that no longer reads as a step marker, so the hit area
     grows instead of the mark: inset -6px on each side is exactly 44x44. The
     pseudo-element is a child of the button, so taps on it land on the button.
     Measured by hit-testing the corners, not by reading the box. */
  .app-checklist button {
    position: relative;
  }

  /* Square, not a circle. border-radius: 50% here looked tidier and was wrong:
     it turns a 44x44 target into a 22px-radius disc, and the corners a thumb
     actually lands on fall outside it. Target size is measured as a bounding
     box, so the hit area is a box. */
  .app-checklist button::after {
    content: "";
    position: absolute;
    /* -7, not -6. An absolutely positioned child is inset from the padding
       box, and the button's 32px is a border box with a 1px border, so the
       padding box is 30px: -6 lands on 42x42 and -7 on the 44x44 this needs. */
    inset: -7px;
  }

  /* The header avatar is the Account button on every touch layout below
     1024px, where the sidebar that replaces it does not exist. 34px is the
     right size for a mark in a 52px header, so the hit area grows and the
     circle does not. border: 0 here, so the padding box is a true 34 and -5
     lands on exactly 44; the checklist marker above needs -7 for the same
     result because it carries a 1px border. */
  .app-shell-avatar {
    position: relative;
  }

  .app-shell-avatar::after {
    content: "";
    position: absolute;
    inset: -5px;
  }
}

/* ---------- stepped sign-up ----------

   The register form posts one RegisterInput as it always did; these carry the
   three-step grouping that replaced the fourteen-field wall. Built on the
   existing .app-field-* / .app-button vocabulary rather than a parallel set,
   so the auth panel keeps one visual system. */

/* Each field owns its label, help and error as one block, so an error pushes
   only its own field rather than shifting the ones below it out of alignment. */
.app-field {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 5px;
}

.app-field .app-field-help {
  margin: 2px 0 0;
}

/* Named alongside .app-form-note--error and coloured from the same token: an
   inline field error and the submit-level error are the same kind of news, and
   nothing else on this surface is --bad. */
.app-field-error {
  margin: 2px 0 0;
  color: var(--bad);
  font: var(--t-label-sm)/1.4 var(--mono);
  letter-spacing: var(--t-label-track-sm);
}

.app-field input[aria-invalid="true"] {
  border-color: rgba(232, 134, 122, 0.55);
}

/* The step bar is the checklist progress bar at a different scale: same track,
   same fill, sitting under the title instead of inside a panel. */
.app-progress--steps {
  margin: 6px 0 14px;
}

.app-step-head {
  display: grid;
  gap: 3px;
  margin: 0 0 6px;
  color: var(--app-ink, var(--ink));
  font: 600 17px var(--display);
  letter-spacing: -0.01em;
}

/* Focused programmatically on step change so the move is announced; it is a
   heading, not a control, so it takes no focus ring of its own. */
.app-step-head:focus {
  outline: none;
}

.app-step-head span {
  color: #737a86;
  font: var(--t-label-sm)/1.2 var(--mono);
  letter-spacing: var(--t-label-track-sm);
  text-transform: uppercase;
}

.app-step-nav {
  display: flex;
  gap: 10px;
  margin-top: 6px;
}

.app-step-nav .app-button--wide {
  flex: 1 1 auto;
}

.app-step-nav .app-button--secondary {
  flex: 0 0 auto;
  padding-inline: 20px;
}

/* .app-auth-panel gives .app-button an explicit opaque surface, which the
   generic --secondary rule cannot outrank. Back is the quieter of the two
   actions and has to read that way, so the override is restated here. */
.app-auth-panel .app-button--secondary {
  border: 1px solid var(--app-line, var(--edge));
  background: transparent;
  color: var(--app-ink, var(--ink));
}

/* ---------- app shell height ----------

   .app-shell was min-height: 100dvh, a floor rather than a ceiling, so the
   shell grew with its content and the sidebar (stretched by .app-shell's
   align-items) grew with it. At a 900px viewport that put the sidebar's status
   chip at 912px, below the fold, on a nav the component itself calls
   persistent. .app-shell-content already declares overflow-y: auto, so the
   architecture always intended an internally scrolling content area: this
   pins the shell to the viewport so that scroll region is the one that moves
   and the nav stays where it was meant to. */
@media (min-width: 1024px) {
  .app-shell {
    height: 100dvh;
  }

  /* The account banner is a sibling above the shell inside #root, so a shell
     that is itself 100dvh starts 36px down and ends 36px below the fold,
     taking the sidebar's status chip with it. The viewport belongs to the root:
     the banner takes what it needs, the shell takes the rest. Scoped with
     :has() so the marketing page, which shares #root and has no banner, is
     untouched; a browser without :has() simply keeps today's behaviour. */
  #root:has(> .app-status-banner) {
    display: flex;
    flex-direction: column;
    height: 100dvh;
  }

  #root:has(> .app-status-banner) > .app-status-banner {
    flex: 0 0 auto;
  }

  #root:has(> .app-status-banner) > .app-shell {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
  }

  /* Without min-height: 0 a flex child refuses to shrink below its content, so
     the overflow-y on .app-shell-content would never engage and the shell would
     grow anyway. */
  .app-shell-main {
    min-height: 0;
  }

  /* Back to the mobile behaviour: display: contents dissolves the grid so the
     balance panel and the checklist are siblings in .app-stack, each full
     width, in the order they are read. */
  .app-grid--hero--stacked {
    display: contents;
  }

  /* Content stacks full width in the pending state, so cap the measure rather
     than the panel: a 985px-wide row would run the step description past 120
     characters. Same intent as .app-panel-copy's 50ch. */
  .app-grid--hero--stacked .app-checklist span {
    display: block;
    max-width: 68ch;
  }
}

/* ---------- referrals ----------

   Extension of the app surface, not a new world: built on .app-panel,
   .app-button and the status chip. The only new idea is that the code itself
   is display type, because handing somebody a code is the whole job of the
   screen and everything else on it is context. */

.app-refer-hero {
  display: grid;
  gap: 14px;
  align-content: start;
}

/* Set to be read aloud one character at a time. Fragment Mono for unambiguous
   figures, tracking opened well past body mono, and a size that makes it the
   first thing the eye lands on in the panel. The generating alphabet already
   excludes 0/1/I/O for the same reason. */
.app-refer-code {
  margin: 0;
  font: 400 clamp(30px, 6vw, 42px)/1.1 var(--mono);
  letter-spacing: 0.16em;
  color: var(--app-ink, var(--ink));
  overflow-wrap: anywhere;
}

.app-refer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.app-refer-actions .app-button--wide {
  flex: 1 1 190px;
}

.app-refer-actions .app-button--secondary {
  flex: 0 0 auto;
  padding-inline: 20px;
}

/* Sized against the balance figure on Home so the two read as the same class
   of number, one money and one not. */
/* Qualified with the element to out-specify `.app-panel h2`, which otherwise
   flattened this to a 19px section heading. It is a figure, not a heading. */
h2.app-refer-points {
  margin: 2px 0 0;
  font: 600 clamp(34px, 5vw, 44px)/1 var(--display);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.app-refer-list {
  display: grid;
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--app-line);
}

/* Every row is a copy target, so the whole row is the button rather than a
   small icon inside it: the code is what you are reaching for and it is
   already the widest thing in the row. */
.app-refer-row {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 56px;
  padding: 10px 14px;
  border: 0;
  background: var(--app-panel, #0c0e12);
  color: inherit;
  cursor: pointer;
  text-align: left;
  transition: background-color 0.15s ease;
}

@media (hover: hover) {
  .app-refer-row:hover {
    background: var(--surface-2);
  }
}

.app-refer-row-code {
  font: 400 var(--t-label)/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--app-ink, var(--ink));
}

.app-refer-row-meta {
  min-width: 0;
  overflow: hidden;
  color: var(--app-muted, var(--muted));
  font: var(--t-label-sm)/1.4 var(--mono);
  letter-spacing: var(--t-label-track-sm);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* At phone width the meta line moves under the code rather than competing
   with it for a third of a 320px row. */
@media (max-width: 560px) {
  .app-refer-row {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 4px;
  }

  .app-refer-row-meta {
    grid-column: 1;
    grid-row: 2;
  }

  .app-refer-row .status-chip {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

/* --- activation: the deposit that finishes onboarding ------------------- */

/* Sized and raised like the auth panel it follows, because it is the same
   moment in the same flow: one task, centred, nothing else reachable. */
.app-activate {
  position: relative;
  width: min(460px, 100%);
  padding: 34px;
  border: 1px solid var(--app-edge);
  border-radius: 18px;
  background: var(--surface-1);
  text-align: left;
  box-shadow:
    0 40px 70px -34px rgba(0, 0, 0, 0.6),
    0 2px 0 rgba(255, 255, 255, 0.02) inset;
}

.app-activate h1 {
  margin: 6px 0 10px;
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* The one number on the screen, and the only reason anyone is on it. Set at
   display scale with tabular figures so the digits do not shift as a partial
   deposit lands and the outstanding amount counts down. */
.app-activate-amount {
  margin: 22px 0 4px;
  font: 600 clamp(40px, 8vw, 54px)/1 var(--display);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--app-ink);
}

.app-activate-picker {
  margin-top: 20px;
}

.app-activate-address {
  margin-top: 20px;
  display: grid;
  gap: 12px;
}

/* Wraps rather than truncates, and breaks anywhere: a deposit address is
   checked character by character against a wallet, so hiding the middle of it
   is exactly the wrong economy. Mono keeps the columns even for that scan. */
.app-activate-address-value {
  margin: 0;
  padding: 13px;
  border: 1px solid var(--app-edge);
  border-radius: 9px;
  background: #090b0f;
  font: 13px/1.5 var(--mono);
  letter-spacing: 0.02em;
  color: var(--app-ink);
  overflow-wrap: anywhere;
}

/* Provider deposit warnings. Body copy, not field-help: these are full
   sentences, and the first one is the difference between a deposit arriving
   and a deposit being lost. Tight leading and a small gap keep the set
   scannable so the important one is not buried in a stack of paragraphs. */
.app-activate-notes {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
  font: 13px/1.5 var(--display);
  color: var(--app-muted);
}

.app-activate-notes > li:first-child {
  color: var(--app-ink);
}

/* The transfer's own state, next to the address it belongs to. Somebody who
   has just sent money needs to see that something is happening; an address
   sitting alone on a page says nothing either way. */
.app-activate-status {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font: 12px/1.4 var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.app-activate-status--waiting {
  color: var(--app-muted);
}

.app-activate-status--waiting .status-chip-dot {
  background: var(--app-muted);
}

.app-activate-status--done {
  color: var(--good);
}

.app-activate-blocked {
  display: grid;
  gap: 10px;
  margin-top: 20px;
}

/* The one outstanding step on a new account. Sits at the top of the dashboard
   as an invitation rather than a barrier: the rest of the app stays reachable
   behind it, including the account page and the way out. */
.app-getcard {
  display: grid;
  gap: 18px;
  align-items: center;
}

@media (min-width: 720px) {
  .app-getcard {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .app-getcard .app-button {
    width: auto;
    min-width: 190px;
  }
}

/* Embedded in the shell rather than owning the viewport, so it sizes to the
   content column instead of centring itself in the window. */
.app-activate--embedded {
  width: 100%;
  max-width: 560px;
}

/* .app-panel-copy carries margin-top: -7px, tuned for the eyebrow-and-heading
   pair it was written for. In these two compositions it pulls the paragraph
   into the heading above it, and under the activation amount it nets to -3px,
   so the sentence sat on the digits. Scoped here rather than changed globally,
   because every other panel still wants the original pairing. */
.app-getcard .app-panel-copy,
.app-activate .app-panel-copy {
  margin-top: 0;
}

.app-getcard h2 {
  margin-bottom: 12px;
}

.app-activate h1 {
  margin-bottom: 12px;
}

/* The number and the sentence explaining it are one thought, but they are not
   the same line: the amount needs room to read as a figure. */
.app-activate-amount + .app-panel-copy {
  margin-top: 10px;
}

/* Date of birth. A bare input[type="date"] keeps its native chrome, which on
   mobile renders as a grey bar sitting at a different height to every field
   around it, with a picker glyph dark enough to be invisible on this
   background. WebKit gives the value its own box with a default margin and its
   own line-height, ignoring the field's, which is what pushes the row out of
   line. Normalised to sit in the same box as every other input. */
.app-choice-form .app-field > input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  /* Explicit, because the shorthand's line-height does not reach the value. */
  height: 46px;
  font-family: var(--display);
  font-size: 12px;
}

.app-choice-form .app-field > input[type="date"]::-webkit-date-and-time-value {
  margin: 0;
  text-align: left;
  line-height: 44px;
}

/* Dark by default, so it disappears against #090b0f. Inverted and dimmed to
   read as an affordance rather than a smudge. */
.app-choice-form .app-field > input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1);
  opacity: 0.45;
  cursor: pointer;
}

.app-choice-form .app-field > input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: 0.75;
}

/* Both add a second control inside a field that already has a picker. */
.app-choice-form .app-field > input[type="date"]::-webkit-inner-spin-button,
.app-choice-form .app-field > input[type="date"]::-webkit-clear-button {
  display: none;
}
