/* Bubble Drift — bubbledrift.app
   Structure, type and rigour: UpLate Garage studio system.
   Palette: Bubble Drift's own deep-sea identity. Dark, never black.
   One earned yellow (#eab308) — the same yellow as the in-game START RUN key. */

:root {
  /* surfaces */
  --ink: #050a0f;
  --ink-2: #070e14;
  --surface: #0b1319;
  --surface-2: #111d26;
  --well: #04080c;
  --border: #1c2b36;
  --border-strong: #2b3f4e;

  /* text */
  --text: #e8eef3;
  --text-dim: #a8b8c4;
  --text-faint: #7e909d;

  /* the one accent */
  --accent: #eab308;
  --accent-hover: #fbbf24;
  --accent-press: #ca8a04;
  --on-accent: #09090b;

  /* title hues, straight from the game */
  --glass-hue: #2ee8b0;
  --abyss-hue: #38bdf8;
  --chaos: #ff3d8b;
  --skin: var(--glass-hue);

  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --shadow: 0 18px 46px rgba(0, 0, 0, .55);
  --shadow-lift: 0 26px 60px rgba(0, 0, 0, .62);

  --font: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --maxw: 1120px;
  --gutter: clamp(18px, 4vw, 44px);
  --tap-min: 44px;
}

[data-skin='abyss'] { --skin: var(--abyss-hue); }

* { box-sizing: border-box; margin: 0; padding: 0; }
/* Anything given a `display` below would otherwise out-specify the UA's
   `[hidden] { display: none }` — the veil and the End-run button both do. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font);
  background: var(--ink);
  color: var(--text);
  line-height: 1.6;
  overflow-x: hidden;
  font-synthesis-weight: none;
}

a { color: var(--skin); text-decoration: none; }
a:hover { color: var(--text); }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  background: var(--accent); color: var(--on-accent);
  padding: 12px 18px; border-radius: var(--radius-sm);
  font-weight: 600; font-size: .9rem; transition: top .12s;
}
.skip:focus { top: 12px; color: var(--on-accent); }

#bubble-canvas {
  position: fixed; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
.content { position: relative; z-index: 1; }

/* ── Nav ───────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 12px var(--gutter);
  background: rgba(5, 10, 15, .86);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.brand {
  display: flex; align-items: center; gap: 11px;
  color: var(--text); font-weight: 600; letter-spacing: -.01em; font-size: 1.02rem;
}
.brand img { width: 30px; height: 30px; border-radius: 8px; display: block; }
.nav-links { display: flex; align-items: center; gap: clamp(8px, 1.8vw, 22px); }
.nav-links a {
  color: var(--text-dim); font-size: .9rem;
  padding: 10px 2px; min-height: var(--tap-min); display: inline-flex; align-items: center;
}
.nav-links a:hover { color: var(--text); }
.nav-cta {
  color: var(--on-accent) !important;
  background: var(--accent);
  padding: 0 18px !important;
  border-radius: var(--radius-sm);
  font-weight: 600; font-size: .88rem !important;
}
.nav-cta:hover { background: var(--accent-hover); color: var(--on-accent) !important; }
@media (max-width: 860px) {
  .nav { gap: 10px; }
  .nav-links {
    overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-right: -4px; padding-right: 4px;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links a { white-space: nowrap; }
  .brand span { display: none; }
}
@media (max-width: 460px) {
  .nav-links a:not(.nav-cta) { display: none; }
}

/* ── Layout primitives ─────────────────────────────── */
section { padding: clamp(56px, 8vw, 108px) var(--gutter); }
.wrap { max-width: var(--maxw); margin: 0 auto; }
.center { text-align: center; }
.mt { margin-top: 14px; }

.eyebrow {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .7rem;
  color: var(--accent);
  margin-bottom: 14px;
}
.eyebrow.dim { color: var(--text-faint); }

h1 {
  font-size: clamp(2.5rem, 7vw, 4.4rem);
  font-weight: 700; letter-spacing: -.025em; line-height: 1.03;
  text-wrap: balance;
}
h2 {
  font-size: clamp(1.7rem, 3.6vw, 2.6rem);
  font-weight: 600; letter-spacing: -.02em; line-height: 1.1;
  text-wrap: balance;
}
h3 { font-size: 1.06rem; font-weight: 600; letter-spacing: -.01em; }
p { text-wrap: pretty; }
.lead { color: var(--text-dim); font-size: clamp(1rem, 1.6vw, 1.14rem); max-width: 62ch; }
.lead.center { margin-inline: auto; }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* Inline code names a real symbol in the app (`MotionGate`). Without this it
   falls back to generic monospace and sits larger than the body text. */
code { font-family: var(--mono); font-size: .92em; color: var(--text); }

/* ── Buttons ───────────────────────────────────────── */
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }
.btn-row.center { justify-content: center; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--tap-min); padding: 12px 22px;
  border-radius: var(--radius-sm); border: 1px solid var(--accent);
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font); font-size: .96rem; font-weight: 600; letter-spacing: -.01em;
  cursor: pointer;
  transition: background .12s cubic-bezier(.2,0,0,1), transform .12s cubic-bezier(.2,0,0,1), border-color .12s;
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
.btn:active { background: var(--accent-press); transform: translateY(1px); }
.btn.ghost {
  background: transparent; border-color: var(--border-strong); color: var(--text);
}
.btn.ghost:hover { border-color: var(--text-faint); background: var(--surface); color: var(--text); }
.btn svg { width: 17px; height: 17px; flex: none; }

.pip {
  display: inline-block; width: 7px; height: 7px; border-radius: 999px;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
  animation: pip 1.8s ease-in-out infinite;
  vertical-align: 1px; margin-right: 8px;
}
@keyframes pip { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* ── Hero ──────────────────────────────────────────── */
.hero { padding-top: clamp(38px, 6vw, 76px); padding-bottom: clamp(46px, 6vw, 84px); }
.hero-grid {
  display: grid; gap: clamp(28px, 5vw, 64px);
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  align-items: center;
}
@media (max-width: 900px) { .hero-grid { grid-template-columns: minmax(0, 1fr); } }
.hero h1 { margin-bottom: 18px; }
.hero .lead { font-size: clamp(1.04rem, 1.9vw, 1.24rem); }
.hero .btn-row { margin-top: 30px; }
.hero-note {
  margin-top: 20px; font-family: var(--mono); font-size: .76rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint);
}

/* skin switch */
.switch {
  display: inline-flex; gap: 4px; margin-bottom: 26px;
  padding: 4px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface);
}
.switch button {
  appearance: none; border: 0; cursor: pointer;
  min-height: var(--tap-min); padding: 0 18px;
  border-radius: var(--radius-sm); background: transparent;
  font-family: var(--mono); font-size: .74rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-faint);
  transition: background .12s, color .12s;
}
.switch button:hover { color: var(--text-dim); }
.switch button[aria-pressed='true'] {
  background: var(--surface-2); color: var(--skin);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}

/* phone frame */
.phone {
  position: relative; width: 100%; max-width: 340px; margin: 0 auto;
  aspect-ratio: 720 / 1565;
  border-radius: 30px; overflow: hidden;
  background: var(--well);
  box-shadow:
    0 0 0 1px var(--border-strong),
    var(--shadow-lift),
    0 0 90px -18px color-mix(in oklab, var(--skin) 55%, transparent);
  transition: box-shadow .22s cubic-bezier(.2,0,0,1);
}
.phone img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
  opacity: 0; transition: opacity .22s cubic-bezier(.2,0,0,1);
}
.phone img.on { opacity: 1; }
.phone-cap {
  margin-top: 16px; text-align: center;
  font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-faint);
}

/* ── Cards ─────────────────────────────────────────── */
.grid {
  display: grid; gap: 16px; margin-top: 36px;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
}
.grid.two { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 24px;
  box-shadow: var(--shadow);
  transition: transform .14s cubic-bezier(.2,0,0,1), border-color .14s;
}
.card h3 { margin-bottom: 7px; }
.card p { color: var(--text-dim); font-size: .94rem; }
.card:hover { border-color: var(--border-strong); }
.card .tag { margin-bottom: 14px; }
.card-accent { border-top: 3px solid var(--accent); }

.tag {
  display: inline-block;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .14em; text-transform: uppercase;
  padding: 5px 9px; border-radius: var(--radius-sm);
  color: var(--text-dim); background: var(--surface-2); border: 1px solid var(--border);
}
.tag.free { color: var(--accent); border-color: color-mix(in oklab, var(--accent) 40%, var(--border)); }
.tag.skin { color: var(--skin); border-color: color-mix(in oklab, var(--skin) 34%, var(--border)); }

/* ── Steps ─────────────────────────────────────────── */
.steps { display: grid; gap: 0; margin-top: 34px; counter-reset: step; }
.step {
  display: grid; grid-template-columns: 46px 1fr; gap: 18px;
  padding: 20px 0; border-top: 1px solid var(--border);
}
.step:first-child { border-top: 0; padding-top: 4px; }
.step-n {
  counter-increment: step;
  font-family: var(--mono); font-size: .82rem; color: var(--accent);
  padding-top: 3px;
}
.step-n::before { content: '0' counter(step); }
.step p { color: var(--text-dim); font-size: .95rem; margin-top: 4px; }

/* ── Specials line-up ──────────────────────────────── */
.creatures {
  display: grid; gap: 14px; margin-top: 38px;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
}
.creature {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 20px 18px 18px;
  text-align: center;
}
.creature-art {
  height: 108px; margin: 0 auto 16px; width: 82px;
  display: flex; align-items: center; justify-content: center;
}
.creature-art svg { overflow: visible; }
.creature .role {
  font-family: var(--mono); font-size: .64rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-faint); margin-bottom: 5px;
}
.creature .name { font-size: .98rem; font-weight: 600; }
.creature .fact { color: var(--text-dim); font-size: .82rem; margin-top: 6px; }

/* ── Compare (glass vs abyss) ──────────────────────── */
.compare { display: grid; gap: 20px; margin-top: 38px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.compare-col {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-xl); padding: 22px;
  display: grid; gap: 18px;
}
/* Not cropped. The launch screens are 720 × 1565 and their composition runs from
   the title at 16% down to the creature at 62%, so the fixed 380px crop this
   used to carry cut the creature in half. The whole screen shows instead,
   width-capped so it reads as a phone — nothing is lost, down to the
   "pop to begin" line at the bottom. */
.compare-col .shot {
  max-width: 250px; margin-inline: auto;
  border-radius: 14px; overflow: hidden; background: var(--well);
  box-shadow: 0 0 0 1px var(--border);
}
.compare-col .shot img { display: block; width: 100%; height: auto; }
.compare-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.compare-head h3 { font-size: 1.24rem; }
.spec-list { display: grid; gap: 9px; }
.spec-list div {
  display: grid; grid-template-columns: 12ch 1fr; gap: 12px;
  font-size: .88rem; color: var(--text-dim);
  padding-bottom: 9px; border-bottom: 1px solid var(--border);
}
.spec-list div:last-child { border-bottom: 0; padding-bottom: 0; }
.spec-list dt, .spec-list .k {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-faint); padding-top: 2px;
}

/* ── Worlds ────────────────────────────────────────── */
.worlds { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 32px; }
.world {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px 9px 11px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); font-size: .9rem;
}
.world .dots { display: flex; align-items: center; gap: 3px; }
.world .dots i {
  display: block; border-radius: 999px; width: 9px; height: 9px;
}
.world .dots i:nth-child(2) { width: 7px; height: 7px; }
.world .dots i:nth-child(3) { width: 5px; height: 5px; }
.world.more { color: var(--text-faint); font-family: var(--mono); font-size: .78rem; letter-spacing: .08em; }

.w-garage .dots i:nth-child(1) { background: #f5c518; } .w-garage .dots i:nth-child(2) { background: #ff3d8b; } .w-garage .dots i:nth-child(3) { background: #2ee8b0; }
.w-sunset .dots i:nth-child(1) { background: #ff8a3d; } .w-sunset .dots i:nth-child(2) { background: #ff6b4a; } .w-sunset .dots i:nth-child(3) { background: #ff4d8d; }
.w-mono .dots i:nth-child(1) { background: #f7c948; } .w-mono .dots i:nth-child(2) { background: #f0a93b; } .w-mono .dots i:nth-child(3) { background: #e8bb52; }
.w-ocean .dots i:nth-child(1) { background: #35c8f5; } .w-ocean .dots i:nth-child(2) { background: #3b9df0; } .w-ocean .dots i:nth-child(3) { background: #38d0d8; }
.w-ember .dots i:nth-child(1) { background: #ff5c3d; } .w-ember .dots i:nth-child(2) { background: #ff7a45; } .w-ember .dots i:nth-child(3) { background: #f2453d; }
.w-forest .dots i:nth-child(1) { background: #3ee07f; } .w-forest .dots i:nth-child(2) { background: #35c86a; } .w-forest .dots i:nth-child(3) { background: #5ce68a; }
.w-neon .dots i:nth-child(1) { background: #ff2fa0; } .w-neon .dots i:nth-child(2) { background: #2ee8d0; } .w-neon .dots i:nth-child(3) { background: #ffd53d; }
.w-candy .dots i:nth-child(1) { background: #ff3d8b; } .w-candy .dots i:nth-child(2) { background: #ff6b6b; } .w-candy .dots i:nth-child(3) { background: #ff9a4d; }
.w-aurora .dots i:nth-child(1) { background: #2ee8b0; } .w-aurora .dots i:nth-child(2) { background: #35d97a; } .w-aurora .dots i:nth-child(3) { background: #38d0f0; }
.w-midnight .dots i:nth-child(1) { background: #3d7ff5; } .w-midnight .dots i:nth-child(2) { background: #5560f0; } .w-midnight .dots i:nth-child(3) { background: #3d9bf0; }
.w-lava .dots i:nth-child(1) { background: #ff4d3d; } .w-lava .dots i:nth-child(2) { background: #ff7a2f; } .w-lava .dots i:nth-child(3) { background: #ffa03d; }
.w-pastel .dots i:nth-child(1) { background: #ff8ab5; } .w-pastel .dots i:nth-child(2) { background: #7ff0d0; } .w-pastel .dots i:nth-child(3) { background: #ffd98a; }

/* ── Shots gallery ─────────────────────────────────── */
.shots {
  display: grid; gap: 16px; margin-top: 36px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.shots figure { margin: 0; }
.shots img {
  display: block; width: 100%; height: auto;
  border-radius: 22px; background: var(--well);
  box-shadow: 0 0 0 1px var(--border), var(--shadow);
}
.shots figcaption {
  margin-top: 10px; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint);
}

/* ── Stats strip ───────────────────────────────────── */
.stats { display: grid; gap: 16px; margin-top: 36px; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 20px;
}
.stat .k {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-faint);
}
.stat .v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.7rem; font-weight: 500; margin-top: 8px; letter-spacing: -.02em;
}
.stat .v.skin { color: var(--skin); }
.stat .v.gold { color: var(--accent); }
.stat .n { color: var(--text-dim); font-size: .84rem; margin-top: 4px; }

/* ── FAQ ───────────────────────────────────────────── */
.faq { display: grid; gap: 10px; margin-top: 32px; }
.faq details {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 2px 18px;
}
.faq details[open] { border-color: var(--border-strong); }
.faq summary {
  cursor: pointer; list-style: none; padding: 15px 0;
  min-height: var(--tap-min);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  font-weight: 500; font-size: .98rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; flex: none; width: 11px; height: 11px;
  border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(45deg) translateY(-2px); transition: transform .16s;
}
.faq details[open] summary::after { transform: rotate(225deg) translateY(-2px); }
.faq details p { color: var(--text-dim); font-size: .94rem; padding: 0 0 18px; max-width: 68ch; }

/* ── Form ──────────────────────────────────────────── */
.form {
  max-width: 620px; margin: 34px auto 0; text-align: left;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-xl); padding: clamp(20px, 3.4vw, 32px);
  box-shadow: var(--shadow);
}
.field { margin-bottom: 20px; }
.field label { display: block; font-size: .84rem; color: var(--text-dim); margin-bottom: 8px; }
.field select, .field textarea, .field input[type='email'] {
  width: 100%; min-height: var(--tap-min);
  background: var(--well); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 12px 13px;
  color: var(--text); font-family: var(--font); font-size: .95rem;
}
.field textarea { min-height: 108px; resize: vertical; }
.field select:hover, .field textarea:hover, .field input:hover { border-color: var(--border-strong); }
.field ::placeholder { color: var(--text-faint); }

.stars { display: flex; gap: 6px; }
.stars button {
  appearance: none; background: var(--well); cursor: pointer;
  width: var(--tap-min); height: var(--tap-min);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-faint); font-size: 1.2rem; line-height: 1;
  transition: color .12s, border-color .12s, background .12s;
}
.stars button:hover { color: var(--accent-hover); border-color: var(--border-strong); }
.stars button[aria-checked='true'] { color: var(--accent); border-color: color-mix(in oklab, var(--accent) 45%, var(--border)); }
.submit { width: 100%; }
.form-note { text-align: center; color: var(--text-faint); font-size: .8rem; margin-top: 14px; }
.form-status { text-align: center; margin-top: 14px; font-size: .92rem; min-height: 1.4em; }
.form-status.ok { color: var(--glass-hue); }
.form-status.err { color: var(--chaos); }

/* ── Sound toggle ──────────────────────────────────── */
.sound {
  position: fixed; right: 16px; bottom: 16px; z-index: 30;
  width: var(--tap-min); height: var(--tap-min);
  display: grid; place-items: center; cursor: pointer;
  background: rgba(11, 19, 25, .9); backdrop-filter: blur(8px);
  border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--text-dim);
  transition: color .12s, border-color .12s;
}
.sound:hover { color: var(--text); border-color: var(--border-strong); }
.sound svg { width: 19px; height: 19px; }

/* ── Doc pages (press kit, privacy) ────────────────── */
.doc { max-width: 780px; margin: 0 auto; }
.doc h1 { font-size: clamp(2rem, 5vw, 2.9rem); margin: 4px 0 10px; }
.doc h2 { font-size: 1.22rem; margin-top: 2.4rem; }
.doc p, .doc li { color: var(--text-dim); }
.doc p { margin-top: .8rem; }
.doc ul { padding-left: 1.15rem; margin-top: .5rem; }
.doc li { margin-top: .35rem; }
.doc a { text-decoration: underline; text-underline-offset: 3px; word-break: break-word; }
.doc .date { font-family: var(--mono); font-size: .8rem; color: var(--text-faint); }
.facts { width: 100%; border-collapse: collapse; margin-top: 20px; }
.facts th, .facts td { padding: 11px 12px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; font-weight: 400; }
.facts th { color: var(--text-faint); width: 38%; font-family: var(--mono); font-size: .74rem; letter-spacing: .08em; text-transform: uppercase; }
.facts td { color: var(--text-dim); }
.boiler {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; color: var(--text-dim); margin-top: 14px;
}

/* A known problem, stated where the claim would otherwise sit. Uses --chaos
   because it is the palette's one "something is wrong" colour, and the left
   rule makes it scannable for someone skimming for what does not work. */
.notice {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--chaos);
  border-radius: var(--radius); padding: 16px 18px; margin-top: 16px;
}
.doc .notice p { margin-top: .6rem; }
.doc .notice p:first-child { margin-top: 0; }
.notice strong { color: var(--text); }

/* ── Footer ────────────────────────────────────────── */
footer {
  padding: 46px var(--gutter) 60px; border-top: 1px solid var(--border);
  text-align: center; color: var(--text-dim);
}
footer nav { display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: center; }
footer a { color: var(--text-dim); }
footer a:hover { color: var(--text); }
footer .small { margin-top: 14px; }
.small { font-size: .8rem; color: var(--text-faint); }

/* ── Utility ───────────────────────────────────────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* ── Scroll reveal ─────────────────────────────────── */
/* Applied by motion.js, and only to elements that start below the fold — so a
   page with no JS, or a dead IntersectionObserver, is still fully readable. */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .52s cubic-bezier(.2,0,0,1), transform .52s cubic-bezier(.2,0,0,1);
}
.reveal.in { opacity: 1; transform: none; }

/* ── Nav scroll progress ───────────────────────────── */
.nav-progress {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--skin); opacity: .85;
  transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform;
}

/* ── Ambient field ─────────────────────────────────── */
/* World chips hue-rotate the whole canvas rather than re-tinting each shape. */
#bubble-canvas { transition: filter .45s cubic-bezier(.2,0,0,1); }

/* Long-form pages hold the field further back. Marketing sections are mostly
   headings and short lines, where drifting shapes read as depth; a `.doc` page
   is dense body copy, where they read as interference — and on the
   accessibility statement in particular, decorative motion across the text
   would be arguing against the page. */
body:has(.doc) #bubble-canvas { opacity: .4; }

/* ── Living geometry ───────────────────────────────── */
/* Each creature moves the way its own anatomy would. Transforms only — no
   layout, no repaint of the page — and every one of these is switched off
   under reduced motion below. */
.bd-p { transform-box: view-box; transform-origin: center; }

.creature-art { transition: transform .18s cubic-bezier(.2,0,0,1); }
.creature:hover .creature-art { transform: translateY(-3px) scale(1.04); }

@keyframes bd-bell { 0%, 100% { transform: scale(1, 1); } 45% { transform: scale(1.05, .93); } }
@keyframes bd-trail { 0%, 100% { transform: scaleY(1) rotate(0deg); } 50% { transform: scaleY(1.09) rotate(1.6deg); } }
@keyframes bd-glow { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@keyframes bd-halo { 0%, 100% { transform: scale(1); opacity: .8; } 50% { transform: scale(1.22); opacity: .3; } }
@keyframes bd-shimmer { 0%, 100% { opacity: 1; } 50% { opacity: .72; } }
@keyframes bd-chase { 0%, 100% { opacity: .35; } 40% { opacity: 1; } }
@keyframes bd-drift-y { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4%); } }
/* The bolt's flicker is the app's own keyframe timing: .35 → .9 → .6 → 1.0
   across 90/70/120/100 ms. */
@keyframes bd-flicker {
  0% { opacity: .35; } 23.7% { opacity: .9; } 42.1% { opacity: .6; }
  73.7% { opacity: 1; } 100% { opacity: .35; }
}

[data-shape^='medusa'] .bd-bell { animation: bd-bell 3.6s ease-in-out infinite; }
[data-shape^='medusa'] .bd-tentacles,
[data-shape^='medusa'] .bd-arms { animation: bd-trail 3.6s ease-in-out infinite; }
[data-shape^='medusa'] .bd-gonads { animation: bd-glow 3.6s ease-in-out infinite; }

[data-shape='lure'] .bd-esca { animation: bd-glow 2.4s ease-in-out infinite; }
[data-shape='lure'] .bd-halo { animation: bd-halo 2.4s ease-in-out infinite; }
[data-shape='lure'] .bd-teeth { animation: bd-shimmer 2.4s ease-in-out infinite; }

[data-shape='squid'] .bd-arms { animation: bd-trail 3.1s ease-in-out infinite; }
[data-shape='squid'] .bd-inner { animation: bd-glow 3.1s ease-in-out infinite; }

/* No rotation here: the log spiral is the one shape not centred on the bubble
   origin, so spinning it about the viewBox centre swings it out of frame.
   The chambers light instead. */
[data-shape='nautilus'] .bd-shell { animation: bd-shimmer 4.6s ease-in-out infinite; }
[data-shape='nautilus'] .bd-septa { animation: bd-chase 3.4s ease-in-out infinite; }

[data-shape='eel'] .bd-core { animation: bd-flicker .38s steps(1, end) infinite; }
[data-shape='eel'] .bd-photophores { animation: bd-chase 1.8s ease-in-out infinite; }

[data-shape='urchin'] .bd-spikes { animation: bd-shimmer 2.8s ease-in-out infinite; }
[data-shape='urchin'] .bd-core { animation: bd-glow 1.6s ease-in-out infinite; }

[data-shape='ghost'] .bd-body { animation: bd-drift-y 3.4s ease-in-out infinite; }
[data-shape='ghost'] .bd-wisp { animation: bd-glow 2.6s ease-in-out infinite; }
[data-shape='bolt'] .bd-core { animation: bd-flicker .38s steps(1, end) infinite; }
[data-shape='star'] .bd-body { animation: bd-shimmer 3s ease-in-out infinite; }
[data-shape='bomb'] .bd-spark { animation: bd-glow 1.1s ease-in-out infinite; }
[data-shape='hex'] .bd-facets { animation: bd-shimmer 4s ease-in-out infinite; }
[data-shape^='glass'] .bd-panes { animation: bd-shimmer 4.4s ease-in-out infinite; }

/* ── The browser round ─────────────────────────────── */
.play {
  display: grid; gap: clamp(20px, 3vw, 32px); margin-top: 38px;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
}
@media (max-width: 820px) { .play { grid-template-columns: minmax(0, 1fr); } }

.play-panel {
  position: relative;
  /* Definite, not a percentage: the panel sits in an `auto` grid track, and a
     percentage width there is circular — the track sizes to the panel, which
     sizes to the track. Height follows from the phone's aspect ratio, and the
     vh term keeps the whole run visible without scrolling. */
  width: min(360px, calc(68vh * 390 / 844));
  max-width: 100%;
  aspect-ratio: 390 / 844;
  margin: 0 auto;
  border-radius: 30px; overflow: hidden;
  background: var(--well);
  box-shadow:
    0 0 0 1px var(--border-strong),
    var(--shadow-lift),
    0 0 90px -18px color-mix(in oklab, var(--skin) 55%, transparent);
  transition: box-shadow .22s cubic-bezier(.2,0,0,1);
}
.play-panel canvas {
  position: absolute; inset: 0; display: block;
  width: 100%; height: 100%;
}
/* Only a live run swallows touches — an idle panel still scrolls the page. */
.play-panel.live canvas { touch-action: none; cursor: crosshair; }
.play-panel canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: -5px; }

.play-hud {
  position: absolute; left: 0; right: 0; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(4, 8, 12, .88), rgba(4, 8, 12, 0));
}
.hud-score {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.16rem; color: var(--text); letter-spacing: -.02em;
}
.hud-combo {
  font-family: var(--mono); font-size: .84rem; color: var(--skin);
  margin-right: auto; min-width: 4ch;
}
.hud-lives { display: flex; gap: 5px; }
.hud-lives i { display: block; width: 8px; height: 8px; border-radius: 999px; background: var(--border-strong); }
.hud-lives i.on { background: var(--chaos); box-shadow: 0 0 8px color-mix(in oklab, var(--chaos) 60%, transparent); }
.hud-lives.zen {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .18em; color: var(--skin);
}

.play-veil {
  position: absolute; inset: 0; z-index: 3;
  display: grid; place-items: center; padding: 26px;
  text-align: center;
  background: rgba(4, 8, 12, .8);
  backdrop-filter: blur(7px);
}
.play-veil[hidden], .veil-in[hidden] { display: none; }
.veil-in { display: grid; justify-items: center; gap: 12px; max-width: 260px; }
.veil-title { font-size: 1.3rem; font-weight: 600; letter-spacing: -.02em; }
.veil-eyebrow {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--text-faint);
}
.veil-note { color: var(--text-dim); font-size: .92rem; }
.veil-hint {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-faint);
}
.veil-score {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 2.9rem; font-weight: 500; line-height: 1; letter-spacing: -.03em;
  color: var(--skin);
}
.veil-stats { display: grid; gap: 6px; width: 100%; margin: 2px 0 4px; }
.veil-stats > div {
  display: flex; justify-content: space-between; gap: 12px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.veil-stats dt {
  font-family: var(--mono); font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-faint);
}
.veil-stats dd { font-family: var(--mono); font-size: .84rem; color: var(--text-dim); }
.veil-in .btn { width: 100%; }

.play-side { display: grid; gap: 16px; align-content: start; max-width: 46ch; }
/* Controls size to their content; the legend and copy still fill the column. */
.play-side .switch, .play-side .btn { justify-self: start; margin-bottom: 0; }
.play-mode-note { color: var(--text-dim); font-size: .92rem; }
.play-legend { display: grid; gap: 2px; }
.play-legend > div {
  display: grid; grid-template-columns: 36px 1fr auto; gap: 14px; align-items: center;
  padding: 8px 0; border-bottom: 1px solid var(--border);
}
.play-legend > div:last-child { border-bottom: 0; }
.play-legend .art { width: 36px; height: 36px; }
.play-legend .art svg { overflow: visible; }
.play-legend .what { font-size: .9rem; color: var(--text-dim); }
.play-legend .what b { color: var(--text); font-weight: 600; }
.play-legend .x {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .78rem; color: var(--skin);
}
.play-foot { color: var(--text-faint); font-size: .84rem; }

/* ── Motion & contrast preferences ─────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .phone img { transition: none; }
  /* Reveals never run, so nothing may be left invisible. */
  .reveal { opacity: 1; transform: none; }
  .creature:hover .creature-art { transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes bd-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
  .phone { animation: bd-float 7.5s ease-in-out infinite; }
}
@media (prefers-contrast: more) {
  :root { --text-dim: #dbe4ea; --text-faint: #b6c4ce; --border: #3a4d5c; --border-strong: #5b7182; }
  .hud-lives i { background: #5b7182; }
}
@media print {
  #bubble-canvas, .sound, .nav-cta, .play, .nav-progress { display: none; }
  body { background: #fff; color: #111; }
  .card, .form, .boiler { border-color: #ccc; box-shadow: none; }
  .reveal { opacity: 1; transform: none; }
}
