:root {
  color-scheme: dark;
  --space: #050713;
  --ink: #f4f8ff;
  --muted: #b4c1d6;
  --cyan: #00edff;
  --line: rgba(186,219,255,.2);
  --display: clamp(3.3rem,5.7vw,6rem);
  --body: 1.1rem;
  --small: .72rem;
  --ease: cubic-bezier(.16,1,.3,1);
  --spring: cubic-bezier(.34,1.56,.64,1);
  --glass-ink: #f6f9ff;
  --focus: #f4f8ff;
  --up: #00ff88;
  --down: #ff5c5c;
}
* {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
  scroll-padding-top: 24px;
}
body {
  margin: 0;
  color: var(--ink);
  background: var(--space);
  font-family: var(--pulse-font);
  -webkit-font-smoothing: antialiased;
}
button,a {
  -webkit-tap-highlight-color: transparent;
}
button {
  font: inherit;
}
a {
  color: inherit;
}
button,a:focus-visible {
  outline-offset: 6px;
}
/* Focus rings follow the glass controls, not the accent (Justin, 8 Oct:
   the flat accent-filled controls go; liquid glass replaces them, focus
   rings included). */
a:focus-visible,button:focus-visible {
  outline: 2px solid var(--focus);
}
button {
  color: inherit;
  cursor: pointer;
}
button:disabled {
  cursor: wait;
}
svg {
  display: block;
}
button svg,a svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
[hidden] {
  display: none!important;
}
.sr-only {
  position: absolute!important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: fixed;
  left: 20px;
  top: -80px;
  padding: 14px;
  background: var(--space);
  z-index: 20;
}
.skip-link:focus {
  top: 10px;
}
.universe {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: -1;
  background: var(--space);
}
.galaxy {
  position: absolute;
  inset: -8%;
  background: url('../space/deep-space-lit-3840x2400.webp') 56% 42%/cover;
  opacity: 1;
  transform-origin: 65% 40%;
  animation: galaxy-drift 44s ease-in-out infinite alternate;
  will-change: transform;
}
.galaxy-light {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,rgba(5,7,19,.55),rgba(5,7,19,.19) 56%,rgba(5,7,19,.2)),linear-gradient(0deg,var(--space),transparent 27%,transparent 78%,rgba(5,7,19,.5));
}
.horizon {
  position: absolute;
  right: 0;
  bottom: 0;
  width: min(48vw,800px);
  aspect-ratio: 1;
  background: url('../space/planet-baby-blue.webp') right bottom/100% 100% no-repeat;
}
/* The planet's atmosphere. Its opacity is driven by pointer and scroll
   energy in cosmos.js (opacity only, so it stays on the compositor). */
.horizon-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(58% 58% at 78% 80%,rgba(190,225,255,0) 62%,rgba(190,225,255,.34) 71%,rgba(150,205,255,.12) 79%,rgba(150,205,255,0) 88%);
  opacity: 0;
}
.star-field {
  position: absolute;
  inset: -10%;
  background-repeat: repeat;
  will-change: transform;
}
.stars-near {
  background-image: radial-gradient(2px 2px at 38px 57px,rgba(228,245,255,.8) 50%,transparent),radial-gradient(1.5px 1.5px at 210px 196px,rgba(139,218,255,.8) 50%,transparent);
  background-size: 450px 380px;
  animation: stars-drift 45s linear infinite;
}
.stars-far {
  background-image: radial-gradient(1px 1px at 130px 102px,rgba(206,223,255,.6) 50%,transparent),radial-gradient(1px 1px at 303px 326px,rgba(255,255,255,.6) 50%,transparent);
  background-size: 380px 420px;
  animation: stars-drift 90s linear infinite reverse;
}
.cosmos {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
}
html:not(.lab) .cosmos {
  display: none;
}
html.cosmos-on .star-field {
  display: none;
}
.page {
  overflow: clip;
  max-width: 1440px;
  min-height: 100svh;
  margin: auto;
  padding: 0 64px;
  position: relative;
}
.masthead {
  height: 92px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
  gap: 20px;
}
.wordmark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  min-width: 44px;
  min-height: 44px;
}
.header-logo {
  display: block;
  height: 60px;
  width: auto;
  object-fit: contain;
}
.web-status,.film-kicker,.film-length,.eyebrow,.sound-note,.footer>p {
  font-family: var(--pulse-font);
  font-size: var(--small);
  letter-spacing: .15em;
}
.web-status {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
}
.web-status i,.eyebrow>span {
  width: 5px;
  height: 5px;
  background: var(--cyan);
  border-radius: 50%;
  display: inline-block;
}
.arrival {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  align-items: center;
  gap: 70px;
  min-height: min(850px,calc(100svh - 170px));
  padding: 30px 0 52px;
}
.hero-copy {
  position: relative;
  padding-bottom: 16px;
}
.logo-stage {
  position: relative;
  width: 350px;
  height: 225px;
  margin: -20px 0 -12px -36px;
  perspective: 900px;
  isolation: isolate;
}
.logo-halo {
  position: absolute;
  inset: 10% 14%;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side,rgba(120,165,255,.26),rgba(170,100,255,.1) 58%,transparent 78%);
  opacity: .7;
  pointer-events: none;
}
.hero-logo {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  animation: logo-arrive 2.3s var(--ease) both;
}
.eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--cyan);
  margin: 26px 0 18px;
  animation-delay: .3s;
}
.eyebrow>span {
  height: 4px;
  width: 4px;
}
h1 {
  font-size: var(--display);
  font-weight: 600;
  line-height: .99;
  letter-spacing: -.045em;
  margin: 0;
  animation-delay: .4s;
}
h1 em {
  font-style: italic;
  font-weight: 600;
}
.intro {
  font-size: var(--body);
  line-height: 1.6;
  font-weight: 500;
  color: var(--muted);
  margin: 24px 0;
  animation-delay: .5s;
}
.stores {
  display: flex;
  gap: 12px;
  margin: 26px 0 24px;
  animation-delay: .6s;
}

/* ── Liquid glass ──────────────────────────────────────────────────────────
   Justin, 8 Oct: the flat accent-filled buttons go; controls become liquid
   glass. Glossy dark body, a refraction rim (a conic gradient masked to a
   1px ring, its bright side turned toward the light), a specular highlight,
   a soft glow on hover and a bright press. arrival.js moves the
   light with the cursor on the CTA; the store tiles are informational, so
   they carry the material without any interactive response.
   The dark base (the background colour) is what keeps the light ink
   legible: states add light as extra image layers over it and never
   replace it. */
.glass {
  --rim: 210deg;
  --sx: 26%;
  --sy: -18%;
  --glass-sheen: linear-gradient(180deg,rgba(255,255,255,.14),rgba(255,255,255,.035) 48%,rgba(255,255,255,.07));
  position: relative;
  isolation: isolate;
  color: var(--glass-ink);
  background: var(--glass-sheen),rgba(8,11,23,.5);
  border: 1px solid rgba(255,255,255,.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.45);
  backdrop-filter: blur(18px) saturate(1.45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3),inset 0 -1px 0 rgba(255,255,255,.05),0 12px 32px rgba(0,0,0,.36);
}
.glass::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: 1;
  padding: 1px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(from var(--rim),rgba(255,255,255,.9),rgba(175,210,255,.24) 16%,rgba(255,255,255,.05) 33%,rgba(215,195,255,.3) 50%,rgba(255,255,255,.07) 66%,rgba(195,240,255,.36) 83%,rgba(255,255,255,.9));
  -webkit-mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.glass::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(150px 90px at var(--sx) var(--sy),rgba(255,255,255,.24),rgba(255,255,255,0) 72%);
  opacity: .9;
  transition: opacity .3s var(--ease);
}
.glass>* {
  position: relative;
  z-index: 2;
}
.store-tile {
  display: flex;
  align-items: center;
  gap: 13px;
  min-width: 170px;
  min-height: 70px;
  padding: 13px 19px 13px 15px;
  border-radius: 14px;
}
.store-tile.glass {
  --rim: 225deg;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22),0 8px 26px rgba(0,0,0,.28);
}
.store-icon {
  width: 33px;
  height: 33px;
  flex: none;
}
.store-tile>span {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.store-tile small {
  font-size: .65rem;
  font-weight: 600;
  letter-spacing: .13em;
  color: var(--muted);
}
.store-tile strong {
  font-size: 1.08rem;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -.03em;
  white-space: nowrap;
}
.hero-actions {
  display: flex;
  align-items: center;
  gap: 23px;
  flex-wrap: wrap;
  animation-delay: .7s;
}
.primary-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  min-height: 56px;
  padding: 0 22px 0 24px;
  text-decoration: none;
  border-radius: 14px;
  font-size: .98rem;
  font-weight: 600;
  letter-spacing: -.01em;
  transition: transform .25s var(--ease),box-shadow .25s var(--ease);
}
/* The primary CTA uses the same polished-metal role as the app controls.
   Its opaque face and fixed geometry come from pulse-card-frame.css. */
.primary-cta.glass {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.primary-cta.glass::before,.primary-cta.glass::after {
  display: none;
}
.primary-cta svg {
  transition: transform .25s var(--ease);
}
.primary-cta:hover {
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.42),inset 0 -1px 0 rgba(255,255,255,.08),0 16px 40px rgba(0,0,0,.42),0 0 30px rgba(255,255,255,.14);
}
.primary-cta:hover::after {
  opacity: 1;
}
.primary-cta:hover svg {
  transform: translateX(4px);
}
.primary-cta:active {
  transform: translateY(0);
  background-image: linear-gradient(rgba(255,255,255,.05),rgba(255,255,255,.05)),var(--glass-sheen);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5),inset 0 -1px 0 rgba(255,255,255,.1),0 8px 24px rgba(0,0,0,.4),0 0 26px rgba(255,255,255,.18);
}
/* The press light sits right under the ink (it follows the pointer), so
   it stays at .2: with the dark base kept, the ink holds >=4.5:1 for as
   long as a finger is held down. The hover sheen stands down while
   pressed; on touch the tap starts it at the same moment as the press. */
.primary-cta:active::after {
  opacity: 1;
  background: radial-gradient(180px 45px at var(--sx) 0%,rgba(255,255,255,.18),transparent 72%);
}
.primary-cta:active .cta-sheen {
  opacity: 0;
}
.primary-cta:focus-visible {
  outline-offset: 4px;
}
/* One sheen sweep on hover, together with the lift, the rim wake and the
   arrow slide (charter §4: one orchestrated moment). */
.cta-sheen {
  position: absolute!important;
  inset: 0;
  z-index: 1!important;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.cta-sheen::before {
  content: '';
  position: absolute;
  top: -40%;
  bottom: -40%;
  left: -45%;
  width: 34%;
  background: linear-gradient(100deg,rgba(255,255,255,0),rgba(255,255,255,.26),rgba(255,255,255,0));
  transform: skewX(-18deg);
  opacity: 0;
}
.primary-cta:hover .cta-sheen::before {
  animation: cta-sheen .85s var(--ease);
}
.watch-link {
  display: none;
  min-height: 44px;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  font-size: .86rem;
  white-space: nowrap;
}
.watch-link:hover {
  text-decoration: underline;
  text-underline-offset: 5px;
}
.small-play {
  font-size: .65rem;
  color: var(--cyan);
}
.availability {
  font-size: .78rem;
  color: var(--muted);
  margin: 15px 0 0;
  animation-delay: .8s;
}
.film-stage {
  position: relative;
  width: 100%;
  max-width: 378px;
  justify-self: center;
  isolation: isolate;
  padding-top: 16px;
  animation: film-arrive 1.8s var(--ease) .4s both;
  scroll-margin-top: 22px;
}
.film-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px 16px;
  color: var(--muted);
}
.film-length {
  font-variant-numeric: tabular-nums;
  color: var(--cyan);
}
/* The phone. Its glass rim and its shadow live on the two pseudo-elements so
   the materialize sequence can fade each in on opacity alone. */
.film-shell {
  position: relative;
  padding: 7px;
  border-radius: 28px;
  isolation: isolate;
  transform-origin: 50% 50%;
}
.film-shell::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(140deg,rgba(125,207,255,.65),rgba(86,127,184,.12) 34%,rgba(146,95,213,.22) 64%,rgba(0,237,255,.58));
}
.film-shell::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  border-radius: inherit;
  box-shadow: 0 25px 100px rgba(0,0,0,.6),0 0 70px rgba(8,123,199,.1);
  transition: box-shadow .4s;
}
.film-shell:has(.film-play:hover)::after {
  box-shadow: 0 25px 100px rgba(0,0,0,.6),0 0 90px rgba(255,255,255,.12);
}
.film-screen {
  position: relative;
  border-radius: 22px;
  overflow: hidden;
  background: #02060d;
  aspect-ratio: 9/16;
  box-shadow: 0 0 0 1px rgba(255,255,255,.14);
  transform-origin: 50% 50%;
}
.film-screen video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background: #000;
}
/* Specular glare on the phone glass; arrival.js moves it with the tilt. */
.film-glint {
  position: absolute;
  left: -30%;
  top: -30%;
  width: 90%;
  height: 70%;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side,rgba(255,255,255,.13),rgba(255,255,255,0));
  pointer-events: none;
  opacity: 0;
  transition: opacity .5s var(--ease);
}
html.lab .film-glint.is-on {
  opacity: 1;
}
.film-stage.is-playing .film-glint {
  opacity: 0!important;
}
.film-play {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  display: flex;
  align-items: flex-end;
  gap: 17px;
  padding: 30px 23px;
  border: 0;
  /* Dense at the foot: the explainer's frames carry burned-in captions in
     their bottom band, and the play copy must sit on a clean ground. */
  background: linear-gradient(rgba(2,6,15,0) 48%,rgba(2,6,15,.86) 74%,rgba(2,6,15,.97) 90%);
  text-align: left;
}
.film-play:focus-visible {
  outline-offset: -6px;
  border-radius: 22px;
}
.play-disc {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  flex: none;
  border: 1px solid rgba(224,246,255,.7);
  border-radius: 50%;
  background: rgba(245,253,255,.95);
  color: #060d19;
  transition: transform .3s var(--ease),background .2s,box-shadow .3s var(--ease);
}
.play-disc svg {
  width: 23px;
  height: 23px;
  fill: currentColor;
  stroke: none;
  margin-left: -2px;
}
.film-play:hover .play-disc {
  transform: scale(1.09);
  background: #fff;
  box-shadow: 0 0 0 6px rgba(255,255,255,.1),0 0 32px rgba(255,255,255,.34);
}
.play-copy {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.play-copy small {
  font-size: .64rem;
  letter-spacing: .18em;
  color: var(--cyan);
  font-weight: 600;
}
.play-copy strong {
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -.02em;
}
.play-copy>span {
  font-size: .75rem;
  color: var(--muted);
}
.play-copy>span>span {
  margin-left: 6px;
}
.film-caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 8px 0;
}
h2 {
  font-size: .86rem;
  line-height: 1.5;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--muted);
  margin: 0;
}
.sound-note {
  font-size: .62rem;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  color: var(--muted);
}
.sound-note svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}
.film-noscript {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  margin: 14px 8px 0;
  font-size: .86rem;
}
.portal-cross {
  position: absolute;
  font-family: var(--pulse-font);
  color: rgba(213,233,255,.5);
  font-size: 1.35rem;
}
.cross-top {
  right: -42px;
  top: 45px;
}
.cross-bottom {
  left: -45px;
  bottom: 130px;
}
.video-error {
  font-size: .85rem;
  line-height: 1.5;
  padding: 12px;
  color: var(--muted);
  background: var(--space);
}
.footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 17px 0 20px;
  border-top: 1px solid var(--line);
}
.footer>p {
  font-size: .66rem;
  color: var(--muted);
  margin: 0;
  line-height: 1.6;
  letter-spacing: .12em;
}
.footer>p strong {
  color: var(--ink);
  font-weight: 500;
}
.footer-links {
  display: flex;
  align-items: center;
  gap: 23px;
}
.footer-links>span {
  color: var(--muted);
  font-size: .68rem;
}
.footer nav {
  display: flex;
  gap: 20px;
}
.footer nav a {
  font-size: .74rem;
  color: var(--muted);
  min-height: 44px;
  display: flex;
  align-items: center;
  text-decoration: none;
}
.footer nav a:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}
.footer .copyright {
  color: var(--muted);
  font-size: .68rem;
  white-space: nowrap;
}
/* backwards, not both: the last keyframe is the natural state, and an
   opacity animation that keeps filling after it ends leaves the element a
   backdrop root in Chrome, so the glass inside (store tiles, CTA) would
   stop blurring what is behind it and stars would show sharp through the
   ink. */
.entrance {
  animation-name: copy-arrive;
  animation-duration: 1s;
  animation-timing-function: var(--ease);
  animation-fill-mode: backwards;
}

/* ── Live tickers (drawn only in the motion lab) ──────────────────────────
   Two chips beside the phone. arrival.js fills the price from the public
   price list (every 5 s at most, never while the tab is hidden) and flashes
   the chip on a real tick; with no data they show the pair alone. The
   direction rides a glyph as well as a hue. */
.tickers {
  display: none;
}
html.lab .tickers {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.ticker {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px 0 7px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .02em;
  white-space: nowrap;
  color: var(--glass-ink);
  background: linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.03)),rgba(8,11,23,.78);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.16),inset 0 1px 0 rgba(255,255,255,.26),0 10px 26px rgba(0,0,0,.4);
  animation: ticker-bob 5.2s ease-in-out infinite alternate;
  transition: opacity .35s var(--ease);
}
.ticker img {
  width: 18px;
  height: 18px;
  flex: none;
}
.ticker b {
  font-weight: 600;
}
.t-price {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.t-price:empty,.t-dir:empty {
  display: none;
}
.t-price::after {
  content: ' USD';
  font-size: .6rem;
  letter-spacing: .08em;
}
.t-dir {
  font-style: normal;
  font-size: .6rem;
  line-height: 1;
}
.ticker[data-dir=up] .t-dir {
  color: var(--up);
}
.ticker[data-dir=down] .t-dir {
  color: var(--down);
}
.t-flash {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.75),0 0 20px rgba(255,255,255,.3);
  opacity: 0;
}
.ticker.t-btc {
  left: -66px;
  top: 24%;
}
/* Anchored by its left edge and pulled back with `translate`, so the chip
   growing when its first price arrives never moves its layout box (no CLS). */
.ticker.t-eth {
  left: calc(100% + 58px);
  translate: -100% 0;
  top: 64%;
  animation-duration: 6.1s;
  animation-delay: -2.3s;
}
.film-stage.is-playing .ticker {
  opacity: 0;
}

@keyframes copy-arrive {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes logo-arrive {
  0% {
    opacity: 0;
    transform: translateZ(-200px) rotateY(-115deg) scale(.75);
    filter: blur(5px);
  }
  50% {
    opacity: 1;
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: translateZ(0) rotateY(0) scale(1);
  }
}
@keyframes film-arrive {
  from {
    opacity: 0;
    transform: perspective(1100px) rotateY(-10deg) translateY(32px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes galaxy-drift {
  from {
    transform: scale(1) translate3d(-1%,0,0);
  }
  to {
    transform: scale(1.08) translate3d(1%,-2%,0);
  }
}
@keyframes stars-drift {
  to {
    transform: translate3d(-45px,-55px,0);
  }
}
@keyframes cta-sheen {
  0% {
    opacity: 0;
    transform: skewX(-18deg) translateX(0);
  }
  15% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: skewX(-18deg) translateX(520%);
  }
}
@keyframes ticker-bob {
  from {
    transform: translateY(-4px);
  }
  to {
    transform: translateY(4px);
  }
}
@media(min-width:1440px) {
  .page {
    padding-inline: 78px;
  }
  .arrival {
    gap: 110px;
  }
  .film-stage {
    max-width: 390px;
  }
}
@media(max-width:1100px) and (min-width:761px) {
  .page {
    padding-inline: 35px;
  }
  .arrival {
    gap: 35px;
    grid-template-columns: 1fr .85fr;
  }
  .film-stage {
    max-width: 310px;
  }
  .logo-stage {
    width: 300px;
    height: 195px;
  }
  .hero-actions {
    gap: 9px;
  }
  .store-tile {
    min-width: 145px;
    padding-inline: 12px;
    gap: 9px;
  }
  .store-tile strong {
    font-size: 1rem;
  }
  .intro {
    font-size: 1rem;
  }
  .footer-links>span {
    display: none;
  }
  .ticker.t-btc {
    left: -18px;
    top: 21%;
  }
  .ticker.t-eth {
    left: calc(100% + 18px);
  }
}
@media(max-width:760px) {
  :root {
    --display: clamp(2.75rem,11.5vw,4.4rem);
    --body: 1rem;
  }
  .page {
    padding: 0 22px;
    overflow: hidden;
  }
  .masthead {
    height: 66px;
    gap: 12px;
  }
  .header-logo {
    height: 44px;
  }
  .web-status {
    display: none;
  }
  .arrival {
    display: flex;
    flex-direction: column;
    gap: 28px;
    padding: 4px 0 42px;
    min-height: 0;
  }
  .hero-copy {
    width: 100%;
    text-align: center;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .logo-stage {
    width: 234px;
    height: 151px;
    margin: 0 0 -13px;
  }
  .eyebrow {
    font-size: .59rem;
    letter-spacing: .12em;
    justify-content: center;
    margin: 12px 0 17px;
    gap: 7px;
  }
  h1 {
    line-height: 1.02;
    letter-spacing: -.045em;
  }
  .intro {
    margin: 14px 0 0;
    line-height: 1.5;
  }
  .stores {
    width: 100%;
    max-width: 355px;
    margin: 20px 0 15px;
    gap: 10px;
  }
  .store-tile {
    min-width: 0;
    flex: 1;
    padding: 12px;
    min-height: 65px;
    gap: 10px;
    text-align: left;
    border-radius: 14px;
  }
  .store-icon {
    width: 29px;
    height: 29px;
  }
  .store-tile small {
    font-size: .65rem;
    letter-spacing: .04em;
  }
  .store-tile strong {
    font-size: 1rem;
  }
  .hero-actions {
    width: 100%;
    max-width: 355px;
    display: flex;
    gap: 7px;
    flex-direction: column;
  }
  .primary-cta {
    width: 100%;
    min-height: 54px;
    font-size: .94rem;
  }
  .watch-link {
    display: flex;
    font-size: .8rem;
    min-height: 44px;
  }
  .availability {
    display: none;
  }
  .film-stage {
    max-width: 345px;
    padding-top: 0;
    width: 100%;
  }
  .film-head {
    padding-bottom: 13px;
  }
  .film-kicker,.film-length {
    font-size: .7rem;
  }
  .film-shell {
    border-radius: 26px;
    padding: 6px;
  }
  .film-screen {
    border-radius: 20px;
  }
  .film-play {
    padding: 25px 19px;
    gap: 14px;
  }
  .play-disc {
    width: 52px;
    height: 52px;
  }
  .play-copy strong {
    font-size: 1.14rem;
  }
  .cross-top {
    right: -13px;
    top: -15px;
  }
  .cross-bottom {
    left: -15px;
    bottom: 68px;
  }
  .film-caption {
    padding: 18px 4px 0;
    gap: 10px;
  }
  .film-caption h2 {
    font-size: .79rem;
  }
  .sound-note {
    font-size: .54rem;
  }
  .ticker {
    height: 30px;
    font-size: .7rem;
    padding-right: 10px;
  }
  .ticker.t-btc {
    left: -10px;
    top: 15%;
  }
  .ticker.t-eth {
    left: calc(100% + 10px);
    top: 52%;
  }
  .galaxy {
    background-image: url('../space/deep-space-lit-1440x3120.webp');
    background-position: 50% 15%;
    background-size: auto 130%;
    opacity: 1;
    inset: -5%;
  }
  .galaxy-light {
    background: linear-gradient(180deg,rgba(5,7,19,.3),rgba(5,7,19,.06) 45%,rgba(5,7,19,.7));
  }
  .horizon {
    width: min(80vw,360px);
  }
  .footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
    padding: 22px 0 24px;
  }
  .footer>p {
    font-size: .62rem;
  }
  .footer-links {
    width: 100%;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
  }
  .footer .copyright {
    flex-basis: 100%;
    font-size: .75rem;
  }
  .footer-links>span {
    font-size: .75rem;
  }
  .footer nav {
    gap: 15px;
  }
  .footer nav a {
    font-size: .75rem;
  }
}
@media(max-width:350px) {
  .page {
    padding-inline: 16px;
  }
  .store-tile {
    gap: 7px;
    padding-inline: 9px;
  }
  .store-tile strong {
    font-size: .92rem;
  }
  .store-icon {
    width: 26px;
    height: 26px;
  }
  .footer-links {
    flex-wrap: wrap;
  }
  .film-caption {
    flex-wrap: wrap;
  }
}
html.motion-paused *,html.motion-paused *:before,html.motion-paused *:after {
  animation-play-state: paused!important;
}
@media(prefers-reduced-motion:reduce) {
  html {
    scroll-behavior: auto;
  }
  *,*:before,*:after {
    animation: none!important;
    transition: none!important;
  }
  .hero-logo,.entrance,.film-stage {
    opacity: 1;
    transform: none;
    filter: none;
  }
  .galaxy,.star-field {
    will-change: auto;
  }
}

/* ── Orbits (drawn by arrival.js) ─────────────────────────────────────────
   Justin, 25 Sep: the spinning outlines read as wireframe; make them more
   real. Each orbit is a FIXED tilted path; a body rides it with a fading
   light trail, grows as it swings toward the viewer and dims behind. The
   front half is a clipped copy drawn above the logo / film, so the body
   passes behind them and back in front. Around Kaira the bodies are the
   markets themselves. motion-paused and reduced motion stop them like
   everything else on the page. */
.orbit {
  position: absolute;
  left: 50%;
  top: 50%;
  pointer-events: none;
  z-index: 0;
  transform: rotate(var(--tilt)) scale(var(--k,1));
}
.film-stage>.orbit {
  z-index: -1;
}
.orbit.front,.film-stage>.orbit.front {
  z-index: 3;
  clip-path: polygon(-40% 50%,140% 50%,140% 160%,-40% 160%);
}
.orbit svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.o-path {
  fill: none;
  stroke: rgba(150,210,255,.11);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.orbit.front .o-path {
  display: none;
}
.o-trail {
  fill: none;
  stroke: var(--o-color);
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  animation: var(--dur) linear var(--delay) infinite both;
}
.o-trail.t1 {
  stroke-width: 1.8;
  stroke-opacity: .8;
  stroke-dasharray: 5 95;
  animation-name: o-trail-5;
}
.o-trail.t2 {
  stroke-width: 1.3;
  stroke-opacity: .32;
  stroke-dasharray: 12 88;
  animation-name: o-trail-12;
}
.o-trail.t3 {
  stroke-width: 1;
  stroke-opacity: .12;
  stroke-dasharray: 24 76;
  animation-name: o-trail-24;
}
/* Live pulses: a comet that runs the orbit when the market under it ticks.
   Forward along the orbit for a move up, backward for a move down; silver
   when no live price is available. arrival.js drives them with the Web
   Animations API. */
.o-pulse,.o-pulse-halo {
  fill: none;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 0;
}
.o-pulse {
  stroke: #fff;
  stroke-width: 2;
  stroke-dasharray: 7 93;
}
.o-pulse-halo {
  stroke: var(--pulse-color,rgba(230,240,255,.8));
  stroke-width: 6;
  stroke-opacity: .32;
  stroke-dasharray: 11 89;
}
.o-body {
  position: absolute;
  left: 0;
  top: 0;
  offset-rotate: 0deg;
  animation: o-ride var(--dur) linear var(--delay) infinite both;
}
.orbit.ccw .o-body {
  animation-name: o-ride-ccw;
}
.o-light {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle,#fff 0,var(--o-color) 45%,transparent 72%);
  box-shadow: 0 0 14px 3px var(--o-color);
}
.o-icon {
  display: block;
  width: 22px;
  height: 22px;
  transform: rotate(calc(var(--tilt) * -1));
  filter: drop-shadow(0 0 7px var(--o-color)) drop-shadow(0 2px 6px rgba(0,0,0,.6));
}
.o-ping {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  box-shadow: 0 0 0 1.5px var(--pulse-color,rgba(255,255,255,.85)),0 0 14px var(--pulse-color,rgba(255,255,255,.5));
  opacity: 0;
  pointer-events: none;
}
@keyframes o-trail-5 { from { stroke-dashoffset: 5; } to { stroke-dashoffset: -95; } }
@keyframes o-trail-12 { from { stroke-dashoffset: 12; } to { stroke-dashoffset: -88; } }
@keyframes o-trail-24 { from { stroke-dashoffset: 24; } to { stroke-dashoffset: -76; } }
/* 0-50% is the near half (in front), 50-100% the far half, for a clockwise path. */
@keyframes o-ride {
  0% { offset-distance: 0%; transform: scale(1); opacity: 1; }
  25% { offset-distance: 25%; transform: scale(1.18); opacity: 1; }
  50% { offset-distance: 50%; transform: scale(.95); opacity: .9; }
  75% { offset-distance: 75%; transform: scale(.62); opacity: .45; }
  100% { offset-distance: 100%; transform: scale(1); opacity: 1; }
}
@keyframes o-ride-ccw {
  0% { offset-distance: 0%; transform: scale(1); opacity: 1; }
  25% { offset-distance: 25%; transform: scale(.62); opacity: .45; }
  50% { offset-distance: 50%; transform: scale(.95); opacity: .9; }
  75% { offset-distance: 75%; transform: scale(1.18); opacity: 1; }
  100% { offset-distance: 100%; transform: scale(1); opacity: 1; }
}
@media(min-width:1440px) {
  .orbit.portal-b { --k: .74; }
}
@media(max-width:760px) {
  .orbit.logo-a { --k: .72; }
  .orbit.logo-b { --k: .78; }
  .orbit.portal-a { --k: .8; }
  .orbit.portal-b { --k: .78; }
}

/* ══ MOTION LAB ═══════════════════════════════════════════════════════════
   Justin, 8 Oct: "let's use this as a greenfield testing ground for
   animations." Everything below applies only under html.lab, which the boot
   script in <head> sets when the visitor has not asked for reduced motion.
   Without it (reduced motion, or scripts off) the page is the calm static
   version above, video included.

   The timeline, from the moment html.arrived is set:
     warp-in (cosmos.js, once per session, <=1.45 s, any input skips) →
     0.00  the mark ignites like neon (flicker → steady)
     0.10  eyebrow · 0.12 headline assembles from star-points (arrival.js)
     0.35  the phone outline draws itself in light, the glass fills,
           the screen boots into the explainer (.film-stage.is-live;
           on a phone this waits until the phone scrolls into view)
     0.55+ intro, store tiles, CTA, availability
   Transform and opacity only; no layout property animates. */
html.lab:not(.arrived) .page {
  opacity: 0;
}
html.lab .entrance,html.lab .hero-logo,html.lab .film-stage {
  animation: none;
}
html.lab.arrived .masthead {
  animation: lab-fade 1s var(--ease) .15s both;
}
html.lab.arrived .footer {
  animation: lab-fade 1s var(--ease) .9s both;
}
html.lab.arrived .entrance {
  animation: copy-arrive 1s var(--ease) backwards;
}
html.lab.arrived .eyebrow {
  animation-delay: .1s;
}
html.lab.arrived h1 {
  animation-delay: .2s;
}
html.lab.arrived h1.is-split {
  animation: none;
}
html.lab.arrived .intro {
  animation-delay: .55s;
}
html.lab.arrived .stores {
  animation-delay: .66s;
}
html.lab.arrived .hero-actions {
  animation-delay: .77s;
}
html.lab.arrived .availability {
  animation-delay: .88s;
}

/* Warp-in: the galaxy and the planet arrive as the streaks decelerate. */
html.lab .galaxy {
  transition: opacity 1.25s var(--ease),scale 1.9s var(--ease);
}
html.lab .horizon {
  transition: opacity 1.3s var(--ease) .12s,translate 1.7s var(--ease) .12s,scale 1.7s var(--ease) .12s;
}
html.lab.warping .galaxy {
  opacity: 0;
  scale: 1.2;
}
html.lab.warping .horizon {
  opacity: 0;
  translate: 9% 12%;
  scale: .9;
}

/* The mark ignites like neon. */
html.lab.arrived .hero-logo {
  animation: neon-ignite 1.2s linear both;
}
html.lab.arrived .logo-halo {
  animation: halo-ignite 1.2s linear both;
}
html.lab.arrived .logo-stage .orbit {
  animation: lab-fade 1.4s var(--ease) .7s both;
}

/* Living headline. arrival.js splits it into an aria-hidden art layer;
   the real sentence stays in a visually hidden span and never changes. */
.h1-art .w {
  display: inline-block;
  white-space: nowrap;
}
.h1-art .c {
  position: relative;
  display: inline-block;
}
.h1-art .g {
  display: inline-block;
}
.h1-art .spark {
  position: absolute;
  left: 50%;
  top: 56%;
  width: .26em;
  height: .26em;
  margin: -.13em 0 0 -.13em;
  border-radius: 50%;
  background: radial-gradient(circle,#fff 0 16%,rgba(205,236,255,.75) 32%,rgba(150,205,255,0) 70%);
  opacity: 0;
  pointer-events: none;
}
.morph-line {
  display: inline-block;
  white-space: nowrap;
  transform: translateX(var(--shift,0px));
  transition: transform .8s var(--ease);
}
.morph-slot {
  display: inline-grid;
  justify-items: start;
}
.morph-word {
  grid-area: 1/1;
  display: inline-block;
  transform-origin: 30% 60%;
}
.morph-word:not(.is-current) {
  opacity: 0;
}

/* The phone materializes (arrival.js adds .mat-pending, then .is-live when
   the phone is in view; --mat-delay offsets the whole sequence). */
.phone-outline {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  opacity: .3;
}
.phone-outline path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.po-glow {
  stroke: rgba(205,232,255,.28);
  stroke-width: 7;
  stroke-dasharray: 1 1;
}
.po-line {
  stroke: rgba(245,250,255,.95);
  stroke-width: 1.4;
  stroke-dasharray: 1 1;
}
.po-tip {
  stroke: #fff;
  stroke-width: 3;
  stroke-dasharray: .05 2;
  opacity: 0;
}
.boot-line {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 50%;
  z-index: 4;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: linear-gradient(90deg,rgba(255,255,255,0),#fff 22%,#fff 78%,rgba(255,255,255,0));
  box-shadow: 0 0 18px 4px rgba(205,235,255,.5);
  opacity: 0;
  pointer-events: none;
}
.boot-flash {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(120% 60% at 50% 50%,rgba(235,246,255,.75),rgba(235,246,255,.2) 60%,rgba(235,246,255,0));
  opacity: 0;
  pointer-events: none;
}
.film-stage.mat-pending:not(.is-live) :is(.film-head,.film-caption,.portal-cross,.tickers,.film-play),
.film-stage.mat-pending:not(.is-live)>.orbit,
.film-stage.mat-pending:not(.is-live) .film-shell::before,
.film-stage.mat-pending:not(.is-live) .film-shell::after,
.film-stage.mat-pending:not(.is-live) .film-screen,
.film-stage.mat-pending:not(.is-live) .phone-outline {
  opacity: 0;
}
.film-stage.mat-pending:not(.is-live) .film-play {
  pointer-events: none;
}
.film-stage.is-live {
  --m: var(--mat-delay,.35s);
}
.film-stage.is-live .film-head {
  animation: lab-fade .9s var(--ease) calc(var(--m) + .1s) both;
}
.film-stage.is-live .phone-outline {
  animation: po-settle 1.1s var(--ease) calc(var(--m) + 1.15s) both;
}
.film-stage.is-live .po-glow,.film-stage.is-live .po-line {
  animation: po-draw .95s cubic-bezier(.65,.05,.36,1) var(--m) both;
}
.film-stage.is-live .po-tip {
  animation: po-tip .95s cubic-bezier(.65,.05,.36,1) var(--m) both;
}
.film-stage.is-live .film-shell::before {
  animation: lab-fade .75s var(--ease) calc(var(--m) + .72s) both;
}
.film-stage.is-live .film-shell::after {
  animation: lab-fade 1.1s var(--ease) calc(var(--m) + .8s) both;
}
.film-stage.is-live .boot-line {
  animation: boot-line .7s var(--ease) calc(var(--m) + .95s) both;
}
.film-stage.is-live .film-screen {
  animation: screen-boot .78s cubic-bezier(.7,0,.2,1) calc(var(--m) + 1.02s) both;
}
.film-stage.is-live .boot-flash {
  animation: boot-flash 1s ease-out calc(var(--m) + 1.38s) both;
}
.film-stage.is-live .film-play {
  animation: lab-fade .8s var(--ease) calc(var(--m) + 1.65s) both;
}
.film-stage.is-live .film-caption,.film-stage.is-live .portal-cross {
  animation: lab-fade .9s var(--ease) calc(var(--m) + 1.6s) both;
}
.film-stage.is-live>.orbit {
  animation: lab-fade 1.6s var(--ease) calc(var(--m) + 1.55s) both;
}
.film-stage.is-live .tickers {
  animation: lab-fade 1s var(--ease) calc(var(--m) + 2s) both;
}
@keyframes lab-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes neon-ignite {
  0% { opacity: 0; filter: brightness(2.4) saturate(.3); }
  7% { opacity: .9; }
  11% { opacity: .08; }
  18% { opacity: .95; }
  22% { opacity: .22; }
  31% { opacity: 1; filter: brightness(1.9) saturate(.6); }
  37% { opacity: .5; }
  46% { opacity: 1; filter: brightness(1.5) saturate(.85); }
  100% { opacity: 1; filter: brightness(1) saturate(1); }
}
@keyframes halo-ignite {
  0% { opacity: 0; transform: scale(.7); }
  7% { opacity: .9; }
  11% { opacity: .1; }
  18% { opacity: 1; }
  22% { opacity: .3; }
  31% { opacity: 1; transform: scale(1.12); }
  46% { opacity: 1; }
  100% { opacity: .7; transform: none; }
}
@keyframes po-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}
@keyframes po-tip {
  0% { stroke-dashoffset: .05; opacity: 0; }
  8% { opacity: 1; }
  90% { opacity: 1; }
  100% { stroke-dashoffset: -.95; opacity: 0; }
}
@keyframes po-settle {
  from { opacity: 1; }
  to { opacity: .3; }
}
@keyframes boot-line {
  0% { opacity: 0; transform: scaleX(0); }
  40% { opacity: 1; transform: scaleX(1); }
  65% { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1) scaleY(.3); }
}
@keyframes screen-boot {
  0% { opacity: 0; transform: scaleY(.006); }
  22% { opacity: 1; transform: scaleY(.006); }
  100% { opacity: 1; transform: none; }
}
@keyframes boot-flash {
  0% { opacity: .55; }
  100% { opacity: 0; }
}
