/* ============================================================================
   HODLearn — shared design foundation
   ============================================================================
   Every page links this file. It holds the design system: tokens,
   typography, the fixed chrome, the background film layer, the signal rail
   shell, layout primitives, the reveal mechanism, cards, panels, buttons, the
   phone mockup.

   What does NOT belong here: a page's signature effects. Those stay inline in
   the page that uses them, so a second page never inherits machinery it has no
   markup for. Index keeps the feature showcase, the simulator grid, the HODL
   hold and the founder quotes; partners keeps its partnership-type lock-on.
   The legal and 404 pages link this file but not hodlearn.js, so nothing they
   rely on may depend on the script running.

   Cascade note: pages link this file first and then declare their own rules in
   an inline <style>, so page rules always win ties against these. Anything here
   that must survive a page override needs !important or higher specificity.
   ========================================================================= */

:root {
  --carbon: #09090b;
  --carbon-soft: #131316;
  --carbon-line: rgba(250, 250, 250, .12);
  --paper: #fafafa;
  --alloy: #c4c4cb;
  --alloy-dim: #9e9ea8;
  --heritage: #f7931a;
  --heritage-soft: #ffb347;
  --signal: #ef4444;
  --display: "Archivo", "Helvetica Neue", system-ui, sans-serif;
  --data: "IBM Plex Mono", ui-monospace, monospace;
  --gutter: clamp(20px, 4.5vw, 84px);
  /* The gutter, but never less than the device's safe area (iPhone in landscape). */
  --pad-l: max(var(--gutter), env(safe-area-inset-left));
  --pad-r: max(var(--gutter), env(safe-area-inset-right));
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --scroll-progress: 0;

  /* Height of the fixed header: its 2px top inset, its padding (which grows
     to the notch inset on iOS), and the 44px tap target inside it. Anything
     that pins below the header must key off this rather than a guessed
     constant, or it slides under the header on notched devices. */
  --header-h: calc(2px + max(14px, env(safe-area-inset-top)) + 44px + 14px);
}

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

html { scroll-padding-top: calc(var(--header-h) + 12px); }

html {
  background: var(--carbon);
  color: var(--paper);
  font-family: var(--display);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-width: 320px;
  background: var(--carbon);
  color: var(--paper);
  overflow-x: clip;
}

a { color: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--heritage); outline-offset: 4px; }

.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;
}

/* ---------- Background film layer (quiet, never competes with content) ---------- */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

#film-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity 1400ms ease;
}

/* --film-alpha is driven by scroll: the film lifts as the reader leaves the
   hero, then settles back behind the content. */
#film-canvas.is-live { opacity: var(--film-alpha, .34); }

/* The veil guarantees a dark floor under all text regardless of frame luminance. */
.backdrop__veil {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 50% 42%, rgba(9, 9, 11, .58) 0%, rgba(9, 9, 11, .78) 62%, rgba(9, 9, 11, .93) 100%),
    linear-gradient(180deg, rgba(9, 9, 11, .7) 0%, rgba(9, 9, 11, .58) 30%, rgba(9, 9, 11, .82) 100%);
}

.backdrop__grid {
  position: absolute;
  inset: 0 var(--gutter);
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent calc(8.333% - 1px),
    rgba(250, 250, 250, .05) calc(8.333% - 1px),
    rgba(250, 250, 250, .05) 8.333%
  );
  -webkit-mask-image: linear-gradient(180deg, transparent, black 12%, black 88%, transparent);
  mask-image: linear-gradient(180deg, transparent, black 12%, black 88%, transparent);
}

/* ---------- Chrome ---------- */

.rail {
  position: fixed;
  inset: 0 0 auto;
  z-index: 80;
  height: 2px;
  background: rgba(250, 250, 250, .1);
}

.rail__fill {
  display: block;
  height: 100%;
  background: var(--heritage);
  transform: scaleX(var(--scroll-progress));
  transform-origin: left;
}

.site-header {
  position: fixed;
  inset: 2px 0 auto;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: max(14px, env(safe-area-inset-top)) var(--pad-r) 14px var(--pad-l);
  background: linear-gradient(180deg, rgba(9, 9, 11, .82), transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 720;
  letter-spacing: 0; /* any tighter and "rn" in HODLearn reads as "m" */
  text-decoration: none;
}

.brand__mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--heritage);
  color: var(--carbon);
  font-size: 12px;
  font-weight: 800;
}

.header-cta {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid rgba(250, 250, 250, .3);
  border-radius: 999px;
  background: rgba(9, 9, 11, .4);
  color: var(--paper);
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .07em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 250ms ease, border-color 250ms ease, color 250ms ease;
}

.header-cta:hover { background: var(--heritage); border-color: var(--heritage); color: var(--carbon); }

/* ---------- Gifting switch ---------- */
/* <html data-gifting="soon"> hides everything marked gifting-live and shows
   everything marked gifting-soon; "live" does the reverse. */
html[data-gifting="soon"] .gifting-live { display: none !important; }
html:not([data-gifting="soon"]) .gifting-soon { display: none !important; }

/* ---------- Header menu ---------- */

.site-nav { display: flex; align-items: center; gap: 10px; }
.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 10px;
  color: var(--alloy);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.site-nav__link:hover { color: var(--paper); }

.menu-btn {
  flex: none;
  display: inline-grid;
  place-content: center;
  gap: 4px;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(250, 250, 250, .3);
  border-radius: 999px;
  background: rgba(9, 9, 11, .4);
  cursor: pointer;
}
.menu-btn span { display: block; width: 16px; height: 1.5px; border-radius: 1px; background: var(--paper); transition: transform 250ms var(--ease-out), opacity 200ms ease; }
.menu-btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }
.menu-btn:hover { border-color: var(--heritage); }
.menu-btn:focus-visible, .site-menu a:focus-visible { outline: 2px solid var(--heritage); outline-offset: 2px; }

.site-menu {
  position: fixed;
  inset: 0;
  z-index: 65;
  background: rgba(9, 9, 11, .74);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.site-menu[hidden] { display: none; }
html.menu-open, html.menu-open body { overflow: hidden; }
html.menu-open .sticky-cta { visibility: hidden; }

.site-menu__panel {
  position: absolute;
  top: calc(max(14px, env(safe-area-inset-top)) + 58px);
  right: max(var(--gutter), env(safe-area-inset-right));
  display: grid;
  gap: 22px;
  width: min(340px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100vh - max(14px, env(safe-area-inset-top)) - 58px - 16px - env(safe-area-inset-bottom));
  max-height: calc(100dvh - max(14px, env(safe-area-inset-top)) - 58px - 16px - env(safe-area-inset-bottom));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 22px;
  border: 1px solid var(--carbon-line);
  border-radius: 20px;
  background: rgba(20, 20, 23, .98);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .9);
}
.site-menu__group { display: grid; gap: 2px; }
.site-menu__group .micro { margin: 0 0 6px; color: var(--alloy-dim); }
.site-menu a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 12px;
  color: var(--paper);
  font-size: 15.5px;
  font-weight: 600;
  text-decoration: none;
}
.site-menu a:hover { background: rgba(250, 250, 250, .06); }
.site-menu a.site-menu__primary { justify-content: center; margin-bottom: 4px; background: var(--heritage); color: #1c1917; }
.site-menu a.site-menu__primary:hover { background: #ffa133; }
.site-menu__note { margin: 6px 12px 0; color: var(--alloy-dim); font-size: 13px; line-height: 1.5; }

/* Phones: the menu button carries everything, so the header stays one tidy row. */
@media (max-width: 560px) {
  .site-nav__link { display: none; }
  .site-nav .header-cta { padding: 0 14px; white-space: nowrap; }
}
@media (max-width: 360px) {
  .site-nav { gap: 6px; }
  .site-nav .header-cta { padding: 0 11px; font-size: 11px; letter-spacing: .04em; }
}

/* Phone frames slide in from the side and their side buttons sit just outside
   the frame; neither may ever make the page scroll sideways. clip (not hidden)
   keeps the sticky showcase phone working. */
main { overflow-x: clip; }

/* ---------- Signal rail ---------- */

/* An analog meter in the right gutter: static at the top of the page,
   resolving into a locked waveform by the closing CTA. Built entirely by JS,
   so without JS there is simply no rail — the hairline at the top of the
   viewport remains the progress indicator. Hidden on narrow screens, where
   the sticky phone and sticky CTA already own the edges. */
.snr {
  --snr-reach: 18px;
  position: fixed;
  z-index: 60;
  top: 96px;
  right: 20px;
  bottom: 40px;
  display: none;
  width: 26px;
  pointer-events: none;
}

@media (min-width: 1024px) {
  .snr:not([hidden]) { display: block; }
}

.snr__canvas { display: block; width: 100%; height: 100%; }

.snr__marks { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }

/* The hit area reaches left of the rail and is 26px tall, so the notch can
   stay a hairline without becoming an unusable target. */
.snr__mark {
  position: absolute;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  box-sizing: border-box;
  width: calc(100% + var(--snr-reach));
  height: 26px;
  padding: 0 0 0 var(--snr-reach);
  border: 0;
  background: none;
  color: var(--alloy-dim);
  transform: translateY(-50%);
  cursor: pointer;
  pointer-events: auto;
}

/* The notch runs the full width of the rail — wider than any waveform tick —
   with a dot on its outer end so it reads as a marker, not as more signal. */
.snr__mark::after {
  content: "";
  width: 100%;
  height: 1px;
  background: currentColor;
  opacity: .5;
  transition: opacity 200ms ease;
}

.snr__mark::before {
  content: "";
  position: absolute;
  left: var(--snr-reach);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: .8;
}

.snr__mark:hover, .snr__mark:focus-visible { color: var(--heritage); }
.snr__mark:hover::after, .snr__mark:focus-visible::after { opacity: 1; }

.snr__label {
  position: absolute;
  right: calc(100% + 10px);
  padding: 5px 9px;
  border: 1px solid var(--carbon-line);
  border-radius: 7px;
  background: rgba(9, 9, 11, .92);
  color: var(--paper);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(6px);
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
  pointer-events: none;
}

.snr__mark:hover .snr__label, .snr__mark:focus-visible .snr__label { opacity: 1; transform: none; }

/* Variant: the signal-strength readout, toggled with ?readout=off */
.snr__readout {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  color: var(--alloy-dim);
  text-align: right;
  white-space: nowrap;
  transition: color 400ms ease;
}

.snr:not(.snr--readout) .snr__readout { display: none; }
.snr.is-locked .snr__readout { color: var(--heritage); }

/* Tight gutters: keep the meter, drop everything that needs room. */
@media (max-width: 1279px) {
  .snr { width: 15px; right: 12px; }
  .snr__label, .snr__readout { display: none; }
}

/* ---------- Layout primitives ---------- */

main { position: relative; z-index: 10; }

.band {
  position: relative;
  padding: clamp(88px, 12vw, 168px) var(--pad-r) clamp(88px, 12vw, 168px) var(--pad-l);
}

.band--tint { background: rgba(9, 9, 11, .84); border-top: 1px solid var(--carbon-line); border-bottom: 1px solid var(--carbon-line); }
.band--solid { background: var(--carbon); }

.wrap { max-width: 1180px; margin: 0 auto; }
.wrap--narrow { max-width: 880px; }

.micro {
  font-family: var(--data);
  font-size: 10px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 24px;
  color: var(--heritage-soft);
}

.eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  background: var(--heritage);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 700ms 120ms var(--ease-out);
}

.is-in .eyebrow::before, .eyebrow.is-in::before { transform: scaleX(1); }

.section-title {
  margin: 0;
  font-size: clamp(34px, 4.6vw, 66px);
  font-weight: 760;
  font-variation-settings: "wdth" 92;
  letter-spacing: -.022em;
  line-height: .95;
  text-wrap: balance;
}

.section-lede {
  max-width: 44rem;
  margin: 22px 0 0;
  color: var(--alloy);
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.55;
}

.accent { color: var(--heritage); }

/* Scroll reveals */
.reveal-up {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out);
}

.reveal-up.is-in { opacity: 1; transform: none; }

.line-mask { overflow: hidden; padding-bottom: .14em; }
.line-mask > span {
  display: block;
  transform: translateY(110%);
  transition: transform 900ms var(--ease-out);
}
.line-mask.is-in > span { transform: translateY(0); }

/* ---------- Hero ---------- */

/* The hero is a plain section: its statement is paced by a load cadence,
   not by scrolling, so nothing here depends on scroll position. The entrance
   runs quicker than the page's scroll reveals so the whole hero is readable
   within about a second of landing. */
.hero .line-mask > span { transition-duration: 620ms; }
/* The ™ on the last line can run a little past the column; give the mask room
   so it is not clipped. */
.hero .line-mask { margin-right: -.8em; padding-right: .8em; }
.hero .reveal-up { transition-duration: 620ms; }

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(32px, 5vw, 80px);
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(120px, 16vh, 190px) var(--pad-r) clamp(72px, 10vh, 120px) var(--pad-l);
  max-width: 1180px;
  margin: 0 auto;
}

.hero__title {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 30px;
  font-size: clamp(42px, 6.6vw, 92px);
  font-weight: 780;
  font-variation-settings: "wdth" 90;
  letter-spacing: -.018em; /* tighter runs "rn" together: "Learning" read as "Leaming" */
  line-height: .92;
}

.hero__title .muted { color: var(--alloy); }
.hero__title .accent { white-space: nowrap; }
.hero__title sup { font-size: .38em; vertical-align: super; }

.hero__deck {
  max-width: 34rem;
  margin: 0 0 32px;
  color: var(--alloy);
  font-size: clamp(16px, 1.4vw, 19px);
  line-height: 1.6;
}

.store-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 30px;
}

.store-btn {
  display: inline-flex;
  align-items: center;
  gap: 13px;
  min-height: 60px;
  padding: 0 22px;
  border: 1px solid rgba(250, 250, 250, .18);
  border-radius: 14px;
  background: rgba(20, 20, 23, .92);
  color: var(--paper);
  text-align: left;
  cursor: pointer;
  transition: border-color 250ms ease, transform 250ms var(--ease-out), background 250ms ease;
}

a.store-btn { text-decoration: none; }
.store-btn:hover { border-color: rgba(247, 147, 26, .6); transform: translateY(-2px); background: rgba(39, 39, 42, .95); }
.store-btn svg { width: 24px; height: 24px; flex: none; }
.store-btn__kicker { display: block; color: var(--heritage-soft); font-family: var(--data); font-size: 10px; letter-spacing: .07em; text-transform: uppercase; }
.store-btn__label { display: block; font-size: 16px; font-weight: 650; letter-spacing: -.005em; }

/* The single consolidated call to action. With no sibling button to balance
   against it carries primary weight rather than the outlined treatment two
   competing store buttons needed. */
.store-btn--solo {
  border-color: transparent;
  background: var(--heritage);
  color: #1c1917;
}

.store-btn--solo:hover { border-color: transparent; background: #ffa133; }
.store-btn--solo .store-btn__kicker { color: rgba(28, 25, 23, .74); }

/* Not open yet: reads as a quiet placeholder, not a button. */
.store-btn--soon { border-style: dashed; color: var(--alloy); cursor: default; }
.store-btn--soon:hover { border-color: rgba(250, 250, 250, .18); transform: none; background: rgba(20, 20, 23, .92); }
.store-btn--soon .store-btn__kicker { color: var(--alloy-dim); }

.trust-row {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  color: var(--alloy-dim);
  font-size: 14px;
}

.trust-row span { display: inline-flex; align-items: center; gap: 8px; }
.trust-row svg { width: 16px; height: 16px; }

/* Phone mockup — the recurring hero object */

/* The frame is an iPhone 17 Pro: a 402 x 874 pt screen with ~55 pt corners, the
   Dynamic Island, a 62 pt status-bar inset at the top and a 34 pt home-indicator
   inset at the bottom. The app captures are exactly the content area between
   those insets (402 x 778), so they sit where they would on the real phone,
   uncropped and unscaled. Every size is a share of the width, so the frame keeps
   its proportions at any size; the island and home bar are the frame's own. */
.device {
  position: relative;
  isolation: isolate; /* keeps the glow behind the phone, not behind the section */
  width: 272px;
  flex: none;
}

.device--small { width: 228px; }

.device__shell {
  position: relative;
  padding: 1.8%; /* the iPhone 17 Pro's black border is thin: about 1.5% of its width */
  border: 3px solid #58585C;
  border-radius: 15.6% / 7.2%;
  background: #050505;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05), 0 4px 60px rgba(0, 0, 0, .7), 0 25px 50px -12px rgba(0, 0, 0, .8);
}

.device__screen {
  position: relative;
  aspect-ratio: 402 / 874;
  box-sizing: border-box;
  padding: 15.42% 0 8.46%;
  overflow: hidden;
  border-radius: 13.7% / 6.3%;
  background: #000;
}

/* Dynamic Island and home indicator. */
.device__screen::before,
.device__screen::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 999px;
}
.device__screen::before { top: 2.74%; width: 31.1%; aspect-ratio: 125 / 37; background: #000; box-shadow: 0 0 0 1px rgba(255, 255, 255, .06); }
.device__screen::after { bottom: 2.1%; width: 34.6%; height: 0; padding-bottom: 1.24%; background: rgba(250, 250, 250, .62); }

.device__screen > div {
  position: relative;
  width: 100%;
  /* Height comes from the aspect ratio, never "100%": Safari resolves 100% against
     the screen's padded box, which zoomed and cropped every capture. */
  height: auto;
  aspect-ratio: 402 / 778;
  overflow: hidden;
  background: #000;
}

.device__screen img,
.device__screen video { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }

/* A real app clip: plays once when it comes into view, then rests on its last
   frame. The button is the only control: Pause while it plays, Play again after.
   With reduced motion or Save-Data nothing starts on its own; the button does. */
.clip-wrap { position: relative; width: 100%; }
.clip-wrap video { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
/* Under the phone, never over the app's own screen. */
.clip-btn {
  display: flex;
  align-items: center;
  width: max-content;
  margin: 14px auto 0;
  min-height: 34px;
  padding: 0 13px;
  border: 1px solid rgba(250, 250, 250, .22);
  border-radius: 999px;
  background: rgba(9, 9, 11, .78);
  color: var(--paper);
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .05em;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.clip-btn:hover { border-color: rgba(247, 147, 26, .6); }
.clip-btn:focus-visible { outline: 2px solid var(--heritage); outline-offset: 2px; }

.device__btn { position: absolute; z-index: 5; background: linear-gradient(90deg, #58585C, #6E6E72, #58585C); }
.device__btn--a { left: -4px; top: 17%; width: 4px; height: 5.1%; border-radius: 2px 0 0 2px; }
.device__btn--b { left: -4px; top: 26.4%; width: 4px; height: 6.4%; border-radius: 2px 0 0 2px; }
.device__btn--c { left: -4px; top: 34.7%; width: 4px; height: 6.4%; border-radius: 2px 0 0 2px; }
.device__btn--d { right: -4px; top: 32.2%; width: 4px; height: 12.5%; border-radius: 0 2px 2px 0; background: linear-gradient(270deg, #58585C, #6E6E72, #58585C); }

.device__glow {
  position: absolute;
  inset: 8%;
  z-index: -1;
  border-radius: 50%;
  background: rgba(247, 147, 26, .22);
  filter: blur(60px);
  transition: background 700ms ease, inset 700ms ease;
}

/* While a phone's clip plays, its glow warms up so the eye goes to it; it
   settles back when the clip stops. Reduced motion gets the warmth, not the
   breathing. Shown on phones too while playing (otherwise hidden there). */
.is-playing .device__glow { display: block !important; inset: -4% -14%; background: rgba(247, 147, 26, .5); filter: blur(70px); }
@media (prefers-reduced-motion: no-preference) {
  .is-playing .device__glow { animation: hl-glow 2.8s ease-in-out infinite alternate; }
}
@keyframes hl-glow { from { opacity: .7; } to { opacity: 1; } }

.device-wrap {
  opacity: 0;
  transform: translateX(70px);
  transition: opacity 900ms var(--ease-out), transform 900ms var(--ease-out);
}

.device-wrap.is-in { opacity: 1; transform: none; }

/* ---------- Sticky mobile CTA ---------- */

.sticky-cta {
  position: fixed;
  z-index: 90;
  right: 0;
  bottom: 0;
  left: 0;
  display: none;
  gap: 10px;
  padding: 10px var(--pad-r) max(10px, env(safe-area-inset-bottom)) var(--pad-l);
  border-top: 1px solid var(--carbon-line);
  background: rgba(9, 9, 11, .94);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transform: translateY(120%);
  transition: transform 400ms var(--ease-out);
}

.sticky-cta.is-visible { transform: none; }

.sticky-cta button,
.sticky-cta a {
  flex: 1 1 0;
  min-height: 46px;
  border: 1px solid rgba(250, 250, 250, .2);
  border-radius: 12px;
  background: rgba(24, 24, 27, .9);
  color: var(--paper);
  font-family: var(--display);
  font-size: 14px;
  font-weight: 640;
  cursor: pointer;
}

/* An anchor in the sticky bar needs the box behaviour a button gets for free. */
.sticky-cta a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
}

.sticky-cta > :first-child { border-color: transparent; background: var(--heritage); color: #1c1917; }

/* ---------- Actions ---------- */

/* The plain one-line action. The store buttons are deliberately not this: they
   carry a platform mark and two lines of text, so they stay their own thing. */
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: 12px;
  font-family: var(--display);
  font-size: 15px;
  font-weight: 640;
  text-decoration: none;
  cursor: pointer;
  transition: background 250ms ease, border-color 250ms ease, color 250ms ease, transform 250ms var(--ease-out);
}

.btn svg { width: 18px; height: 18px; flex: none; }
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--heritage); color: #1c1917; }
.btn--primary:hover { background: var(--heritage-soft); }
.btn--ghost { border-color: var(--carbon-line); background: rgba(24, 24, 27, .6); color: var(--paper); }
.btn--ghost:hover { border-color: rgba(250, 250, 250, .34); }
.btn--lg { min-height: 56px; padding: 0 28px; font-size: 17px; }

.card__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: 18px;
  border-radius: 14px;
  background: rgba(247, 147, 26, .18);
  color: var(--heritage);
}

.card__icon svg { width: 22px; height: 22px; }

/* ---------- Why panel ---------- */

.panel {
  margin-top: clamp(36px, 5vw, 56px);
  padding: clamp(28px, 4vw, 46px);
  border: 1px solid var(--carbon-line);
  border-radius: 22px;
  background: rgba(20, 20, 23, .9);
}

.panel p { margin: 0 0 20px; color: #d4d4d8; font-size: clamp(16px, 1.35vw, 18px); line-height: 1.7; }
.panel p:last-child { margin-bottom: 0; }
.panel strong { color: var(--heritage-soft); font-weight: 600; }

.why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 18px; margin-top: 22px; }
.why-card { padding: 26px; border: 1px solid var(--carbon-line); border-radius: 18px; background: rgba(20, 20, 23, .86); text-align: center; transition: border-color 300ms ease, transform 400ms var(--ease-out); }
.why-card:hover { border-color: rgba(247, 147, 26, .42); transform: translateY(-4px); }
.why-card .card__icon { margin: 0 auto 16px; border-radius: 50%; }
.why-card h3 { margin: 0 0 8px; font-size: 17px; font-weight: 660; }
.why-card p { margin: 0; color: var(--alloy); font-size: 14px; line-height: 1.6; }

/* ---------- Footer ---------- */

.site-footer {
  position: relative;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 40px var(--pad-r) max(40px, env(safe-area-inset-bottom)) var(--pad-l);
  border-top: 1px solid var(--carbon-line);
  background: var(--carbon);
  color: var(--alloy-dim);
}

.site-footer p { margin: 0; max-width: 46rem; }
.site-footer a { display: inline-flex; align-items: center; min-height: 44px; text-underline-offset: 4px; }

/* Keeps several footer links on one row instead of letting the parent's
   space-between scatter them across the full width. */
.site-footer__links { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; }

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  .hero {
    grid-template-columns: 1fr;
    justify-items: start;
    min-height: auto;
    padding-top: clamp(96px, 15vh, 132px);
  }

  .hero__copy { width: 100%; }
  .device-wrap { justify-self: center; transform: translateY(40px); }
  .device-wrap.is-in { transform: none; }
  .device { width: 244px; }
  .hero__title { font-size: clamp(38px, 10.5vw, 60px); }
  .store-row { width: 100%; }
  .store-btn { flex: 1 1 220px; }
  .backdrop__grid { display: none; }

  .sticky-cta { display: flex; }
  body { padding-bottom: 72px; }
}

@media (max-width: 560px) {
  .band { padding-top: 72px; padding-bottom: 72px; }
  .why-card { padding: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  .reveal-up { opacity: 1; transform: none; }
  .line-mask > span { transform: none; }
  .device-wrap { opacity: 1; transform: none; }
  .eyebrow::before { transform: scaleX(1); }
  .sticky-cta { transform: none; }
  #film-canvas.is-live { opacity: .22; }
}

/* ---------- Legal documents (privacy, terms) ---------- */
/* These are static prose pages with no scroll choreography, so nothing here
   may depend on the shared script running. Deliberately avoid .reveal-up and
   .line-mask on these pages: both start hidden and are only revealed by JS,
   so a script failure would leave the legal text invisible — which is exactly
   the content that must never be unreachable. */

/* The header CTA is a <button> on the app pages and a link here. */
a.header-cta { display: inline-flex; align-items: center; text-decoration: none; }

.legal {
  padding: calc(var(--header-h) + clamp(52px, 8vw, 96px)) var(--pad-r) clamp(72px, 10vw, 128px) var(--pad-l);
}

.legal__head, .legal__body { max-width: 820px; margin: 0 auto; }

.legal__title {
  margin: 0;
  font-size: clamp(32px, 4.4vw, 56px);
  font-weight: 760;
  font-variation-settings: "wdth" 92;
  letter-spacing: -.022em;
  line-height: .98;
}

.legal__meta { margin: 18px 0 0; color: var(--alloy-dim); }

.legal__lede {
  margin: 22px 0 0;
  max-width: 60ch;
  color: var(--alloy);
  font-size: clamp(16px, 1.5vw, 18px);
  line-height: 1.65;
}

.legal__section {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: 0 22px;
  margin-top: clamp(30px, 3.6vw, 44px);
  padding-top: clamp(30px, 3.6vw, 44px);
  border-top: 1px solid var(--carbon-line);
}

.legal__num {
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .09em;
  color: var(--heritage);
  padding-top: .5em;
}

.legal__section > :not(.legal__num) { grid-column: 2; }

.legal__section h2 {
  margin: 0 0 14px;
  font-size: clamp(19px, 1.9vw, 23px);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.25;
}

.legal p {
  margin: 0 0 14px;
  color: var(--alloy);
  font-size: 16px;
  line-height: 1.72;
}

.legal p:last-child { margin-bottom: 0; }
.legal strong { color: var(--paper); font-weight: 640; }
.legal a { color: var(--heritage-soft); text-underline-offset: 3px; }

@media (max-width: 640px) {
  .legal__section { grid-template-columns: 1fr; gap: 0; }
  .legal__section > :not(.legal__num) { grid-column: 1; }
  .legal__num { padding: 0 0 10px; }
}

/* ---------- Skip link ---------- */
/* Keyboard and screen-reader users otherwise tab the whole header on every
   page before reaching content. Hidden until focused, so it costs nothing
   visually. */
.skip-link {
  position: fixed;
  top: -4rem;
  left: 12px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: 10px;
  background: #f7931a;
  color: #18181b;
  font-weight: 650;
  font-size: 0.95rem;
  text-decoration: none;
  transition: top 140ms ease-out;
}
.skip-link:focus {
  top: 12px;
  outline: 2px solid #fff;
  outline-offset: 2px;
}
/* The jump target should never show a focus ring just from being landed on. */
main:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* ---------- Laptop mockup (a MacBook): for the desktop web app ----------
   A dark lid with a thin black bezel and a camera dot around a 16:10 screen,
   then the aluminium base with its opening notch. Sizes are shares of the
   width, so it scales; the capture fills the screen uncropped. */
.macbook { position: relative; isolation: isolate; width: 100%; max-width: 1000px; margin: 0 auto; }
.macbook__lid {
  position: relative;
  padding: 2.1% 2.1% 2.4%;
  border: 2px solid #3b3b40;
  border-radius: 2.6% / 4%;
  background: #08080a;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05), 0 30px 60px -28px rgba(0, 0, 0, .9);
  transition: box-shadow 700ms ease, border-color 700ms ease;
}
.macbook__lid::before {
  content: "";
  position: absolute;
  top: 0.85%;
  left: 50%;
  width: 0.7%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #1d1d22;
  transform: translateX(-50%);
}
.macbook__screen { position: relative; overflow: hidden; aspect-ratio: 16 / 10; border-radius: 0.5%; background: #000; }
.macbook__screen img,
.macbook__screen video { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.macbook__base {
  position: relative;
  width: 112%;
  height: 0;
  margin-left: -6%;
  padding-bottom: 2.6%;
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  background: linear-gradient(180deg, #8d8e93 0%, #5d5e63 35%, #3a3b3f 100%);
  box-shadow: 0 14px 30px -14px rgba(0, 0, 0, .9);
}
.macbook__base::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 14%;
  height: 38%;
  border-radius: 0 0 10px 10px;
  background: #2c2d31;
  transform: translateX(-50%);
}
.is-playing .macbook__lid { border-color: rgba(247, 147, 26, .4); box-shadow: 0 0 90px -10px rgba(247, 147, 26, .45), 0 30px 60px -28px rgba(0, 0, 0, .9); }
