/* ==========================================================================
   Dust - design system
   Layout, type scale and motion follow the Matter reference 1:1.
   The only palette change: the reference mint (#0f8054) is replaced by our
   brand green (hue ~120), sampled from the Dust glass mark.
   ========================================================================== */

:root {
  /* Surfaces */
  --bg:            #000000;
  --bg-2:          #030303;
  --surface:       #141414;
  --surface-2:     #1c1c1c;
  --surface-3:     #262626;
  --hairline:      rgba(255, 255, 255, .10);
  --hairline-soft: rgba(255, 255, 255, .06);

  /* Text */
  --text:   #ffffff;
  --text-2: #c9c9c9;
  --text-3: #7c7c7c;
  --on-brand: #12240b;

  /* Brand green - sampled from the inflated D of the Dust mark. The sky
     stays blue everywhere it is a photograph; the brand colour is the glyph. */
  --brand:        #7bc62d;
  --brand-bright: #9ade4a;
  --brand-glow:   #c8f08a;
  --brand-pale:   #e9f8cf;
  --brand-deep:   #3f6b18;

  /* Kept from the reference */
  --accent: #fbbc00;

  /* three stops sampled off the logo, used wherever the mark's own colours
     should show through - the collapsed nav indicator, for one */
  --rainbow-1: #bff85a;   /* the glyph's highlight, lifted to read on the dark bar */
  --rainbow-2: #7bc62d;   /* the glyph's body green */
  --rainbow-3: #3f6b18;   /* the glyph's shadow side */

  /* Geometry */
  --r-block: 32px;
  --r-card:  24px;
  --r-chip:  999px;
  --gutter:  clamp(16px, 4vw, 56px);
  --edge:    8px;
  --maxw:    1440px;

  /* Type */
  --font: 'Inter', 'Inter Placeholder', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Geist', 'Inter', sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --ease: cubic-bezier(.22, 1, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }
/* The [hidden] attribute is only a `display:none` in the UA sheet, so ANY
   component rule carrying its own display silently outranks it - which is how
   an empty state stayed on screen next to the list that had just filled, and
   how a copy button kept offering an all-zero address. Make the attribute mean
   what everyone writing `el.hidden = true` assumes it means. */
[hidden] { display: none !important; }

html {
  background: var(--bg);
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: -0.011em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--brand); color: var(--on-brand); }

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

:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 3px;
  border-radius: 6px;
}

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

.block {
  position: relative;
  margin: 0 var(--edge) var(--edge);
  border-radius: var(--r-block);
  overflow: hidden;
  background: var(--bg-2);
}
.block--brand { background: var(--brand); color: var(--on-brand); }

/* Sky block - the photographic plate that replaces the reference's flat green.
   Layers, bottom up: photo, a light veil that guarantees text contrast, then
   the parallax cloud layer (see .clouds). */
.block--sky { color: var(--on-brand); background: var(--brand); isolation: isolate; }
.block--sky::before {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  background-image: url('/assets/img/sky.webp');
  background-size: cover;
  background-position: 50% 42%;
}
.block--sky::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(255,255,255,.30) 0%, rgba(255,255,255,.05) 34%, rgba(255,255,255,.34) 100%),
    radial-gradient(90% 70% at 50% 6%, rgba(4,44,80,.26), transparent 62%);
}
.block--sky > * { position: relative; z-index: 3; }
@media (max-width: 900px) {
  .block--sky::before { background-image: url('/assets/img/sky-1100.webp'); }
}
.block--flush { background: transparent; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.pad     { padding-block: clamp(72px, 10vw, 160px); }
.pad-tight { padding-block: clamp(46px, 5.4vw, 92px); }
.pad-sm  { padding-block: clamp(48px, 6vw, 96px); }
.pad-lg  { padding-block: clamp(96px, 14vw, 220px); }

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

.eyebrow {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--text-3);
  margin: 0 0 clamp(24px, 4vw, 56px);
  display: flex;
  align-items: center;
  gap: 10px;
}

.display {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(56px, 12vw, 168px);
  line-height: 0.92;
  letter-spacing: -0.045em;
  margin: 0;
}
.display--sm { font-size: clamp(40px, 7vw, 96px); }

.lead {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(24px, 3.4vw, 52px);
  line-height: 1.18;
  letter-spacing: -0.035em;
  margin: 0;
  max-width: 22ch;
}
.lead--wide { max-width: 30ch; }

.body   { font-size: clamp(15px, 1.2vw, 18px); line-height: 1.55; color: var(--text-2); margin: 0; }
.body-2 { font-size: 14px; line-height: 1.5; color: var(--text-3); margin: 0; }
.mono   { font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.01em; }

.txt-brand  { color: var(--brand-bright); }
.txt-accent { color: var(--accent); }
.txt-muted  { color: var(--text-3); }

/* Word-by-word reveal used on the big statement paragraphs (Matter behaviour) */
.reveal-words span {
  display: inline-block;
  opacity: .18;
  transition: opacity .45s var(--ease);
}
.reveal-words.is-in span { opacity: 1; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  --btn-bg: var(--brand);
  --btn-fg: var(--on-brand);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 20px;
  border-radius: var(--r-chip);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease), height .45s var(--ease), padding .45s var(--ease);
}
.btn:hover { --btn-bg: var(--brand-bright); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn--ghost { --btn-bg: transparent; --btn-fg: var(--text); border: 1px solid var(--hairline); }
.btn--ghost:hover { --btn-bg: var(--surface-2); }
.btn--dark { --btn-bg: var(--surface); --btn-fg: var(--text); }
.btn--dark:hover { --btn-bg: var(--surface-2); }
.btn--lg { height: 54px; padding: 0 28px; font-size: 15px; }
.btn[aria-disabled="true"] { cursor: not-allowed; --btn-bg: var(--surface); --btn-fg: var(--text-3); transform: none; }

/* Rolling label - two stacked copies, so kerning is never broken. */
.btn__lbl { display: grid; overflow: hidden; line-height: 1.25; }
.btn__lbl > span { grid-area: 1 / 1; transition: transform .42s var(--ease); }
.btn__lbl > span:nth-child(2) { transform: translateY(115%); }
.btn:hover .btn__lbl > span:nth-child(1) { transform: translateY(-115%); }
.btn:hover .btn__lbl > span:nth-child(2) { transform: translateY(0); }

/* --------------------------------------------------------------------------
   Chips / notices
   -------------------------------------------------------------------------- */

.chip {
  display: inline-flex; align-items: center; gap: 8px;
  height: 30px; padding: 0 13px;
  border-radius: var(--r-chip);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-2);
  white-space: nowrap;
}
.chip--brand  { background: var(--brand);  border-color: transparent; color: var(--on-brand); }
.chip--accent { background: var(--accent); border-color: transparent; color: #1a1400; font-weight: 500; }
.chip--soon   { background: transparent; color: var(--text-3); }
.block--brand .chip, .block--sky .chip { border-color: rgba(5,36,64,.28); background: rgba(5,36,64,.06); color: rgba(5,36,64,.72); }
.block--sky .chip { background: rgba(255,255,255,.52); border-color: rgba(5,36,64,.16); color: rgba(5,36,64,.82); backdrop-filter: blur(6px); }
.block--sky .notice { background: rgba(255,255,255,.5); border-color: rgba(5,36,64,.24); color: rgba(5,36,64,.78); backdrop-filter: blur(6px); }
.block--sky .notice b { color: #7a4b00; }

.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: none; }
.dot--live { background: var(--brand-bright); }

.notice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 16px;
  border: 1px dashed var(--hairline);
  border-radius: 14px;
  background: rgba(255,255,255,.02);
  font-family: var(--font-mono); font-size: 12px; line-height: 1.55; color: var(--text-3);
}
.notice b { color: var(--accent); font-weight: 500; }
.block--brand .notice, .block--sky .notice { border-color: rgba(5,36,64,.3); background: rgba(5,36,64,.07); color: rgba(5,36,64,.74); }
.block--brand .notice b, .block--sky .notice b { color: var(--on-brand); }

/* --------------------------------------------------------------------------
   Section head - centred eyebrow, oversized title, action on the right
   -------------------------------------------------------------------------- */

/* Section divider: a hairline across the whole block with a pill sitting on it,
   the way the reference marks every section boundary. */
.eyebrow {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  margin: 0;
  padding-block: clamp(26px, 3.4vw, 44px);
}
/* The rule used to be one absolutely-positioned line at `top: 50%`, which is
   50% of the PADDING box - so the moment a section gave its eyebrow extra
   padding-top, the line sat above the pill instead of through it. The two
   halves are flex items now: they share the pill's centred line box, so they
   are always on its centre line whatever the padding does. */
.eyebrow::before,
.eyebrow::after {
  content: '';
  flex: 1 1 0; min-width: 0;
  height: 1px; background: var(--hairline);
}
.eyebrow__pill {
  /* deliberately NO z-index: the pill must stay in the positioned layer so its
     own ::before bloom (z-index: -1) paints underneath it. The rule halves no
     longer run behind the pill, so it has nothing left to sit above. */
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 15px;
  border-radius: var(--r-chip);
  background: var(--surface);
  border: 1px solid var(--hairline-soft);
  font-family: var(--font-mono); font-size: 12.5px; color: var(--text-2);
  white-space: nowrap;
}
.eyebrow img { width: 11px; opacity: .95; }
/* the bloom below sits at z-index -1, so the eyebrow needs its own stacking
   context or it would slip behind an opaque ancestor */
.block--sky .eyebrow, .sky-page .eyebrow { isolation: isolate; }

/* On the sky the divider cannot be a drawn dark line - it reads as a crack in
   the photograph. It becomes a light seam instead: a hairline that fades out
   long before the block edges, sitting on a wide, very soft bloom, so the
   boundary reads like a horizon the pill is resting on. Each half fades from
   the pill outwards, so the two together read as one continuous seam. */
.block--sky .eyebrow::before {
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.30) 26%, rgba(255,255,255,.62) 100%);
  box-shadow: 0 1px 0 rgba(6, 48, 88, .10);
}
.block--sky .eyebrow::after {
  background: linear-gradient(90deg,
    rgba(255,255,255,.62) 0%, rgba(255,255,255,.30) 74%, rgba(255,255,255,0) 100%);
  box-shadow: 0 1px 0 rgba(6, 48, 88, .10);
}
/* the bloom hangs off the PILL, so it stays centred on the pill no matter what
   padding the section gives the eyebrow */
.block--sky .eyebrow__pill::before {
  content: '';
  position: absolute; inset: -130px -50vw;
  background:
    radial-gradient(46% 62% at 50% 50%, rgba(255,255,255,.30), transparent 72%),
    radial-gradient(80% 100% at 50% 50%, rgba(255,255,255,.10), transparent 76%);
  pointer-events: none; z-index: -1;
}
.block--sky .eyebrow__pill {
  background: rgba(255,255,255,.66); border-color: rgba(5,36,64,.14);
  color: rgba(5,36,64,.84); backdrop-filter: blur(6px);
}

.head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  margin-bottom: clamp(28px, 4vw, 56px);
}
.head .display { position: relative; }
.head .display sup {
  position: absolute; left: 100%; top: .04em;
  margin-left: .05em;
  font-family: var(--font-mono); font-size: .09em;
  color: var(--accent); letter-spacing: 0;
}

/* --------------------------------------------------------------------------
   Nav - full pill at rest. Scrolling down collapses it to the wordmark with an
   animated bar indicator on the right; scrolling up opens it again.
   The collapse animates a grid track from 1fr to 0fr, which is the only way to
   transition "auto" width smoothly without measuring anything in JS.
   -------------------------------------------------------------------------- */

.nav { position: fixed; inset: 18px 0 auto; z-index: 90; display: flex; justify-content: center; pointer-events: none; }
.nav__inner {
  pointer-events: auto;
  /* the reference bar's proportions: a tight shell, a big gap between the mark
     and the links, and the CTA sitting 6px off the right edge. The wide gap is
     most of why it reads as a widget rather than a menu bar. */
  display: flex; align-items: center; gap: clamp(26px, 3.4vw, 60px);
  padding: 6px 6px 6px 18px;
  border-radius: var(--r-chip);
  background: rgba(18, 18, 18, .82);
  border: 1px solid var(--hairline-soft);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 14px 44px rgba(0, 0, 0, .55);
  transition: padding .55s var(--ease), background .55s var(--ease),
              gap .55s var(--ease), box-shadow .55s var(--ease);
}
.nav.is-collapsed .nav__inner { padding: 6px 12px 6px 18px; gap: 16px; }

/* the bar is always dark, so it sets its own colour: inheriting from the page
   turned the wordmark navy-on-navy on the sky pages */
.nav__inner, .nav__inner * { color: var(--text); }
.nav__inner .nav__link { color: var(--text-2); }
.nav__inner .nav__link:hover, .nav__inner .nav__link.is-on { color: var(--text); }
.nav__inner .nav__link--primary,
.nav__inner .nav__link--primary:hover { color: var(--on-brand); }
.nav__inner .nav__x { color: var(--text-2); }
.nav__inner .nav__x:hover { color: var(--text); }

.nav__brand {
  display: flex; align-items: center; gap: 9px; flex: none;
  font-family: var(--font-display); font-weight: 600; letter-spacing: -0.02em;
  font-size: 15px;
}
.nav__brand img { width: 15px; }
.nav__brand sup { font-size: 8px; }

/* the collapsing half */
.nav__fold {
  display: grid; grid-template-columns: 1fr;
  transition: grid-template-columns .55s var(--ease), opacity .3s var(--ease);
}
.nav__fold > div { overflow: hidden; display: flex; align-items: center; gap: 20px; min-width: 0; }
.nav.is-collapsed .nav__fold { grid-template-columns: 0fr; opacity: 0; }

.nav__links { display: flex; align-items: center; gap: clamp(20px, 2.2vw, 34px); }
/* every control in the bar is the same 36px box on one centre line - an inline
   <a> with vertical padding does not make a box, which is what made the hover
   backgrounds sit at different heights and overlap each other */
/* No hover slab any more. The reference bar leaves the links as bare type and
   puts the whole hover into the label rolling over - a background chip behind a
   rolling word fights it. */
.nav__link {
  position: relative;
  display: inline-flex; align-items: center;
  height: 36px; padding: 0;
  font-size: 14.5px; font-weight: 500; line-height: 1;
  color: var(--text-2); white-space: nowrap;
  transition: color .25s var(--ease);
}
.nav__link:hover { color: var(--text); }
/* the page you are on: full-strength label and its index lit in brand colour */
.nav__inner .nav__link.is-on { color: var(--text); }
.nav__link.is-on .nav__num { color: var(--brand-bright); opacity: 1; }

.nav__num {
  position: absolute; top: 2px; right: -13px;
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
  letter-spacing: -.04em; line-height: 1;
  color: var(--accent); opacity: .8;
}

/* ---- the rolling label ----
   One line-height tall, clipped, with the second copy painted underneath by a
   text-shadow. Hover lifts every letter by exactly that line-height, on a
   per-letter stagger, so the word rolls over itself. */
.roll {
  display: inline-flex; overflow: hidden; vertical-align: top;
  --lh: 1.25em;
  text-shadow: 0 var(--lh) 0 currentColor;
}
.roll > i {
  display: block; flex: none; white-space: pre; font-style: normal;
  line-height: var(--lh);
  transition: transform .52s cubic-bezier(.16, 1, .3, 1);
  transition-delay: calc(var(--i, 0) * 16ms);
  backface-visibility: hidden;
}
a:hover > .roll > i,
a:focus-visible > .roll > i { transform: translateY(calc(var(--lh) * -1)); }
@media (prefers-reduced-motion: reduce) { .roll > i { transition: none; } }

/* Terminal is the one accented control in the bar - it is the product, not a
   fourth tab - so it is the only thing here carrying brand colour.
   No drop shadow: the collapsing half clips with overflow:hidden, so a glow can
   only ever be sliced off at the fold edge. That cut is what looked broken. */
.nav__link--primary {
  height: 34px; padding: 0 16px;
  border-radius: var(--r-chip);
  background: var(--brand); color: var(--on-brand); font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28);
  transition: background .25s var(--ease);
}
.nav__link--primary:hover { background: var(--brand-bright); color: var(--on-brand); }

/* the X link is a plain glyph now: with Terminal accented, a second filled
   circle next to it just competed for the same attention */
.nav__x {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 34px; height: 36px; border-radius: var(--r-chip);
  background: transparent; color: var(--text-2);
  transition: color .25s var(--ease);
}
.nav__x svg { width: 14px; height: 14px; display: block; }
.nav__x:hover { color: var(--text); background: transparent; }

/* the bar indicator that takes the nav's place while it is closed */
.nav__eq {
  display: grid; grid-template-columns: 0fr;
  transition: grid-template-columns .55s var(--ease), opacity .3s var(--ease);
  opacity: 0;
}
.nav.is-collapsed .nav__eq { grid-template-columns: 1fr; opacity: 1; }
.nav__eq > span {
  overflow: hidden;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  height: 36px; min-width: 0; padding-inline: 4px;
}
/* Three dots, and one at a time stretches into a bar and settles back - the
   reference widget's own idea, and it reads as "working" rather than as a level
   meter. The box is fixed at bar height and the resting state is a scaled-down
   circle, so nothing in the row moves: animating `height` shifted the whole
   line every frame, which is what made it look ragged.
   Each one carries a colour from the logo. */
.nav__eq i {
  display: block; width: 4px; height: 15px; border-radius: 99px;
  transform: scaleY(.2667); transform-origin: 50% 50%;
  animation: eq 1.9s cubic-bezier(.5, 0, .2, 1) infinite;
}
.nav__eq i:nth-child(1) { background: var(--rainbow-1); }
.nav__eq i:nth-child(2) { background: var(--rainbow-2); animation-delay: .63s; }
.nav__eq i:nth-child(3) { background: var(--rainbow-3); animation-delay: 1.26s; }
@keyframes eq {
  0%,  4%   { transform: scaleY(.2667); }
  15%, 24%  { transform: scaleY(1); }
  35%, 100% { transform: scaleY(.2667); }
}

.nav__burger { display: none; width: 36px; height: 36px; border-radius: 50%; background: var(--surface-2); flex: none; }
.nav__burger i { display: block; width: 14px; height: 1.5px; background: var(--text); margin: 3.5px auto; transition: transform .3s var(--ease); }
.nav.is-open .nav__burger i:nth-child(1) { transform: translateY(2.5px) rotate(45deg); }
.nav.is-open .nav__burger i:nth-child(2) { transform: translateY(-2.5px) rotate(-45deg); }

@media (prefers-reduced-motion: reduce) { .nav__eq i { animation: none; } }

/* --------------------------------------------------------------------------
   Hero - full-bleed looping video, copy bottom-left, wordmark on the floor
   -------------------------------------------------------------------------- */

.hero { position: relative; min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden; }
.hero__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top, rgba(0,0,0,.94) 0%, rgba(0,0,0,.72) 26%, rgba(0,0,0,.30) 58%, rgba(0,0,0,.48) 100%),
    radial-gradient(70% 55% at 50% 100%, rgba(11,78,138,.42), transparent 70%);
}
.hero__inner { position: relative; z-index: 2; padding-bottom: clamp(20px, 3vw, 34px); }
/* Hero copy is deliberately small and low-left, the way the reference sets it -
   the video is the subject, the words are the caption. */
.hero__body { display: grid; gap: clamp(14px, 1.7vw, 20px); max-width: 560px; }
.hero__title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(27px, 2.7vw, 40px); line-height: 1.14; letter-spacing: -0.035em;
  max-width: 15ch;
  text-shadow: 0 2px 26px rgba(0, 0, 0, .55);
}
.hero__sub {
  margin: 0; max-width: 44ch;
  font-size: clamp(15px, 1.25vw, 17.5px); line-height: 1.5;
  color: #dfe4e8;
  text-shadow: 0 1px 18px rgba(0, 0, 0, .65);
}
/* the X mark set inline in the headline, at the weight of the surrounding type */
.hero__title .xmark {
  display: inline-block; vertical-align: -.04em;
  width: .78em; height: .78em;
  /* .06em read as a kerning tweak, not a word space, so "on" and the mark
     collided. A real word gap is what the eye expects here. */
  margin-left: .3em;
  fill: currentColor;
  filter: drop-shadow(0 2px 20px rgba(0, 0, 0, .5));
}

.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; }

/* Hero buttons - the Apple pair: one solid, one glass, both on the same pill
   geometry. The solid one carries a hairline top highlight and a coloured
   shadow so it reads as lit rather than painted on. */
.hero__cta .btn { height: 54px; padding: 0 26px; font-size: 15px; border-radius: 999px; }
.btn--hero {
  --btn-bg: #fff; --btn-fg: #0b0d10;
  box-shadow: 0 1px 0 rgba(255,255,255,.9) inset, 0 12px 30px rgba(0, 0, 0, .38);
}
.btn--hero:hover { --btn-bg: #fff; transform: translateY(-2px); box-shadow: 0 1px 0 rgba(255,255,255,.9) inset, 0 18px 38px rgba(0, 0, 0, .46); }
.btn--hero svg { width: 16px; height: 16px; flex: none; }

.btn--glass {
  --btn-bg: rgba(255, 255, 255, .12);
  --btn-fg: #fff;
  border: 1px solid rgba(255, 255, 255, .26);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  box-shadow: 0 1px 0 rgba(255,255,255,.22) inset, 0 10px 26px rgba(0, 0, 0, .3);
}
.btn--glass:hover { --btn-bg: rgba(255, 255, 255, .2); transform: translateY(-2px); }

/* The wordmark on the floor is glass, not paint: `overlay` lets the footage
   through, so a letter over a bright cloud lifts and one over a bear darkens.
   A second copy behind it carries the crisp edge. */
.hero__floor {
  position: relative; z-index: 2;
  overflow: hidden; line-height: .78;
  padding-bottom: clamp(6px, 1vw, 14px);
}
.hero__floor span {
  display: block; position: relative;
  font-family: var(--font-display); font-weight: 600;
  /* The wordmark is the floor of the hero, so it should reach the gutters
     rather than stop short of them. JELLYPONS(R) is ten glyphs and the (R) is
     narrow, so the ratio that fills the line differs from the old GUMMY PONS
     measure - hence the larger vw and the tighter tracking. */
  /* 16vw is measured, not guessed: it is the ratio at which the glyph run
     equals the viewport minus both gutters. Larger and the (R) slides past the
     gutter, where .hero__floor's overflow:hidden silently clips it - the bug
     looks like a missing character, not like overflow. */
  font-size: clamp(40px, 16vw, 307px);
  letter-spacing: -0.055em;
  white-space: nowrap;
  padding-inline: var(--gutter);
  color: rgba(255, 255, 255, .5);
  mix-blend-mode: overlay;
}
.hero__floor span::before {
  content: attr(data-word);
  position: absolute; inset: 0;
  padding-inline: var(--gutter);
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, .16);
  mix-blend-mode: normal;
  pointer-events: none;
}

.bubbles { position: absolute; inset: auto 0 42% 0; z-index: 2; pointer-events: none; display: none; }
@media (min-width: 1100px) { .bubbles { display: block; } }
.bubble {
  position: absolute; max-width: 268px;
  padding: 11px 15px; border-radius: 16px;
  background: rgba(12,12,12,.72);
  border: 1px solid rgba(255,255,255,.14);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 16px 40px rgba(0,0,0,.5);
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.45; color: #dcdcdc;
  animation: bubble-in .75s var(--ease) both;
}
.bubble b { color: var(--brand-glow); font-weight: 400; }
.bubble:nth-child(1) { right: 30%; top: -230px; animation-delay: .5s; }
.bubble:nth-child(2) { right: 6%;  top: -150px; animation-delay: .75s; }
.bubble:nth-child(3) { right: 22%; top: -56px;  animation-delay: 1s; }
.bubble:nth-child(4) { right: 4%;  top: 24px;   animation-delay: 1.25s; }
@keyframes bubble-in { from { opacity: 0; transform: translateY(16px) scale(.97); } to { opacity: 1; transform: none; } }

/* --------------------------------------------------------------------------
   Marquee / ticker
   -------------------------------------------------------------------------- */

.marquee { overflow: hidden; width: 100%; }
.marquee__track { display: flex; width: max-content; animation: marquee 30s linear infinite; }
.marquee--rev .marquee__track { animation-direction: reverse; }
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(56px, 13vw, 200px); line-height: 1;
  letter-spacing: -0.05em; padding-right: .16em; white-space: nowrap;
}
.marquee__item--outline { -webkit-text-stroke: 1px rgba(5,36,64,.22); color: transparent; }
@keyframes marquee { to { transform: translateX(-50%); } }

.ticker { border-block: 1px solid var(--hairline-soft); background: var(--bg-2); padding-block: 12px; }
.ticker .marquee__item {
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 400;
  letter-spacing: .02em; color: var(--text-3);
  padding-right: 0; display: flex; align-items: center; gap: 14px;
}
.ticker .marquee__track { animation-duration: 46s; }
.ticker .sep { color: var(--brand); }

/* --------------------------------------------------------------------------
   About - centred statement + capability grid (the reference's logo wall)
   -------------------------------------------------------------------------- */

.stmt {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(23px, 3.05vw, 46px); line-height: 1.22; letter-spacing: -0.032em;
  max-width: 1320px; margin: 0 auto clamp(48px, 6vw, 96px); text-align: center;
}
.stmt--narrow { max-width: 26ch; font-size: clamp(21px, 2.5vw, 36px); }

/* About: the statement and the wall share one right-weighted column, left
   aligned - the empty third on the left is what the reference does. */
.about { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
.about__col { grid-column: 2; display: grid; gap: clamp(30px, 3.6vw, 56px); }
.about__col .stmt {
  max-width: none; margin: 0; text-align: left;
  font-size: clamp(21px, 2.45vw, 36px); line-height: 1.24;
}
.about__col .wall { gap: 14px; }
.about__col .notice { margin: -12px 0 0; }
@media (max-width: 1000px) {
  .about { grid-template-columns: 1fr; }
  .about__col { grid-column: 1; gap: 36px; }
}
.reveal-words span { display: inline-block; opacity: .16; transition: opacity .45s var(--ease); }
.reveal-words.is-in span { opacity: 1; }

/* Ecosystem wall - the FrogPools behaviour: hovering lights the cell up. Here
   the lit state is the sky plate rather than a flat white tile, with a thin
   scrim over it so every mark keeps its contrast. */
.wall { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.wall__cell {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center; justify-content: center;
  min-height: clamp(104px, 10.5vw, 146px); padding: 18px;
  border-radius: var(--r-card);
  border: 1px solid var(--hairline-soft);
  background: var(--surface);
  transition: border-color .38s var(--ease), transform .38s var(--ease), box-shadow .38s var(--ease);
}
/* the sky plate */
.wall__cell::before {
  content: ''; position: absolute; inset: 0; z-index: 0; opacity: 0;
  background: url('/assets/img/sky-tile.webp') center / cover;
  transform: scale(1.06);
  transition: opacity .38s var(--ease), transform .6s var(--ease);
}
/* contrast scrim, so white and pale marks still read against the clouds */
.wall__cell::after {
  content: ''; position: absolute; inset: 0; z-index: 1; opacity: 0;
  background:
    radial-gradient(66% 66% at 50% 50%, rgba(255, 255, 255, .34), transparent 72%),
    linear-gradient(180deg, rgba(6, 46, 84, .10), rgba(6, 46, 84, .22));
  transition: opacity .38s var(--ease);
}
.wall__cell img {
  position: relative; z-index: 2;
  height: clamp(38px, 4.4vw, 62px);
  width: auto; max-width: 64%; object-fit: contain; flex: none;
  filter: grayscale(1) brightness(1.75) contrast(.75);
  opacity: .46;
  transition: filter .38s var(--ease), opacity .38s var(--ease);
}
.wall__cell--wordmark img { height: auto; width: clamp(130px, 15vw, 215px); max-width: 76%; }

.wall__cell:hover {
  border-color: transparent;
  transform: translateY(-3px);
  box-shadow: 0 18px 42px rgba(0, 0, 0, .45);
}
.wall__cell:hover::before { opacity: 1; transform: scale(1); }
.wall__cell:hover::after  { opacity: 1; }
.wall__cell:hover img {
  opacity: 1;
  filter: drop-shadow(0 3px 10px rgba(4, 34, 62, .38));
}
/* marks whose brand colour is black-on-white - re-ink them on the lit tile */
.wall__cell--ink:hover img {
  filter: invert(1) drop-shadow(0 3px 9px rgba(255, 255, 255, .5));
}
/* the Pons mark is pale glass - give it back its own contrast on the sky */
.wall__cell--pale:hover img {
  filter: saturate(1.8) contrast(1.22) brightness(.92)
          drop-shadow(0 3px 9px rgba(12, 48, 20, .45));
}
@media (max-width: 900px) {
  .wall__cell::before { background-image: url('/assets/img/sky-tile-sm.webp'); }
}

/* --------------------------------------------------------------------------
   Horizontal rail - used by Launches, Terminal and Leaderboard
   -------------------------------------------------------------------------- */

.rail {
  display: flex; gap: 14px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  padding-bottom: 14px;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--surface-3) transparent;
}
.rail::-webkit-scrollbar { height: 5px; }
.rail::-webkit-scrollbar-track { background: transparent; }
.rail::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 99px; }
.rail > * { scroll-snap-align: start; flex: 0 0 auto; }

/* --------------------------------------------------------------------------
   Launch card
   -------------------------------------------------------------------------- */

.launch-bar { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.filters { display: flex; flex-wrap: wrap; gap: 8px; }
.filter {
  height: 34px; padding: 0 15px; border-radius: var(--r-chip);
  border: 1px solid var(--hairline); font-size: 13px; color: var(--text-3);
  transition: all .25s var(--ease);
}
.filter:hover { color: var(--text); border-color: rgba(255,255,255,.24); }
.filter.is-active { background: var(--brand); border-color: transparent; color: var(--on-brand); }

.search { position: relative; flex: 0 1 320px; min-width: 240px; }
.search input {
  width: 100%; height: 40px; padding: 0 16px 0 40px;
  border-radius: var(--r-chip); border: 1px solid var(--hairline);
  background: var(--surface); color: var(--text); font: inherit; font-size: 14px;
}
.search input::placeholder { color: var(--text-3); }
.search svg { position: absolute; left: 15px; top: 12px; width: 15px; opacity: .45; }

.launch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 14px; }
.rail .launch { width: 268px; }

.launch {
  position: relative; display: flex; flex-direction: column;
  border-radius: var(--r-card); border: 1px solid var(--hairline-soft);
  background: var(--surface); overflow: hidden;
  transition: transform .35s var(--ease), border-color .35s var(--ease);
}
.launch:hover { transform: translateY(-4px); border-color: rgba(63,169,240,.38); }
.launch__art {
  position: relative; aspect-ratio: 4 / 3; display: grid; place-items: center;
  background:
    radial-gradient(72% 72% at 34% 24%, rgba(169,216,247,.26), transparent 70%),
    linear-gradient(150deg, var(--surface-2), #0b0b0b);
}
.launch__glyph { font-family: var(--font-display); font-weight: 600; font-size: 40px; letter-spacing: -.05em; color: rgba(255,255,255,.15); }
.launch__tag { position: absolute; left: 10px; top: 10px; }
.launch__mcap {
  position: absolute; right: 10px; bottom: 10px;
  padding: 5px 10px; border-radius: var(--r-chip);
  background: rgba(0,0,0,.66); backdrop-filter: blur(8px);
  font-family: var(--font-mono); font-size: 11.5px; color: var(--brand-glow);
}
.launch__meta { padding: 14px 15px 15px; display: grid; gap: 4px; }
.launch__name { font-weight: 600; font-size: 15px; letter-spacing: -.02em; }
.launch__ticker { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.launch__row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 9px; margin-top: 5px; border-top: 1px solid var(--hairline-soft);
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3);
}
.launch__row b { color: var(--text-2); font-weight: 400; }

/* Live feed. A card is an <a> now, so kill the inherited link styling and let
   the card's own hover state do the work. */
.launch--live { color: inherit; text-decoration: none; }

/* Token art for indexed launches: a generated jelly badge drawn as inline SVG,
   or the image from the launch post when the API has one. Either way it fills
   the frame, so the container just needs to stop painting its own gradient. */
/* ---------------------------------------------------- nav wallet menu
   The panel is a child of <body>, deliberately. `.nav__inner` carries a
   transform and a backdrop-filter; either makes it the containing block for
   position:fixed descendants, so a panel inside the nav measured against the
   pill instead of the viewport and then got clipped by the fold's
   overflow:hidden. Out here neither applies. */
.nav__wbtn { cursor: pointer; }
.nav__wav { width: 18px; height: 18px; border-radius: 50%; object-fit: cover; }

.nav__wpop {
  position: fixed; z-index: 200;
  min-width: 216px; padding: 8px;
  border-radius: 16px; border: 1px solid var(--hairline);
  background: rgba(16, 16, 16, .94);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow: 0 22px 60px rgba(0, 0, 0, .55);
  transform-origin: 50% 0;
  opacity: 0; transform: translateY(-10px) scale(.94);
  transition: opacity .26s var(--ease), transform .26s var(--ease);
}
.nav__wpop.is-open { opacity: 1; transform: translateY(0) scale(1); }
.nav__wpop[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .nav__wpop { transition: none; }
}

.nav__whandle {
  margin: 4px 10px 8px; padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline-soft);
  font-family: var(--font-mono); font-size: 12px; color: var(--text-3);
}
.nav__wrow {
  display: block; width: 100%; text-align: left;
  padding: 10px; border: 0; border-radius: 10px;
  background: transparent; color: var(--text);
  font-family: inherit; font-size: 13.5px; cursor: pointer; text-decoration: none;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.nav__wrow:hover { background: rgba(255, 255, 255, .07); }
/* Sign out is the one destructive action here, so it reads as one. */
.nav__wrow--out {
  color: #ff7a6b;
  margin-top: 4px; padding-top: 11px;
  border-top: 1px solid var(--hairline-soft); border-radius: 0 0 10px 10px;
}
.nav__wrow--out:hover { background: rgba(255, 92, 74, .12); color: #ff9a8f; }
.nav__wrow--out:disabled { opacity: .6; cursor: default; }

.launch__art--gen { background: #0b0b0b; padding: 0; }
/* The rail card became an <a> when the feed went live; strip link styling and
   let the card's own hover do the work. */
.p3d__card--live { color: inherit; text-decoration: none; }
.p3d__card--live .p3d__art { background: #0b0b0b; }
.chip--live { background: rgba(53, 207, 98, .14); border-color: rgba(53, 207, 98, .4); color: #6fe08f; }
.jart { display: block; width: 100%; height: 100%; object-fit: cover; }



/* One line under the filter bar saying what the grid is showing and where it
   came from. It carries the failure message too - the grid itself is never
   blanked or filled with invented rows when the API is unreachable. */
.launch-status {
  margin: 0 0 14px; font-family: var(--font-mono); font-size: 12px;
  color: var(--text-3); min-height: 1.2em;
}
.launch-status.is-err { color: #ff9a8f; }

.launch-more { margin: 22px auto 0; display: block; }


/* --------------------------------------------------------------------------
   Commands - a pinned three-beat sequence driven by one scroll progress value.
   JS writes three unitless vars on the section and CSS does the rest:
     --t  title recede      --s  cloud sweep-in      --c  card reveal
   Keeping the maths in CSS means one style write per frame instead of one per
   element, and the transforms stay composable with the parallax on each cloud.
   -------------------------------------------------------------------------- */

.svc { position: relative; overflow: clip; --t: 0; --s: 0; --c: 0; }
/* this section pins at the top of the viewport, so its divider would land
   under the fixed nav - push it clear */
.svc > .eyebrow { position: relative; z-index: 9; padding-top: clamp(62px, 8vh, 104px); }

/* The plate belongs to the whole section, not to the pinned stage. One photo
   stretched over five viewports is a huge upscale - that is the point: the sky
   is plain blue where you enter it and only reaches its cloud band near the
   bottom, so a long scroll actually travels somewhere. Softness down there is
   part of the look, not a bug to fix.
   `background-attachment` stays default, so the image scrolls with the section
   while the stage stays pinned in front of it. */
.svc.block--sky { background: #2585d0; }
.svc.block--sky::before {
  content: ''; display: block;
  position: absolute; inset: 0; z-index: 0;
  /* composed tall on purpose (2400x5200): plain gradient at the top, the cloud
     band at the foot. Covering five viewports with it is barely an upscale,
     where one landscape photo would have been stretched about six times. */
  background: url('/assets/img/sky-long.webp') 50% 0 / cover no-repeat;
}
@media (max-width: 1500px) { .svc.block--sky::before { background-image: url('/assets/img/sky-long-md.webp'); } }
@media (max-width: 900px)  { .svc.block--sky::before { background-image: url('/assets/img/sky-long-sm.webp'); } }

/* Clouds belong to the SECTION, not to the pinned stage. Anchored here they
   simply scroll up past the viewport and leave, instead of hanging in front of
   the camera the way stage-mounted ones did. `--y` is a percentage of the whole
   section, so they are spread down its full height. */
.skydrift { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.skydrift--front { z-index: 8; }

/* --------------------------------------------------------------- bear fall
   Same anchoring idea as .skydrift: the bears belong to the SECTION, not to
   the pinned stage, so they travel up and out as you scroll instead of hanging
   in front of the camera. Two planes bracket the tweet card (z-index 5): the
   far plane behind it, the near plane in front, which is what makes a bear
   pass ACROSS the card rather than always around it. */
/* ------------------------------------------------------------ light block
   A dark page end to end is heavy to read, so long-form pages alternate: a
   light section takes the reading load, the dark ones carry the imagery. The
   variant re-points the same tokens the components already use rather than
   restyling each one, so a card dropped into a light section adapts on its
   own. A cloud band sits at the top edge to hand over from the dark section
   above instead of cutting to white. */
.block--light {
  --text:   #04223c;
  --text-2: rgba(5, 32, 52, .78);
  --text-3: rgba(5, 32, 52, .55);
  --surface:   #ffffff;
  --surface-2: #eef4fb;
  --surface-3: #e3ecf7;
  --hairline:      rgba(5, 36, 64, .14);
  --hairline-soft: rgba(5, 36, 64, .08);
  --on-brand: #ffffff;
  position: relative; isolation: isolate;
  background: linear-gradient(180deg, #eaf3fd 0%, #f7fafd 34%, #ffffff 100%);
  color: var(--text);
}
/* The handover band: the cloud strip fades in at the very top of the section
   so the seam between dark and light is weather, not a rule. */
.block--light::before {
  content: ''; position: absolute; z-index: -1;
  left: 0; right: 0; top: 0; height: clamp(140px, 22vw, 300px);
  background: url('/assets/img/sky-tile.webp') 50% 0 / cover no-repeat;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.55) 46%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.55) 46%, transparent 100%);
  opacity: .9;
}
.block--light .eyebrow__pill {
  background: rgba(255, 255, 255, .9);
  border-color: rgba(5, 36, 64, .12);
  color: rgba(5, 32, 52, .8);
  box-shadow: 0 6px 20px rgba(4, 34, 60, .1);
}
/* The tweet mock deliberately keeps its dark X skin inside a light section.
   Painting it white left its own hardcoded light type invisible, and a dark
   card on white is the stronger read anyway - it looks like a screenshot,
   which is what it is. It only needs a shadow that suits a light ground. */
.block--light .tw { box-shadow: 0 20px 50px rgba(4, 34, 60, .18); }
/* Accent yellow is a dark-page colour; on white it is barely there. */
.block--light .step__no { color: #b06f00; }
.block--light .exl li { border-color: rgba(5, 36, 64, .14); }
.block--light .btn:not(.btn--hero):not(.btn--dark) { --btn-fg: #fff; }
.block--light .btn--ghost { --btn-fg: #04223c; border-color: rgba(5, 36, 64, .2); }
.block--light .btn--ghost:hover { --btn-bg: rgba(5, 36, 64, .06); }

.bearfall { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.bearfall--front { z-index: 8; }

.bear {
  position: absolute; left: var(--x, 0%); top: var(--y, 0%); width: var(--w, 5%);
  /* No will-change. One layer per element, held for the life of the page,
     across sixty-six elements - that is past where the hint helps and into
     where it costs memory and layer churn. The parallax writes transform on
     every frame these actually move, and browsers promote for that on their
     own, for exactly as long as it is needed. */
}
/* Two transforms, two elements, on purpose: the scroll parallax owns the outer
   span and the idle tumble owns the inner img, so neither can overwrite the
   other mid-frame. */
.bear img {
  display: block; width: 100%; height: auto;
  transform: rotate(var(--rot, 0deg)) scaleX(var(--flip, 1));
  animation: bear-bob var(--dur, 9s) ease-in-out infinite alternate;
  animation-delay: var(--lag, 0s);
}
@keyframes bear-bob {
  from { transform: rotate(var(--rot, 0deg)) scaleX(var(--flip, 1)) translateY(0); }
  to   { transform: rotate(calc(var(--rot, 0deg) + 9deg)) scaleX(var(--flip, 1)) translateY(-10px); }
}
/* Depth is sold by blur, scale and shadow. The far plane is deliberately soft
   so it never competes with the tweet for attention. */
/* Small sprites lose their modelling, so a little goes back on top: a sheen
   masked to the bear's own alpha, which reads as light catching a wet,
   translucent sweet. Masked rather than overlaid so it never spills into a
   rectangle around the shape. */
/* No filters on bears, and no sheen overlay.
 *
 * There were three per-element effects here: a mask-and-blend sheen, a depth
 * blur, and a drop-shadow. Thirty-two elements each carrying a filter is
 * thirty-two offscreen render passes per frame, and the profile showed it -
 * fifty-two blurred elements on this page alone.
 *
 * None of them were earning it. The sheen existed to fake gloss on the old
 * low-resolution sprites; the new source is 5x larger and glossy already. The
 * blur was 0.7px on a sprite drawn at 18-52px, which is invisible. Depth is
 * now carried by size and opacity, which are free - the compositor animates
 * them without repainting.
 */
.bear--far  { opacity: .72; }
.bear--near { opacity: .96; }

@media (prefers-reduced-motion: reduce) { .bear img { animation: none; } }
/* On a phone the card fills most of the width, so a near bear would sit on the
   text rather than beside it. Keep the fall, drop the ones that would cover. */
@media (max-width: 700px) {
  /* Thirty-two bears spread across 1440px is weather. The same thirty-two on a
     390px phone is a swarm sitting on the text. Keep every third one, drop the
     near plane entirely - it is the one that crosses the card - and scale what
     remains up so a bear still reads as a bear at a third the width. */
  .bear { width: calc(var(--w, 2%) * 2.4); }
  .bearfall .bear:not(:nth-child(3n + 1)) { display: none; }
  .bearfall--front { display: none; }
}

.skydrift .cloud { position: absolute; left: var(--x, 0%); top: var(--y, 0%); width: var(--w, 26%); }
.svc.block--sky::after {
  content: ''; display: block;
  position: absolute; inset: 0; z-index: 1;
  background:
    radial-gradient(72% 40% at 50% 22%, rgba(255,255,255,.16), transparent 72%),
    linear-gradient(180deg, rgba(4,44,84,.14) 0%, transparent 26%, rgba(4,44,84,.10) 100%);
}

.svc__stage {
  position: sticky; top: 0;
  height: 100svh;
  display: grid; place-items: center;
  overflow: hidden;
  isolation: isolate;
}
/* Stacking inside the stage, bottom to top:
   2 far/mid clouds · 3 the word · 5 the post · 6 near clouds.
   The near plane sitting ABOVE the post is the whole 3D overlap. */
.svc__stage > * { position: relative; z-index: 3; }
/* the visually-hidden heading must stay out of flow, or it becomes a second
   grid item and pushes the post off centre */
.svc__stage > .sr-only { position: absolute; }
.svc__stage > .clouds { z-index: 2; }
.svc__stage > .clouds--over { z-index: 6; }
.svc__deck, .svc__nav { z-index: 5; }

/* beat 1 - the word arrives oversized and front-of-stage, then settles back
   into the sky as the backdrop. It never leaves: the card lands on top of it
   and both stay on screen for the rest of the section. */
.svc__title {
  position: absolute; left: 0; right: 0;
  text-align: center;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(64px, 15vw, 240px); line-height: 1;
  letter-spacing: -0.055em;
  color: var(--on-brand);
  pointer-events: none;
  /* solid ink, never faded or softened - it is a filled word on the sky, not a
     watermark. Only the scale settles. */
  transform: translateY(calc(var(--t) * -2%)) scale(calc(1.16 - var(--t) * 0.16));
  opacity: 1;
  will-change: transform;
}

/* beat 2 - the cloud banks slide in from both edges */
.cloudset { position: absolute; inset: 0; will-change: transform, opacity; }
.cloudset[data-side="left"]  { transform: translate3d(calc((1 - var(--s)) * -72%), 0, 0); }
.cloudset[data-side="right"] { transform: translate3d(calc((1 - var(--s)) *  72%), 0, 0); }
.clouds--svc .cloudset { opacity: calc(.15 + var(--s) * .85); transition: none; }

/* beat 3 - the post lands, centred in the stage */
.svc__deck {
  position: relative;
  justify-self: center; align-self: center;
  width: min(520px, 92vw);
  min-height: clamp(224px, 23vw, 262px);
  opacity: var(--c);
  transform: translateY(calc((1 - var(--c)) * 46px)) scale(calc(.94 + var(--c) * .06));
  will-change: transform, opacity;
}
/* Switching posts is a cross-dissolve through depth, not a cut: the outgoing
   card lifts and blurs away upwards, the incoming one rises out of focus from
   below. Two slides are on screen together for most of the move, which is what
   makes it read as one object changing rather than two swapping. Direction is
   carried by `is-out` (everything already passed sits above), so scrubbing
   backwards reverses the move instead of replaying it. */
.svc__slide {
  position: absolute; inset: 0;
  display: grid; align-items: center;
  opacity: 0;
  transform: translate3d(0, 34px, 0) scale(.955);
  filter: blur(10px);
  pointer-events: none;
  will-change: transform, opacity, filter;
  transition:
    opacity .62s cubic-bezier(.32, .72, 0, 1),
    transform .92s cubic-bezier(.16, 1, .3, 1),
    filter .58s cubic-bezier(.32, .72, 0, 1);
}
.svc__slide.is-out { transform: translate3d(0, -30px, 0) scale(.965); }
.svc__slide.is-on {
  opacity: 1; transform: none; filter: blur(0);
  pointer-events: auto;
}
/* the card's own rows come in a beat behind the card, so the change has a
   direction inside it too */
.svc__slide .tw > *,
.svc__slide .xp > *,
.svc__slide > .svc__hint {
  opacity: 0; transform: translate3d(0, 12px, 0);
  transition: opacity .5s var(--ease), transform .62s cubic-bezier(.16, 1, .3, 1);
}
.svc__slide.is-on .tw > *,
.svc__slide.is-on .xp > *,
.svc__slide.is-on > .svc__hint { opacity: 1; transform: none; }
.svc__slide.is-on .tw__head  { transition-delay: .10s; }
.svc__slide.is-on .tw__text  { transition-delay: .16s; }
.svc__slide.is-on .tw__reply { transition-delay: .23s; }
.svc__slide.is-on .tw__bar   { transition-delay: .30s; }
/* The question lands first, then the post answers it - the order the reader
   would have lived it. */
.svc__slide.is-on > .svc__hint { transition-delay: .04s; }
.svc__slide.is-on .xp__head  { transition-delay: .12s; }
.svc__slide.is-on .xp__auto  { transition-delay: .16s; }
.svc__slide.is-on .xp__to    { transition-delay: .19s; }
.svc__slide.is-on .xp__body  { transition-delay: .23s; }
.svc__slide.is-on .xp__card  { transition-delay: .29s; }
.svc__slide.is-on .xp__bar   { transition-delay: .33s; }
@media (prefers-reduced-motion: reduce) {
  .svc__slide,
  .svc__slide .tw > *,
  .svc__slide .xp > *,
  .svc__slide > .svc__hint { transition-duration: .01s; filter: none; }
}

/* The slide holds a caption and a card now, stacked and centred, instead of
   one card filling the box. */
.svc__slide { justify-items: center; align-content: center; }

/* The middle object is a post, because a post is what the product takes as
   input. Solid X-dark card on the bright sky - the glass version was too
   transparent to read against moving clouds. */
.tw {
  width: 100%;
  padding: 16px 18px 12px;
  border-radius: 18px;
  background: #16181c;
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 0 30px 70px rgba(4, 34, 66, .42), 0 2px 0 rgba(255,255,255,.06) inset;
  color: #e7e9ea;
  text-align: left;
}
.tw__head { display: flex; align-items: center; gap: 11px; }
.tw__av {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: #2f3336; color: #8b98a5;
}
.tw__av svg { width: 22px; height: 22px; }
.tw__av img { width: 24px; }
.tw__who { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.tw__who b { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.tw__who span { font-size: 13.5px; color: #71767b; }
.tw__no {
  margin-left: auto; align-self: flex-start;
  font-family: var(--font-mono); font-size: 11px; color: #5b6570;
}
.tw__text {
  margin: 11px 0 0;
  font-size: clamp(16px, 1.5vw, 19px); line-height: 1.4; letter-spacing: -.01em;
  word-break: break-word;
}
.tw__text a { color: #4aa9f0; }
.tw__reply {
  margin-top: 13px; padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, .10);
  display: grid; grid-template-columns: 26px 1fr; gap: 10px; align-items: start;
}
.tw__reply-av {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: #0f1419; border: 1px solid rgba(255,255,255,.12);
}
.tw__reply-av img { width: 13px; }
.tw__reply b { display: block; font-size: 13px; font-weight: 600; margin-bottom: 2px; }
.tw__reply b span { font-weight: 400; color: #71767b; }
.tw__reply p { margin: 0; font-size: 13.5px; line-height: 1.45; color: #a9b1b9; }
.tw__bar {
  display: flex; align-items: center; gap: 34px;
  margin-top: 12px; padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .07);
  color: #5b6570;
}
.tw__bar svg { width: 16px; height: 16px; }

/* dots */
.svc__nav { display: none; }
.svc__nav button {
  width: 26px; height: 3px; border-radius: 99px;
  background: rgba(5, 36, 64, .22);
  transition: background .3s var(--ease), width .3s var(--ease);
}
.svc__nav button.is-on { background: var(--on-brand); width: 38px; }

/* Not pinned (small screens, reduced motion): a plain stack, no choreography */
.svc:not(.is-pinned) { --t: 1; --s: 1; --c: 1; }
.svc:not(.is-pinned) .svc__stage {
  position: static; height: auto; display: block;
  padding: clamp(30px, 6vw, 60px) var(--gutter) clamp(10px, 2vw, 24px);
  max-width: var(--maxw); margin-inline: auto;
}
.svc:not(.is-pinned) .svc__title {
  position: static; text-align: left;
  font-size: clamp(48px, 12vw, 110px);
  margin: 0 0 clamp(22px, 4vw, 36px);
  transform: none; opacity: 1; filter: none;
}
.svc:not(.is-pinned) .svc__deck {
  width: 100%; min-height: 0;
  display: grid; gap: 10px;
  opacity: 1; transform: none;
}
/* the stack shows every post at once, so none of the cross-dissolve state
   applies here - blur, offset and the per-row stagger all have to be undone */
.svc:not(.is-pinned) .svc__slide {
  position: static; opacity: 1; transform: none; filter: none;
  pointer-events: auto; transition: none;
}
.svc:not(.is-pinned) .svc__slide .tw > * {
  opacity: 1; transform: none; transition: none;
}
.svc:not(.is-pinned) .svc__nav { display: none; }
.svc:not(.is-pinned) .cloudset { transform: none; opacity: 1; }
/* stacked layout has no depth story, and the front plane would cover the posts */
.svc:not(.is-pinned) .clouds--over,
.svc:not(.is-pinned) .skydrift--front { display: none; }
/* the back plane stays, but thinned out - a dense field behind a plain stack
   just fights the text */
.svc:not(.is-pinned) .skydrift .cloud--mid { display: none; }
.svc:not(.is-pinned) .skydrift { opacity: .55; }
.svc:not(.is-pinned) .clouds { z-index: 0; opacity: .8; }

@media (max-width: 760px) {
  .tw__bar { gap: 22px; }
}

/* --------------------------------------------------------------------------
   Fees - three tiers, the third highlighted (reference "Pricing")
   -------------------------------------------------------------------------- */

.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: start; }
.tier {
  display: grid; gap: 16px; align-content: start;
  padding: clamp(22px, 2.4vw, 32px);
  border-radius: var(--r-card);
  border: 1px solid var(--hairline-soft);
  background: var(--surface);
}
.tier--hl { background: var(--brand); border-color: transparent; color: var(--on-brand); }
.tier__name { font-family: var(--font-display); font-weight: 600; font-size: 20px; letter-spacing: -.03em; margin: 0; }
.tier__desc { font-size: 14px; line-height: 1.5; color: var(--text-3); margin: 0; }
.tier--hl .tier__desc { color: rgba(5,36,64,.72); }
.tier__price { display: flex; align-items: flex-start; gap: 3px; font-family: var(--font-display); font-weight: 600; letter-spacing: -.05em; }
.tier__price .v { font-size: clamp(38px, 4.4vw, 62px); line-height: 1; }
.tier__price .u { font-size: 18px; margin-top: .35em; }
.tier__price .per { align-self: flex-end; font-family: var(--font); font-weight: 400; font-size: 13px; color: var(--text-3); margin-left: 6px; }
.tier--hl .tier__price .per { color: rgba(5,36,64,.7); }
.tier__inc { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); margin: 4px 0 0; }
.tier--hl .tier__inc { color: rgba(5,36,64,.66); }
.tier__list { display: grid; gap: 9px; font-size: 14px; color: var(--text-2); }
.tier--hl .tier__list { color: rgba(5,36,64,.84); }
.tier__list li { display: flex; gap: 10px; align-items: flex-start; }
.tier__list li::before { content: '|'; color: var(--brand-bright); flex: none; }
.tier--hl .tier__list li::before { color: var(--on-brand); }

/* --------------------------------------------------------------------------
   Terminal - the reference's testimonial rail, rebuilt as a command feed
   -------------------------------------------------------------------------- */

.term {
  width: 330px; padding: 18px;
  border-radius: var(--r-card);
  border: 1px solid var(--hairline-soft);
  background: var(--surface);
  display: grid; gap: 12px; align-content: start;
}
.term--brand { background: var(--brand); border-color: transparent; color: var(--on-brand); }
.term__head { display: flex; align-items: center; gap: 9px; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }
.term--brand .term__head { color: rgba(5,36,64,.7); }
.term__av { width: 26px; height: 26px; border-radius: 50%; background: var(--surface-3); display: grid; place-items: center; font-size: 11px; color: var(--text-2); flex: none; }
.term--brand .term__av { background: rgba(5,36,64,.16); color: var(--on-brand); }
.term__cmd {
  padding: 11px 13px; border-radius: 12px; background: #0a0a0a;
  font-family: var(--font-mono); font-size: 12px; line-height: 1.5; color: var(--brand-glow);
}
.term--brand .term__cmd { background: rgba(5,36,64,.86); }
.term__cmd .h { color: #fff; }
.term__out { font-family: var(--font-mono); font-size: 11.5px; line-height: 1.6; color: var(--text-3); display: grid; gap: 4px; }
.term--brand .term__out { color: rgba(5,36,64,.74); }
.term__out b { color: var(--text-2); font-weight: 400; }
.term--brand .term__out b { color: var(--on-brand); }

/* --------------------------------------------------------------------------
   Roadmap rows (reference "Awards")
   -------------------------------------------------------------------------- */

.rows { border-top: 1px solid var(--hairline-soft); }
.row {
  display: grid; grid-template-columns: 44px 28px 1fr 1fr auto;
  gap: clamp(10px, 2vw, 28px); align-items: center;
  padding-block: 20px; border-bottom: 1px solid var(--hairline-soft);
  transition: background .3s var(--ease), padding-left .35s var(--ease);
}
.row:hover { background: rgba(255,255,255,.02); padding-left: 8px; }
.row__no { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.row__ico { width: 26px; height: 26px; border-radius: 8px; background: var(--surface-2); display: grid; place-items: center; color: var(--brand-bright); }
.row__ico svg { width: 13px; height: 13px; }
.row__title { font-size: 16px; font-weight: 500; letter-spacing: -.02em; }
.row__desc { font-size: 14px; color: var(--text-3); }
.row__chips { display: flex; gap: 7px; }

/* --------------------------------------------------------------------------
   Fee split - odometer figures (reference "Stats")
   -------------------------------------------------------------------------- */

.figs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.fig {
  border-radius: var(--r-card); border: 1px solid var(--hairline-soft);
  background: var(--surface);
  padding: clamp(20px, 2.2vw, 30px);
  display: grid; grid-template-rows: auto 1fr auto; gap: 18px; min-height: 260px;
}
.fig__label { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.fig__n {
  align-self: center;
  display: flex; align-items: baseline; gap: 0;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(46px, 5.6vw, 84px); line-height: 1; letter-spacing: -.05em;
}
.fig__n sup {
  font-size: .34em; color: var(--brand-bright);
  align-self: flex-start; margin-top: .38em;
}
/* a word unit reads as a caption, not an exponent */
.fig__n sup:not(:empty) { letter-spacing: -.01em; }
.fig__n:has(sup:not(:empty)) { gap: .12em; }
.fig__sub { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }

/* digit reel */
.odo { display: inline-block; height: 1em; overflow: hidden; text-align: center; }
.odo i { display: block; font-style: normal; transition: transform 1.4s cubic-bezier(.16,1,.3,1); }
.odo i span { display: block; height: 1em; }

/* --------------------------------------------------------------------------
   Leaderboard (reference "Team")
   -------------------------------------------------------------------------- */

.lb {
  width: 250px; border-radius: var(--r-card);
  border: 1px solid var(--hairline-soft); background: var(--surface); overflow: hidden;
  transition: transform .35s var(--ease), border-color .35s var(--ease);
}
.lb:hover { transform: translateY(-4px); border-color: rgba(63,169,240,.35); }
.lb__art {
  aspect-ratio: 3 / 4; display: grid; place-items: center; position: relative;
  background: radial-gradient(70% 60% at 50% 32%, rgba(26,143,227,.42), transparent 72%), #0c0c0c;
}
.lb__rank { font-family: var(--font-display); font-weight: 600; font-size: 56px; letter-spacing: -.06em; color: rgba(255,255,255,.16); }
.lb__tag { position: absolute; left: 10px; top: 10px; }
.lb__meta { padding: 14px 15px 16px; display: grid; gap: 3px; }
.lb__handle { font-weight: 600; font-size: 15px; letter-spacing: -.02em; }
.lb__stat { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }

/* --------------------------------------------------------------------------
   FAQ - title + card on the left, accordion on the right
   -------------------------------------------------------------------------- */

.faq-wrap { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: clamp(28px, 5vw, 80px); align-items: start; }
.faq-aside { display: grid; gap: 20px; }
.faq-card {
  border-radius: var(--r-card); overflow: hidden;
  border: 1px solid var(--hairline-soft); background: var(--surface);
  padding: 20px; display: grid; gap: 14px; max-width: 300px;
}
.faq-card__art {
  aspect-ratio: 3 / 4; border-radius: 16px;
  background: radial-gradient(70% 60% at 50% 34%, rgba(26,143,227,.5), transparent 72%), #0c0c0c;
  display: grid; place-items: center;
}
.faq-card__art img { width: 52%; }

.faq { display: grid; gap: 8px; }
.faq__item {
  border-radius: 16px; border: 1px solid var(--hairline-soft);
  background: var(--surface); overflow: hidden;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.faq__item.is-open { border-color: rgba(63,169,240,.3); }
.faq__q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 18px 20px; text-align: left;
  font-size: clamp(15px, 1.3vw, 17px); font-weight: 500; letter-spacing: -.02em;
  transition: color .25s var(--ease);
}
.faq__q:hover { color: var(--brand-bright); }
.faq__sign {
  position: relative; width: 22px; height: 22px; flex: none;
  border-radius: 50%; background: var(--brand); color: var(--on-brand);
}
.faq__sign::before, .faq__sign::after {
  content: ''; position: absolute; left: 6px; right: 6px; top: 50%; height: 1.5px;
  background: currentColor; transition: transform .35s var(--ease);
}
.faq__sign::after { transform: rotate(90deg); }
.faq__item.is-open .faq__sign::after { transform: rotate(0); }
.faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .4s var(--ease); }
.faq__item.is-open .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }
.faq__a p { margin: 0 20px 20px; color: var(--text-2); font-size: 14.5px; line-height: 1.6; }

/* --------------------------------------------------------------------------
   Docs cards (reference "Blogs")
   -------------------------------------------------------------------------- */

.docs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.doc {
  border-radius: var(--r-card); border: 1px solid var(--hairline-soft);
  background: var(--surface); overflow: hidden; display: grid; gap: 0;
  transition: transform .35s var(--ease), border-color .35s var(--ease);
}
.doc:hover { transform: translateY(-4px); border-color: rgba(63,169,240,.3); }
.doc__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 14px; }
.doc__date { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }
.doc__art {
  aspect-ratio: 4 / 3; margin: 0 14px; border-radius: 14px;
  background: radial-gradient(70% 70% at 40% 26%, rgba(26,143,227,.32), transparent 72%), #0b0b0b;
  display: grid; place-items: center; padding: 18px; text-align: center;
}
.doc__art span { font-family: var(--font-display); font-weight: 600; font-size: 18px; letter-spacing: -.03em; color: rgba(255,255,255,.5); }
.doc__title { padding: 14px; font-size: 15px; font-weight: 500; letter-spacing: -.02em; }

/* --------------------------------------------------------------------------
   Contact strip + green footer
   -------------------------------------------------------------------------- */

.need {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 12px 12px 28px;
  border-radius: var(--r-chip);
  background: var(--brand); color: var(--on-brand);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(16px, 2vw, 26px); letter-spacing: -.03em;
}
.need::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: url('/assets/img/sky-1100.webp') 50% 46% / cover;
}
.need::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(255,255,255,.34), rgba(255,255,255,.06) 46%, rgba(255,255,255,.30));
}
.need > * { position: relative; z-index: 2; }

.foot { background: var(--brand); color: var(--on-brand); }
/* the footer carries the most text of any sky plate, so it gets a heavier veil */
.foot.block--sky::after {
  background:
    linear-gradient(180deg, rgba(255,255,255,.22) 0%, rgba(255,255,255,.46) 30%, rgba(255,255,255,.62) 100%),
    radial-gradient(80% 50% at 50% 0%, rgba(4,44,80,.18), transparent 60%);
}
/* White outline on a bright sky is invisible; the wordmark is drawn in the
   same navy the rest of the sky plate uses for type. */
.foot .marquee__item--outline {
  -webkit-text-stroke: 1px rgba(5, 36, 64, .30);
  color: transparent;
}

/* On a sky page the footer was sky sitting on sky: no seam, no ending, just
   more blue. The first fix inverted it to a black slab, which was worse - a
   dark rounded box floating on a bright photograph, with raw sky showing
   above and beside it. This is the third answer and the right one: frosted
   glass. The plate still closes the page, the sky still reads through it, and
   the type sits on the same navy the rest of a sky page uses. */
.sky-page footer.foot {
  background: rgba(255, 255, 255, .66);
  backdrop-filter: blur(26px) saturate(150%);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, .7);
  color: #04223c;
  box-shadow: 0 -24px 60px rgba(4, 32, 62, .16);
}
.sky-page footer.foot::before { display: none; }
/* Keep a veil, but a light one: it lifts the type off whatever cloud happens
   to be behind the panel at that scroll position. */
.sky-page footer.foot::after {
  background: linear-gradient(180deg, rgba(255,255,255,.28) 0%, rgba(255,255,255,.10) 100%);
}
.sky-page footer.foot .clouds { display: none; }
.sky-page .foot__col h4 { color: rgba(5, 32, 52, .62); }
.sky-page .foot__col a:not(.btn) { color: rgba(5, 32, 52, .84); }
.sky-page .foot__col a:not(.btn):hover { color: #04223c; }
.sky-page .foot__bar { border-top-color: rgba(5, 36, 64, .16); color: rgba(5, 32, 52, .66); }
.sky-page .foot .marquee__item--outline { -webkit-text-stroke: 1px rgba(5, 36, 64, .22); color: transparent; }
.sky-page .foot__card { box-shadow: 0 16px 40px rgba(4, 32, 62, .26); }
/* Back to top stays a dark pill: on a frosted-glass panel a dark control is
   the one that reads as a control. */
.sky-page .foot .btn--dark {
  --btn-bg: #04223c;
  --btn-fg: #fff;
  border-color: transparent;
}
.sky-page .foot .btn--dark:hover { --btn-bg: #062f52; }

/* Minimal by design: a card and one button, two short link columns, nothing
   else. The columns are narrow and the left one is mostly air - that space is
   what makes the wordmark below read as the closing note. */
.foot__top {
  display: grid; grid-template-columns: 1.25fr repeat(2, minmax(130px, .5fr));
  gap: clamp(28px, 4vw, 64px);
  padding-block: clamp(52px, 6.5vw, 96px) clamp(40px, 5vw, 72px);
}
.foot__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.foot__card {
  position: relative; overflow: hidden;
  width: clamp(112px, 11vw, 148px); aspect-ratio: .82;
  border-radius: 16px;
  background: url('/assets/img/sky-tile.webp') 50% 42% / cover no-repeat;
  box-shadow: 0 16px 40px rgba(4, 44, 80, .22);
  display: grid; place-items: center;
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.foot__card img { width: 46%; height: auto; filter: drop-shadow(0 6px 14px rgba(4, 40, 76, .34)); }
.foot__card:hover { transform: translateY(-3px); box-shadow: 0 22px 52px rgba(4, 44, 80, .3); }
.foot__totop { align-self: flex-start; }

.foot__col { display: flex; flex-direction: column; align-items: flex-start; }
.foot__col h4 {
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 400;
  letter-spacing: .06em; text-transform: uppercase;
  color: rgba(5, 36, 64, .52); margin: 0 0 18px;
}
.foot__col a:not(.btn) {
  display: block; padding-block: 6px; font-size: 15.5px;
  color: rgba(5, 36, 64, .86); transition: color .2s var(--ease);
}
.foot__col a:not(.btn):hover { color: var(--on-brand); }

.foot__bar {
  display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: baseline;
  justify-content: space-between;
  padding-block: 22px 26px;
  border-top: 1px solid rgba(5, 36, 64, .16);
  font-family: var(--font-mono); font-size: 11.5px; color: rgba(5, 36, 64, .62);
}
/* the disclosure lives here now - one line rather than the old paragraph, but
   it still says the three things it has to: independent, pre-launch, at risk */
.foot__legal { flex: 1 1 340px; max-width: 76ch; line-height: 1.6; }
.foot__bar a:hover { color: var(--on-brand); }

/* --------------------------------------------------------------------------
   Scroll reveal
   -------------------------------------------------------------------------- */

[data-anim] { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
[data-anim].is-in { opacity: 1; transform: none; }
[data-anim][data-delay="1"] { transition-delay: .07s; }
[data-anim][data-delay="2"] { transition-delay: .14s; }
[data-anim][data-delay="3"] { transition-delay: .21s; }
[data-anim][data-delay="4"] { transition-delay: .28s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  [data-anim] { opacity: 1; transform: none; }
  .reveal-words span { opacity: 1; }
}

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

@media (max-width: 1100px) {
  .wall { grid-template-columns: repeat(2, 1fr); }
  .tiers { grid-template-columns: 1fr; }
  .figs { grid-template-columns: repeat(2, 1fr); }
  .docs { grid-template-columns: repeat(2, 1fr); }
  .faq-wrap { grid-template-columns: 1fr; }
  .faq-card { max-width: none; grid-template-columns: 150px 1fr; align-items: center; }
  .foot__top { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  :root { --r-block: 24px; --r-card: 18px; }
  .nav__fold { display: none; }
  .nav.is-open .nav__fold { display: block; grid-template-columns: 1fr; opacity: 1; }
  .nav.is-open .nav__fold > div {
    flex-direction: column; align-items: stretch; gap: 2px;
    position: absolute; top: 60px; left: var(--edge); right: var(--edge);
    padding: 10px;
    background: rgba(18,18,18,.96); border: 1px solid var(--hairline-soft);
    border-radius: 22px; backdrop-filter: blur(18px);
  }
  .nav.is-open .nav__links { flex-direction: column; align-items: stretch; gap: 2px; }
  /* stacked links are full width, so the index cannot hang off the right edge
     of the label any more - it sits at the end of the row instead */
  .nav.is-open .nav__link { height: 44px; padding: 0 12px; justify-content: space-between; }
  .nav.is-open .nav__link--primary { justify-content: center; margin-top: 8px; height: 46px; }
  .nav.is-open .nav__x { width: 44px; height: 44px; margin-inline: 12px 0; }
  .nav.is-open .nav__num { position: static; top: auto; right: auto; opacity: .7; }
  .nav__inner { width: calc(100% - 16px); justify-content: space-between; gap: 12px; }
  .nav__burger { display: block; }
  .nav__eq { display: none; }
  .cmd { grid-template-columns: 36px 1fr; }
  .cmd > .chip { grid-column: 2; justify-self: start; }
  .row { grid-template-columns: 30px 1fr; row-gap: 4px; }
  .row__ico { display: none; }
  .row__desc, .row__chips { grid-column: 2; }
  .hero { min-height: 92svh; }
}

@media (max-width: 560px) {
  .wall { grid-template-columns: 1fr; }
  .figs, .docs { grid-template-columns: 1fr; }
  .foot__top { grid-template-columns: 1fr; gap: 26px; }
  .launch-bar { flex-direction: column; align-items: stretch; }
  .launch-grid { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px; }
  .launch__glyph { font-size: 30px; }
  .launch__meta { padding: 11px 12px 12px; }
  .launch__row { font-size: 10.5px; }
  .faq-card { grid-template-columns: 1fr; }
  .need { flex-direction: column; align-items: stretch; text-align: center; padding: 20px; border-radius: 22px; }
}

/* --------------------------------------------------------------------------
   Parallax clouds
   Real cutouts on their own depth planes. Each cloud is a positioned <span>
   that JS moves on scroll; the <img> inside carries a slow idle drift, so the
   two transforms never fight each other.
   Depth is sold three ways at once: speed, scale and a touch of blur - the
   nearest plane sits ABOVE the section content so clouds clip across cards
   and headlines instead of sitting flat behind them.
   -------------------------------------------------------------------------- */

.clouds {
  position: absolute; inset: -16% -10%;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}
.clouds--spill { overflow: visible; inset: -22% 0; }
/* a spill layer must never widen the document */
.block--flush:has(.clouds--spill) { overflow-x: clip; }

.cloud {
  position: absolute;
  left: var(--x, 0%); top: var(--y, 0%);
  width: var(--w, 30%);
  transform: translate3d(0, 0, 0);
}
.cloud img {
  display: block; width: 100%; height: auto;
  scale: var(--flip, 1) 1;
  animation: cloud-drift var(--dur, 26s) ease-in-out infinite alternate;
  animation-delay: var(--delay, 0s);
}
@keyframes cloud-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(2.5%, -3%, 0) scale(1.035); }
}

/* Depth planes.
   Filters are the expensive part of this page and clouds are the most numerous
   thing on it, so only the near plane keeps one - its big soft shadow is what
   actually sells the depth, and there are few of them. The far and mid planes
   used a 1.4px blur on an image that is already soft-edged and a shadow small
   enough to be invisible behind other clouds; both are now carried by opacity,
   which the compositor handles without a repaint. */
.cloud--far  { opacity: .46; }
.cloud--mid  { opacity: .8; }
.cloud--near {
  z-index: 6;
  opacity: .96;
  filter: drop-shadow(0 30px 52px rgba(4, 40, 74, .34));
}

/* The near plane rides above section content - that is the whole 3D trick. */
.clouds--over { z-index: 7; }

@media (prefers-reduced-motion: reduce) {
  .cloud img { animation: none; }
}
@media (max-width: 860px) {
  .cloud--far { display: none; }
  .cloud { width: calc(var(--w, 30%) * 1.5); }
  .clouds--spill { inset: -14% 0; overflow: hidden; }
}

/* --------------------------------------------------------------------------
   3D launch carousel
   The whole track is rotated on Y inside a perspective box, so cards further
   along the row genuinely recede - the depth comes from the projection, not
   from faked per-card scaling.
   -------------------------------------------------------------------------- */

.p3d {
  perspective: 2000px;
  perspective-origin: 6% 50%;
  overflow-x: auto;
  overflow-y: hidden;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--surface-3) transparent;
}
.p3d::-webkit-scrollbar { height: 5px; }
.p3d::-webkit-scrollbar-track { background: transparent; }
.p3d::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 99px; }

.p3d__track {
  display: flex;
  gap: clamp(18px, 2.4vw, 34px);
  width: max-content;
  transform-style: preserve-3d;
  transform: rotateY(var(--rot, 24deg));
  transition: transform .6s var(--ease);
  padding-block: clamp(28px, 4.6vw, 76px);
}

.p3d__card {
  flex: 0 0 auto;
  width: clamp(210px, 22vw, 330px);
  transform-style: preserve-3d;
  transition: transform .45s var(--ease);
}
.p3d__card:hover { transform: translateZ(60px); }

.p3d__art {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: 0 40px 80px rgba(0, 0, 0, .6);
}
.p3d__art img { width: 100%; height: 100%; object-fit: cover; }
.p3d__tag { position: absolute; right: 12px; top: 12px; }
.p3d__flag { position: absolute; left: 12px; top: 12px; }
.p3d__name {
  display: block;
  margin-top: 16px;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(20px, 2.1vw, 32px); letter-spacing: -.035em;
  color: var(--text-2);
}
.p3d__meta {
  display: flex; gap: 14px; flex-wrap: wrap;
  margin-top: 6px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3);
}
.p3d__meta b { color: var(--text-2); font-weight: 400; }

.p3d__hint {
  display: flex; align-items: center; gap: 8px;
  margin-top: 26px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3);
}

@media (max-width: 860px) {
  .p3d { perspective: none; }
  .p3d__track { transform: none; padding-block: 8px 20px; }
  .p3d__card { width: 250px; }
  .p3d__art { box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .p3d__track { transform: none; transition: none; }
}

/* --------------------------------------------------------------------------
   Page hero - the layout every inner page opens with: oversized title bottom
   left, the standfirst set right against the same baseline, one hairline.
   -------------------------------------------------------------------------- */

.phero { padding-block: clamp(132px, 19vh, 216px) 0; }
.phero__grid {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  align-items: end; gap: clamp(24px, 4vw, 64px);
}
.phero__title {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(52px, 11vw, 150px); line-height: .94;
  letter-spacing: -0.05em; margin: 0;
}
.phero__desc {
  /* the near cloud plane is deliberately allowed over the big title, but it
     must never land on running copy - a cloud sitting on the last two words
     reads as clipped text */
  position: relative; z-index: 8;
  margin: 0 0 .6em; justify-self: end; text-align: right;
  max-width: 42ch; font-size: clamp(15px, 1.35vw, 19px); line-height: 1.5;
  color: var(--text-2);
}
.phero__rule { height: 1px; background: var(--hairline); margin-top: clamp(34px, 5vw, 70px); }

@media (max-width: 800px) {
  .phero__grid { grid-template-columns: 1fr; }
  .phero__desc { justify-self: start; text-align: left; margin-bottom: 0; }
}

/* --------------------------------------------------------------------------
   Page transition - the new page rises from the bottom
   The nav lives outside <main> and never animates, so the only thing that moves
   is the content slab: the old one lifts and softens away, the new one slides
   up into place. `main` carries a solid ground, which is what makes it read as
   a whole page arriving rather than a list of elements fading in.
   -------------------------------------------------------------------------- */

main { transform-origin: 50% 30%; }

/* --------------------------------------------------------------------------
   Page transition - cross-document view transitions

   The browser keeps the outgoing page on screen while the next document loads,
   then animates between the two snapshots. That is the whole reason this works
   where the JS version did not: a normal navigation destroys the old document
   and the new one cannot paint until it has parsed, so anything driven from JS
   was always animating into a gap. Here there is no gap - the old page is a
   held snapshot, and the new one slides up over it as one sheet.

   Browsers without support just navigate. No half-played effect, no fallback
   that looks like a bug.
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-group(root) { animation-duration: 1.5s; }

/* both snapshots paint normally: the default `plus-lighter` blend is for
   cross-fades, and it would make the rising sheet glow where it overlaps */
::view-transition-old(root),
::view-transition-new(root) { mix-blend-mode: normal; }

::view-transition-old(root) {
  z-index: 0;
  animation: page-sink .8s cubic-bezier(.6, 0, .35, 1) both;
}
::view-transition-new(root) {
  z-index: 1;
  animation: page-rise 1.5s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes page-sink {
  to { transform: translateY(-3vh) scale(.972); opacity: .38; }
}
@keyframes page-rise {
  from { transform: translateY(100vh); box-shadow: 0 -34px 70px rgba(0, 0, 0, .75); }
  to   { transform: none;              box-shadow: 0 -34px 70px rgba(0, 0, 0, 0); }
}

/* The nav is identical on both pages, so it is captured as its own group and
   held still. That stillness is the whole trick - the sheet reads as passing
   behind a fixed shell rather than the whole window moving. */
.nav { view-transition-name: nav; }
/* Long enough to cover the crossfade above, short enough that the bar
   never appears to travel. */
::view-transition-group(nav) { animation-duration: .18s; }
/* A short crossfade, not `animation: none`.
   Holding both snapshots at opacity 1 draws two navbars on top of each other
   for the length of the transition - fine while they are identical, visibly
   wrong the moment they are not (signed out on one page, signed in on the
   next). The session cache makes them match almost always; this makes the
   remaining case dissolve instead of stack. */
::view-transition-old(nav) { animation: nav-out .18s ease both; mix-blend-mode: normal; }
::view-transition-new(nav) { animation: nav-in .18s ease both; mix-blend-mode: normal; }
@keyframes nav-out { to { opacity: 0; } }
@keyframes nav-in  { from { opacity: 0; } }

/* the nav gets one soft settle on first paint and nothing after - during a
   transition it must not replay, or it would be caught in the new snapshot */
.nav__inner { animation: nav-in .8s cubic-bezier(.22, 1, .36, 1) both; }
@keyframes nav-in { from { opacity: 0; transform: translateY(-16px); } }
:root:active-view-transition .nav__inner { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .nav__inner { animation: none; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* --------------------------------------------------------------------------
   Inner-page grids
   -------------------------------------------------------------------------- */

.posts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.posts .tw { box-shadow: 0 18px 44px rgba(0, 0, 0, .45); }
.term-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.term-grid .term { width: auto; }

@media (max-width: 860px) {
  .posts { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Process - the media that grows into the page
   The picture sits alone in a viewport-tall block and scales up until it is
   larger than the viewport. Because a scale transform does not touch layout,
   the panel that follows rides straight over it and the picture keeps showing
   as strips down both edges - that overlap is the whole effect, and it costs
   no sticky positioning at all.
   One scroll var drives it (--m, 0 to 1). --grow is written by JS, because CSS
   cannot divide a viewport unit by a pixel width to work out the cover scale.
   ========================================================================== */

.proc { --m: 0; --grow: 1.9; background: var(--bg-2); }

.proc__media {
  position: relative; z-index: 0;
  height: 100svh;
  display: grid; place-items: center;
  padding-top: clamp(64px, 9vh, 120px);
}
.proc__frame {
  position: relative;
  width: min(880px, 78vw);
  aspect-ratio: 1.611;
  border-radius: calc(24px * (1 - var(--m)));
  overflow: hidden;
  /* the poster sits under the video as a background, so there is never a
     black box while the file is still buffering */
  background: #2585d0 url('/assets/media/process-poster.webp') 50% 50% / cover no-repeat;
  transform: scale(calc(1 + (var(--grow) - 1) * var(--m)));
  transform-origin: 50% 50%;
  box-shadow: 0 50px 110px rgba(0, 0, 0, calc(.62 * (1 - var(--m))));
  will-change: transform;
  backface-visibility: hidden;
}
/* The bear animation is baked onto the sky rather than layered over it as an
   alpha video: alpha in WebM is not reliable across browsers, and the sky has
   no motion of its own, so one opaque file costs less than two layers. The
   file already contains its own reverse, so `loop` gives a ping-pong with no
   jump at the seam. */
.proc__vid {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  display: block;
  filter: saturate(1.04) contrast(1.02);
}
/* a whisper of vignette so the panel edge does not cut a flat blue */
.proc__frame::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(80% 68% at 50% 34%, transparent 56%, rgba(4, 42, 80, .18)),
    linear-gradient(180deg, transparent 66%, rgba(4, 38, 72, .20));
}

/* --------------------------------------------------------------- the panel */
.proc__panel {
  position: relative; z-index: 6;
  background: var(--bg-2);
  max-width: 1400px; margin-inline: auto;
  padding: clamp(72px, 8.4vw, 124px) clamp(20px, 3.6vw, 50px) clamp(80px, 9vw, 132px);
}
.proc__grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(30px, 4vw, 70px);
  align-items: start;
}
.proc__label {
  margin: 0 0 18px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 400;
  letter-spacing: .34em; text-transform: uppercase;
  color: var(--brand-bright);
}
.proc__head .display {
  margin: 0;
  /* the reference headline is two calm lines, not the page's hero scale */
  font-size: clamp(38px, 4.6vw, 72px); line-height: 1.03; letter-spacing: -.035em;
}
.proc__more {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: clamp(24px, 3vw, 40px);
  font-size: 14px; color: var(--text-2);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 3px;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.proc__more:hover { color: var(--text); border-color: currentColor; }
.proc__note {
  margin: clamp(26px, 3vw, 40px) 0 0;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .02em;
  color: var(--text-3);
}

/* each step keeps its own rail segment, so the column reads as three marks
   on a path rather than one long line */
.proc__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.proc__item {
  --f: 0;
  display: grid; grid-template-columns: 32px minmax(0, 1fr);
  gap: clamp(26px, 5vw, 100px);
  align-items: stretch;
}
.proc__rail {
  position: relative; width: 3px; justify-self: center;
  border-radius: 4px; overflow: hidden;
  background: rgba(250, 250, 250, .09);
}
.proc__rail i {
  position: absolute; inset: 0; display: block;
  border-radius: 4px; background: var(--brand);
  transform: scaleY(var(--f)); transform-origin: 50% 0;
  box-shadow: 0 0 18px rgba(26, 143, 227, .55);
}
.proc__body {
  padding: clamp(30px, 3.6vw, 50px) 0;
  /* dim until the rail reaches it, then it stays lit - the section reads as a
     path already walked, not a spotlight that moves on */
  opacity: calc(.24 + .76 * min(1, var(--f) * 5));
  transition: opacity .45s var(--ease);
}
.proc__body h3 {
  margin: 0 0 14px;
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(28px, 3.1vw, 46px); line-height: 1.05; letter-spacing: -.032em;
}
.proc__body p { margin: 0; max-width: 32ch; color: var(--text-2); font-size: clamp(15px, 1.15vw, 17px); line-height: 1.55; }

@media (prefers-reduced-motion: reduce) {
  .proc__frame { transform: none; }
  .proc__body { opacity: 1; }
  .proc__vid { display: none; }
  .proc__frame { background: #2585d0 url('/assets/media/process-poster.webp') 50% 50% / cover no-repeat; }
}
@media (max-width: 900px) {
  .proc__media { height: 74svh; padding-top: 40px; }
  .proc__frame { width: 88vw; }
  .proc__grid { grid-template-columns: 1fr; gap: 34px; }
  .proc__item { grid-template-columns: 26px minmax(0, 1fr); gap: 22px; }
  .proc__body { padding: 24px 0; }
  .proc__body p { max-width: none; }
}

/* ==========================================================================
   Wallet - the page every bot reply links to
   Deliberately plain: an address, what is in it, and a way out to the explorer.
   The whole point is that anyone can check the same address and get the same
   answer, so the page should not look like it is doing arithmetic of its own.
   ========================================================================== */

.wal__top {
  display: flex; flex-wrap: wrap; gap: 24px;
  align-items: flex-end; justify-content: space-between;
}
.wal__handle {
  margin: clamp(14px, 1.4vw, 22px) 0 0;
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(19px, 1.9vw, 28px); letter-spacing: -.032em; line-height: 1.15;
  color: var(--brand-bright);
}
.wal__acts { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* the address, and the one thing everybody does with it */
.copyaddr {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-radius: var(--r-chip);
  background: var(--surface); border: 1px solid var(--hairline-soft);
  color: var(--text-2); cursor: pointer;
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.copyaddr code { font-family: var(--font-mono); font-size: 13px; }
.copyaddr svg { width: 15px; height: 15px; flex: none; opacity: .7; }
.copyaddr:hover { border-color: var(--hairline); color: var(--text); }
.copyaddr.is-done { border-color: var(--brand); color: var(--brand-bright); }
.copyaddr--lg {
  margin-bottom: clamp(26px, 3.2vw, 44px);
  padding: clamp(12px, 1.2vw, 17px) clamp(16px, 1.6vw, 22px);
  gap: 14px;
}
.copyaddr--lg code { font-size: clamp(13px, 1.3vw, 18px); word-break: break-all; text-align: left; }
.copyaddr--lg svg { width: 18px; height: 18px; }

/* The two states this page can be in when there is nothing to list: no wallet
   linked, and not signed in. Both had no styles at all - a heading, a
   paragraph and a button stacked flush left in an otherwise empty page. They
   are the same shape as the empty state, so they share it. */
.wal__empty, .wal__link {
  display: grid; place-items: center; gap: clamp(12px, 1.2vw, 18px);
  text-align: center;
  padding: clamp(48px, 8vw, 110px) clamp(24px, 4vw, 64px);
  border-radius: var(--r-card);
  border: 1px dashed var(--hairline);
}
.wal__status {
  margin: 0; min-height: 1.2em; max-width: 46ch;
  font-size: clamp(13.5px, 1.05vw, 16px); line-height: 1.55; color: var(--text-3);
}
/* On a photograph a dashed outline reads as a placeholder box. Give the state
   the same frosted panel every other surface on a sky page gets. */
.sky-page .wal__empty, .sky-page .wal__link {
  border: 1px solid rgba(255, 255, 255, .72);
  background: rgba(255, 255, 255, .58);
  backdrop-filter: blur(30px) saturate(160%);
  -webkit-backdrop-filter: blur(30px) saturate(160%);
  box-shadow:
    0 34px 80px rgba(6, 42, 78, .16),
    0 2px 10px rgba(6, 42, 78, .08),
    0 1px 0 rgba(255, 255, 255, .95) inset;
}
.wal__empty-t {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(26px, 3.2vw, 40px); letter-spacing: -.035em; line-height: 1.1;
}
.wal__empty-s {
  margin: 0; max-width: 46ch; color: var(--text-2);
  font-size: clamp(15px, 1.2vw, 18px); line-height: 1.55;
}

/* ---- the holdings list ----
   .hlist/.hrow are what renderHoldings() writes, and they had no styles at
   all: the rows arrived as three bare spans running together on one line.
   A balance sheet is a table of two columns - what you hold on the left, how
   much on the right - so that is what this is, with the row as the hit area. */
.wal__mount { display: block; }
.hlist { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.hrow {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 15px 18px; border-radius: 14px;
  background: var(--surface-3);
  border: 1px solid var(--hairline-soft);
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.hrow:hover { background: var(--surface-2); border-color: var(--hairline); }
.hrow__tok {
  display: flex; align-items: baseline; gap: 10px; min-width: 0;
  color: inherit; text-decoration: none;
}
/* The ticker and the amount are the two things anyone came here to read, so
   they are set in the display face at heading weight - the same type the rest
   of the site speaks in. Mono at 13px made a balance sheet look like a log. */
.hrow__sym {
  font-family: var(--font-display); font-weight: 600;
  font-size: 15px; letter-spacing: -.02em; flex: none;
}
.hrow__name {
  font-size: 14px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* tabular figures so the column of numbers lines up on the decimal */
.hrow__amt {
  flex: none; font-family: var(--font-display); font-weight: 600;
  font-size: 15px; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
}

/* ---- the wallet page runs the same rows one scale step up ----
   The terminal panel is a dashboard and stays compact; the wallet page is a
   page about one thing, and its rows carry the page. */
.wal__mount .hrow {
  padding: clamp(17px, 1.7vw, 26px) clamp(18px, 1.8vw, 28px);
  border-radius: clamp(14px, 1.3vw, 20px);
}
.wal__mount .hrow + .hrow { margin-top: clamp(2px, .5vw, 8px); }
.wal__mount .hrow__tok { gap: clamp(10px, 1vw, 16px); }
.wal__mount .hrow__sym { font-size: clamp(17px, 1.65vw, 24px); letter-spacing: -.03em; }
.wal__mount .hrow__name { font-size: clamp(14px, 1.15vw, 17px); }
.wal__mount .hrow__amt { font-size: clamp(19px, 1.9vw, 28px); letter-spacing: -.035em; }
.wal__mount .hold__empty { font-size: clamp(15px, 1.2vw, 18px); line-height: 1.55; }
/* the native balance is the one row that is not an ERC-20 - mark it quietly */
.hrow--native { background: var(--surface-2); }
.hrow--native .hrow__sym { color: var(--brand-bright); }
a.hrow__tok:hover .hrow__name { color: var(--text-2); }

.wal__list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.wal__note {
  margin: clamp(28px, 3.2vw, 46px) 0 0;
  font-size: clamp(13.5px, 1.05vw, 16px); line-height: 1.6;
  color: var(--text-3); max-width: 62ch;
}

/* ------------------------------------- holdings + actions on the terminal */
.hold { padding: clamp(22px, 2.6vw, 34px); }
.hold__l {
  margin: 0 0 10px; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.hold__head {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: center; justify-content: space-between;
}
.hold__title {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(22px, 2.4vw, 30px); letter-spacing: -.035em;
}
.hold__empty { margin: 22px 0 0; color: var(--text-3); font-size: 15px; }

.acts__scroll { overflow-x: auto; margin-top: 20px; }
.acts { width: 100%; min-width: 620px; border-collapse: collapse; }
.acts th {
  text-align: left; padding: 0 14px 12px 0;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
  border-bottom: 1px solid var(--hairline);
}
.acts td { padding: 16px 14px 16px 0; font-size: 14px; color: var(--text-2); border-bottom: 1px solid var(--hairline); }
.acts tr:last-child td { border-bottom: 0; }
.acts__empty td { color: var(--text-3); }

/* ------------------------------------------------- the nav wallet control */
.nav__wallet { position: relative; flex: none; }
.nav__wbtn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 14px;
  border-radius: var(--r-chip);
  border: 1px solid var(--hairline);
  font-size: 13.5px; font-weight: 500; white-space: nowrap;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
.nav__wbtn svg { width: 15px; height: 15px; flex: none; opacity: .85; }
.nav__wbtn:hover { border-color: var(--surface-3); background: var(--surface-2); }
/* signed in: the same button opens a small disclosure menu */
.nav__wallet details > summary { list-style: none; cursor: pointer; }
.nav__wallet details > summary::-webkit-details-marker { display: none; }
.nav__menu {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 20;
  min-width: 200px; padding: 8px;
  border-radius: 16px; background: rgba(18, 18, 18, .97);
  border: 1px solid var(--hairline-soft);
  backdrop-filter: blur(18px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .6);
}
.nav__menu b {
  display: block; padding: 8px 10px 10px;
  font-family: var(--font-mono); font-size: 12px; font-weight: 400; color: var(--text-3);
  border-bottom: 1px solid var(--hairline);
}
.nav__menu a, .nav__menu button {
  display: block; width: 100%; text-align: left;
  padding: 9px 10px; border-radius: 10px;
  font-size: 14px; color: var(--text-2);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.nav__menu a:hover, .nav__menu button:hover { background: var(--surface-2); color: var(--text); }
.nav__menu button { color: #ef6b62; }

@media (max-width: 860px) {
  .nav.is-open .nav__wallet { width: 100%; margin-top: 8px; }
  .nav.is-open .nav__wbtn { width: 100%; height: 44px; justify-content: center; }
  .wal__top { align-items: flex-start; }
}

/* ==========================================================================
   How it works - the command reference
   Ten cards is a lot of surface, so each one is built to be skimmed: number,
   title, one paragraph, three rules, and the post you would actually type. The
   example line is the thing people copy, so it gets the strongest contrast.
   ========================================================================== */

.cmdgrid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
  margin-top: clamp(34px, 4.5vw, 68px);
}
.cmdc {
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(22px, 2.6vw, 34px);
  border-radius: var(--r-card);
  background: var(--surface); border: 1px solid var(--hairline-soft);
  transition: border-color .3s var(--ease), transform .4s var(--ease);
}
.cmdc:hover { border-color: var(--hairline); transform: translateY(-2px); }
.cmdc__head { display: flex; align-items: baseline; gap: 12px; }
.cmdc__no {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  color: var(--brand-bright); flex: none;
}
.cmdc__title {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(19px, 1.8vw, 24px); letter-spacing: -.03em; line-height: 1.15;
}
.cmdc__text { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--text-2); }
.cmdc__list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.cmdc__list li {
  display: flex; gap: 10px; font-size: 13.5px; line-height: 1.5; color: var(--text-3);
}
.cmdc__list li::before {
  content: ''; flex: none; width: 4px; height: 4px; margin-top: .58em;
  border-radius: 50%; background: var(--surface-3);
}
.cmdc__ex {
  display: block; margin-top: auto; padding: 13px 15px;
  border-radius: 12px; background: #0c141c; border: 1px solid rgba(255, 255, 255, .07);
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.5;
  color: var(--brand-glow); overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}
.cmdc__ex .h { color: #fff; }

.hiw__note {
  margin: clamp(34px, 4vw, 56px) 0 0;
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.65;
  color: var(--text-3); max-width: 72ch;
}

/* ------------------------------------------------------- launch checklist */
.lreq {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 18px);
  margin-top: clamp(34px, 4vw, 62px);
}
.lreq__item {
  padding: clamp(20px, 2.2vw, 28px);
  border-radius: var(--r-card);
  background: var(--surface); border: 1px solid var(--hairline-soft);
}
.lreq__item h3 {
  margin: 0 0 10px; font-family: var(--font-mono); font-size: 11px;
  font-weight: 400; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-bright);
}
.lreq__item p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--text-2); }
.lreq__item em { font-style: normal; color: var(--text); }

/* ---------------------------------------------------------- example posts */
.exl__l {
  margin: 0 0 clamp(20px, 2.4vw, 32px);
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-3);
}
.exl { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.exl li {
  padding: clamp(14px, 1.6vw, 20px) 0;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(17px, 2.1vw, 28px); letter-spacing: -.03em; color: var(--text-2);
  transition: color .25s var(--ease), padding-left .3s var(--ease);
}
.exl li:last-child { border-bottom: 1px solid var(--hairline); }
.exl li:hover { color: var(--text); padding-left: 10px; }

@media (max-width: 1100px) { .lreq { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 820px) {
  .cmdgrid { grid-template-columns: 1fr; }
  .lreq { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Terminal
   Two entrances into one command parser: a form for people who want fields, a
   chat for people who want to type. Both build the same command object, which
   is why the layout puts them side by side as equals rather than making one a
   fallback for the other.
   ========================================================================== */

/* these three carry a display value, so plain [hidden] would not hide them */
.tgate[hidden], .tapp[hidden], .tgrid[hidden] { display: none !important; }

.tgate { display: grid; place-items: center; padding-block: clamp(30px, 6vw, 90px); }
.tgate__card { max-width: 560px; padding: clamp(30px, 4vw, 54px); text-align: center; }
.tgate__title {
  margin: 0 0 14px; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(26px, 3.2vw, 40px); letter-spacing: -.035em; line-height: 1.1;
}
.tgate__text { margin: 0 auto 26px; max-width: 42ch; color: var(--text-2); font-size: 15.5px; line-height: 1.6; }
/* X's own dark-background button is white with black type - #0f1419 on a
   #141414 card is a button you cannot see, which is what the gate had. This is
   the only control on the page, so it gets the light treatment. */
.btn.tgate__btn {
  margin-inline: auto;
  --btn-bg: #ffffff; --btn-fg: #0b0d10;
}
.btn.tgate__btn:hover { --btn-bg: #e8eaed; }
/* Disabled has to look disabled and still be legible, or "sign-in is not
   switched on yet" reads as "the button is broken". */
.btn.tgate__btn[aria-disabled="true"] {
  --btn-bg: rgba(255,255,255,.10); --btn-fg: rgba(255,255,255,.55);
  border: 1px solid var(--hairline);
}
.tgate__note { margin: 26px auto 0; max-width: 46ch; font-size: 13px; line-height: 1.6; color: var(--text-3); }
.tgate__note b { color: var(--text-2); }
.tgate__soon {
  margin: 18px auto 0; max-width: 46ch;
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.6; color: var(--text-3);
}
.tgate__soon a { color: var(--brand-bright); text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------------ header */
.tapp__head {
  display: flex; flex-wrap: wrap; gap: 24px;
  align-items: flex-end; justify-content: space-between;
  margin-bottom: clamp(24px, 3vw, 40px);
}
.tapp__eyebrow {
  margin: 0 0 12px; font-family: var(--font-mono); font-size: 11.5px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--brand-bright);
}
.tapp__hi {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(34px, 5.4vw, 68px); line-height: .98; letter-spacing: -.045em;
}
.tapp__sub { margin: 16px 0 0; color: var(--text-2); font-size: 15.5px; max-width: 46ch; }
.tapp__aside { display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }

.seg {
  display: inline-flex; gap: 4px; padding: 4px;
  border-radius: var(--r-chip); background: var(--surface); border: 1px solid var(--hairline-soft);
}
.seg__btn {
  height: 34px; padding: 0 16px; border-radius: var(--r-chip);
  font-size: 13.5px; font-weight: 500; color: var(--text-3); white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.seg__btn:hover { color: var(--text-2); }
.seg__btn.is-on { background: var(--brand); color: var(--on-brand); }

/* ------------------------------------------------------------------- grid */
.tgrid {
  display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
  gap: clamp(14px, 1.6vw, 22px); align-items: start;
}
.tgrid + .twallet { margin-top: clamp(14px, 1.6vw, 22px); }

/* ------------------------------------------------------------------- form */
.tform { padding: 14px; }
.tform__tabs {
  display: flex; gap: 2px; padding: 4px; margin-bottom: 20px;
  border-radius: var(--r-chip); background: rgba(255, 255, 255, .04);
}
.tform__tab {
  flex: 1; height: 34px; border-radius: var(--r-chip);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3); white-space: nowrap;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.tform__tab:hover { color: var(--text-2); }
.tform__tab.is-on { background: var(--text); color: #000; }
.tform__body { padding: 6px 8px 10px; display: grid; gap: 16px; }
.tform__row { display: grid; grid-template-columns: 1fr 116px; gap: 12px; align-items: end; }
.tform__row--half { grid-template-columns: 1fr; max-width: 200px; }

.fld { display: grid; gap: 7px; min-width: 0; }
.fld__l {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3);
}
.fld__i {
  width: 100%; height: 44px; padding: 0 13px;
  border-radius: 12px; border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, .03); color: var(--text);
  font-family: var(--font); font-size: 15px;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.fld__i::placeholder { color: var(--text-3); }
.fld__i:focus { outline: none; border-color: var(--brand); background: rgba(26, 143, 227, .07); }
.fld__i:disabled { opacity: .5; cursor: not-allowed; }
select.fld__i { appearance: none; cursor: pointer; }
.fld__ro {
  display: flex; align-items: center; height: 44px; padding: 0 13px;
  border-radius: 12px; border: 1px dashed var(--hairline);
  color: var(--text-2); font-family: var(--font-mono); font-size: 13px;
}
.tform__go { width: 100%; justify-content: center; margin-top: 4px; }
.tform__go:disabled { opacity: .45; cursor: not-allowed; }
.tform__note { margin: 0; font-size: 12px; color: var(--text-3); text-align: center; }

/* ------------------------------------------------------------------- chat */
.tchat { display: flex; flex-direction: column; min-height: clamp(380px, 46vh, 520px); padding: 18px; }
.tchat__who {
  margin: 0 0 12px; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.tchat__log { flex: 1; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; }
.tchat__msg {
  align-self: flex-start; max-width: 80%; margin: 0;
  padding: 13px 16px; border-radius: 14px;
  background: rgba(255, 255, 255, .05);
  font-family: var(--font-mono); font-size: 13px; line-height: 1.55; color: var(--text-2);
}
.tchat__msg--me { align-self: flex-end; background: var(--brand); color: var(--on-brand); }
.tchat__bar { display: flex; gap: 10px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--hairline); }
.tchat__in {
  flex: 1; min-width: 0; height: 46px; padding: 0 15px;
  border-radius: var(--r-chip); border: 1px solid var(--hairline);
  background: rgba(255, 255, 255, .03); color: var(--text); font-size: 14.5px;
}
.tchat__in::placeholder { color: var(--text-3); }
.tchat__in:focus { outline: none; border-color: var(--brand); }
.tchat__send { flex: none; }
.tchat__send:disabled { opacity: .45; cursor: not-allowed; }

/* ------------------------------------------------------------ cross-chain */
.tpromo { padding: clamp(24px, 3vw, 38px); background: var(--surface); }
.tpromo__kicker {
  margin: 0 0 16px; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--brand-bright);
}
.tpromo__title {
  margin: 0 0 16px; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(28px, 3.4vw, 44px); line-height: 1.02; letter-spacing: -.04em;
}
.tpromo__text { margin: 0; color: var(--text-2); font-size: 15px; line-height: 1.6; }
.tpromo__soon {
  margin: 22px 0 0; padding-top: 18px; border-top: 1px solid var(--hairline);
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.6; color: var(--text-3);
}
.tcross { padding: 20px; display: grid; gap: 16px; align-content: start; }
/* the cross-chain form pairs equal fields, unlike the buy form's amount+unit */
.tcross .tform__row { grid-template-columns: 1fr 1fr; }
.tcross__route {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 12px;
  padding: 15px 16px; border-radius: 14px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--hairline);
}
.tcross__route span, .tcross__route b {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
}
.tcross__route span { color: var(--text-3); }
.tcross__route p { grid-column: 1 / -1; margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--text-3); }

/* ----------------------------------------------------------------- wallet */
.twallet { padding: 20px 22px; }
.twallet__l {
  margin: 0 0 12px; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.twallet__row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.twallet__addr { font-family: var(--font-mono); font-size: 14px; color: var(--text); }
.twallet__note { margin: 12px 0 0; font-size: 12.5px; color: var(--text-3); }

@media (max-width: 900px) {
  .tgrid { grid-template-columns: 1fr; }
  .tapp__head { align-items: flex-start; }
  .tapp__aside { align-items: flex-start; width: 100%; }
  .tform__tab { font-size: 9.5px; padding: 0 6px; }
}
@media (max-width: 560px) {
  .tform__row { grid-template-columns: 1fr; }
  .seg { width: 100%; }
  .seg__btn { flex: 1; }
}

/* ==========================================================================
   Sky pages - Docs, How it works, Terminal
   The plate is fixed to the viewport, so it renders ~1:1 and never upscales,
   and it drifts vertically with scroll so the sky still travels with the page.
   Clouds live in the content flow instead, which is what gives the parallax
   something real to move against.
   ========================================================================== */

.sky-page { background: #2585d0; color: var(--on-brand); }
.skybg { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.skybg__plate {
  position: absolute; inset: -18% 0;
  background: url('/assets/img/sky-hero.webp') center / cover no-repeat;
  transform: translate3d(0, calc(var(--sy, 0) * 1px), 0);
  will-change: transform;
}
/* The photograph is beautiful and busy, and a docs page is a reading surface
   first. The scrim keeps the sky readable as sky while dropping its contrast
   under the middle of the page, where the text column sits. */
.skybg__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(4,44,84,.24) 0%, rgba(4,44,84,.02) 26%, rgba(4,44,84,.18) 100%),
    linear-gradient(90deg, transparent 0%, rgba(255,255,255,.26) 26%, rgba(255,255,255,.26) 74%, transparent 100%),
    radial-gradient(72% 54% at 50% 34%, rgba(255,255,255,.18), transparent 76%);
}
@media (max-width: 1500px) { .skybg__plate { background-image: url('/assets/img/sky-hero-md.webp'); } }
@media (max-width: 900px)  { .skybg__plate { background-image: url('/assets/img/sky-hero-sm.webp'); } }

.sky-page #shell-nav, .sky-page main, .sky-page footer { position: relative; z-index: 1; }

/* Every component on this site was drawn for a dark page, so it reads its ink
   and its surfaces from tokens. A sky page is a bright page, so re-point the
   tokens once instead of restyling each component - the same trick
   .block--light uses. Scoped to <main>: the nav pill and the footer are their
   own dark chrome and keep the root values.
   --on-brand deliberately stays as it is: on a sky page it already means
   "ink on something bright", and every .pane and heading depends on that. */
.sky-page main {
  --text:   #04223c;
  --text-2: rgba(5, 32, 52, .80);
  --text-3: rgba(5, 32, 52, .60);
  --surface:   rgba(255, 255, 255, .82);
  --surface-2: rgba(255, 255, 255, .94);
  --surface-3: rgba(255, 255, 255, .70);
  --hairline:      rgba(5, 36, 64, .18);
  --hairline-soft: rgba(5, 36, 64, .10);
  /* the accent has to move too: #3fa9f0 is a blue drawn to glow on black and
     it vanishes against sky. The handle, the copied-address confirmation and
     the native-balance row all read from this one token. */
  --brand-bright: #0b4e8a;
}
/* A ghost button on a photograph needs a real edge - a hairline over cloud
   disappears exactly where the cloud is white. */
.sky-page main .btn--ghost {
  --btn-bg: rgba(255, 255, 255, .55);
  border-color: rgba(5, 36, 64, .16);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.sky-page main .btn--ghost:hover { --btn-bg: rgba(255, 255, 255, .82); }
/* Type on a moving sky needs more weight than type on a flat panel: darker ink
   and a soft white halo so a cloud drifting behind never eats a line. */
.sky-page .phero__title { color: #04223c; text-shadow: 0 2px 26px rgba(255, 255, 255, .55); }
.sky-page .phero__desc  { color: #052034; font-weight: 500; text-shadow: 0 1px 8px rgba(255,255,255,.95), 0 0 22px rgba(255,255,255,.75); }
.sky-page .phero__rule  { background: rgba(5, 36, 64, .20); }
/* same light seam as the sky block on the home page */
.sky-page .eyebrow::before {
  background: linear-gradient(90deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.26) 26%, rgba(255,255,255,.58) 100%);
  box-shadow: 0 1px 0 rgba(6, 48, 88, .10);
}
.sky-page .eyebrow::after {
  background: linear-gradient(90deg,
    rgba(255,255,255,.58) 0%, rgba(255,255,255,.26) 74%, rgba(255,255,255,0) 100%);
  box-shadow: 0 1px 0 rgba(6, 48, 88, .10);
}
.sky-page .eyebrow__pill::before {
  content: '';
  position: absolute; inset: -110px -50vw;
  background: radial-gradient(46% 62% at 50% 50%, rgba(255,255,255,.24), transparent 72%);
  pointer-events: none; z-index: -1;
}
.sky-page .eyebrow__pill {
  background: rgba(255,255,255,.64); border-color: rgba(5,36,64,.14);
  color: rgba(5,36,64,.84); backdrop-filter: blur(6px);
}

/* The one surface every inner page is built from. Dark by default, because the
   site is dark; the glass variant only exists inside a sky page. */
.pane {
  position: relative;
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--hairline-soft);
  color: var(--text);
}
.sky-page .pane {
  background: rgba(255, 255, 255, .76);
  backdrop-filter: blur(40px) saturate(170%);
  -webkit-backdrop-filter: blur(40px) saturate(170%);
  border-color: rgba(255, 255, 255, .72);
  /* two shadows, not one: a wide soft drop for the lift, a tight one right
     under the edge so the card still has a defined boundary on bright cloud */
  box-shadow:
    0 34px 80px rgba(6, 42, 78, .18),
    0 2px 10px rgba(6, 42, 78, .10),
    0 1px 0 rgba(255, 255, 255, .95) inset;
  color: var(--on-brand);
}
.sky-page .gb__body { background: rgba(255, 255, 255, .86); }
/* the rails are chrome, not content - they sit back a step from the page */
.sky-page .gb__side, .sky-page .gb__toc {
  background: rgba(255, 255, 255, .62);
  box-shadow: 0 18px 46px rgba(6, 42, 78, .12), 0 1px 0 rgba(255, 255, 255, .8) inset;
}

/* --------------------------------------------------------------------------
   Docs - GitBook shape: sticky index, one column of prose, a right rail
   -------------------------------------------------------------------------- */

.gb {
  display: grid; grid-template-columns: 252px minmax(0, 1fr) 208px;
  gap: clamp(20px, 2.4vw, 38px); align-items: start;
}
/* Two separate reasons the rails never stuck, both worth naming:
   1. .pane sets `position: relative` further down the sheet and was quietly
      winning on equal specificity;
   2. .block clips, and ANY ancestor with overflow:hidden becomes the scroll
      container for position:sticky - hence .gb-host below. */
.gb-host { overflow: visible; }
.gb .gb__side, .gb .gb__toc { position: sticky; top: 96px; align-self: start; }

/* ---- the index rail ----
   GitBook's active state is a tint and an accent edge, never a filled slab.
   The solid navy pill we had before sat on the glass like a sticker and was
   the single dirtiest thing on the page. */
.gb__side { padding: 20px 12px; }
.gb__group + .gb__group { margin-top: 20px; padding-top: 18px; border-top: 1px solid rgba(5,36,64,.10); }
.gb__group h4 {
  margin: 0 0 10px 12px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .09em;
  text-transform: uppercase; color: rgba(5,36,64,.42);
}
.gb__side a {
  position: relative;
  display: block; padding: 8px 12px; border-radius: 10px;
  font-size: 14.5px; line-height: 1.35; color: rgba(5,36,64,.72);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.gb__side a::before {
  content: ''; position: absolute; left: 2px; top: 50%;
  width: 2px; height: 0; border-radius: 2px;
  background: var(--brand-deep);
  transform: translateY(-50%);
  transition: height .28s var(--ease);
}
.gb__side a:hover { color: var(--on-brand); }
/* No fill on the active item. A tinted slab behind one line of a nav is the
   thing that made this rail look cheap; GitBook marks the current page with
   weight, colour and an edge, and nothing else. */
.gb__side a.is-on { color: var(--brand-deep); font-weight: 600; }
.gb__side a.is-on::before { height: 15px; }

/* ---- the page ---- */
.gb__body {
  /* grid items default to min-width:auto, so any wide child could blow the
     column open - this is what keeps the reading measure honest */
  min-width: 0;
  padding: clamp(28px, 3.2vw, 52px) clamp(24px, 3.4vw, 56px) clamp(34px, 4vw, 60px);
}
.gb__body > * + * { margin-top: 1.05em; }
.gb__body h2 {
  position: relative;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(25px, 2.4vw, 34px); letter-spacing: -.036em; line-height: 1.12;
  margin-top: 2.4em; padding-top: 1.25em; scroll-margin-top: 110px;
  border-top: 1px solid rgba(5,36,64,.10);
}
/* a short brand tick on the rule, so a new section registers before you read */
.gb__body h2::before {
  content: ''; position: absolute; top: -1px; left: 0;
  width: 34px; height: 2px; border-radius: 2px; background: var(--brand);
}
.gb__body h2:first-child::before { display: none; }
.gb__body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.gb__body h3 {
  font-size: 17px; font-weight: 600; letter-spacing: -.02em;
  margin-top: 1.8em; color: var(--on-brand);
}
.gb__body p, .gb__body li { font-size: 15.5px; line-height: 1.72; color: rgba(5,36,64,.78); }
/* a comfortable measure - long lines are the other half of "looks cheap" */
.gb__body > p, .gb__body > ul { max-width: 68ch; }
.gb__body strong { color: var(--on-brand); font-weight: 600; }
.gb__body ul { display: grid; gap: 9px; padding-left: 2px; }
.gb__body li { display: flex; gap: 11px; }
.gb__body li::before {
  content: ''; flex: none; width: 5px; height: 5px; margin-top: .62em;
  border-radius: 50%; background: rgba(13,111,190,.5);
}
.gb__body a:not(.btn) {
  color: var(--brand-deep); text-decoration: underline;
  text-decoration-color: rgba(11,78,138,.32); text-underline-offset: 3px;
  transition: text-decoration-color .2s var(--ease);
}
.gb__body a:not(.btn):hover { text-decoration-color: currentColor; }

.gb__code {
  display: block; padding: 15px 17px; border-radius: 14px;
  background: #0c141c; color: var(--brand-glow);
  border: 1px solid rgba(255,255,255,.07);
  box-shadow: 0 14px 34px rgba(4, 34, 64, .22);
  font-family: var(--font-mono); font-size: 12.5px; line-height: 1.65;
  overflow-x: auto; white-space: pre;
}
.gb__code .h { color: #fff; }
.gb__code .c { color: #6b8ca6; }

.gb__note {
  display: grid; grid-template-columns: 20px 1fr; gap: 12px;
  padding: 15px 17px; border-radius: 14px;
  background: rgba(255,255,255,.42);
  border: 1px solid rgba(5,36,64,.10);
  box-shadow: inset 3px 0 0 var(--brand);
}
.gb__note svg { width: 18px; height: 18px; color: var(--brand-deep); margin-top: 1px; }
.gb__note p { margin: 0; font-size: 14.2px; line-height: 1.6; color: rgba(5,36,64,.82); }
.gb__note--warn { box-shadow: inset 3px 0 0 #d8a200; }
.gb__note--warn svg { color: #a37600; }

/* A table is the one thing in here that can be wider than its column. It gets
   its own scroller so it can never push the column out - which is exactly what
   happened on mobile the moment the section stopped clipping. */
.gb__scroll { overflow-x: auto; margin-inline: -2px; }
.gb__table { width: 100%; min-width: 420px; border-collapse: collapse; font-size: 14.2px; }
.gb__table th, .gb__table td { text-align: left; padding: 11px 14px; border-bottom: 1px solid rgba(5,36,64,.10); }
.gb__table tr:last-child td { border-bottom: 0; }
.gb__table th {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: rgba(5,36,64,.46);
  border-bottom-color: rgba(5,36,64,.16);
}
.gb__table td { color: rgba(5,36,64,.8); }
.gb__table td:first-child { font-family: var(--font-mono); color: var(--on-brand); white-space: nowrap; }
.gb__table tbody tr { transition: background .2s var(--ease); }
.gb__table tbody tr:hover { background: rgba(255,255,255,.34); }

/* ---- on this page ----
   one hairline rail with the current entry marked on it, so the eye can see
   how far down the page it is without reading anything */
.gb__toc { padding: 18px 14px 18px 6px; }
.gb__toc h4 {
  margin: 0 0 10px 14px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .09em;
  text-transform: uppercase; color: rgba(5,36,64,.42);
}
.gb__toc nav { position: relative; padding-left: 13px; }
.gb__toc nav::before {
  content: ''; position: absolute; left: 0; top: 4px; bottom: 4px;
  width: 1px; background: rgba(5,36,64,.16);
}
.gb__toc a {
  position: relative; display: block; padding: 6px 8px;
  font-size: 13px; line-height: 1.4; color: rgba(5,36,64,.6);
  transition: color .2s var(--ease);
}
.gb__toc a::before {
  content: ''; position: absolute; left: -13px; top: 50%;
  width: 1px; height: 0; background: var(--brand-deep);
  transform: translateY(-50%);
  transition: height .28s var(--ease);
}
.gb__toc a:hover { color: var(--on-brand); }
.gb__toc a.is-on { color: var(--brand-deep); font-weight: 600; }
.gb__toc a.is-on::before { height: 100%; }

@media (max-width: 1180px) { .gb { grid-template-columns: 220px minmax(0,1fr); } .gb__toc { display: none; } }
@media (max-width: 820px)  { .gb { grid-template-columns: 1fr; } .gb .gb__side { position: static; } }

/* --------------------------------------------------------------------------
   How it works - the four posts, one per step, on the sky
   -------------------------------------------------------------------------- */

.steps { display: grid; gap: clamp(46px, 6vw, 92px); }
.step {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 64px); align-items: center;
}
.step:nth-child(even) .step__copy { order: 2; }
.step__copy { display: grid; gap: 12px; align-content: start; }
.step__no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--hairline-soft);
  font-family: var(--font-mono); font-size: 13px; color: var(--accent);
}
.step__title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(28px, 3.2vw, 46px); letter-spacing: -.04em; line-height: 1.04;
  color: var(--text);
}
.step__text { margin: 0; max-width: 44ch; font-size: clamp(15px, 1.25vw, 17px); line-height: 1.55; color: var(--text-2); }
.step__more { display: grid; gap: 7px; margin: 4px 0 0; }
.step__more li { display: flex; gap: 10px; font-size: 14px; color: var(--text-3); }
.step__more li::before { content: '-'; color: var(--surface-3); flex: none; }
.step .tw { box-shadow: 0 30px 70px rgba(4, 34, 66, .34); }

@media (max-width: 900px) {
  .step { grid-template-columns: 1fr; gap: 22px; }
  .step:nth-child(even) .step__copy { order: 0; }
}

/* --------------------------------------------------------------------------
   Terminal - the two-step start panel plus the command feed
   -------------------------------------------------------------------------- */

.start { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.start__card { padding: clamp(22px, 2.6vw, 32px); display: grid; gap: 14px; align-content: start; }
.start__head { display: flex; align-items: center; gap: 12px; }
.start__no {
  width: 30px; height: 30px; border-radius: 9px; flex: none;
  display: grid; place-items: center;
  background: var(--surface-2);
  font-family: var(--font-mono); font-size: 12px; color: var(--accent);
}
.start__title { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: 20px; letter-spacing: -.03em; }
.start__text { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--text-2); }
.start__list { display: grid; gap: 7px; }
.start__list li { display: flex; gap: 9px; font-size: 13.5px; color: var(--text-3); }
.start__list li::before { content: '-'; color: var(--surface-3); flex: none; }
.start__action { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 2px; }

.btn--xdark { --btn-bg: #0f1419; --btn-fg: #fff; }
.btn--xdark:hover { --btn-bg: #1d2530; }
.btn--xdark svg { width: 15px; height: 15px; }
.btn--wallet { --btn-bg: var(--surface-2); --btn-fg: var(--text); border: 1px solid var(--hairline); }
.btn--wallet:hover { --btn-bg: var(--surface-3); }
.btn--wallet img { width: 17px; height: 17px; object-fit: contain; }

.feed { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.feed .term { width: auto; }

@media (max-width: 820px) { .start { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Launches - the counter strip that opens the feed
   -------------------------------------------------------------------------- */

/* auto-fit, not a hardcoded four: the strip now carries only the numbers we
   can actually measure, and a fixed column count left a dead third of the row
   sitting there the moment two cells were removed. Cells added back later
   place themselves. */
.lstrip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px; background: var(--hairline-soft);
  border: 1px solid var(--hairline-soft); border-radius: var(--r-card);
  overflow: hidden;
}
.lstrip__cell {
  display: grid; gap: 6px; align-content: center;
  padding: clamp(18px, 2vw, 26px) clamp(16px, 2vw, 24px);
  background: var(--surface);
}
.lstrip__n {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(28px, 3.2vw, 44px); line-height: 1; letter-spacing: -.045em;
  color: var(--text);
}
.lstrip__l { font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }

@media (max-width: 760px) { .lstrip { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); } }

/* ==========================================================================
   Contact strip + reveal footer
   The last content section is one tall black field with the CTA in the middle,
   and the footer sits FIXED behind the page. Scrolling the last section up
   uncovers it - the footer is never pushed, it is revealed.
   ========================================================================== */

.contact { min-height: 100svh; display: grid; place-items: center; background: var(--bg); }
.contact__inner { position: relative; display: grid; justify-items: center; width: 100%; }

/* The pill. It is no longer a link - only the button inside it is - so it has
   no hover lift and no pointer affordance of its own. */
.need {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  width: min(680px, 92vw);
  padding: 10px 10px 10px 30px;
  border-radius: var(--r-chip);
  background: var(--brand); color: var(--on-brand);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(19px, 2.2vw, 30px); letter-spacing: -.035em;
}
/* The sky is a plate the size of the viewport, held still against the viewport
   by JS while the pill scrolls over it. So the picture does not travel with the
   pill - the pill is an opening in the black page, and scrolling moves the sky
   through it, until the footer opens the same sky full width. */
.need__sky {
  position: absolute; z-index: 0; top: 0; left: 0;
  width: 100vw; height: 100svh;
  background: url('/assets/img/sky-hero.webp') 50% 50% / cover no-repeat;
  transform: translate3d(0, 0, 0);
  will-change: transform;
}
@media (max-width: 1500px) { .need__sky { background-image: url('/assets/img/sky-hero-md.webp'); } }
@media (max-width: 900px)  { .need__sky { background-image: url('/assets/img/sky-hero-sm.webp'); } }
.need::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(255,255,255,.34), rgba(255,255,255,.06) 46%, rgba(255,255,255,.30));
}
.need > *:not(.need__sky) { position: relative; z-index: 2; }

.need__lead { display: inline-flex; align-items: baseline; gap: .32em; white-space: nowrap; }
/* the word is typed out, then deleted, then the next one - a caret blinks on
   the end. Reserving the width of the longest word stops the pill from
   breathing in and out on every character. */
.need__type { display: inline-flex; align-items: baseline; min-width: 4.9em; }
.need__type b { font-weight: 600; }
.need__caret {
  display: inline-block; width: .07em; height: .96em;
  margin-left: .06em; border-radius: 1px;
  background: currentColor;
  animation: caret 1.05s steps(1, end) infinite;
}
@keyframes caret { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

.need__btn {
  display: inline-flex; align-items: center;
  height: 46px; padding: 0 22px; border-radius: var(--r-chip);
  background: #0f1419; color: #fff;
  font-family: var(--font); font-weight: 500; font-size: 14px; letter-spacing: -.01em;
  white-space: nowrap;
  transition: background .3s var(--ease);
}
/* the hover belongs to the button now, not to the whole pill - it is the only
   thing in here that is actually clickable */
.need__btn:hover { background: #1d2530; transform: translateY(-1px); }
.need__btn { transition: background .3s var(--ease), transform .3s var(--ease); }


/* ---- the reveal itself ----
   `main` needs an opaque ground so it can slide over the fixed footer. That
   rules out sky pages, whose own background is a fixed layer BEHIND main - an
   opaque main would paint straight over the sky. `app.js` never sets
   .has-reveal on those, and this guard makes the rule safe either way. */
/* The footer is only painted once the page is inside the last screenful. Even
   if a stacking or margin edge case ever let it peek out earlier, there is
   nothing to see. */
@media (min-width: 861px) {
  .has-reveal:not(.sky-page) footer.foot { visibility: hidden; }
  .has-reveal.foot-near:not(.sky-page) footer.foot { visibility: visible; }
}

@media (min-width: 861px) {
  .has-reveal:not(.sky-page) main {
    position: relative; z-index: 1;
    background: var(--bg);
    margin-bottom: var(--foot-h, 0px);
  }
  .has-reveal:not(.sky-page) footer.foot {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 0;
    margin: 0; border-radius: 0;
  }
}

@media (max-width: 860px) {
  .contact { min-height: auto; padding-block: clamp(70px, 12vh, 120px) clamp(120px, 20vh, 180px); }
  .need { flex-direction: column; gap: 14px; padding: 18px; text-align: center; }
  .need__lead { white-space: normal; justify-content: center; }
  .need__btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   Token page - /launch/{address}

   Laid out the way a person reads it: what the token is, who launched it, what
   it is worth, and then the details. Two columns on a desktop - figures and
   chart on the left, a details panel on the right - collapsing to one column
   on a phone in that same reading order.

   Every figure on this page is computed from state read off the chain (see the
   token page block in app.js). A dash is a real answer here: it means nothing
   measured the value, which is different from the value being zero, and the
   styling must never make a dash look like a failure.
   ========================================================================== */

.tok__top {
  display: grid; gap: clamp(22px, 3vw, 44px);
  grid-template-columns: clamp(140px, 18vw, 232px) minmax(0, 1fr);
  align-items: center;
}
@media (max-width: 720px) { .tok__top { grid-template-columns: 1fr; } }

.tok__art {
  position: relative; aspect-ratio: 1; border-radius: clamp(18px, 2vw, 28px);
  overflow: hidden; background: var(--surface-2);
  border: 1px solid var(--hairline-soft);
}
.tok__art img, .tok__art svg { width: 100%; height: 100%; object-fit: cover; display: block; }

.tok__name {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(38px, 6vw, 84px); letter-spacing: -.05em; line-height: .96;
}
.tok__sym {
  margin: .35em 0 0; font-family: var(--font-mono);
  font-size: clamp(14px, 1.5vw, 19px); color: var(--brand-bright);
}
.tok__id .copyaddr--lg { margin-block: clamp(16px, 2vw, 24px) clamp(14px, 1.6vw, 20px); }
.tok__acts { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------------------------------------------------------- the plaque

   Who asked for this launch. A chip rather than a line of text because it is
   the one thing on the page that is about a person, and because it has to
   survive being the only clickable thing someone notices. */
.plaque {
  display: inline-flex; align-items: center; gap: 12px;
  margin-bottom: clamp(16px, 1.8vw, 22px);
  padding: 8px 16px 8px 8px; border-radius: 99px;
  background: var(--surface-2); border: 1px solid var(--hairline-soft);
  color: var(--text); text-decoration: none;
  transition: border-color .18s ease, background .18s ease, transform .18s ease;
}
.plaque:hover {
  border-color: var(--hairline); background: var(--surface-3, var(--surface-2));
  transform: translateY(-1px);
}
.plaque__av {
  width: 38px; height: 38px; border-radius: 50%; flex: none; overflow: hidden;
  display: grid; place-items: center;
  background: var(--brand); color: #fff;
  font-family: var(--font-display); font-weight: 600; font-size: 17px;
}
.plaque__av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plaque__txt { display: grid; gap: 1px; line-height: 1.25; }
.plaque__k {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-3);
}
.plaque__h { font-weight: 600; font-size: 15px; }
.plaque__x { width: 14px; height: 14px; flex: none; opacity: .5; margin-left: 2px; }
.plaque:hover .plaque__x { opacity: .85; }

/* ------------------------------------------------------------ the grid */

.tokpg {
  display: grid; gap: clamp(16px, 2vw, 26px);
  grid-template-columns: minmax(0, 1fr) clamp(300px, 30%, 400px);
  align-items: start;
}
.tokpg__main { display: grid; gap: clamp(16px, 2vw, 26px); min-width: 0; }
@media (max-width: 960px) { .tokpg { grid-template-columns: 1fr; } }

/* --------------------------------------------------------- the figures

   Four cells, each a number and the sentence that says what the number is.
   The unit line is not decoration: "0.0219" means nothing without "ETH ·
   price x total supply" under it, and a market cap with no stated
   denomination is how a page ends up implying dollars. */
.tstat {
  display: grid; gap: 1px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--hairline-soft);
  border: 1px solid var(--hairline-soft); border-radius: var(--r-card);
  overflow: hidden;
}
.tstat__c {
  display: grid; gap: 6px; align-content: start;
  padding: clamp(16px, 1.9vw, 24px) clamp(14px, 1.7vw, 22px);
  background: var(--surface); min-width: 0;
}
.tstat__k {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3);
}
.tstat__v {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(22px, 2.6vw, 34px); letter-spacing: -.035em; line-height: 1.05;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.tstat__u { font-size: 11.5px; color: var(--text-3); line-height: 1.4; }
@media (max-width: 1100px) { .tstat { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px)  { .tstat { grid-template-columns: 1fr; } }

/* ----------------------------------------------------------- the chart */

.chartbox { overflow: hidden; }
.chartbox__hd {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline;
  padding: clamp(16px, 1.8vw, 22px) clamp(18px, 2vw, 26px);
  border-bottom: 1px solid var(--hairline-soft);
}
.chartbox__t {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(15px, 1.4vw, 18px); letter-spacing: -.02em;
}
.chartbox__s {
  margin: 0; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-3);
}
.chartbox__body { min-height: clamp(240px, 34vh, 420px); display: grid; }
.chartbox__body iframe {
  display: block; width: 100%; height: clamp(340px, 44vh, 500px); border: 0;
}
/* The no-chart state. Deliberately a sentence, not a spinner or a grey
   rectangle: there is nothing loading and nothing broken. */
.chartbox__none {
  display: grid; align-content: center; gap: 10px;
  padding: clamp(28px, 4vw, 56px) clamp(20px, 3vw, 44px); text-align: center;
}
.chartbox__none-t {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(16px, 1.6vw, 20px); letter-spacing: -.02em;
}
.chartbox__none-s {
  margin: 0 auto; max-width: 52ch; color: var(--text-2);
  font-size: clamp(13.5px, 1.05vw, 15px); line-height: 1.6;
}

/* A market cap that just changed. One quiet pulse - enough to notice if you
   were watching, invisible if you were not. Anything louder turns a feed into
   a slot machine, which is exactly the wrong feeling for a number that is
   supposed to be checkable. */
@keyframes jpFresh {
  from { background: color-mix(in srgb, var(--brand-bright) 55%, transparent); }
  to   { background: rgba(0, 0, 0, .55); }
}
.launch__mcap.is-fresh { animation: jpFresh 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) { .launch__mcap.is-fresh { animation: none; } }

/* "not live yet" beside a command title. Quiet, but not hidden: a reader
   scanning the list has to be able to tell what runs today from what is
   described. */
.cmdc__soon {
  display: inline-block; margin-left: 8px; padding: 3px 8px; border-radius: 99px;
  background: var(--surface-2); border: 1px solid var(--hairline-soft);
  color: var(--text-3); font-family: var(--font-mono); font-size: 9.5px;
  letter-spacing: .08em; text-transform: uppercase; vertical-align: middle;
  font-weight: 500;
}

/* ------------------------------------------------- planned launches
   Deliberately quieter than a live card: flat, no hover lift, nothing that
   reads as a market. These are announcements, and the styling has to keep
   saying so after the reader has stopped reading the heading. */
.plan { margin-bottom: clamp(28px, 3.4vw, 48px); }
.plan__hd { margin-bottom: clamp(14px, 1.8vw, 22px); }
.plan__t {
  margin: 0 0 6px; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(19px, 2vw, 26px); letter-spacing: -.03em;
}
.plan__s { margin: 0; max-width: 62ch; color: var(--text-3); font-size: 13.5px; line-height: 1.55; }
.plan__grid {
  display: grid; gap: clamp(12px, 1.4vw, 18px);
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.plan__card {
  border: 1px dashed var(--hairline); border-radius: var(--r-card);
  background: var(--surface); overflow: hidden;
}
.plan__art {
  aspect-ratio: 1; background: var(--surface-2);
  display: grid; place-items: center; overflow: hidden;
}
.plan__art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plan__meta { display: grid; gap: 5px; padding: 14px 16px 16px; }
.plan__name { font-weight: 600; font-size: 15px; }
.plan__tick { font-family: var(--font-mono); font-size: 12px; color: var(--brand-bright); }
.plan__soon {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3);
}
.plan__note { color: var(--text-2); font-size: 12.5px; line-height: 1.5; }
.plan__state {
  margin-top: 4px; font-family: var(--font-mono); font-size: 9.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--text-3);
}

/* ------------------------------------------------------- key export
   Deliberately not styled like a feature. No accent colour, no gradient, no
   invitation - a warning block and a plain button. The one thing on this site
   that can lose somebody everything should not look like a call to action. */
.wal__export {
  margin-top: clamp(28px, 3.4vw, 48px); padding: clamp(20px, 2.4vw, 30px);
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: var(--surface);
}
.wal__export-t {
  margin: 0 0 8px; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(17px, 1.7vw, 22px); letter-spacing: -.02em;
}
.wal__export-s {
  margin: 0 0 16px; max-width: 68ch; color: var(--text-2);
  font-size: 14px; line-height: 1.6;
}
.wal__warn {
  margin: 0 0 18px; padding: 14px 16px 14px 32px; border-radius: 14px;
  background: var(--surface-2); border: 1px solid var(--hairline-soft);
  color: var(--text-2); font-size: 13px; line-height: 1.6;
}
.wal__warn li + li { margin-top: 7px; }
.wal__export-l { display: block; margin-bottom: 8px; font-size: 13px; color: var(--text-2); }
.wal__export-l b { color: var(--text); font-weight: 600; }
.wal__export-i {
  display: block; width: 100%; max-width: 460px; margin-bottom: 12px;
  padding: 11px 14px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--hairline);
  color: var(--text); font: inherit; font-size: 14px;
}
.wal__export-i:focus { outline: none; border-color: var(--text-3); }
.wal__export-e { margin: 12px 0 0; color: var(--text-2); font-size: 13px; }

.wal__key {
  margin-top: 18px; padding: 16px; border-radius: 14px;
  border: 1px solid var(--hairline); background: var(--surface-2);
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
}
.wal__key-l {
  flex-basis: 100%; margin: 0 0 4px; font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3);
}
.wal__key-v {
  flex-basis: 100%; font-family: var(--font-mono); font-size: 12.5px;
  word-break: break-all; line-height: 1.5; color: var(--text);
  -webkit-user-select: all; user-select: all;
}

/* range buttons */
.rngs { display: flex; gap: 2px; margin-left: auto; }
.rngs button {
  appearance: none; border: 0; cursor: pointer;
  padding: 5px 10px; border-radius: 8px;
  background: transparent; color: var(--text-3);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
  transition: background .15s ease, color .15s ease;
}
.rngs button:hover { color: var(--text); background: var(--surface-2); }
.rngs button[aria-pressed="true"] { color: var(--text); background: var(--surface-2); }

/* the chart itself - SVG drawn in app.js, styled here so it follows the theme */
.chartbox__body { position: relative; }
.jpc { display: block; width: 100%; touch-action: pan-y; }
.jpc__grid { stroke: var(--hairline-soft); stroke-width: 1; stroke-dasharray: 3 5; }
.jpc__area { stroke: none; }
.jpc__line {
  fill: none; stroke: var(--brand-bright); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
}
.jpc__ax {
  fill: var(--text-3); font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .04em;
}
.jpc__ax--end { text-anchor: end; }
.jpc__cursor { stroke: var(--hairline); stroke-width: 1; pointer-events: none; }
.jpc__dot {
  fill: var(--brand-bright); stroke: var(--surface); stroke-width: 2;
  pointer-events: none;
}
.jpc__tip {
  position: absolute; pointer-events: none; z-index: 3;
  display: grid; gap: 2px; padding: 7px 10px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--hairline-soft);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
  font-size: 12px; white-space: nowrap;
}
.jpc__tip b { font-weight: 600; font-variant-numeric: tabular-nums; }
.jpc__tip span { color: var(--text-3); font-size: 10.5px; }

.chartbox__ft {
  margin: 0; padding: 0 clamp(18px, 2vw, 26px) clamp(16px, 1.8vw, 22px);
  color: var(--text-3); font-size: 11.5px; line-height: 1.55; max-width: 78ch;
}

/* --------------------------------------------------------- the details */

.tdet { padding: clamp(18px, 2vw, 26px); position: sticky; top: 92px; }
@media (max-width: 960px) { .tdet { position: static; } }
.tdet__t {
  margin: 0 0 clamp(12px, 1.4vw, 18px);
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(15px, 1.4vw, 18px); letter-spacing: -.02em;
}
.tdet__l { margin: 0; display: grid; }
.tdet__r {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  justify-content: space-between; align-items: baseline;
  padding: 11px 0; border-top: 1px solid var(--hairline-soft);
}
.tdet__r:first-child { border-top: 0; padding-top: 0; }
.tdet__r dt {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); flex: none;
}
.tdet__r dd {
  margin: 0; font-size: 14px; font-weight: 500; text-align: right;
  overflow-wrap: anywhere; min-width: 0;
}
.tdet__r dd code { font-family: var(--font-mono); font-size: 12.5px; }
.tdet__r dd a { color: var(--brand-bright); text-decoration: none; }
.tdet__r dd a:hover { text-decoration: underline; }
.tdet__hint { color: var(--text-3); font-weight: 400; font-size: 12px; }
.tdet__n {
  margin: clamp(14px, 1.6vw, 20px) 0 0; color: var(--text-3);
  font-size: 11.5px; line-height: 1.55;
}

/* where the token is in its life */
.tok__phase { padding: clamp(22px, 2.6vw, 34px); }
.tok__phase-t {
  margin: 0 0 10px; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(19px, 2vw, 26px); letter-spacing: -.03em;
}
.tok__phase-s {
  margin: 0; max-width: 62ch; color: var(--text-2);
  font-size: clamp(14.5px, 1.15vw, 17px); line-height: 1.6;
}

.tok__err {
  margin: 0; max-width: 60ch; color: var(--text-2);
  font-size: clamp(15px, 1.2vw, 18px); line-height: 1.6;
}

/* ==========================================================================
   Wallet page - dark, with the light coming from the page rather than a photo
   The sky plate that used to sit behind this competed with the one thing the
   page is for: a column of numbers. What replaces it is a soft bloom under the
   header and panels that carry their own light, which is how a dark product
   page stays premium without turning into a slab.
   ========================================================================== */

/* The bloom goes ON main, not behind it. A separate fixed layer was invisible:
   main carries an opaque black background and z-index 1 so the page-transition
   can slide it over the outgoing page, and that covered anything underneath.
   background-attachment: fixed keeps the light anchored to the viewport while
   the content scrolls past it, which is the effect the separate layer was for. */
/* Two selectors, and the second is the point. The page-transition rule
   `.has-reveal:not(.sky-page) main` sets `background: var(--bg)` with two
   classes' worth of specificity, which beat a single attribute and - being a
   shorthand - wiped the gradients to none. Matching its weight and sitting
   later in the sheet is what makes this stick. */
[data-page="wallet"] main,
.has-reveal[data-page="wallet"] main {
  background:
    radial-gradient(58% 40% at 50% -4%, rgba(120, 186, 255, .30), transparent 64%),
    radial-gradient(42% 30% at 88% 4%,  rgba(158, 130, 255, .18), transparent 68%),
    radial-gradient(50% 34% at 6% 88%,  rgba(74, 142, 230, .14), transparent 70%),
    radial-gradient(90% 60% at 50% 30%, rgba(255, 255, 255, .045), transparent 70%),
    #000;
  background-attachment: fixed;
}

/* The feed page wants a 150px headline; a page of balances does not. Two lines
   at that size pushed the first number below the fold, which is the opposite of
   premium - it is a poster with the content hidden behind it. */
[data-page="wallet"] .phero__title { font-size: clamp(44px, 7vw, 104px); }

/* a hairline of light along the top edge, the way a lit surface catches it */
[data-page="wallet"] .phero__rule {
  background: linear-gradient(90deg,
    transparent, rgba(255,255,255,.22) 22%, rgba(255,255,255,.22) 78%, transparent);
}

/* ---- panels ----
   Not black on black. Each surface is a few percent of white over the page,
   with a lighter hairline on top than on the bottom so it reads as lit from
   above rather than as a rectangle someone drew. */
[data-page="wallet"] .wal__empty,
[data-page="wallet"] .wal__link,
[data-page="wallet"] .hrow {
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.022));
  border: 1px solid rgba(255,255,255,.09);
  box-shadow:
    0 1px 0 rgba(255,255,255,.07) inset,
    0 24px 60px rgba(0,0,0,.45);
}
[data-page="wallet"] .wal__empty,
[data-page="wallet"] .wal__link { border-style: solid; }

[data-page="wallet"] .hrow {
  transition: background .32s var(--ease), border-color .32s var(--ease),
              transform .32s var(--ease);
}
[data-page="wallet"] .hrow:hover {
  background: linear-gradient(180deg, rgba(255,255,255,.085), rgba(255,255,255,.035));
  border-color: rgba(255,255,255,.16);
  transform: translateY(-2px);
}

/* the handle, set at the scale of the page it titles */
[data-page="wallet"] .wal__handle { color: #7fc3ff; }

[data-page="wallet"] .copyaddr {
  background: rgba(255,255,255,.05);
  border-color: rgba(255,255,255,.10);
}
[data-page="wallet"] .copyaddr:hover { border-color: rgba(255,255,255,.22); }

/* ---- the rows arrive one after another, not all at once ----
   Six identical rows appearing together read as a page that finished loading.
   Staggered, they read as a list being filled in - the same trick the rest of
   the site uses on its sections, applied to content that arrives from an API
   after the reveal observer has already run. */
.hrow--in { animation: hrowIn .52s var(--ease) both; }
@keyframes hrowIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hrow--in { animation: none; }
}

/* the two custody paths, side by side so the trade is a comparison, not a wall of text */
.wal__paths {
  display: grid; gap: clamp(14px, 1.6vw, 22px); width: 100%;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-top: clamp(8px, 1.2vw, 16px); text-align: left;
}
.wal__path {
  display: grid; gap: 12px; align-content: start;
  padding: clamp(20px, 2.2vw, 30px); border-radius: clamp(16px, 1.6vw, 22px);
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.09);
}
.wal__path-t {
  margin: 0; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(18px, 1.8vw, 24px); letter-spacing: -.03em;
}
.wal__path-s {
  margin: 0; color: var(--text-2);
  font-size: clamp(14px, 1.1vw, 16px); line-height: 1.6;
}
.wal__path-s b { color: var(--text); font-weight: 600; }
.wal__path .btn { justify-self: start; margin-top: 4px; }

/* ------------------------------------------------------- terminal chat
   The log carries three kinds of line: what the person typed, what the bot
   answered, and a failure. They have to be distinguishable at a glance, and
   an address in a reply has to stay selectable and unwrapped mid-word - a
   0x string broken across a line is a string nobody can copy. */
.tchat__msg--you {
  color: var(--ink);
  opacity: .72;
  padding-left: 14px;
  border-left: 2px solid color-mix(in srgb, var(--ink) 22%, transparent);
}
.tchat__msg--pending { opacity: .5; font-style: italic; }
.tchat__msg--err { color: #ff8b7a; }
.tchat__log .tchat__msg {
  white-space: pre-wrap;      /* the replies are line-broken on purpose */
  overflow-wrap: anywhere;    /* an address wraps, but only where it must */
  margin: 0 0 10px;
}
.tchat__in:disabled { opacity: .5; cursor: not-allowed; }

/* A failed action. Distinct from "soon" - one is waiting, the other is over.
   Red enough to find in a table, not so red it shouts on a dark page. */
.chip--bad {
  background: rgba(255, 107, 90, .13);
  border-color: rgba(255, 107, 90, .38);
  color: #ff8b7a;
}
.acts a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.acts a:hover { color: var(--ink); }

/* ------------------------------------------------- curve progress
   A balance against a threshold. Deliberately plain: a bar that glows and
   pulses would read as a promise, and this is a measurement. */
.curvebar { margin-top: 18px; }
.curvebar__track {
  height: 8px; border-radius: 99px; overflow: hidden;
  background: color-mix(in srgb, var(--ink, #fff) 10%, transparent);
}
.curvebar__fill {
  display: block; height: 100%; width: 0;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--brand, #1a8fe3), var(--brand-bright, #3fa9f0));
  transition: width .9s cubic-bezier(.22,.61,.36,1);
}
.curvebar__l {
  margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline;
  font-size: 15px;
}
.curvebar__l > span:first-child { font-weight: 600; }
.curvebar__of { color: var(--text-3); font-size: 13px; }
.curvebar__of b { color: var(--text-2); font-weight: 600; }
.curvebar__note { margin: 6px 0 0; color: var(--text-3); font-size: 12px; }
@media (prefers-reduced-motion: reduce) { .curvebar__fill { transition: none; } }

/* ------------------------------------------------- wallet balance
   One figure, large enough to read from across the room while you watch a
   transfer land. Tabular numerals so the digits do not shuffle sideways when
   the amount changes on refresh. */
.ethbal { margin: clamp(18px, 2.4vw, 30px) 0 clamp(22px, 3vw, 36px); }
.ethbal__l {
  margin: 0 0 6px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-3);
}
.ethbal__v {
  margin: 0; display: flex; align-items: baseline; gap: 10px;
  font-family: var(--font-display, inherit);
  font-size: clamp(38px, 6vw, 64px); line-height: 1; font-weight: 600;
  letter-spacing: -.02em; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ethbal__u { font-size: .34em; font-weight: 500; color: var(--text-3); letter-spacing: .04em; }
.ethbal__n { margin: 10px 0 0; font-size: 12px; color: var(--text-3); max-width: 46ch; }

/* Links inside the token facts grid. Underlined rather than coloured: the
   grid is a table of values, and a blue word in a column of black ones reads
   as a different kind of data rather than as the same data, clickable. */
.tok__v a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 3px;
}
.tok__v a:hover { text-decoration-color: currentColor; }

/* ================================================ commands: real X posts

   These are the bot's actual replies, transcribed from live posts, not
   invented copy. That has one consequence worth stating: if a reply's wording
   changes in src/worker/replies.js, this section is now wrong, and fixing it
   there means fixing it here too.

   The card is a facsimile of an X post because that is where the product
   lives. A stylised abstraction of a tweet would be a picture of the idea;
   this is a picture of the thing. */

/* The cards sit ABOVE the falling bears. .bearfall--front is z-index 8 and
   was landing gummy bears in the middle of a wallet address - so the deck
   takes 12 and the bears drift behind it, still visible past the edges,
   which is where they were charming rather than in the way. */
.svc__deck { z-index: 12; }

/* What was asked. Small, above the card, so the reply below has something to
   be a reply TO - a bot answer with no visible question reads as an
   announcement. */
.svc__hint {
  margin: 0 auto 14px;
  max-width: var(--xp-w, 560px);
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
  font-size: 13px; color: rgba(255,255,255,.62);
}
.svc__hint-k {
  font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255,255,255,.42);
}
.svc__hint code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; color: #fff;
  background: rgba(255,255,255,.09);
  border: 1px solid rgba(255,255,255,.13);
  padding: 3px 9px; border-radius: 8px;
}
.svc__hint code a { color: #4aa9f0; }
.svc__hint-by { color: rgba(255,255,255,.42); }

/* ---- the post itself ------------------------------------------------- */
.xp {
  --xp-w: 560px;
  width: 100%; max-width: var(--xp-w); margin: 0 auto;
  background: #000;
  border: 1px solid #2f3336;          /* X's own hairline value */
  border-radius: 16px;
  padding: 16px 16px 8px;
  text-align: left;
  color: #e7e9ea;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 24px 60px rgba(0,0,0,.45);
}
.xp--sm { --xp-w: 500px; }
.xp--md { --xp-w: 560px; }
.xp--lg { --xp-w: 640px; }
.svc__slide:has(.xp--sm) .svc__hint { max-width: 500px; }
.svc__slide:has(.xp--lg) .svc__hint { max-width: 640px; }

.xp__head { display: flex; align-items: flex-start; gap: 12px; }
.xp__av { width: 44px; height: 44px; border-radius: 50%; flex: none; object-fit: cover; }
.xp__id { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.xp__id b {
  display: flex; align-items: center; gap: 4px;
  font-size: 15px; font-weight: 700; color: #e7e9ea; letter-spacing: -.01em;
}
.xp__badge { width: 18px; height: 18px; flex: none; fill: #1d9bf0; }
.xp__meta { font-size: 15px; color: #71767b; }
.xp__more { color: #71767b; font-size: 18px; line-height: 1; margin-left: auto; }

/* The automation disclosure. X requires it on the account, and reproducing it
   here is the difference between showing a bot and showing something
   pretending not to be one. */
.xp__auto {
  display: flex; align-items: center; gap: 6px;
  margin: 2px 0 0 56px; font-size: 14px; color: #71767b;
}
.xp__auto svg { width: 17px; height: 17px; fill: #71767b; flex: none; }
.xp__auto a { color: #1d9bf0; text-decoration: none; }

.xp__to { margin: 4px 0 0 56px; font-size: 14px; color: #71767b; }
.xp__to a { color: #1d9bf0; text-decoration: none; }

.xp__body {
  margin: 10px 0 0; font-size: 15px; line-height: 1.42; color: #e7e9ea;
  overflow-wrap: anywhere;
}
/* Addresses keep their own face. A 42-character hex string in a proportional
   font is a smear; in mono it is something you can compare character by
   character, which is the only thing anyone does with one. */
.xp__addr { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; }
.xp__link { color: #1d9bf0; text-decoration: none; }

/* ---- link preview ----------------------------------------------------- */
.xp__card {
  display: flex; margin-top: 12px; overflow: hidden;
  border: 1px solid #2f3336; border-radius: 14px; text-decoration: none;
}
.xp__card-img { width: 132px; flex: none; background: #16181c; overflow: hidden; }
.xp__card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.xp__card-txt { display: flex; flex-direction: column; gap: 2px; padding: 11px 13px; min-width: 0; }
.xp__card-dom { font-size: 13px; color: #71767b; }
.xp__card-txt b { font-size: 14px; font-weight: 400; color: #e7e9ea; }
.xp__card-txt > span:last-child {
  font-size: 13px; color: #71767b;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---- action row ------------------------------------------------------- */
.xp__bar { display: flex; gap: 0; justify-content: space-between; padding: 12px 8px 8px; }
.xp__bar svg {
  width: 18px; height: 18px; fill: none; stroke: #71767b;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}

@media (max-width: 720px) {
  .xp { --xp-w: 100%; padding: 14px 14px 6px; }
  .xp--sm, .xp--md, .xp--lg { --xp-w: 100%; }
  .xp__card-img { width: 96px; }
  .xp__auto, .xp__to { margin-left: 0; }
  .svc__hint { max-width: 100%; }
}

/* ---------------------------------------------------------------- clouds
   Empty state for the clouds rail. Lives at the end of the sheet on purpose:
   it is ours, not the reference's, so it stays easy to find and to drop. */
.cloud-empty {
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  padding: clamp(24px, 4vw, 44px);
  background: var(--surface);
  max-width: 62ch;
}
.cloud-empty__lead {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 600;
  letter-spacing: -.02em;
  margin: 0 0 10px;
}
.cloud-empty__sub {
  color: var(--text-3);
  font-size: 15px;
  line-height: 1.6;
  margin: 0;
  max-width: 54ch;
}

/* ---------------------------------------------------------- launch console
   Ours, not the reference's: the donor had no form anywhere, so these are the
   only components on the site without a counterpart in its design system.
   They borrow its tokens (surface, hairline, radii, mono kickers) so the page
   reads as the same product rather than a bolted-on app. */
.lc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: clamp(24px, 3vw, 48px);
  align-items: start;
  margin-top: clamp(32px, 4vw, 56px);
}
@media (max-width: 1000px) { .lc { grid-template-columns: 1fr; } }

.lc__form { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.lcs {
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  background: var(--surface);
  padding: clamp(20px, 2.4vw, 30px);
}
.lcs__h {
  display: flex; align-items: baseline; gap: 12px;
  font-family: var(--font-display); font-size: 20px; font-weight: 600;
  letter-spacing: -.02em; margin: 0 0 18px;
}
.lcs__h i {
  font-family: var(--font-mono); font-style: normal; font-size: 11px;
  color: var(--text-3); letter-spacing: .1em;
}
.lcs__note {
  font-family: var(--font-mono); font-size: 11px; line-height: 1.6;
  color: var(--text-3); margin: 14px 0 0;
}

.lcf { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .lcf { grid-template-columns: 1fr; } }

.fld { display: block; margin-bottom: 12px; }
.fld:last-child { margin-bottom: 0; }
.fld__k {
  display: block; font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; letter-spacing: .1em; color: var(--text-3);
  margin-bottom: 7px;
}
.fld__k em { font-style: normal; opacity: .6; text-transform: none; letter-spacing: 0; }
.fld__i {
  width: 100%; height: 46px; padding: 0 14px;
  border: 1px solid var(--hairline); border-radius: 12px;
  background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: 15px;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.fld__i::placeholder { color: var(--text-3); }
.fld__i:focus { outline: none; border-color: var(--brand); background: var(--surface-2); }

.segs { display: inline-flex; gap: 4px; padding: 4px; border-radius: var(--r-chip); background: var(--bg); border: 1px solid var(--hairline); margin-bottom: 16px; }
.seg {
  appearance: none; border: 0; cursor: pointer;
  padding: 8px 18px; border-radius: var(--r-chip);
  background: transparent; color: var(--text-3);
  font-family: var(--font); font-size: 13px; font-weight: 500;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.seg.is-on { background: var(--brand); color: var(--on-brand); }

.mkt { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 8px; }
.mk {
  appearance: none; cursor: pointer; text-align: left;
  display: grid; grid-template-columns: 1fr auto; gap: 2px 8px;
  padding: 12px 14px; border-radius: 14px;
  border: 1px solid var(--hairline); background: var(--bg); color: var(--text);
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.mk:hover { border-color: rgba(255,255,255,.24); background: var(--surface-2); }
.mk.is-on { border-color: var(--brand); background: var(--surface-2); }
.mk__top { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; }
.mk__top b { font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.mk__lev { font-family: var(--font-mono); font-size: 10px; color: var(--text-3); }
.mk__name { grid-column: 1 / -1; font-size: 11px; color: var(--text-3); margin-bottom: 6px; }
.mk__px { font-family: var(--font-mono); font-size: 13px; }
.mk__chg { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); text-align: right; }
.mk__chg.is-up { color: var(--brand-bright); }
.mk__chg.is-dn { color: #ff6a5e; }

.dirs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 560px) { .dirs { grid-template-columns: 1fr; } }
.dir {
  appearance: none; cursor: pointer; text-align: left;
  padding: 16px 18px; border-radius: 14px;
  border: 1px solid var(--hairline); background: var(--bg); color: var(--text);
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.dir b { display: block; font-family: var(--font-display); font-size: 16px; font-weight: 600; margin-bottom: 5px; }
.dir span { font-size: 12px; color: var(--text-3); line-height: 1.5; }
.dir.is-on { border-color: var(--brand); background: var(--surface-2); }

.levs { display: flex; flex-wrap: wrap; gap: 8px; }
.lev {
  appearance: none; cursor: pointer; min-width: 62px;
  padding: 11px 0; border-radius: 12px;
  border: 1px solid var(--hairline); background: var(--bg); color: var(--text);
  font-family: var(--font-mono); font-size: 13px;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.lev.is-on { border-color: var(--brand); background: var(--brand); color: var(--on-brand); }
.lev.is-off { opacity: .28; cursor: not-allowed; }

/* ---- the ticket ------------------------------------------------------- */
.tick {
  position: sticky; top: 96px;
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: var(--surface); padding: clamp(20px, 2.4vw, 28px);
}
.tick__top { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.tick__logo {
  width: 44px; height: 44px; border-radius: 12px; overflow: hidden;
  background: var(--bg); display: grid; place-items: center; flex: none;
}
.tick__logo img { width: 100%; height: 100%; object-fit: cover; }
.tick__id { display: flex; flex-direction: column; min-width: 0; }
.tick__id b { font-family: var(--font-display); font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.tick__id span { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.tick__line {
  font-family: var(--font-mono); font-size: 12px; color: var(--brand-bright);
  text-transform: uppercase; letter-spacing: .06em;
  padding: 10px 12px; border-radius: 10px; background: var(--bg);
  margin: 0 0 16px;
}
.tick__rows { margin: 0 0 18px; display: flex; flex-direction: column; gap: 0; }
.tick__rows > div {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--hairline-soft);
}
.tick__rows > div:last-child { border-bottom: 0; }
.tick__rows dt { font-size: 12px; color: var(--text-3); }
.tick__rows dd { margin: 0; font-family: var(--font-mono); font-size: 12px; text-align: right; }
.tick__k {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .1em; color: var(--text-3); margin: 0 0 8px;
}
.split { display: flex; height: 8px; border-radius: 999px; overflow: hidden; gap: 2px; }
.split__seg { width: var(--w); display: block; }
.split__seg--m { background: var(--brand); }
.split__seg--c { background: var(--brand-glow); }
.split__seg--t { background: var(--text-3); }
.split__seg--b { background: var(--brand-deep); }
.split__key {
  list-style: none; padding: 0; margin: 10px 0 20px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px;
}
.split__key li { display: flex; align-items: center; gap: 7px; font-size: 11px; color: var(--text-3); }
.split__key i { width: 9px; height: 9px; border-radius: 3px; display: block; flex: none; }
.tick__go { width: 100%; justify-content: center; }
.tick__note { font-family: var(--font-mono); font-size: 10px; line-height: 1.7; color: var(--text-3); margin: 12px 0 0; }
.tick__note.is-flash { animation: tickFlash .9s var(--ease); }
@keyframes tickFlash { 0%, 100% { color: var(--text-3); } 20% { color: var(--brand-bright); } }
.tick__x { display: inline-block; margin-top: 12px; font-size: 12px; color: var(--text-2); }

/* ---- day simulator ---------------------------------------------------- */
.sim {
  margin-top: clamp(28px, 3vw, 44px);
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: var(--surface); padding: clamp(20px, 2.6vw, 34px);
}
.sim__ctl { display: block; margin-bottom: 26px; }
.sim__ctl .fld__k b { color: var(--text); font-family: var(--font-mono); }
.sim__ctl input[type="range"] {
  width: 100%; appearance: none; height: 4px; border-radius: 999px;
  background: var(--surface-3); outline: none;
}
.sim__ctl input[type="range"]::-webkit-slider-thumb {
  appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--brand); cursor: pointer; border: 0;
}
.sim__ctl input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%; background: var(--brand);
  cursor: pointer; border: 0;
}
.sim__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
.sim__cell {
  border: 1px solid var(--hairline); border-radius: 14px;
  background: var(--bg); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 6px;
}
.sim__k { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-3); }
.sim__cell b { font-family: var(--font-display); font-size: clamp(22px, 2.4vw, 30px); font-weight: 600; letter-spacing: -.02em; }
.sim__s { font-size: 11px; color: var(--text-3); line-height: 1.5; }
.sim__s i { font-style: normal; font-family: var(--font-mono); }

/* These pages open on a section rather than a hero, so their eyebrow pill
   would otherwise sit directly under the floating nav. */
#console, #paper, #board { padding-top: clamp(56px, 7vw, 104px); }

/* ------------------------------------------------------------------- docs
   Two-column paper: a sticky table of contents and the body. Ours; the donor
   shipped no long-form page at all. */
.doc {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  gap: clamp(28px, 4vw, 72px);
  margin-top: clamp(32px, 4vw, 56px);
  align-items: start;
}
@media (max-width: 900px) { .doc { grid-template-columns: 1fr; } }

.toc { position: sticky; top: 104px; display: flex; flex-direction: column; gap: 2px; }
@media (max-width: 900px) { .toc { position: static; } }
.toc__k {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .12em; color: var(--text-3); margin: 18px 0 6px;
}
.toc__k:first-child { margin-top: 0; }
.toc a {
  font-size: 13px; color: var(--text-2); padding: 5px 0;
  border-left: 1px solid var(--hairline); padding-left: 12px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.toc a:hover { color: var(--text); border-color: var(--brand); }

.doc__body { display: flex; flex-direction: column; gap: clamp(34px, 4vw, 56px); min-width: 0; }
.doc__s { scroll-margin-top: 110px; }
.doc__k {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .12em; color: var(--brand-bright); margin: 0 0 8px;
}
.doc__s h3 {
  font-family: var(--font-display); font-size: clamp(26px, 3vw, 38px);
  font-weight: 600; letter-spacing: -.03em; margin: 0 0 16px;
}
.doc__s p { font-size: 15px; line-height: 1.7; color: var(--text-2); margin: 0 0 14px; max-width: 68ch; }
.doc__s p b { color: var(--text); font-weight: 600; }
.doc__s a { color: var(--brand-bright); }
.doc__ol { counter-reset: s; list-style: none; padding: 0; margin: 0 0 14px; }
.doc__ol li {
  counter-increment: s; position: relative; padding-left: 34px;
  font-size: 15px; line-height: 1.7; color: var(--text-2); margin-bottom: 12px; max-width: 68ch;
}
.doc__ol li::before {
  content: counter(s); position: absolute; left: 0; top: 2px;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text-3);
  font-family: var(--font-mono); font-size: 10px;
}
.doc__ol li b { color: var(--text); font-weight: 600; }
.doc__note { font-family: var(--font-mono); font-size: 11px; line-height: 1.7; color: var(--text-3); }

.ptab { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 0 28px; margin: 4px 0 16px; }
.ptab > div {
  display: flex; justify-content: space-between; gap: 14px;
  padding: 10px 0; border-bottom: 1px solid var(--hairline-soft);
}
.ptab dt { font-size: 13px; color: var(--text-3); }
.ptab dd { margin: 0; font-family: var(--font-mono); font-size: 12px; text-align: right; }

.doc__cta { display: flex; gap: 10px; flex-wrap: wrap; padding-top: 8px; }

/* ------------------------------------------------------------------ coins */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-top: clamp(28px, 3vw, 44px); }
.stat {
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: var(--surface); padding: 20px 22px;
  display: flex; flex-direction: column; gap: 7px;
}
.stat__k { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-3); }
.stat b { font-family: var(--font-display); font-size: clamp(26px, 3vw, 38px); font-weight: 600; letter-spacing: -.03em; }
.stat__s { font-size: 11px; color: var(--text-3); line-height: 1.5; }

.cols {
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: var(--surface); padding: clamp(20px, 2.4vw, 28px); margin-top: 12px;
}
.cols__k { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--text-3); margin: 0 0 14px; }
.cols__list { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px 28px; }
.cols__list li { display: flex; flex-direction: column; gap: 3px; }
.cols__list b { font-size: 14px; font-weight: 600; }
.cols__list span { font-size: 12px; color: var(--text-3); line-height: 1.55; }

/* ------------------------------------------------------- market marks + logo
   The market's own mark on each card, and the coin logo picker. Both ours. */
.mk__id { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mk__ic {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  object-fit: cover; background: var(--surface-3);
}
.tick__mk {
  width: 18px; height: 18px; border-radius: 50%; margin-right: 8px;
  vertical-align: -4px; object-fit: cover; background: var(--surface-3);
}

.drop {
  display: flex; align-items: center; gap: 14px;
  border: 1px dashed var(--hairline); border-radius: 14px;
  background: var(--bg); padding: 14px 16px; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.drop:hover, .drop.is-over { border-color: var(--brand); background: var(--surface-2); }
.drop.is-set { border-style: solid; }
.drop__prev {
  width: 46px; height: 46px; border-radius: 12px; overflow: hidden; flex: none;
  background: var(--surface-2); display: grid; place-items: center;
}
.drop__prev img { width: 100%; height: 100%; object-fit: cover; }
.drop__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.drop__body b { font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drop__body span { font-family: var(--font-mono); font-size: 10px; color: var(--text-3); line-height: 1.5; }
.drop__btn { flex: none; height: 38px; padding: 0 16px; font-size: 13px; }
.drop__clear {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-mono); font-size: 10px; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .1em; padding: 6px;
}
.drop__clear:hover { color: #ff6a5e; }
@media (max-width: 520px) {
  .drop { flex-wrap: wrap; }
  .drop__btn { width: 100%; }
}

/* ------------------------------------------------- optional block, seed, cost */
.more { margin-top: 14px; border-top: 1px solid var(--hairline-soft); padding-top: 14px; }
.more summary {
  cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 8px;
  font-size: 14px; color: var(--text-2);
}
.more summary::-webkit-details-marker { display: none; }
.more summary::before {
  content: '›'; color: var(--text-3); font-size: 15px;
  transition: transform .18s var(--ease); display: inline-block;
}
.more[open] summary::before { transform: rotate(90deg); }
.more summary em {
  font-style: normal; font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; letter-spacing: .1em; color: var(--text-3);
}
.more summary:hover { color: var(--text); }
.more__body { padding-top: 16px; }
.fld__i--ta { height: auto; padding: 12px 14px; line-height: 1.55; resize: vertical; font-family: var(--font); }

.lcs__lead { font-size: 14px; line-height: 1.6; color: var(--text-3); margin: -6px 0 18px; max-width: 62ch; }

.seed { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.seed__in { margin-bottom: 0; flex: 1 1 200px; }
.seed__wrap { position: relative; display: block; }
.seed__unit {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3); pointer-events: none;
}
.seed__wrap .fld__i { padding-right: 48px; }
.seed__quick { display: flex; gap: 8px; flex-wrap: wrap; }

.tick__links { display: flex; gap: 6px; margin: -8px 0 14px; flex-wrap: wrap; }
.tick__chip {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3);
  border: 1px solid var(--hairline); border-radius: 999px; padding: 3px 9px;
}
.tick__rows--cost { margin-top: 8px; }
.tick__rows--cost .is-total dt { color: var(--text); }
.tick__rows--cost .is-total dd { color: var(--brand-bright); }

/* --------------------------------------------------------- wallet + result */
.nav__wallet.is-on .nav__wbtn { border-color: var(--brand); color: var(--brand-bright); }
.nav__wallet.is-wrong .nav__wbtn { border-color: #ff6a5e; color: #ff6a5e; }
.nav__wbtn { cursor: pointer; font: inherit; }

.lcs__warn {
  margin: 14px 0 0; padding: 12px 14px;
  border-left: 2px solid var(--brand); border-radius: 0 10px 10px 0;
  background: var(--surface-2);
  font-size: 12.5px; line-height: 1.6; color: var(--text-2);
}

.done {
  margin-top: 18px; padding: 16px;
  border: 1px solid var(--brand); border-radius: 14px; background: var(--surface-2);
}
.done__k {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .1em; color: var(--brand-bright); margin: 0 0 8px;
}
.done__addr {
  font-family: var(--font-mono); font-size: 11px; line-height: 1.5;
  word-break: break-all; margin: 0 0 12px;
}
.done__links { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.done__links a { font-size: 12px; color: var(--text-2); }
.done__links a:hover { color: var(--brand-bright); }
.done__note { font-family: var(--font-mono); font-size: 10px; line-height: 1.7; color: var(--text-3); margin: 0; }
