/* BUBBLE BUTTS · $JUICY
   One screen, fatfellas formula: gate -> fullscreen video + song, bling wordmark,
   how-to-buy, socials, CA tapes pinned top and bottom, sound toggle.
   Look: blackberry-black night, gold bling type, Robinhood-green tape, juice-magenta stamp.
   Motion thesis: everything shines, nothing scrolls. Mobile-first. */

:root {
  --night: #0b0611;      --night: oklch(12.5% 0.033 320);
  --cream: #f6eef7;      --cream: oklch(95.5% 0.012 325);
  --dim: #cbb4d4;        --dim: oklch(80% 0.05 318);
  --gold: #f4d478;       --gold: oklch(87% 0.11 90);
  --gold-hi: #fff4c6;    --gold-hi: oklch(96% 0.07 95);
  --gold-mid: #d3a544;   --gold-mid: oklch(75% 0.13 85);
  --gold-deep: #8a5c1c;  --gold-deep: oklch(52% 0.1 80);
  --gold-shadow: #45290a;--gold-shadow: oklch(30% 0.07 75);
  --juice: #ff4fa3;      --juice: oklch(70% 0.21 355);
  --juice-hi: #ffc1de;   --juice-hi: oklch(87% 0.09 355);
  --juice-deep: #a1195f; --juice-deep: oklch(46% 0.19 350);
  --money: #43f584;      --money: oklch(86% 0.23 150);
  --tape-bg: #04030a;    --tape-bg: oklch(8% 0.02 300);

  --spring: linear(0, 0.034, 0.121, 0.24, 0.376, 0.515, 0.647, 0.766, 0.867, 0.95, 1.013, 1.058, 1.087, 1.102, 1.107, 1.103, 1.094, 1.081, 1.067, 1.052, 1.038, 1.025, 1.014, 1.006, 0.999, 0.994, 1);
  --pop: linear(0, 0.054, 0.192, 0.378, 0.581, 0.776, 0.945, 1.077, 1.168, 1.218, 1.234, 1.221, 1.189, 1.145, 1.098, 1.052, 1.013, 0.982, 0.961, 0.949, 0.945, 0.948, 0.956, 0.966, 0.977, 0.988, 1);

  --tape-h: 38px;
  --display: 'Titan One', 'Arial Black', sans-serif;
  --speech: 'General Sans', system-ui, sans-serif;
}

* { margin: 0; box-sizing: border-box; }
html { scrollbar-color: var(--gold-deep) var(--night); }
body {
  background: var(--night);
  color: var(--cream);
  font-family: var(--speech);
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.55;
  overflow-x: clip;
}
::selection { background: var(--juice); color: var(--night); }
img, svg, video { max-width: 100%; display: block; }
a { color: var(--gold); }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; border-radius: 4px; }
button { font: inherit; color: inherit; }
strong { font-weight: 700; }
/* every display-face use pins weight 400: Titan One ships one weight, and a
   synthesised weight is an invisible bug the font check rightly fails */
.btn, .hero-play span { font-weight: 400; }

.grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 40; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- bling type ----------
   Two layers make the metal read as cast rather than printed:
   (1) a ::before silhouette carrying a dark contour and a stepped extrusion,
       sitting at z-index -1 behind the parent's own text-clipped background;
   (2) the parent, filled with a 16-stop ramp whose stops crowd around a HARD
       horizon at 50% — that abrupt light-to-dark flip is what the eye reads as
       a reflective surface. A smooth 4-stop gradient always reads as plastic.
   The filter on .bling/.blingp is load-bearing beyond looks: it establishes the
   stacking context that keeps the z-index:-1 layer from escaping behind the page. */
.bling, .blingp {
  position: relative;
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.96;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
/* The PARENT is the cast edge: dark contour plus a stepped extrusion.
   The ::before overlay carries the metal and paints on top of it.
   This order is not a style choice, it is required: a negative-z-index child
   paints ABOVE its parent's own background, so putting the edge in the
   pseudo-element hides the fill completely (measured, 2026-09-07). */
.bling, .blingp {
  -webkit-text-stroke: 0.055em var(--edge);
  paint-order: stroke fill;
  /* The fill sits entirely under the ::before metal, so this colour is never
     seen. It is set to a representative mid-tone of that metal anyway, because
     it is what the page falls back to if the overlay ever fails, and because a
     contrast checker can only measure THIS layer. A dark edge colour here
     measures as dark-on-dark and is both a false alarm and a real fallback bug. */
  color: var(--face);
  text-shadow:
    0 0.014em 0 var(--edge-1),
    0 0.028em 0 var(--edge-2),
    0 0.042em 0 var(--edge-3),
    0 0.056em 0.008em #150b01,
    0 0.09em 0.05em rgba(0, 0, 0, 0.55),
    0 0.17em 0.34em rgba(0, 0, 0, 0.7);
}
.bling {
  --edge: #2b1806;
  --edge-1: #7a4d12;
  --edge-2: #533207;
  --edge-3: #341e04;
  --face: #f7cf6a;
  filter: drop-shadow(0 0.1em 0.28em rgba(0, 0, 0, 0.45));
}
.blingp {
  --edge: #45072a;
  --edge-1: #a3175d;
  --edge-2: #700f40;
  --edge-3: #47072a;
  --face: #ff8ec2;
  filter: drop-shadow(0 0.09em 0.24em rgba(0, 0, 0, 0.45));
}

.bling[data-text]::before,
.blingp[data-text]::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: transparent;
  -webkit-text-stroke: 0;
  text-shadow: none;
  -webkit-background-clip: text;
  background-clip: text;
  background-size: 260% 100%, 100% 100%;
  /* no-repeat is mandatory: at 260% width the default repeat tiles the shine
     band straight back over the glyphs and washes the metal out. And because
     the image is wider than the box, percentage positions run BACKWARDS, so
     100% parks the band off the left edge and 0% sends it off the right. */
  background-repeat: no-repeat;
  background-position: 100% 0, 0 0;
  pointer-events: none;
}
.bling[data-text]::before {
  background-image:
    linear-gradient(100deg,
      transparent 0 36%,
      rgba(255, 255, 255, 0.10) 42%,
      rgba(255, 255, 255, 0.72) 48.5%,
      rgba(255, 255, 255, 0.98) 50.2%,
      rgba(255, 255, 255, 0.72) 52%,
      rgba(255, 255, 255, 0.10) 58%,
      transparent 64% 100%),
    linear-gradient(178deg,
      #fff2c4 0%,
      #ffe07c 11%,
      #ffd050 23%,
      #f7bf3e 35%,
      #e9b033 44%,
      #dfa72d 48.4%,
      #6d3f0a 48.6%,
      #5a3206 50.4%,
      #a86a14 51.2%,
      #dda42c 54%,
      #f4c351 61%,
      #ffda7b 69%,
      #ffefb8 79%,
      #fff9dc 86%,
      #eec25e 93%,
      #bf8b2b 100%);
}
.blingp[data-text]::before {
  background-image:
    linear-gradient(100deg,
      transparent 0 36%,
      rgba(255, 255, 255, 0.08) 42%,
      rgba(255, 255, 255, 0.62) 48.5%,
      rgba(255, 255, 255, 0.92) 50.2%,
      rgba(255, 255, 255, 0.62) 52%,
      rgba(255, 255, 255, 0.08) 58%,
      transparent 64% 100%),
    linear-gradient(178deg,
      #ffe4f1 0%,
      #ffa8ce 11%,
      #ff77b4 23%,
      #ff4f9f 35%,
      #f43a8e 44%,
      #e62f82 48.4%,
      #7a0a40 48.6%,
      #690837 50.4%,
      #b81760 51.2%,
      #ef3d8c 54%,
      #ff69ad 61%,
      #ff9fcb 69%,
      #ffd4e8 79%,
      #fff0f7 86%,
      #ff92c6 93%,
      #db3179 100%);
}

/* the shine sweep: a narrow bright band that crosses, then a long rest.
   It lives on the metal layer, so it animates the ::before, not the element. */
.js .wm-line::before { animation: sheen 6.5s ease-in-out infinite; }
.js .wm-2::before { animation-delay: 0.55s; }
.js .stamp-in::before { animation: sheen 6.5s ease-in-out 1.1s infinite; }
@keyframes sheen {
  0%, 62% { background-position: 100% 0, 0 0; }
  88%, 100% { background-position: 0% 0, 0 0; }
}

/* sparkles: clip-path stars, twinkled by scale (an opacity cycle reads as a stuck reveal) */
.sp {
  position: absolute;
  width: 0.22em; height: 0.22em;
  background: linear-gradient(180deg, #fffbe9, var(--gold));
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  filter: drop-shadow(0 0 6px rgba(255, 240, 190, 0.8));
}
.js .sp { animation: twinkle 2.6s ease-in-out infinite; }
.sp-1 { top: -0.06em; right: -0.14em; }
.sp-2 { bottom: 0.02em; left: -0.16em; animation-delay: 0.8s; }
.sp-3 { top: -0.1em; right: -0.05em; width: 0.13em; height: 0.13em; animation-delay: 1.6s; }
@keyframes twinkle {
  0%, 100% { transform: scale(0.45) rotate(0deg); }
  50% { transform: scale(1.15) rotate(24deg); }
}

.eyebrow {
  font-family: var(--speech);
  font-weight: 700;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.32em;
  color: var(--juice);
}

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: clamp(1rem, 3.6vw, 1.2rem);
  text-decoration: none;
  text-align: center;
  border-radius: 16px;
  border: 0;
  padding: 0.8em 1.5em;
  min-height: 44px;
  cursor: pointer;
  transition: transform 0.45s var(--spring), filter 0.2s ease, box-shadow 0.2s ease;
}
.btn-gold {
  color: #2c1a04;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold) 45%, var(--gold-mid) 55%, var(--gold) 100%);
  border: 2px solid var(--gold-hi);
  box-shadow: 0 0.22em 0 var(--gold-deep), 0 12px 28px rgba(0, 0, 0, 0.5), inset 0 1px 0 #fffef2;
  text-shadow: 0 1px 0 rgba(255, 250, 220, 0.6);
}
.btn-gold:hover { transform: translateY(-2px); filter: brightness(1.06); }
.btn-gold:active { transform: translateY(1px); box-shadow: 0 0.08em 0 var(--gold-deep), 0 6px 14px rgba(0, 0, 0, 0.5); }
.btn-gold.big { font-size: clamp(1.1rem, 4.5vw, 1.45rem); }

/* ---------- the gate ---------- */
.gate {
  margin: auto;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--cream);
  max-width: min(92vw, 40rem);
  overflow: visible;
}
.gate::backdrop { background: rgba(5, 2, 9, 0.86); backdrop-filter: blur(10px); }
.gate-inner {
  text-align: center;
  padding: clamp(2rem, 6vw, 3.5rem) clamp(1.2rem, 5vw, 3rem);
  border-radius: 28px;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(140, 50, 170, 0.28), transparent 60%),
    linear-gradient(180deg, rgba(28, 14, 38, 0.96), rgba(12, 6, 18, 0.96));
  border: 1px solid rgba(244, 212, 120, 0.22);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.gate-title { display: grid; font-size: clamp(2.6rem, 9.5vw, 4.6rem); margin-block: 0.3em 0.55em; }
.gate-fine { margin-top: 1rem; color: var(--dim); font-size: 0.9rem; letter-spacing: 0.06em; }
/* entry by keyframe animation, deliberately: @starting-style + transition on a
   dialog has wedged mid-flight twice in Chromium (once on close at ~0.95, once
   on open at ~0.05). Animations do not touch that machinery. Close is instant. */
.gate[open] { animation: dlg-in 0.8s var(--spring); }
.gate[open]::backdrop { animation: fade-in 0.5s ease; }
@keyframes dlg-in { from { opacity: 0; translate: 0 28px; scale: 0.94; } }
@keyframes fade-in { from { opacity: 0; } }

/* ---------- CA tapes ---------- */
.tape {
  position: fixed; left: 0; right: 0; z-index: 30;
  background: var(--tape-bg);
  overflow: hidden;
  white-space: nowrap;
  height: var(--tape-h);
  display: flex;
  align-items: center;
}
.tape-top { top: 0; border-bottom: 1px solid rgba(67, 245, 132, 0.28); }
.tape-bottom { bottom: 0; border-top: 1px solid rgba(67, 245, 132, 0.28); }
.tape-track { display: flex; width: max-content; }
.js .tape-track { animation: roll 36s linear infinite; }
@keyframes roll { to { transform: translateX(-50%); } }
.tape-seq { display: flex; align-items: center; }
.tape-seq span, .tape-seq i {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-style: normal;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--money);
  padding-inline: 1.1em;
}
.tape-seq i { color: var(--juice); padding-inline: 0.2em; }
.tape.is-ca { cursor: pointer; min-height: 44px; }
.tape.is-ca:hover .tape-seq span { color: #8bffb5; }
.tape-copied {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center;
  background: var(--tape-bg);
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.82rem; letter-spacing: 0.2em; font-weight: 700;
  color: var(--money); text-transform: uppercase;
}

/* ---------- hero: the whole site ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: calc(var(--tape-h) + clamp(1rem, 3vh, 2rem)) 1.25rem calc(var(--tape-h) + clamp(1rem, 3vh, 2rem));
  overflow: clip;
  text-align: center;
}
.hero-media, .hero-media video, .hero-media img { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-media video, .hero-media img { object-fit: cover; }
.hero-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(90% 60% at 50% 58%, rgba(8, 4, 13, 0.42), transparent 70%),
    linear-gradient(180deg, rgba(8, 4, 13, 0.75), transparent 26% 68%, rgba(8, 4, 13, 0.85));
}
.hero-inner { position: relative; display: grid; justify-items: center; max-width: 60rem; }

/* --beat is a decaying impulse written by app.js on each detected 808 kick.
   Scale only: compositor-cheap, and it makes the whole wordmark punch as one
   mass rather than blinking per line. Because it now fires on kicks alone
   rather than continuously, it can hit harder without reading as jitter. */
.wordmark {
  display: grid;
  justify-items: center;
  scale: calc(1 + var(--beat, 0) * 0.058);
  transform-origin: 50% 55%;
}

.wm-line { position: relative; font-size: clamp(3.6rem, 17.5vw, 10rem); }
.stamp {
  font-size: clamp(2.1rem, 9vw, 4.1rem);
  margin-top: 0.08em;
  transform: rotate(-4deg);
  transform-origin: 50% 100%; /* squash from the base, so it reads as landing on something */
}
/* Three stacked animations: it falls in once, then bobs forever, and the shine
   crosses on its own clock. Timing functions live on the KEYFRAMES, not the
   animation, because a single bezier cannot both accelerate a fall and settle
   an overshoot. */
.js .stamp-in {
  animation:
    juicy-slam 1.5s linear 0.55s both,
    juicy-bob 3.6s ease-in-out 2.05s infinite;
}
/* Liquid, not rubber. What separates the two is the DECAY: a ball gives two
   clean bounces, a body of liquid keeps wobbling in ever-smaller opposing
   squashes long after it has stopped travelling. So the settle runs seven
   decaying oscillations instead of two, and each carries a little skew, which
   is the mass sloshing sideways rather than the whole shape rotating. */
@keyframes juicy-slam {
  0%   { opacity: 0; transform: translate3d(0, -62vh, 0) scale(0.70, 1.30) skewX(0deg) rotate(8deg);
         animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.35); }     /* gravity, drawn thin */
  38%  { opacity: 1; transform: translate3d(0, -22vh, 0) scale(0.66, 1.36) skewX(-1deg) rotate(2deg);
         animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.4); }      /* stretched by the fall */
  50%  { transform: translate3d(0, 0, 0) scale(1.44, 0.56) skewX(0deg) rotate(-4deg);
         animation-timing-function: cubic-bezier(0.15, 0.75, 0.35, 1); }   /* splat */
  59%  { transform: translate3d(0, -13%, 0) scale(0.84, 1.24) skewX(2.2deg) rotate(-6deg);
         animation-timing-function: cubic-bezier(0.5, 0, 0.75, 0.5); }
  68%  { transform: translate3d(0, 0, 0) scale(1.20, 0.84) skewX(-1.6deg) rotate(-2.6deg);
         animation-timing-function: cubic-bezier(0.15, 0.75, 0.35, 1); }
  76%  { transform: translate3d(0, -6%, 0) scale(0.92, 1.12) skewX(1.2deg) rotate(-5.2deg);
         animation-timing-function: cubic-bezier(0.5, 0, 0.75, 0.5); }
  83%  { transform: translate3d(0, 0, 0) scale(1.10, 0.93) skewX(-0.8deg) rotate(-3.2deg);
         animation-timing-function: cubic-bezier(0.15, 0.75, 0.35, 1); }
  89%  { transform: translate3d(0, -2.5%, 0) scale(0.96, 1.055) skewX(0.5deg) rotate(-4.7deg); }
  94%  { transform: translate3d(0, 0, 0) scale(1.04, 0.975) skewX(-0.3deg) rotate(-3.6deg); }
  97%  { transform: translate3d(0, 0, 0) scale(0.985, 1.02) skewX(0.15deg) rotate(-4.15deg); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1, 1) skewX(0deg) rotate(-4deg); }
}
/* the idle: a slow gelatinous breathe, the squash and the drift deliberately
   out of phase so it never reads as a clean mechanical bob */
@keyframes juicy-bob {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1, 1) skewX(0deg) rotate(-4deg); }
  18%      { transform: translate3d(0, -3.5%, 0) scale(0.972, 1.042) skewX(-1.1deg) rotate(-5.1deg); }
  38%      { transform: translate3d(0, -1.2%, 0) scale(1.032, 0.972) skewX(0.7deg) rotate(-3.3deg); }
  58%      { transform: translate3d(0, -3%, 0) scale(0.986, 1.026) skewX(-0.5deg) rotate(-4.8deg); }
  78%      { transform: translate3d(0, -0.6%, 0) scale(1.018, 0.986) skewX(0.3deg) rotate(-3.6deg); }
}
.pair-line {
  margin-top: 1.4rem;
  font-weight: 600;
  font-size: clamp(0.95rem, 3.4vw, 1.15rem);
  letter-spacing: 0.04em;
  color: var(--cream);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}
.pair-line strong { color: var(--money); }
.cta { display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center; margin-top: 1.6rem; }

/* hero entrance: type settles in once, video underneath */
.js .wm-1, .js .wm-2, .js .pair-line, .js .cta, .js .hero .socials { animation: rise 0.85s var(--spring) both; }
.js .wm-2 { animation-delay: 0.12s; }
.js .pair-line { animation-delay: 0.5s; }
.js .cta { animation-delay: 0.62s; }
.js .hero .socials { animation-delay: 0.74s; }
@keyframes rise { from { opacity: 0; translate: 0 30px; } to { opacity: 1; translate: 0; } }

/* play button shown instead of autoplay under reduced motion */
.hero-play {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: end center;
  padding-bottom: 14svh;
  background: none; border: 0; cursor: pointer;
}
.hero-play span {
  display: inline-flex; align-items: center; gap: 0.6em;
  font-family: var(--display); text-transform: uppercase; letter-spacing: 0.05em;
  font-size: 1rem; color: #2c1a04;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold) 50%, var(--gold-mid));
  border: 2px solid var(--gold-hi); border-radius: 999px;
  padding: 0.7em 1.3em;
  box-shadow: 0 0.2em 0 var(--gold-deep), 0 12px 28px rgba(0, 0, 0, 0.5);
}

/* ---------- socials ---------- */
.socials { display: flex; gap: 0.7rem; margin-top: 1.7rem; justify-content: center; }
.soc {
  position: relative;
  display: grid; place-items: center;
  width: 48px; height: 48px;
  border-radius: 14px;
  color: var(--gold);
  background: rgba(16, 8, 24, 0.72);
  border: 1px solid rgba(244, 212, 120, 0.35);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
  transition: transform 0.45s var(--spring), border-color 0.2s ease, color 0.2s ease;
}
.soc svg { width: 22px; height: 22px; }
a.soc:hover { transform: translateY(-3px) scale(1.06); border-color: var(--gold); color: var(--gold-hi); }
.soc-soon { opacity: 0.45; }
.soon-tag {
  position: absolute; bottom: -0.45rem;
  font-style: normal; font-size: 0.55rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--night); background: var(--dim);
  padding: 0.1em 0.5em; border-radius: 999px;
}

/* ---------- how-to-buy sheet ---------- */
.sheet {
  margin: auto;
  width: min(92vw, 34rem);
  border: 1px solid rgba(244, 212, 120, 0.22);
  border-radius: 24px;
  padding: clamp(1.4rem, 4vw, 2.2rem);
  color: var(--cream);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(140, 50, 170, 0.22), transparent 60%),
    linear-gradient(180deg, #1c0e26, #0d0714);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.sheet::backdrop { background: rgba(5, 2, 9, 0.8); backdrop-filter: blur(8px); }
.sheet[open] { animation: sheet-in 0.7s var(--spring); }
.sheet[open]::backdrop { animation: fade-in 0.45s ease; }
@keyframes sheet-in { from { opacity: 0; translate: 0 24px; } }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.2rem; }
.sheet-head h2 { font-size: clamp(1.6rem, 6vw, 2.2rem); }
.sheet-x {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  background: rgba(244, 212, 120, 0.1);
  border: 1px solid rgba(244, 212, 120, 0.35);
  border-radius: 12px;
  color: var(--gold);
  cursor: pointer;
  font-size: 1.1rem;
}
.sheet-x:hover { background: rgba(244, 212, 120, 0.2); }
.buy-now { display: block; width: 100%; margin-bottom: 1.3rem; }
.steps { list-style: none; padding: 0; display: grid; gap: 0.9rem; counter-reset: step; }
.steps li { position: relative; padding-left: 2.6rem; counter-increment: step; color: var(--dim); }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0.1em;
  width: 1.9rem; height: 1.9rem;
  display: grid; place-items: center;
  font-family: var(--display); font-size: 0.95rem;
  color: #2c1a04;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold) 55%, var(--gold-mid));
  border-radius: 50%;
  box-shadow: 0 0.12em 0 var(--gold-deep);
}
.steps strong { color: var(--gold); }
.sheet-fine { margin-top: 1.1rem; font-size: 0.82rem; color: var(--dim); }

/* ---------- sound toggle ---------- */
.sound {
  position: fixed; right: 16px; bottom: calc(var(--tape-h) + 12px); z-index: 45;
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(14, 7, 20, 0.8);
  border: 1.5px solid rgba(244, 212, 120, 0.5);
  color: var(--gold);
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  transition: transform 0.45s var(--spring), border-color 0.2s ease;
}
.sound:hover { transform: scale(1.08); border-color: var(--gold); }
.sound svg { width: 24px; height: 24px; }
.sound .snd-off { display: none; }
.sound[aria-pressed="false"] .snd-on { display: none; }
.sound[aria-pressed="false"] .snd-off { display: block; }

/* ---------- wider screens ---------- */
@media (min-width: 720px) {
  :root { --tape-h: 42px; }
}

/* ---------- reduced motion: the page is complete, just still ---------- */
@media (prefers-reduced-motion: reduce) {
  .js .wm-line, .js .sp, .js .tape-track,
  .js .wm-1, .js .wm-2, .js .pair-line, .js .cta, .js .hero .socials { animation: none; }
  /* the stamp still arrives, it just does not fall or bob */
  .js .stamp-in { animation: fade-in 0.5s ease both; }
  .wordmark { scale: 1; }
  .gate[open], .gate[open]::backdrop, .sheet[open], .sheet[open]::backdrop { animation: none; }
  .btn, .soc, .sound { transition: none; }
}
