/* MotionDuel landing — one night in the game's world. The hero is the
   whole first screen: the game's own forest with a fight under way in it
   and the app's HUD over it. Everything after it keeps that mood: a dark
   page — one quiet wall of dungeon masonry behind all of it, so that what's
   read is the content — glass cards, Zagadka for the titles with the warm
   glow the app's titles have, and the app-icon tiles as the small symbols.
   The nav
   is a glass capsule in the middle: just the icon and the name over the
   hero, the whole menu on hover and from the second screen on. */

/* ── Fonts ─────────────────────────────────────────────────────────── */
@font-face { font-family: "Onest"; src: url("assets/fonts/Onest-Regular.woff2") format("woff2"), url("assets/fonts/Onest-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Onest"; src: url("assets/fonts/Onest-Medium.woff2") format("woff2"), url("assets/fonts/Onest-Medium.ttf") format("truetype"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Onest"; src: url("assets/fonts/Onest-Bold.woff2") format("woff2"), url("assets/fonts/Onest-Bold.ttf") format("truetype"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Onest"; src: url("assets/fonts/Onest-ExtraBold.woff2") format("woff2"), url("assets/fonts/Onest-ExtraBold.ttf") format("truetype"); font-weight: 800; font-display: swap; }
@font-face { font-family: "Onest"; src: url("assets/fonts/Onest-Black.woff2") format("woff2"), url("assets/fonts/Onest-Black.ttf") format("truetype"); font-weight: 900; font-display: swap; }
/* The game's own display face: Zagadka (Mystery Quest with a Cyrillic
   extension, OFL) — the app's titles, the wordmark, the TV's enemy names. */
@font-face { font-family: "Zagadka"; src: url("assets/fonts/Zagadka-Regular.woff2") format("woff2"), url("assets/fonts/Zagadka-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }

/* ── Tokens ────────────────────────────────────────────────────────── */
:root {
  --bg: #0b0c10;            /* the dungeon's dark: what the hero's forest fades into */
  --surface: rgba(255, 255, 255, 0.055);
  --surface-2: rgba(255, 255, 255, 0.09);
  --edge: rgba(255, 255, 255, 0.1);
  --ink: #f3f0e9;
  --muted: rgba(243, 240, 233, 0.62);
  --hairline: rgba(255, 255, 255, 0.09);
  --night: #070a08;
  --glow: rgba(255, 196, 120, 0.35);     /* the titles' warm halo */
  --dlc: #3381ff;           /* Day One DLC, as the app marks it */

  --page: 1180px;
  --gutter: clamp(16px, 4vw, 40px);
  --tile: clamp(50px, 7.6vw, 104px);

  /* Tile gradients — the arena's accent family (strike red, block blue,
     dungeon purple, boss gold, stamina green, feed cyan, lava orange). */
  --g-red: linear-gradient(145deg, #ff7a52, #e5245a);
  --g-blue: linear-gradient(145deg, #5bb2ff, #3b55f5);
  --g-purple: linear-gradient(145deg, #b879ff, #6534ea);
  --g-gold: linear-gradient(145deg, #ffd24a, #ff8a1c);
  --g-green: linear-gradient(145deg, #74e38f, #13a86a);
  --g-cyan: linear-gradient(145deg, #62e6ff, #2887f4);
  --g-pink: linear-gradient(145deg, #ff86cf, #b53cf2);
  --g-orange: linear-gradient(145deg, #ffa24a, #ff4a1f);
}

/* ── Base ──────────────────────────────────────────────────────────── */
/* --svh: a hundredth of the small viewport's height (a phone's, with the
   browser's bars counted in) — and of the plain viewport's where a browser
   doesn't know that unit: written out in svh, every band's height and
   every size cut from it was thrown away whole there, and the sections
   fell in on their headings. */
:root { --svh: 1vh; }
@supports (height: 1svh) { :root { --svh: 1svh; } }
* { margin: 0; padding: 0; box-sizing: border-box; }
/* (The bar's place is kept when the page is locked under the wave's card:
   without it every band grew by the bar's width, and the map was laid out
   and drawn again in the middle of the card's opening.) */
html { scrollbar-gutter: stable; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
/* What's off the screen stands still (script.js sets .is-away): its loops
   ran on for the whole visit, screens away. */
.is-away, .is-away *, .is-away *::before, .is-away *::after { animation-play-state: paused !important; }
body {
  font-family: "Onest", -apple-system, system-ui, sans-serif;
  /* The wall behind every section after the hero (the hero and the footer
     cover it with their own): dungeon masonry, a few hundredths strong
     (tools/stone-wall.py). The sections once stood each in a room of the
     game's — its still, blurred, behind the content — and that was what
     the eye went to, away from what's on the page. */
  background: var(--bg) url("assets/brand/stone-wall.svg") center top / 720px 480px;
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
ul, ol { list-style: none; }
/* Over `img { display: block }` and every flex or grid below. */
[hidden] { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ── Type ──────────────────────────────────────────────────────────── */
/* Titles in the game's face, lit warm like the hero's. */
.display {
  font-family: "Zagadka", "Onest", serif;
  font-weight: 400;
  font-size: clamp(44px, 7.6vw, 104px);
  line-height: 1;
  letter-spacing: 0.005em;
  text-wrap: balance;
  color: var(--ink);
  text-shadow: 0 0 34px var(--glow), 0 3px 0 rgba(0, 0, 0, 0.35);
}
.display-m { font-size: clamp(36px, 5.6vw, 72px); }
.display-s { font-size: clamp(30px, 4vw, 50px); }
/* A section's heading stands at the left, over the left edge of what it
   heads and close over it (.section: --head): the chip, the title, a line
   of words. (It stood in the middle of the page, a screen's worth of air
   under it.) */
.kicker {
  display: block;
  width: fit-content;
  margin: 0 0 16px;
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.38);
  border: 1px solid rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-weight: 600;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.86);
}
.lede {
  max-width: 640px;
  margin: 16px 0 0;
  font-weight: 500;
  font-size: clamp(17px, 1.6vw, 20px);
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}
.on-dark { color: #fff; }
.lede.on-dark { color: rgba(255, 255, 255, 0.82); }

/* ── Buttons ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 16px;
  padding: 15px 24px;
  white-space: nowrap;
  transition: transform 0.2s cubic-bezier(0.3, 1.4, 0.5, 1), box-shadow 0.2s;
}
.btn:hover { transform: translateY(-1px) scale(1.02); }
.btn:active { transform: scale(0.97); }
.btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn-black { background: #0c0c0e; color: #fff; }
.btn-white { background: #fff; color: #0c0c0e; }
.btn-light { background: #f3f0e9; color: #0c0c0e; }
.btn-s { padding: 10px 18px; font-size: 15px; }
/* Second to the white one: glass, a hairline. */
.btn-glass { background: rgba(255, 255, 255, 0.1); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22); }
.btn-glass:hover { background: rgba(255, 255, 255, 0.16); }
/* The way to the fight's screen (stage.html) — a page for the screen the
   fight is watched on, a computer's or a TV's, not for the phone that is the
   sword: a button in the page's top right corner, level with the bar,
   wherever there's room for one — whatever it's pointed at with (a TV box
   has a remote, not a mouse). The footer's link is there on every screen.
   In the game's own cobalt (Brand.accent), lit — as dark glass with a
   hairline it was lost on the page; the white «Скачать» stays the first
   thing to press. */
.on-desktop { display: none !important; }
.stage-link { position: fixed; top: 16px; right: 20px; z-index: 60;
  padding: 12px 20px 12px 16px;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(145deg, #4c97f6, #1b6cde);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.38), 0 0 0 1px rgba(8, 30, 70, 0.5), 0 10px 26px -8px rgba(27, 108, 222, 0.95), 0 2px 6px rgba(0, 0, 0, 0.4);
  transition: transform 0.2s cubic-bezier(0.3, 1.4, 0.5, 1), box-shadow 0.2s, opacity 0.25s, visibility 0s; }
/* A window too narrow for the open menu and the link beside it (the menu
   is some 730px across; under about 1100 the link lay over its right end,
   the beta capsule): while the menu is open the link steps aside. It
   stands after the nav in the page for this. */
@media (max-width: 1100px) {
  #nav:is(.is-open, .is-tapped, :hover, :focus-within) ~ .stage-link { opacity: 0; visibility: hidden; transition: opacity 0.25s, visibility 0s 0.25s; }
}
.stage-link:hover { background: linear-gradient(145deg, #62a7ff, #2a7bee); }
.stage-link svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (min-width: 861px) {
  .btn.on-desktop { display: inline-flex !important; }
}

/* ── Tiles (the page's building block) ─────────────────────────────── */
.tile {
  --grad: var(--g-blue);
  position: relative;
  display: grid;
  place-items: center;
  width: var(--tile);
  aspect-ratio: 1;
  border-radius: 23%;
  background: var(--grad);
  box-shadow:
    inset 0 1.5px 0 rgba(255, 255, 255, 0.4),
    inset 0 -3px 8px rgba(0, 0, 0, 0.12),
    0 14px 28px -12px rgba(30, 10, 60, 0.45),
    0 2px 5px rgba(0, 0, 0, 0.08);
}
.t-red { --grad: var(--g-red); }
.t-blue { --grad: var(--g-blue); }
.t-purple { --grad: var(--g-purple); }
.t-gold { --grad: var(--g-gold); }
.t-green { --grad: var(--g-green); }
.t-cyan { --grad: var(--g-cyan); }
.t-pink { --grad: var(--g-pink); }
.t-orange { --grad: var(--g-orange); }

/* A symbol from the inline sprite (tools/build_sprite.py), drawn in the
   current colour — white on a tile. Secondary layers keep their opacity. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.glyph {
  display: block;
  width: 56%;
  height: auto;
  aspect-ratio: 1;
  color: #fff;
  fill: currentColor;
  overflow: visible;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.12));
}
/* An enemy stands IN the tile and pops its head out over the top edge. */
.tile > img {
  position: absolute;
  left: 50%;
  bottom: -2%;
  width: 118%;
  max-width: none;
  translate: -50% 0;
  clip-path: inset(-60% 7.5% 2% 7.5% round 0 0 20% 20%);
  filter: drop-shadow(0 6px 6px rgba(0, 0, 0, 0.22));
}
.tile-sm { --tile: 46px; border-radius: 13px; }
.tile-xs { --tile: 34px; border-radius: 10px; }
.tile-xs .glyph { width: 62%; }

/* ── Nav — a glass capsule in the middle ──────────────────────────── */
/* Closed over the hero: the icon and the name. The rest sits in a grid
   track animated from 0fr to 1fr — the capsule grows out sideways from the
   middle, the links fading in as it does — on hover, on a tap (touch) and,
   for good, once the hero is behind (script.js: .is-open). */
#nav {
  position: fixed;
  z-index: 50;
  top: 14px;
  /* Centred by its margins, not left: 50% — that capped it at half the
     screen, and on a phone the open menu came out cut off. */
  left: 0;
  right: 0;
  width: fit-content;
  margin: 0 auto;
  display: flex;
  align-items: center;
  max-width: calc(100% - 24px);
  padding: 7px;
  border-radius: 999px;
  background: rgba(10, 14, 11, 0.5);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  backdrop-filter: blur(22px) saturate(1.6);
  border: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: 0 12px 34px -14px rgba(0, 0, 0, 0.6);
  color: #fff;
  transition: background 0.45s, box-shadow 0.45s, padding 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: "Zagadka", "Onest", serif;
  font-weight: 400;
  font-size: 21px;
  line-height: 1;
}
#nav .wordmark { padding: 0 8px 0 4px; }
/* A space's worth of room on the left: the «D»/«M» swashes curl out past
   the glyph box (the app pads its title for the same reason). */
.wordmark span { padding: 0 2px 0 3px; }
.wordmark img { width: 28px; height: 28px; }
.nav-more {
  display: grid;
  grid-template-columns: 0fr;
  transition: grid-template-columns 0.55s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.nav-more-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  overflow: hidden;
  opacity: 0;
  translate: -8px 0;
  transition: opacity 0.3s, translate 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}
#nav:hover .nav-more, #nav:focus-within .nav-more, #nav.is-open .nav-more, #nav.is-tapped .nav-more { grid-template-columns: 1fr; }
#nav:hover .nav-more-inner, #nav:focus-within .nav-more-inner, #nav.is-open .nav-more-inner, #nav.is-tapped .nav-more-inner {
  opacity: 1;
  translate: 0 0;
  transition-delay: 0.12s;
}
#nav.is-open { background: rgba(10, 14, 11, 0.66); }
.nav-links { display: flex; gap: 2px; padding-left: 6px; border-left: 1px solid rgba(255, 255, 255, 0.12); }
.nav-links a {
  padding: 8px 12px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 15px;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.82);
  transition: background 0.2s, color 0.2s;
}
.nav-links a:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }

/* ── Hero — a fight already under way ──────────────────────────────── */
/* One dark card: the game's forest, the goblin in it, the fight HUD drawn
   the way the app draws it on the TV (dark capsules, a lit health pill,
   clock-hand timer discs), the pitch on the left over a shade. */
.hero { position: relative; }
.quest {
  --hud: clamp(5px, 0.62vw, 7.5px); /* the HUD's unit, like the app's `u` */
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  /* The whole first screen. */
  min-height: max(calc(100 * var(--svh)), 560px);
  /* Where the left block starts: the words and, under them, the pickers. */
  --inset: max(var(--gutter), calc((100vw - 1320px) / 2 + 56px));
  overflow: hidden;
  background: #0d130e;
  color: #fff;
}
/* The forest runs on into the page below: its bottom fades into the night. */
.quest::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 22%;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--bg));
}
.quest-still { transition: opacity 0.35s ease; }
.quest-still.is-swapping, .foe-img.is-swapping { opacity: 0 !important; }
.foe-img { transition: opacity 0.35s ease; }
.quest-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: 60% 50%;
  z-index: -3;
  transform-origin: 70% 60%;
}
/* Dark where the words are, open where the goblin stands, and a warm glow
   behind him, like the stage's own key light. */
.quest-shade {
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(42% 52% at 72% 64%, rgba(255, 200, 120, 0.22), rgba(255, 200, 120, 0) 70%),
    linear-gradient(90deg, rgba(7, 11, 9, 0.9) 0%, rgba(7, 11, 9, 0.74) 34%, rgba(7, 11, 9, 0.18) 58%, rgba(7, 11, 9, 0.05) 100%),
    linear-gradient(0deg, rgba(5, 8, 6, 0.55) 0%, rgba(5, 8, 6, 0) 30%);
}
/* The forest's fireflies (the TV has them too). */
.fireflies { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.fireflies i {
  position: absolute;
  left: calc(var(--x) * 1%);
  top: calc(var(--y) * 1%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #d9ff8a;
  box-shadow: 0 0 10px 3px rgba(190, 255, 110, 0.55);
  opacity: 0.7;
}

.quest-copy {
  position: relative;
  align-self: center;
  padding: clamp(88px, 9vw, 120px) 0 clamp(28px, 4.4vw, 64px) var(--inset);
}
.quest-title {
  font-family: "Zagadka", "Onest", serif;
  font-weight: 400;
  font-size: clamp(42px, 5.1vw, 78px);
  line-height: 1;
  letter-spacing: 0.005em;
  color: #f4f1ea;
  text-shadow: 0 0 34px rgba(255, 196, 120, 0.35), 0 3px 0 rgba(0, 0, 0, 0.35);
}
/* Two lines, broken where the sentence breaks — never the dash alone. */
.quest-title span { display: block; white-space: nowrap; }
.quest-lede {
  margin-top: 18px;
  max-width: 460px;
  font-weight: 500;
  font-size: clamp(16px, 1.35vw, 18.5px);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.8);
  text-wrap: pretty;
}

.quest-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 18px;
  margin-top: 26px;
}
.quest-cta .btn { box-shadow: 0 12px 30px -12px rgba(0, 0, 0, 0.6); }
.quest-cta .btn-glass { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.24), 0 12px 30px -12px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
/* Where the download button stood while the game is in a closed beta: not
   a button — nothing to press — but the state of things, said in its
   place: a glass capsule, a lit amber dot. */
.beta {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 14px 24px 14px 19px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 16px;
  white-space: nowrap;
  color: #fff3dc;
  background: rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 0 0 1px rgba(255, 226, 170, 0.3), 0 12px 30px -12px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.beta i { position: relative; flex: none; width: 9px; height: 9px; border-radius: 50%; background: #ffc24a; box-shadow: 0 0 10px 1px rgba(255, 194, 74, 0.8); }
.beta i::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 1.5px solid rgba(255, 194, 74, 0.7); opacity: 0; }
.beta-s { gap: 9px; padding: 10px 17px 10px 13px; font-size: 15px; background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 1px rgba(255, 226, 170, 0.26);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.beta-s i { width: 8px; height: 8px; }
.footer-cta .beta { margin-top: 30px; }
@media (prefers-reduced-motion: no-preference) {
  .beta i::after { animation: beta-ring 2.4s ease-out infinite; }
}
@keyframes beta-ring { 0% { opacity: 0.9; scale: 0.5; } 70%, 100% { opacity: 0; scale: 1.5; } }
.plays-on {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 500;
  font-size: 14.5px;
  color: rgba(255, 255, 255, 0.66);
}
.plays-on .dev { width: 21px; height: 21px; fill: none; stroke: rgba(255, 255, 255, 0.8); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ── The fight on the right ── */
.quest-stage {
  position: relative;
  pointer-events: none;
  /* The pickers' row under him, and the room he stands up in above it. */
  --pick-row: clamp(64px, 5vw, 76px);
  /* On a tall screen he stands higher still — the spare height goes under
     his feet, not over his head (nothing at 720 px, up to 140 px). */
  --lift: clamp(0px, calc((calc(100 * var(--svh)) - 720px) * 0.32), 140px);
}
.foe {
  position: absolute;
  left: 60%;
  bottom: calc(var(--pick-row) + clamp(18px, 3vw, 40px) + var(--lift));
  width: min(66%, calc(var(--hud) * 50));
  aspect-ratio: 1;
  translate: -50% 0;
}
.foe-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  filter: drop-shadow(0 18px 18px rgba(0, 0, 0, 0.35));
  transform-origin: 50% 92%;
}
/* The 3D goblin (enemy3d.js): a canvas well past his box, so the swings and
   the recoil have room; the portrait gives way once he's loaded. */
.foe-3d {
  position: absolute;
  inset: -40% -60% -10%;
  width: 220%;
  height: 150%;
  opacity: 0;
  transition: opacity 0.6s ease;
  filter: saturate(1.08) contrast(1.06);
}
.foe.is-3d .foe-3d { opacity: 1; }
/* The 3D forest (enemy3d.js RoomStage) over the still, graded like the game's camera. */
.quest-3d { opacity: 0; transition: opacity 0.8s ease; filter: saturate(1.06) contrast(1.05); }
.quest-3d.is-on { opacity: 1; }
.foe.is-3d .foe-img { opacity: 0; transition: opacity 0.6s ease; }
.foe-shadow {
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: 4%;
  height: 9%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
}
/* His name and health just over his head, in the TV's pill. */
.hud-name {
  position: absolute;
  left: 50%;
  /* Over his health, which rides on his head (--head, set by enemy3d.js
     from where the 3D model's head lands; the portrait's own by default). */
  top: calc(var(--head, 0.05) * 100% - var(--hud) * 5.6);
  translate: -50% -100%;
  transition: top 0.3s ease;
  font-family: "Zagadka", "Onest", serif;
  font-size: calc(var(--hud) * 4.2);
  color: var(--foe-color, #9be37a);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: calc(var(--hud) * 1);
}
.hud-boss {
  font-family: "Onest", sans-serif;
  font-style: normal;
  font-weight: 900;
  font-size: calc(var(--hud) * 1.7);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: calc(var(--hud) * 0.35) calc(var(--hud) * 1);
  border-radius: 999px;
  color: #2a1a00;
  background: linear-gradient(#ffe08a, #f4b13c);
  text-shadow: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.hud-boss[hidden] { display: none; }
.hud-hp {
  --hp: 1;
  position: absolute;
  left: 50%;
  top: calc(var(--head, 0.05) * 100% - var(--hud) * 5);
  transition: top 0.3s ease;
  translate: -50% 0;
  width: 46%;
  height: calc(var(--hud) * 3);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.62);
  box-shadow: 0 0 0 calc(var(--hud) * 0.22) rgba(255, 255, 255, 0.14), 0 4px 10px rgba(0, 0, 0, 0.45);
}
.hud-hp i {
  position: absolute;
  inset: 0 auto 0 0;
  width: max(calc(var(--hud) * 3), calc(var(--hp) * 100%));
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(235, 92, 51, 0.8), #eb5c33);
  box-shadow: 0 0 calc(var(--hud) * 0.9) rgba(235, 92, 51, 0.6);
  transition: width 0.35s ease-out;
}
.hud-hp i::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  top: 14%;
  height: 28%;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.28);
}
.hud-hp b {
  position: absolute;
  right: calc(var(--hud) * 1.2);
  top: 50%;
  translate: 0 -50%;
  font-weight: 900;
  font-size: calc(var(--hud) * 2);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55);
}

/* His blow: the disc fills like a clock hand as the block window runs out,
   the name hangs on the side away from him. */
.hud-attack {
  position: absolute;
  left: 4%;
  top: 44%;
  display: flex;
  align-items: center;
  gap: calc(var(--hud) * 1.2);
  opacity: 0;
  scale: 0.4;
  transition: opacity 0.25s, scale 0.3s cubic-bezier(0.3, 1.5, 0.5, 1);
}
.atk-name {
  font-weight: 900;
  font-size: calc(var(--hud) * 2.5);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
  white-space: nowrap;
}
@property --p { syntax: "<number>"; inherits: true; initial-value: 0; }
.atk-disc {
  --p: 0;
  --accent: #ff6b57;
  position: relative;
  display: grid;
  place-items: center;
  width: calc(var(--hud) * 8.2);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  border: calc(var(--hud) * 0.55) solid rgba(255, 255, 255, 0.88);
  box-shadow: 0 0 calc(var(--hud) * (0.8 + 1.6 * var(--p))) var(--accent);
}
.atk-disc::before {
  content: "";
  position: absolute;
  inset: 11%;
  border-radius: 50%;
  background: conic-gradient(var(--accent) calc(var(--p) * 1turn), transparent 0);
}
.atk-disc .glyph { position: relative; width: 44%; }
/* The ring that snaps off the rim when the blow is stopped. */
.atk-disc::after {
  content: "";
  position: absolute;
  inset: calc(var(--hud) * -0.55);
  border-radius: 50%;
  border: calc(var(--hud) * 0.6) solid #80d6ff;
  opacity: 0;
}
[data-beat="windup"] .hud-attack,
[data-beat="block"] .hud-attack { opacity: 1; scale: 1; }
[data-beat="windup"] .atk-disc { --p: 1; transition: --p var(--windup, 1.3s) linear; }
[data-beat="block"] .atk-disc { --p: 1; --accent: #80d6ff; }
[data-beat="block"] .atk-name { color: #80d6ff; }
[data-beat="block"] .atk-disc::after { animation: ring-out 0.5s ease-out; }
@keyframes ring-out { from { opacity: 0.95; scale: 1; } to { opacity: 0; scale: 2.2; } }

/* The sword's cut across him, and the number it took. */
.slash {
  position: absolute;
  inset: 4% -6% 10% -6%;
  width: 112%;
  height: 86%;
  overflow: visible;
  filter: drop-shadow(0 0 6px rgba(255, 236, 170, 0.95));
}
.slash path {
  fill: none;
  stroke: url(#slash-grad);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 260;
  stroke-dashoffset: 260;
  opacity: 0;
}
.slash path.is-on { animation: slash 0.42s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
@keyframes slash {
  0% { stroke-dashoffset: 260; opacity: 1; stroke-width: 9; }
  55% { stroke-dashoffset: 0; opacity: 1; }
  100% { stroke-dashoffset: -260; opacity: 0; stroke-width: 2; }
}
.dmg {
  position: absolute;
  left: 50%;
  top: 34%;
  font-weight: 900;
  font-size: calc(var(--hud) * 5.4);
  background: linear-gradient(#fff, #ffd98a);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.7));
  opacity: 0;
  translate: -50% 0;
}
.dmg.is-on { animation: dmg 1s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
@keyframes dmg {
  0% { opacity: 0; scale: 0.4; translate: -50% 0; }
  18% { opacity: 1; scale: 1.15; }
  30% { scale: 1; }
  100% { opacity: 0; translate: -40% calc(var(--hud) * -14); }
}
.foe-img.is-hit { animation: flinch 0.38s ease-out; }
@keyframes flinch {
  0% { translate: 0 0; scale: 1; filter: drop-shadow(0 18px 18px rgba(0, 0, 0, 0.35)) brightness(1.8); }
  35% { translate: 4% 0; scale: 1.04 0.95; }
  100% { translate: 0 0; scale: 1; }
}
.foe-img.is-recoil { animation: recoil 0.45s ease-out; }
@keyframes recoil { 40% { translate: 3% 1%; rotate: 4deg; } }

/* The last few strikes, as the TV's feed pills. */
.hud-feed {
  position: absolute;
  left: 4%;
  /* Level with his feet, over the pickers' row. */
  bottom: calc(var(--pick-row) + clamp(18px, 3vw, 40px) + var(--lift) + 8px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--hud) * 0.8);
}
.hud-feed span {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--hud) * 1.1);
  padding: calc(var(--hud) * 0.8) calc(var(--hud) * 1.6);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.45);
  font-weight: 700;
  font-size: calc(var(--hud) * 2.4);
  white-space: nowrap;
  animation: feed-in 0.3s ease-out both;
}
.hud-feed span::before {
  content: "";
  width: calc(var(--hud) * 1.2);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--dot, #35c8ff);
}
@keyframes feed-in { from { opacity: 0; translate: 0 10px; } }

/* ── The fight's pickers: where and whom ── */
/* Right under him, centred on him. */
.quest-pick {
  position: absolute;
  left: 60%;
  translate: -50% 0;
  bottom: calc(clamp(18px, 3vw, 40px) + var(--lift));
  z-index: 3;
  display: flex;
  gap: 8px;
  /* As wide as its words: left to shrink-to-fit, an absolute box at
     left: 47% gets only the rest of the stage, and a long room's name ran
     out under the arrow. Past the stage's own width it gives way (the
     name is cut with an ellipsis). */
  width: max-content;
  max-width: 94%;
  pointer-events: auto;
}
.quest-pick .pick, .quest-pick .pick-open, .quest-pick .pick-label { min-width: 0; }
.quest-pick .pick-step, .quest-pick .pick-thumb { flex: none; }
.quest-pick .pick-label b { overflow: hidden; text-overflow: ellipsis; }
.pick {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  padding: 4px;
  border-radius: 999px;
  background: rgba(8, 10, 9, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.6);
}
/* The blur on a layer of its own: on the capsule itself, backdrop-filter
   would make it the containing block of its menu — on a phone the menu,
   meant to span the card, came out one capsule wide. */
.pick::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
}
.pick-step {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: rgba(255, 255, 255, 0.82);
  transition: background 0.2s, color 0.2s;
}
.pick-step:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.pick-step svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.pick-open {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 3px 10px 3px 3px;
  border-radius: 999px;
  text-align: left;
  transition: background 0.2s;
}
.pick-open:hover, .pick-open[aria-expanded="true"] { background: rgba(255, 255, 255, 0.1); }
.pick-thumb {
  width: 48px;
  height: 30px;
  border-radius: 9px;
  object-fit: cover;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.5);
}
.pick-face {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 30%;
  background: radial-gradient(circle at 50% 35%, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.04));
}
.pick-label { display: grid; line-height: 1.1; min-width: 74px; }
.pick-label small {
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}
.pick-label b { font-weight: 800; font-size: 15px; white-space: nowrap; }

/* The whole set, opening upward over the fight. */
.pick-menu {
  position: absolute;
  left: 0;
  right: auto;
  bottom: calc(100% + 10px);
  width: min(430px, calc(100vw - 40px));
  max-height: min(430px, 66vh);
  /* Down only, and without the bars: a strict grid of equal cells. */
  overflow: hidden auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-content: start;
  gap: 6px;
  padding: 8px;
  border-radius: 22px;
  background: rgba(12, 14, 13, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.8);
  animation: pick-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.pick-menu::-webkit-scrollbar { display: none; }
.pick-menu[hidden] { display: none; }
/* The enemy's opens leftwards, over him rather than off the screen. */
.pick[data-pick="enemy"] .pick-menu { left: auto; right: 0; }
@keyframes pick-in { from { opacity: 0; translate: 0 8px; scale: 0.98; } }
.pick-menu[data-kind="room"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* A cell: the picture's row and the name's row are the same in every one,
   whatever is in them — one line of name, or none. */
.pick-option {
  position: relative;
  display: grid;
  grid-template-rows: 64px 1.2em;
  justify-items: center;
  align-items: center;
  gap: 5px;
  min-width: 0;
  padding: 8px 3px 9px;
  border-radius: 14px;
  font-weight: 700;
  font-size: 12px;
  line-height: 1.2;
  text-align: center;
  color: rgba(255, 255, 255, 0.86);
  transition: background 0.18s;
}
.pick-option span { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pick-option:hover { background: rgba(255, 255, 255, 0.08); }
.pick-option[aria-checked="true"] { background: rgba(255, 255, 255, 0.14); color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.4); }
.pick-option img { width: 64px; height: 64px; object-fit: contain; }
.pick-menu[data-kind="room"] .pick-option { grid-template-rows: auto 1.2em; }
.pick-menu[data-kind="room"] .pick-option img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 10px; }
.pick-option .boss-dot {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #f4b13c;
}
.pick-menu-head {
  grid-column: 1 / -1;
  padding: 2px 6px 4px;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}

/* Without the script (or with reduced motion before it fills the feed), the
   fight stands still mid-blow. */
.quest-stage:not([data-beat]) .hud-attack { opacity: 1; scale: 1; }
.quest-stage:not([data-beat]) .atk-disc { --p: 0.62; }

/* Wide screens: the fight on the LEFT, the words on the right — everything
   that hung off his left side (the shade under the words, the warm light
   behind him, his blow and the strike feed between him and the words, the
   fireflies over the open part) mirrored with it. Phones keep the words on
   top and the fight under them. */
@media (min-width: 861px) {
  .quest { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
  .quest-stage { grid-column: 1; grid-row: 1; }
  .quest-copy {
    grid-column: 2;
    grid-row: 1;
    padding-left: clamp(8px, 2vw, 32px);
    padding-right: var(--inset);
  }
  .quest-bg { object-position: 40% 50%; transform-origin: 30% 60%; }
  .quest-shade {
    background:
      radial-gradient(42% 52% at 28% 64%, rgba(255, 200, 120, 0.22), rgba(255, 200, 120, 0) 70%),
      linear-gradient(270deg, rgba(7, 11, 9, 0.9) 0%, rgba(7, 11, 9, 0.74) 34%, rgba(7, 11, 9, 0.18) 58%, rgba(7, 11, 9, 0.05) 100%),
      linear-gradient(0deg, rgba(5, 8, 6, 0.55) 0%, rgba(5, 8, 6, 0) 30%);
  }
  .fireflies i { left: calc((100 - var(--x)) * 1%); }
  .foe, .quest-pick { left: 47%; }
  .hud-attack { left: auto; right: 4%; flex-direction: row-reverse; }
  .hud-feed { left: auto; right: 4%; align-items: flex-end; }
}

/* A narrow desktop: the pickers without their pictures, so the names fit
   (what they name is on the screen behind them). */
@media (min-width: 861px) and (max-width: 1180px) {
  .quest-pick .pick-thumb { display: none; }
  .quest-pick .pick-open { padding-left: 10px; }
}

/* Phone width: exactly one screen (svh: Safari's bars counted in). The
   title and a line under the nav, the fight in everything left between them
   and the button — him in the middle, his name and health on his head, his
   blow coming in beside him — the pickers at his feet and the button under
   them, where the thumb is. Type and gaps give with the screen's height, so
   a short phone gets the same screen, smaller. The words and the button are
   two ends of one block on a wide screen; here that block dissolves
   (display: contents) and its pieces take their own rows. */
@media (max-width: 860px) {
  .quest {
    --hud: clamp(4.8px, 1.5vw, 6.4px);
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    min-height: max(calc(100 * var(--svh)), 500px);
  }
  .quest-bg { object-position: 60% 50%; }
  /* Dark under the words and under the button, open where he stands. */
  .quest-shade {
    background:
      radial-gradient(70% 26% at 50% 68%, rgba(255, 200, 120, 0.2), rgba(255, 200, 120, 0) 70%),
      linear-gradient(180deg, rgba(7, 11, 9, 0.94) 0%, rgba(7, 11, 9, 0.8) 20%, rgba(7, 11, 9, 0.16) 44%, rgba(7, 11, 9, 0.1) 68%, rgba(7, 11, 9, 0.88) 100%);
  }
  .quest-copy { display: contents; }
  .quest-title {
    grid-row: 1;
    padding: clamp(62px, calc(10 * var(--svh)), 76px) 16px 0;
    text-align: center;
    font-size: clamp(30px, min(11.4vw, calc(6.8 * var(--svh))), 54px);
  }
  .quest-lede {
    grid-row: 2;
    justify-self: center;
    max-width: 30em;
    margin-top: clamp(6px, calc(1.2 * var(--svh)), 10px);
    padding: 0 22px;
    text-align: center;
    font-size: clamp(14px, calc(2.35 * var(--svh)), 15.5px);
    line-height: 1.4;
  }
  .quest-stage {
    grid-row: 3;
    container-type: size;
    min-height: 220px;
    --pick-row: 62px;
    /* On a tall phone the spare height goes under his feet, a little. */
    --lift: clamp(0px, calc((100cqh - 380px) * 0.16), 56px);
    /* As big as the row lets him be: by its width, or by its height. */
    --foe-size: min(78cqw, 62cqh, 360px);
  }
  .quest-cta {
    grid-row: 4;
    position: relative;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    margin: 0;
    padding: 10px 12px max(12px, env(safe-area-inset-bottom));
  }
  .quest-cta .btn { justify-content: center; padding: 15px 20px; font-size: 16.5px; }
  .quest-cta .beta { justify-content: center; padding: 15px 20px; font-size: 16.5px; }
  .plays-on { justify-content: center; font-size: 13px; }
  .plays-on .dev { width: 18px; height: 18px; }
  .foe { left: 50%; width: var(--foe-size); bottom: calc(var(--pick-row) + 10px + var(--lift)); }
  /* His name and health never climb over the words above the stage: on a
     short phone a boss's head stands past its top, and they stop at it. */
  .hud-hp { top: max(calc(var(--head, 0.05) * 100% - var(--hud) * 5), calc(var(--hud) * 6.4 + var(--pick-row) + 18px + var(--lift) + var(--foe-size) - 100cqh)); }
  .hud-name { top: max(calc(var(--head, 0.05) * 100% - var(--hud) * 5.6), calc(var(--hud) * 5.8 + var(--pick-row) + 18px + var(--lift) + var(--foe-size) - 100cqh)); }
  /* His blow in the margin beside him, its name under the disc in two lines
     (beside it, it ran into his ear). */
  .hud-attack { left: 10px; top: 34%; flex-direction: column-reverse; align-items: flex-start; gap: 5px; }
  .atk-name { max-width: 26cqw; white-space: normal; line-height: 1.1; font-size: calc(var(--hud) * 2.1); }
  /* No room for the feed's pills beside him: the strike's name rides under
     the number it took instead. */
  .hud-feed { display: none; }
  .dmg::after {
    content: attr(data-name);
    display: block;
    margin-top: -0.2em;
    font-size: 0.32em;
    font-weight: 800;
    letter-spacing: 0.02em;
    white-space: nowrap;
    translate: -30% 0;
  }
  /* The pickers: two capsules of ONE size, whatever they name — half the
     row each, a fixed height; an arrow either side and the name between
     them (two lines, a size down, when it is long). No thumbnail: what it
     names is on the screen behind it. */
  .quest-pick {
    position: absolute;
    left: 12px;
    right: 12px;
    width: auto;
    max-width: none;
    translate: none;
    bottom: 4px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 8px;
  }
  .pick { position: static; justify-content: space-between; background: rgba(8, 10, 9, 0.78); }
  /* Static (so the menu can span the card), its blur layer would span the
     whole row too — the second capsule's blur lay over the first one. */
  .pick::before { content: none; }
  .quest-pick .pick { height: 58px; padding: 3px; border-radius: 29px; }
  .quest-pick .pick-step { width: 34px; height: 52px; flex: none; border-radius: 26px; }
  .quest-pick .pick-step svg { width: 22px; height: 22px; }
  .quest-pick .pick-open { flex: 1; min-width: 0; height: 52px; justify-content: center; padding: 0; border-radius: 22px; text-align: center; }
  .quest-pick .pick-thumb { display: none; }
  .quest-pick .pick-label { min-width: 0; justify-items: center; gap: 2px; }
  .quest-pick .pick-label small { font-size: 10px; }
  .quest-pick .pick-label b { max-width: 100%; font-size: 16px; line-height: 1.06; white-space: nowrap; }
  .quest-pick .pick-label b[data-long] { font-size: 12.5px; white-space: normal; text-wrap: balance; }
  /* The whole list over the fight. */
  .pick-menu, .pick[data-pick="enemy"] .pick-menu {
    left: 0;
    right: 0;
    width: auto;
    bottom: calc(100% + 8px);
    /* Up to the screen's top: the nav steps aside while a list is open
       (body.is-picking, script.js). */
    max-height: min(470px, calc(calc(100 * var(--svh)) - 190px));
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
  }
  .pick-option { grid-template-rows: 52px 1.2em; gap: 4px; padding: 6px 1px 6px; font-size: 10.5px; letter-spacing: -0.01em; }
  #nav { transition: opacity 0.2s, background 0.45s, box-shadow 0.45s, padding 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }
  .is-picking #nav { opacity: 0; pointer-events: none; }
  .pick-option img { width: 52px; height: 52px; }
}
/* A short phone: the line under the button gives its place to the fight. */
@media (max-width: 860px) and (max-height: 640px) {
  .plays-on { display: none; }
}

/* ── The sections after the hero ───────────────────────────────────── */
/* Each is built the way the app builds a screen: ONE stage, a name under it
   to pick by, a couple of numbers, and plain words beside it. No panels of
   tabs and chips: what isn't needed at a glance waits behind a tap. */
.section {
  --air: clamp(40px, 5.6vw, 76px); /* between a section's blocks */
  --head-gap: clamp(26px, 3vw, 40px);  /* from its heading down to the first of them */
  width: min(var(--page), calc(100% - 2 * var(--gutter)));
  margin: 0 auto;
  padding-top: clamp(110px, 14vw, 200px);
}
.section-tight { padding-top: clamp(90px, 11vw, 150px); }

/* Small shared pieces. */
.quiet {
  margin-top: 14px;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(243, 240, 233, 0.6);
  text-wrap: pretty;
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 15px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.15;
  color: rgba(255, 255, 255, 0.86);
  background: rgba(255, 255, 255, 0.07);
  transition: background 0.2s, color 0.2s, transform 0.2s cubic-bezier(0.3, 1.5, 0.5, 1);
}
button.chip:hover { background: rgba(255, 255, 255, 0.14); }
button.chip:active { transform: scale(0.96); }
.chip small { font-weight: 800; font-size: 13px; color: #ff9d8a; }
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.86);
  background: rgba(255, 255, 255, 0.12);
}
.tag .glyph { width: 13px; filter: none; }
.tag-boss { color: #2a1a00; background: linear-gradient(#ffe08a, #f4b13c); }
.tag-friend { color: #06301c; background: linear-gradient(#9af0b4, #38c987); }
.tag-dlc { color: #fff; background: var(--dlc); }
.link-btn {
  padding: 6px 2px;
  font-weight: 700;
  font-size: 15px;
  color: rgba(255, 255, 255, 0.66);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.28);
  text-underline-offset: 5px;
  transition: color 0.2s;
}
.link-btn:hover { color: #fff; }
:where(button, a, summary, input):focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* (The run's map, reached by the keyboard: its ring inside it — the band
   round it cuts off whatever stands outside.) */
#run-map:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* A stage: the one object of a section. */
.dojo-stage, .lair-stage {
  position: relative;
  isolation: isolate;
  border-radius: 36px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--edge), 0 50px 90px -50px rgba(0, 0, 0, 0.9);
}
/* What floats over a stage's bottom edge: the name to pick by on one side,
   the numbers (or a hint) on the other — the app's bottom row. */
.stage-bar {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 18px;
  z-index: 4;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  pointer-events: none;
}
.stage-bar > * { pointer-events: auto; }
/* The hero's picker capsule, a size up: these are a section's main control. */
.stage-bar .pick { padding: 5px; background: rgba(8, 10, 9, 0.62); }
.stage-bar .pick-step { width: 44px; height: 44px; }
.stage-bar .pick-step svg { width: 21px; height: 21px; }
.stage-bar .pick-open { gap: 11px; min-height: 44px; padding: 2px 12px 2px 4px; }
.stage-bar .pick-plain .pick-open { padding-left: 14px; }
.stage-bar .pick-label { min-width: 0; }
.stage-bar .pick-label b { font-size: 18px; letter-spacing: -0.01em; }
.stage-bar .pick-label small:empty { display: none; }
.stage-bar .pick-face { width: 40px; height: 40px; }
.pick-caret { flex: none; width: 18px; height: 18px; fill: none; stroke: rgba(255, 255, 255, 0.5); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* Its list, opening upward over the stage. */
.stage-bar .pick-menu { left: 0; right: auto; width: min(460px, calc(100vw - 48px)); max-height: min(420px, 60vh); }
.pick-menu.pick-list { grid-template-columns: minmax(0, 1fr); gap: 2px; width: min(340px, calc(100vw - 48px)); padding: 8px; }
.pick-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 7px 12px 7px 7px;
  border-radius: 14px;
  text-align: left;
  font-weight: 700;
  font-size: 15.5px;
  color: rgba(255, 255, 255, 0.86);
  transition: background 0.18s;
}
.pick-row:hover { background: rgba(255, 255, 255, 0.08); }
.pick-row[aria-checked="true"] { background: rgba(255, 255, 255, 0.14); color: #fff; }
.pick-row .tile { --tile: 34px; border-radius: 10px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); }
.pick-row .tile .glyph { width: 62%; }
.pick-row em { font-style: normal; font-weight: 700; font-size: 13.5px; color: rgba(255, 255, 255, 0.5); font-variant-numeric: tabular-nums; }
.pick-menu-head.is-dlc { color: #8db8ff; }
.pick-option.is-dlc[aria-checked="true"] { box-shadow: inset 0 0 0 1.5px #5c9cff; }

.pills { display: flex; gap: 8px; }
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 54px;
  padding: 0 20px 0 16px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 19px;
  font-variant-numeric: tabular-nums;
  background: rgba(8, 10, 9, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
}
.pill .glyph { width: 20px; filter: none; }
.pill.p-dmg .glyph { color: #ff6b8e; }
.pill.p-sta .glyph { color: #5fe0a0; }
.pill.p-combo { color: #ffd98a; }
.pill[hidden] { display: none; }
.pane-tag {
  position: absolute;
  left: 22px;
  top: 20px;
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
}

/* ── How to play: the training ground ──────────────────────────────── */
.dojo { margin-top: var(--head-gap); text-align: center; }
.dojo-stage {
  /* The HUD's unit, as in the hero — a share of the stage's own width. */
  --hud: clamp(4.6px, 0.58cqw, 7px);
  container-type: inline-size;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  height: clamp(400px, 43vw, 540px);
  background: #07080b;
  text-align: left;
}
.dojo-pane { position: relative; overflow: hidden; min-width: 0; }
/* Your hand: the phone over the lined floor, as the Полигон draws it. */
.dojo-hand { background: radial-gradient(75% 60% at 50% 58%, #1c2029, #07080b 78%); }
.dojo-hand::after { content: ""; position: absolute; inset: 0 0 0 auto; width: 1px; background: rgba(255, 255, 255, 0.08); }
.dojo-phone { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 0.5s ease; }
.dojo-stage.has-phone .dojo-phone { opacity: 1; }
.dojo-stage.no-phone { grid-template-columns: minmax(0, 1fr); }
.dojo-stage.no-phone .dojo-hand { display: none; }
/* A combo's steps over the phone, the one being swung lit. */
.dojo-steps { position: absolute; right: 18px; top: 14px; display: flex; gap: 6px; }
.dojo-steps .tile { --tile: 36px; border-radius: 11px; opacity: 0.4; transition: opacity 0.2s, scale 0.25s cubic-bezier(0.3, 1.5, 0.5, 1); }
.dojo-steps .tile.is-now { opacity: 1; scale: 1.12; }
.dojo-steps .tile .glyph { width: 62%; }

.dojo-room {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  filter: brightness(1.05) saturate(1.1);
}
/* The floor's shade under him, and a little dark at both ends. */
.dojo-fight::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(26% 8% at 50% 80%, rgba(0, 0, 0, 0.55), transparent 70%),
    linear-gradient(180deg, rgba(10, 4, 6, 0.5) 0%, rgba(10, 4, 6, 0) 24%, rgba(10, 4, 6, 0) 62%, rgba(10, 4, 6, 0.62) 100%);
}
.dojo-foe-img {
  position: absolute;
  left: 50%;
  bottom: 20%;
  width: auto;
  height: 56%;
  max-width: none;
  translate: -50% 0;
  transform-origin: 50% 92%;
  filter: drop-shadow(0 16px 16px rgba(0, 0, 0, 0.4));
  transition: opacity 0.4s ease;
}
.dojo-foe-3d, .dojo-sword {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.dojo-foe-3d { filter: saturate(1.08) contrast(1.05); }
.dojo-stage.is-3d .dojo-foe-3d, .dojo-stage.has-sword .dojo-sword { opacity: 1; }
.dojo-stage.is-3d .dojo-foe-img { opacity: 0; }
.dojo-stage.is-swapping .dojo-foe-3d, .dojo-stage.is-swapping .dojo-foe-img { opacity: 0; }
.dojo-foe-img.is-hit { animation: flinch 0.38s ease-out; }
/* His health, the one bar of the fight. */
.dojo-hp {
  --hp: 1;
  position: absolute;
  left: 50%;
  top: 22px;
  translate: -50% 0;
  width: min(34%, 220px);
  height: calc(var(--hud) * 2);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  box-shadow: 0 0 0 calc(var(--hud) * 0.22) rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
.dojo-hp i {
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(var(--hp) * 100%);
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(235, 92, 51, 0.8), #eb5c33);
  transition: width 0.35s ease-out;
}
/* The hero's disc, here on the fight's left with its name beside it. */
.dojo-fight .hud-attack { left: 6%; right: auto; top: 30%; flex-direction: row; align-items: center; gap: calc(var(--hud) * 1.2); }
.dojo-fight .atk-name { max-width: none; white-space: nowrap; font-size: calc(var(--hud) * 2.4); }

/* What the blow did: the number, and what the game calls it — in the
   corner over the blade's tip, away from his face. */
.dojo-pop {
  position: absolute;
  right: 6%;
  top: 15%;
  display: grid;
  justify-items: end;
  gap: 3px;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transform-origin: 100% 50%;
}
.dojo-pop b {
  font-weight: 900;
  font-size: calc(var(--hud) * 6.8);
  line-height: 1;
  background: linear-gradient(#fff, #ffd98a);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.7));
}
.dojo-pop span {
  padding: calc(var(--hud) * 0.5) calc(var(--hud) * 1.4);
  border-radius: 999px;
  font-weight: 900;
  font-size: calc(var(--hud) * 1.9);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #2a1a00;
  background: linear-gradient(#ffe08a, #f4b13c);
}
.dojo-pop span:empty { display: none; }
.dojo-pop[data-tone="block"] b { background-image: linear-gradient(#fff, #9fdcff); }
.dojo-pop[data-tone="block"] span { color: #04243a; background: linear-gradient(#bfe9ff, #62bdf5); }
.dojo-pop.is-on { animation: pop 1.1s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
@keyframes pop {
  0% { opacity: 0; scale: 0.4; translate: 0 calc(var(--hud) * 3); }
  16% { opacity: 1; scale: 1.12; translate: 0 0; }
  28% { scale: 1; }
  72% { opacity: 1; translate: 0 0; }
  100% { opacity: 0; translate: 0 calc(var(--hud) * -4); }
}
/* The numbers ride beside the name, under the phone: the fight's own
   corner is the sword's. */
.dojo .stage-bar { justify-content: flex-start; align-items: center; }
@keyframes swap-in { from { opacity: 0; translate: 0 6px; } }

/* ── Bestiary: one at a time ───────────────────────────────────────── */
.lair {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(32px, 5.5vw, 84px);
  /* From the top: the name stays where it is as the words under it change. */
  align-items: start;
  margin-top: var(--head-gap);
  text-align: left;
}
.lair-stage {
  height: clamp(460px, 48vw, 620px);
  background:
    radial-gradient(60% 40% at 50% 84%, rgba(var(--tint), 0.34), transparent 72%),
    radial-gradient(40% 9% at 50% 82%, rgba(0, 0, 0, 0.5), transparent 70%),
    linear-gradient(180deg, #15171d, #0b0c10);
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  transition: background 0.4s;
}
.lair-stage:active { cursor: grabbing; }
/* Him, on a layer of his own (a phone shrinks it when its sheet opens). */
.lair-figure { position: absolute; inset: 0; transform-origin: 50% 0; }
.lair-grip { display: none; }
.beast-img {
  position: absolute;
  left: 50%;
  bottom: 18%;
  width: auto;
  height: 60%;
  max-width: none;
  translate: -50% 0;
  filter: drop-shadow(0 16px 16px rgba(0, 0, 0, 0.45));
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.beast-3d {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.45s ease;
  pointer-events: none;
}
.lair-stage.is-3d .beast-3d { opacity: 1; }
/* (While the next one's model is being read in, his picture stands there —
   not nothing: the stage went bare between two creatures.) */
.lair-stage.is-3d:not(.is-swapping) .beast-img { opacity: 0; }
.lair-stage.is-swapping .beast-3d { opacity: 0; }
/* The two sets: what the game ships with, and the Day One DLC. */
.seg {
  position: absolute;
  left: 18px;
  top: 18px;
  z-index: 3;
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(8, 10, 9, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.seg button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 15px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 14.5px;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.7);
  transition: background 0.25s, color 0.25s;
}
.seg button small { font-weight: 700; font-size: 12.5px; opacity: 0.7; }
.seg button .glyph { width: 15px; filter: none; color: currentColor; }
.seg button:hover { color: #fff; }
.seg button[aria-selected="true"] { background: #f3f0e9; color: #0c0c0e; }
.seg button[data-group="dlc"][aria-selected="true"] { background: var(--dlc); color: #fff; }
/* His health over his head (--head: where the model's head lands, set by
   sections3d.js; the portrait's own by default). */
.lair-hp {
  position: absolute;
  left: 50%;
  top: max(74px, calc(var(--head, 0.2) * 100% - 38px));
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 7px;
  transition: top 0.35s ease, opacity 0.3s;
  pointer-events: none;
}
.lair-hp[hidden] { display: none; }
.lair-hp svg { width: 19px; height: 19px; color: #ff5a4a; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); }
.lair-hp i {
  display: grid;
  place-items: center;
  min-width: 124px;
  height: 20px;
  padding: 0 10px;
  border-radius: 999px;
  font-style: normal;
  background: linear-gradient(90deg, #f0603a, #e23d4c);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.16), 0 6px 14px -6px rgba(0, 0, 0, 0.7);
}
.lair-hp b { font-weight: 900; font-size: 12.5px; font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45); }
/* The dungeon's ranks, I–IV: a column on the stage's edge. */
.ranks {
  position: absolute;
  right: 18px;
  top: 50%;
  translate: 0 -50%;
  z-index: 3;
  display: grid;
  gap: 4px;
  padding: 5px;
  border-radius: 999px;
  background: rgba(8, 10, 9, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.ranks button {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  font-family: "Zagadka", "Onest", serif;
  font-size: 18px;
  color: rgba(255, 255, 255, 0.7);
  transition: background 0.2s, color 0.2s;
}
/* (What a finger lands on is wider than what's drawn: a phone's ranks are
   32px across, 4 apart — the gaps are theirs. The same for the two sets'
   switch and the pace's three.) */
:is(.ranks, .seg, .fit-pace) button { position: relative; }
:is(.ranks, .seg, .fit-pace) button::after { content: ""; position: absolute; inset: -4px -2px; }
.ranks button:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.ranks button[aria-checked="true"] { background: #f3f0e9; color: #0c0c0e; }
.ranks::before {
  content: "ранг";
  justify-self: center;
  padding: 5px 0 1px;
  font-weight: 700;
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
/* (The English page's: en.html, tools/i18n.py — which checks that every
   word the stylesheet itself writes has one.) */
:lang(en) .ranks::before { content: "rank"; }
.turn-hint {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 14px;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
  transition: opacity 0.4s;
}
.turn-hint svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.is-turned .turn-hint, .no-3d .turn-hint { opacity: 0; }

/* Beside the stage, in plain words. */
.lair-info { display: grid; gap: 26px; min-width: 0; padding-top: clamp(8px, 2.4vw, 36px); }
/* (His name in the page's own face — not the titles' — as every other
   heading inside a block is.) */
.lair-info h3 {
  margin-top: -12px;
  font-weight: 800;
  font-size: clamp(38px, 4.4vw, 58px);
  letter-spacing: -0.035em;
  line-height: 1.02;
  color: rgb(var(--tint));
}
.lair-about { margin-top: -10px; font-weight: 500; font-size: clamp(17px, 1.5vw, 19px); line-height: 1.55; color: var(--muted); text-wrap: pretty; }
.lair-info small {
  display: block;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
/* The app's pair under the name: what breaks him, what he shrugs off. */
.axes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.axis { padding: 14px 18px 15px; border-radius: 22px; background: rgba(255, 255, 255, 0.06); }
.axis b { display: block; margin-top: 4px; font-weight: 800; font-size: 18px; letter-spacing: -0.01em; }
.axis b::first-letter { text-transform: uppercase; }
.axis.is-weak { background: rgba(255, 190, 60, 0.13); }
.axis.is-weak small { color: rgba(255, 210, 126, 0.75); }
.axis.is-weak b { color: #ffd27e; }
.axes[hidden], .lair-trick[hidden] { display: none; }
.lair-trick { padding-left: 18px; border-left: 2px solid rgba(var(--tint), 0.7); }
.lair-trick small { color: rgb(var(--tint)); }
.lair-trick p { margin-top: 6px; font-weight: 500; font-size: 16.5px; line-height: 1.5; color: rgba(255, 255, 255, 0.84); text-wrap: pretty; }
.lair-moves .chips { margin-top: 12px; }
.lair-moves .chip.is-on { background: #f3f0e9; color: #0c0c0e; }
.lair-moves .chip.is-on small { color: #c23a14; }
.no-3d ~ .lair-info .lair-moves button.chip { pointer-events: none; }
.lair-dlc { margin-top: -8px; }
.lair-info .swap { animation: swap-in 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }

/* ── Dungeon: the run, as a map ────────────────────────────────────── */
/* The section is ONE block, and the block is the dungeon: the board fills
   it as its background, and the section's heading stands inside, over the
   board's top (.map-top) — the dark over the floor thinning out under the
   words, the rooms below. */
.run { text-align: left; }
/* The map: the game's own board of a run — rooms cut like a jigsaw's pieces
   and locked edge to edge — drawn in 3D (sections3d.js, RunBoard) in a
   window that stays put while the map slides sideways under it; the waves'
   buttons ride a layer over it (script.js: .map-nodes), each on its piece.
   Until the board is in — and where there's no WebGL — the waves are discs
   on the dark, as they were. Cheap to slide on purpose: no filters, no
   blurred shadows and no backdrop blur on or over it. */
.map-wrap {
  --top: 78px;      /* kept clear for what lies on the map: the bar above */
  --node: 88px;
  --paper: #09080b;
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  border-radius: 36px;
  overflow: hidden;
  background: var(--paper);
}
/* Under the heading: the room the board itself takes. (script.js lays the
   board out in what's left of the block under the heading — it measures
   the heading — so the block is the heading's height and this.) */
.map-wrap::after { content: ""; flex: none; height: clamp(410px, 37vw, 520px); }
/* The block's edge, over everything in it. */
.map-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(240, 222, 180, 0.16);
  pointer-events: none;
}
.map {
  position: absolute;
  inset: 0;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
/* The heading over it: a drag goes through to the map. */
.map-top {
  position: relative;
  z-index: 2;
  padding: clamp(26px, 3.2vw, 44px) clamp(22px, 3.2vw, 44px) 60px;
  background: linear-gradient(180deg, rgba(9, 8, 11, 0.94), rgba(9, 8, 11, 0.8) 58%, rgba(9, 8, 11, 0));
  pointer-events: none;
}
/* (Narrower than the block by the new-run button's width and then some.) */
.map-head { max-width: min(700px, 100% - 190px); }
.map::-webkit-scrollbar { display: none; }
.map.is-dragging { cursor: grabbing; }
.map.is-dragging .node { pointer-events: none; }
.map-inner { position: relative; height: 100%; }
.map-view { position: sticky; left: 0; top: 0; height: 100%; overflow: hidden; }
.map-3d { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 0.6s ease; pointer-events: none; }
.map.is-3d .map-3d { opacity: 1; }
.map-nodes { position: absolute; left: 0; top: 0; height: 100%; will-change: transform; }

/* A wave: where script.js puts it (left / top are its middle). */
.node {
  position: absolute;
  translate: -50% calc(var(--node) / -2);
  display: grid;
  justify-items: center;
  gap: 7px;
  padding: 0;
  font-weight: 800;
  font-size: 13px;
  color: rgba(246, 232, 200, 0.7);
}
/* The enemy standing in its room. */
.node-disc {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--node);
  height: var(--node);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 110%, rgba(var(--tint, 255, 255, 255), 0.5), rgba(12, 10, 20, 0.25) 70%),
    var(--room, none) center / cover,
    #17141f;
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px rgba(240, 222, 180, 0.6);
  transition: transform 0.25s cubic-bezier(0.3, 1.5, 0.5, 1);
}
.node-disc img { width: 104%; max-width: none; height: 104%; margin-top: -8%; object-fit: contain; pointer-events: none; }
.node:hover .node-disc, .node:focus-visible .node-disc { transform: translateY(-4px) scale(1.06); box-shadow: 0 0 0 3px var(--paper), 0 0 0 5.5px #fff; }
.node:hover, .node:focus-visible { color: #fff; }
.node:active .node-disc { transform: scale(0.96); }
/* A boss: bigger, in gold, crowned. */
.node.is-boss { --node: 118px; color: #ffd98a; }
.node.is-boss .node-disc, .node.is-boss:hover .node-disc, .node.is-boss:focus-visible .node-disc { box-shadow: 0 0 0 3px var(--paper), 0 0 0 7px #f4b13c; }
.node.is-boss .node-disc::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -23px;
  width: 32px;
  height: 23px;
  translate: -50% 0;
  background: #f4b13c;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.5 18.5h17l1.2-10.2-5.4 3.6L12 5l-4.3 6.9-5.4-3.6z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.5 18.5h17l1.2-10.2-5.4 3.6L12 5l-4.3 6.9-5.4-3.6z'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* A mini-game, the angel, the summit: a tile instead of a face. */
.node.is-mini, .node.is-mark { --node: 70px; }
.node.is-mini .node-disc, .node.is-mark .node-disc { border-radius: 30%; background: var(--g-orange); box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.4), 0 0 0 3px var(--paper); }
.node.is-mini .glyph, .node.is-mark .glyph { width: 54%; filter: none; }
.node.is-mark { color: #f6e8c8; font-size: 12.5px; letter-spacing: 0.04em; }
.node[data-mark="angel"] .node-disc { background: linear-gradient(145deg, #fff6d8, #ffd24a); }
.node[data-mark="angel"] .glyph { color: #7a4a00; }
.node[data-mark="summit"] .node-disc { background: var(--g-purple); }
/* Under the disc: the wave's number, and his rank on it. */
.node-tag { display: inline-flex; align-items: center; gap: 6px; }
.node-tag .glyph { display: none; }
.node.is-gate { display: none; }
.node-rank {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 22px;
  padding: 0 6px;
  border-radius: 999px;
  font-family: "Zagadka", "Onest", serif;
  font-style: normal;
  font-weight: 400;
  font-size: 15px;
  line-height: 1;
  color: #fff;
  background: #2a2638;
}

/* Over the board: the button IS its piece — as wide as the room, as tall as
   whoever stands in it, its middle the piece's own (--u: a unit of the
   board in pixels, from script.js) — and all it shows is the plate with the
   wave's number, on the piece's near corner. */
.map.is-3d .node { display: block; width: calc(var(--u) * 2.3); height: calc(var(--u) * 2.5); translate: -50% -56%; color: #fff; }
.map.is-3d .node.is-gate { pointer-events: none; }
.map.is-3d .node-disc { display: none; }
.map.is-3d .node-tag {
  position: absolute;
  left: 50%;
  top: calc(56% + var(--u) * 0.98);
  translate: -50% -50%;
  height: 30px;
  padding: 0 11px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 14px;
  line-height: 1;
  white-space: nowrap;
  color: #fff;
  background: rgba(14, 12, 19, 0.88);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.2);
  transition: background 0.2s, color 0.2s, scale 0.25s cubic-bezier(0.3, 1.5, 0.5, 1);
}
.map.is-3d .node-tag .glyph { display: block; width: 15px; height: 15px; filter: none; }
.map.is-3d .node-tag .node-rank { margin-right: -5px; }
.map.is-3d .node.is-boss .node-tag { padding-left: 9px; color: #1c1304; background: #f4b13c; box-shadow: none; }
.map.is-3d .node.is-boss .node-tag::before {
  content: "";
  width: 17px;
  height: 13px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.5 18.5h17l1.2-10.2-5.4 3.6L12 5l-4.3 6.9-5.4-3.6z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.5 18.5h17l1.2-10.2-5.4 3.6L12 5l-4.3 6.9-5.4-3.6z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.map.is-3d .node.is-mini .node-tag { background: #e8742c; box-shadow: none; }
.map.is-3d .node[data-mark="angel"] .node-tag { color: #5a3a00; background: #ffe08a; box-shadow: none; }
.map.is-3d .node[data-mark="summit"] .node-tag { background: #7642ee; box-shadow: none; }
.map.is-3d .node.is-gate .node-tag { color: rgba(255, 255, 255, 0.72); }
.map.is-3d button.node:hover .node-tag, .map.is-3d button.node:focus-visible .node-tag { color: #14101c; background: #fff; scale: 1.1; }
.map.is-3d button.node:focus-visible { outline: none; }
.map.is-3d button.node:focus-visible .node-tag { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.45); }

/* On the map, over its top edge: a new run, on the right. Solid plaques —
   a blur over a sliding map costs every frame. */
.map-bar {
  position: absolute;
  left: 14px;
  right: 14px;
  top: 14px;
  z-index: 3;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 10px;
  pointer-events: none;
}
.map-bar > * { pointer-events: auto; }
.map-roll, .map-nav {
  color: #f6e8c8;
  background: rgba(19, 16, 23, 0.94);
  box-shadow: inset 0 0 0 1px rgba(240, 226, 255, 0.18);
}
.map-roll {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 50px;
  padding: 0 20px 0 15px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
  transition: background 0.2s;
}
.map-roll svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: rotate 0.5s cubic-bezier(0.3, 1.4, 0.5, 1); }
.map-roll:hover, .map-nav:hover { background: #2a2433; }
.map-roll:active svg { rotate: 200deg; }
/* The map's own arrows, for a mouse. */
/* (--clear: how far down the heading reaches, as script.js found it — the
   arrows stand by the middle of the board, not of the block.) */
.map-nav {
  position: absolute;
  top: calc(var(--clear, var(--top)) + (100% - var(--clear, var(--top))) / 2);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  translate: 0 -50%;
  border-radius: 50%;
  transition: opacity 0.25s, background 0.2s;
}
.map-nav[data-dir="-1"] { left: 14px; }
.map-nav[data-dir="1"] { right: 14px; }
.map-nav svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.map-nav[disabled] { opacity: 0; pointer-events: none; }
@media (hover: none) { .map-nav { display: none; } }

/* A wave, opened. */
.wave {
  position: fixed;
  inset: 0;
  width: min(780px, calc(100vw - 32px));
  max-height: calc(calc(100 * var(--svh)) - 32px);
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: 36px;
  overflow: hidden;
  color: var(--ink);
  background: #14121c;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 60px 120px -30px #000;
  text-align: left;
}
.wave[open] {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  /* Out of the tapped wave: --ox / --oy are where it is (script.js). */
  transform-origin: var(--ox, 50%) var(--oy, 50%);
  animation: wave-in 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.1);
}
.wave.is-closing { animation: wave-out 0.16s ease-in forwards; }
.wave::backdrop { background: rgba(4, 5, 8, 0.78); animation: fade-in 0.25s ease-out; }
@keyframes wave-in { from { opacity: 0; scale: 0.5; } }
@keyframes wave-out { to { opacity: 0; scale: 0.92; } }
@keyframes fade-in { from { opacity: 0; } }
.wave-stage {
  position: relative;
  min-height: 360px;
  overflow: hidden;
  background: radial-gradient(70% 40% at 50% 88%, rgba(var(--tint, 255, 150, 70), 0.4), transparent 72%), linear-gradient(180deg, #1b1826, #0d0b13);
}
.wave-room { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; filter: brightness(0.8) saturate(1.05); }
.wave-stage::after { content: ""; position: absolute; inset: 0; background: radial-gradient(34% 9% at 50% 84%, rgba(0, 0, 0, 0.5), transparent 70%); pointer-events: none; }
.run-img { position: absolute; z-index: 1; left: 50%; bottom: 12%; width: auto; height: 66%; max-width: none; translate: -50% 0; transition: opacity 0.35s ease; filter: drop-shadow(0 10px 10px rgba(0, 0, 0, 0.45)); }
.run-3d { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 0.4s ease; }
.wave-stage.is-3d .run-3d { opacity: 1; }
.wave-stage.is-3d .run-img, .wave-stage.is-swapping .run-img, .wave-stage.is-swapping .run-3d { opacity: 0; }
.wave-stage .tile { position: absolute; z-index: 1; inset: 0; margin: auto; --tile: 124px; border-radius: 30%; }
.wave-stage .tile .glyph { width: 54%; }
.wave-stage .tile.t-angel { background: linear-gradient(145deg, #fff6d8, #ffd24a); }
.wave-stage .tile.t-angel .glyph { color: #7a4a00; filter: none; }

.wave-info { display: grid; align-content: center; gap: 16px; padding: clamp(24px, 3.4vw, 40px); padding-right: clamp(30px, 4vw, 48px); }
.wave-info small { font-weight: 700; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255, 255, 255, 0.5); }
.wave-info h3 {
  margin-top: -8px;
  font-family: "Zagadka", "Onest", serif;
  font-weight: 400;
  font-size: clamp(34px, 4vw, 48px);
  line-height: 1.02;
  color: rgb(var(--tint, 243, 240, 233));
}
.wave-info > p { font-weight: 500; font-size: 17px; line-height: 1.5; color: rgba(243, 240, 233, 0.8); text-wrap: pretty; }
.wave-info .pills { flex-wrap: wrap; }
.wave-info .pill { height: 42px; padding: 0 15px 0 12px; font-size: 16px; background: rgba(255, 255, 255, 0.07); border: 0; -webkit-backdrop-filter: none; backdrop-filter: none; }
.wave-info .pill .glyph, .wave-info .pill svg { width: 17px; height: 17px; }
.wave-info .pill.p-hp svg { color: #ff5a4a; }
.wave-info .pill.p-chest { color: #ffd98a; background: rgba(255, 190, 60, 0.14); }
.wave-info .rank-pill { color: #fff; background: #2a2638; font-family: "Zagadka", "Onest", serif; font-weight: 400; font-size: 18px; }
.node-rank[data-rank="1"], .wave-info .rank-pill[data-rank="1"] { background: #3f5fd0; }
.node-rank[data-rank="2"], .wave-info .rank-pill[data-rank="2"] { background: #8a4be0; }
.node-rank[data-rank="3"], .wave-info .rank-pill[data-rank="3"] { background: #e2572e; }
.rank-pill small { font-family: "Onest", sans-serif; font-weight: 700; font-size: 11px; letter-spacing: 0.08em; color: rgba(255, 255, 255, 0.7); }
/* The room's rule (or a gift): a quieter note under the rest. */
.wave-note { padding-left: 16px; border-left: 2px solid rgba(var(--tint, 255, 255, 255), 0.6); }
.wave-note b { display: block; font-weight: 700; font-size: 14px; color: var(--ink); }
.wave-note span { display: block; margin-top: 3px; font-weight: 500; font-size: 14.5px; line-height: 1.45; color: var(--muted); }
.wave-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: rgba(255, 255, 255, 0.86);
  background: rgba(255, 255, 255, 0.1);
  transition: background 0.2s;
}
.wave-close:hover { background: rgba(255, 255, 255, 0.2); }
.wave-close svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }


/* ── More: the duel, the workout, the road ─────────────────────────── */
.duel {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(32px, 5.5vw, 84px);
  align-items: center;
  margin-top: var(--head-gap);
  text-align: left;
}
.duel-copy h3, .fit h3, .road h3 { font-weight: 800; font-size: clamp(26px, 2.6vw, 34px); letter-spacing: -0.035em; line-height: 1.1; }
.duel-copy > p { margin-top: 12px; font-weight: 500; font-size: clamp(17px, 1.5vw, 19px); line-height: 1.55; color: var(--muted); text-wrap: pretty; }
.duel-steps { display: grid; gap: 2px; margin: 22px 0 0 -12px; counter-reset: step; }
.duel-steps button {
  position: relative;
  display: block;
  width: 100%;
  padding: 11px 14px 11px 50px;
  border-radius: 18px;
  text-align: left;
  counter-increment: step;
  transition: background 0.25s;
}
.duel-steps button::before {
  content: counter(step);
  position: absolute;
  left: 12px;
  top: 10px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  font-weight: 800;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.09);
  transition: background 0.25s, color 0.25s;
}
.duel-steps b { font-weight: 700; font-size: 17px; color: rgba(255, 255, 255, 0.6); transition: color 0.25s; }
.duel-steps span { display: none; margin-top: 3px; font-weight: 500; font-size: 15.5px; line-height: 1.5; color: var(--muted); }
.duel-steps button:hover b { color: #fff; }
.duel-steps button.is-on { background: rgba(255, 255, 255, 0.06); }
.duel-steps button.is-on b { color: #fff; }
.duel-steps button.is-on span { display: block; animation: swap-in 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.duel-steps button.is-on::before { background: var(--g-blue); color: #fff; }

/* The scene: the lobby's map, and on it whatever the beat is. */
.duel-scene { container-type: inline-size; }
.duel-map {
  position: relative;
  aspect-ratio: 1;
  max-width: 480px;
  margin: 0 auto;
  border-radius: 36px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 78%, rgba(90, 150, 255, 0.28), transparent 55%),
    repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.028) 0 2px, transparent 2px 15px),
    linear-gradient(180deg, #121826, #0b0e17);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.09), 0 50px 90px -50px rgba(0, 0, 0, 0.9);
}
.duel-map .ring {
  position: absolute;
  left: 50%;
  top: 78%;
  width: 46%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 1.5px solid rgba(140, 180, 255, 0.24);
  transition: opacity 0.4s;
}
.duel-map .ring:nth-child(2) { width: 92%; }
.duel-map .ring:nth-child(3) { width: 140%; }
.duel-map .sweep {
  position: absolute;
  left: 50%;
  top: 78%;
  width: 150%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(120, 170, 255, 0.34), transparent 22%);
  transition: opacity 0.4s;
}
.who {
  position: absolute;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 5px;
  translate: -50% -50%;
  transition: left 0.7s cubic-bezier(0.3, 1.1, 0.4, 1), top 0.7s cubic-bezier(0.3, 1.1, 0.4, 1), opacity 0.4s, scale 0.5s cubic-bezier(0.3, 1.4, 0.5, 1), filter 0.4s;
}
/* The game's own 3D heads (avatars.glb, AvatarHeads.portrait), on the
   race's colour as the lobby draws them. */
.who img {
  width: clamp(54px, 16cqw, 76px);
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  background: radial-gradient(circle at 50% 30%, rgb(var(--tint)), rgba(var(--tint), 0.6));
  box-shadow: 0 0 0 2.5px rgba(255, 255, 255, 0.86), 0 8px 18px -6px rgba(0, 0, 0, 0.7);
}
.who b { padding: 3px 9px; border-radius: 999px; font-weight: 800; font-size: 12.5px; white-space: nowrap; background: rgba(0, 0, 0, 0.5); }
.who small { margin-left: 5px; font-weight: 600; font-size: 11px; color: rgba(255, 255, 255, 0.6); }
.who-me { left: 50%; top: 78%; }
.who-a { left: 28%; top: 30%; }
.who-b { left: 76%; top: 46%; }
.route { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity 0.4s; }
.route path { fill: none; stroke: #ffd98a; stroke-linecap: round; stroke-dasharray: 2.4 2.4; vector-effect: non-scaling-stroke; stroke-width: 2.5px; }
.raven {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 78%;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  translate: -50% -50%;
  border-radius: 50%;
  color: #2a1a00;
  background: linear-gradient(#ffe08a, #f4b13c);
  box-shadow: 0 6px 14px -4px rgba(0, 0, 0, 0.7);
  opacity: 0;
}
.raven svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
.apart {
  position: absolute;
  left: 50%;
  top: 54%;
  display: flex;
  align-items: center;
  gap: 8px;
  translate: -50% -50%;
  font-weight: 800;
  font-size: 16px;
  opacity: 0;
  transition: opacity 0.4s;
}
.apart b { padding: 5px 12px; border-radius: 999px; color: #06301c; background: linear-gradient(#9af0b4, #38c987); }
.apart i { width: clamp(22px, 9cqw, 48px); height: 2px; border-radius: 1px; background: rgba(255, 255, 255, 0.5); }
.bout { position: absolute; inset: 0; opacity: 0; transition: opacity 0.4s; }
.bar { position: absolute; left: 14%; right: 14%; height: 10px; border-radius: 999px; background: rgba(0, 0, 0, 0.55); overflow: hidden; }
.bar i { display: block; height: 100%; width: 100%; border-radius: inherit; }
.bar-foe { top: 9%; }
.bar-foe i { background: linear-gradient(90deg, #ff7a52, #e5245a); }
.bar-me { bottom: 7%; }
.bar-me i { background: linear-gradient(90deg, #36d27a, #9dff8a); }
.bout-flash {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  padding: 7px 15px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 16px;
  white-space: nowrap;
  color: #2a1a00;
  background: linear-gradient(#ffe08a, #f4b13c);
  opacity: 0;
}
.bout-flash.is-block { color: #04243a; background: linear-gradient(#bfe9ff, #62bdf5); }
.result { position: absolute; left: 50%; top: 50%; display: grid; justify-items: center; gap: 12px; translate: -50% -50%; opacity: 0; scale: 0.8; transition: opacity 0.4s, scale 0.5s cubic-bezier(0.3, 1.4, 0.5, 1); }
.result b { font-family: "Zagadka", "Onest", serif; font-weight: 400; font-size: clamp(36px, 12cqw, 54px); line-height: 1; color: #ffe08a; text-shadow: 0 0 30px rgba(255, 200, 100, 0.6); }
.result span { padding: 10px 22px; border-radius: 999px; font-weight: 800; font-size: 14.5px; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; background: var(--g-blue); box-shadow: 0 8px 20px -8px rgba(59, 85, 245, 0.9); }

/* 1 · the challenge: the others fade, the raven flies the route. */
.duel[data-step="1"] .who-b { opacity: 0.25; scale: 0.8; filter: saturate(0.3); }
.duel[data-step="1"] .route { opacity: 1; }
.duel[data-step="1"] .sweep { opacity: 0; }
/* 2 · step apart: the two of you on one line, a gap between. */
.duel[data-step="2"] .who-b, .duel[data-step="3"] .who-b, .duel[data-step="4"] .who-b { opacity: 0; scale: 0.5; }
.duel[data-step="2"] .sweep, .duel[data-step="3"] .sweep, .duel[data-step="4"] .sweep,
.duel[data-step="2"] .ring, .duel[data-step="3"] .ring, .duel[data-step="4"] .ring { opacity: 0; }
.duel[data-step="2"] .who-me { left: 20%; top: 54%; }
.duel[data-step="2"] .who-a { left: 80%; top: 54%; }
.duel[data-step="2"] .apart { opacity: 1; }
/* 3 · the bout: him above, you below, the bars, the flashes. */
.duel[data-step="3"] .who-me, .duel[data-step="4"] .who-me { left: 50%; top: 76%; }
.duel[data-step="3"] .who-a, .duel[data-step="4"] .who-a { left: 50%; top: 27%; }
.duel[data-step="3"] .bout { opacity: 1; }
/* 4 · the result. */
.duel[data-step="4"] .who-a { opacity: 0.4; filter: saturate(0.2); scale: 0.86; }
.duel[data-step="4"] .who-me { scale: 1.1; }
.duel[data-step="4"] .result { opacity: 1; scale: 1; }

/* The workout and the road, side by side: a title, one big figure, one
   line — and the thing to play with. */
.pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(40px, 7vw, 110px);
  margin-top: clamp(72px, 9vw, 130px);
  text-align: left;
}
.figure { display: flex; align-items: baseline; gap: 10px; margin-top: 18px; line-height: 0.95; }
.figure b { font-weight: 900; font-size: clamp(72px, 8.4vw, 112px); letter-spacing: -0.05em; font-variant-numeric: tabular-nums; }
.figure span { font-weight: 800; font-size: clamp(22px, 2.4vw, 30px); letter-spacing: -0.02em; }
.figure small { align-self: center; font-weight: 700; font-size: clamp(28px, 3vw, 40px); opacity: 0.55; }
.fig-green { color: #a6ff3c; }
.fig-purple { color: #c79bff; }
.figure-note { margin-top: 10px; font-weight: 500; font-size: clamp(17px, 1.5vw, 19px); line-height: 1.45; color: var(--muted); }
.figure-note b { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.fit-range { display: block; width: 100%; height: 32px; margin-top: 26px; accent-color: #a6ff3c; }
.fit-pace { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; margin-top: 12px; padding: 4px; border-radius: 999px; background: rgba(0, 0, 0, 0.34); box-shadow: inset 0 0 0 1px var(--edge); }
.fit-pace button { padding: 11px 4px; border-radius: 999px; font-weight: 700; font-size: 15px; color: rgba(255, 255, 255, 0.66); transition: background 0.2s, color 0.2s; }
.fit-pace button[aria-checked="true"] { background: #f3f0e9; color: #0c0c0e; }

/* A little chest, drawn. */
.chest-box {
  position: relative;
  flex: none;
  width: 40px;
  height: 30px;
  border-radius: 6px 6px 5px 5px;
  background: linear-gradient(#c98a3a, #8d5420);
  box-shadow: inset 0 0 0 2px #5d3613, inset 0 -9px 0 rgba(0, 0, 0, 0.16);
}
.chest-box::before {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  top: -8px;
  height: 14px;
  border-radius: 9px 9px 2px 2px;
  background: linear-gradient(#e0a24a, #b06f28);
  box-shadow: inset 0 0 0 2px #5d3613;
  transform-origin: 50% 100%;
  transition: transform 0.3s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.chest-box i { position: absolute; left: 50%; top: 3px; width: 9px; height: 11px; margin-left: -4.5px; border-radius: 2px; background: #ffd24a; box-shadow: inset 0 0 0 1.5px #8a5a10; }

/* The road: the next few levels and what waits on them. */
.road-steps { position: relative; display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; margin-top: 34px; }
.road-steps::before { content: ""; position: absolute; left: 6%; right: 6%; top: 27px; height: 4px; border-radius: 2px; background: linear-gradient(90deg, #b879ff 0 42%, rgba(255, 255, 255, 0.12) 42%); }
.road-steps li { position: relative; display: grid; justify-items: center; gap: 8px; }
.road-steps .tile { --tile: 56px; border-radius: 17px; }
.road-steps .glyph { width: 58%; }
.road-steps .chest-box { scale: 0.74; }
.road-steps b { font-weight: 800; font-size: 14px; color: rgba(255, 255, 255, 0.5); }
.road-steps li:not(.is-done):not(.is-ready) .tile { filter: saturate(0.2) brightness(0.6); }
.road-steps .is-done .tile::after {
  content: "";
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #13a86a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12.5 10.5 17 18 8'/%3E%3C/svg%3E") center / 11px no-repeat;
  box-shadow: 0 0 0 2px #0e1210;
}
.road-steps .is-ready b { color: #ffd98a; }
.road-steps .is-ready .tile { box-shadow: 0 0 0 2.5px #ffd24a, 0 0 22px -2px rgba(255, 210, 74, 0.8); }


/* ── FAQ ───────────────────────────────────────────────────────────── */
/* Its title at the left, as the others'; the questions beside it, the width
   a line of an answer reads at. (On a phone: under it.) */
.faq { display: grid; grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.38fr); gap: clamp(28px, 4vw, 64px); align-items: start; }
.faq-list { display: grid; gap: 10px; }
.faq details {
  border-radius: 22px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--edge);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.faq summary {
  position: relative;
  padding: 20px 60px 20px 24px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 18px;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  font-weight: 500;
  font-size: 20px;
  transition: rotate 0.3s;
}
.faq details[open] summary::after { rotate: 45deg; }
.faq details p { padding: 0 24px 22px; color: var(--muted); font-weight: 500; font-size: 16px; line-height: 1.55; text-wrap: pretty; }
.faq details a { color: var(--ink); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.35); text-underline-offset: 4px; }

/* ── Footer — black, dot grid, arc of tiles ────────────────────────── */
.footer {
  position: relative;
  margin-top: clamp(60px, 8vw, 110px);
  padding-top: clamp(90px, 11vw, 140px);
  color: #fff;
  /* (Out of the wall, not across it: the page's dark runs into the footer's.) */
  background: linear-gradient(180deg, transparent, var(--night) 150px);
  overflow: hidden;
  isolation: isolate;
}
.footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(rgba(255, 255, 255, 0.13) 1px, transparent 1.4px) 0 0 / 22px 22px;
  -webkit-mask: linear-gradient(180deg, transparent, #000 150px, rgba(0, 0, 0, 0.35) 70%, #000);
  mask: linear-gradient(180deg, transparent, #000 150px, rgba(0, 0, 0, 0.35) 70%, #000);
}
.footer-cta { text-align: center; padding: 0 var(--gutter); }
.footer-cta .lede { margin-inline: auto; }
.footer-cta .btn { margin-top: 30px; }
.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 32px 72px;
  width: min(var(--page), calc(100% - 2 * var(--gutter)));
  margin: clamp(70px, 9vw, 110px) auto 0;
  padding-top: 36px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.footer-links .wordmark { margin-right: auto; }
.footer-links nav { display: grid; gap: 10px; }
.footer-links nav b { font-weight: 700; font-size: 14px; color: rgba(255, 255, 255, 0.5); }
/* (A finger's worth of height each: the gap between two links is theirs.) */
.footer-links nav a { font-weight: 500; font-size: 15.5px; color: rgba(255, 255, 255, 0.85); padding-block: 5px; margin-block: -5px; }
.footer-links nav a:hover { color: #fff; }
.legal {
  width: min(var(--page), calc(100% - 2 * var(--gutter)));
  margin: 40px auto 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.55);
}

/* Tiles sit on a big circle whose centre is far below the page, so they
   bow upward around the icon and the outer ones fall off the bottom. */
.arc {
  --R: clamp(430px, 62vw, 780px);
  --big: clamp(76px, 10.5vw, 148px);
  position: relative;
  height: calc(var(--big) * 1.9);
  margin-top: clamp(40px, 6vw, 70px);
}
.arc .tile {
  --tile: var(--big);
  position: absolute;
  left: calc(50% + sin(var(--a) * 1deg) * var(--R));
  top: calc((1 - cos(var(--a) * 1deg)) * var(--R) + var(--big) * 0.25);
  translate: -50% 0;
  rotate: calc(var(--a) * 1deg);
  border-radius: 24%;
}
.arc-icon {
  position: absolute;
  left: 50%;
  top: 0;
  width: calc(var(--big) * 1.3);
  translate: -50% 0;
  filter: drop-shadow(0 0 60px rgba(255, 170, 80, 0.35));
}

/* ── Motion ────────────────────────────────────────────────────────── */
.js .reveal {
  opacity: 0;
  translate: 0 26px;
  transition: opacity 0.8s cubic-bezier(0.2, 0.8, 0.2, 1), translate 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.js .reveal.is-in { opacity: 1; translate: 0 0; }
/* (script.js, which reveals them, not to be had: shown as they stand.) */
.no-script .reveal { opacity: 1; translate: 0 0; }

@media (prefers-reduced-motion: no-preference) {
  /* The forest breathes: fireflies drift, the goblin bobs in his stance. */
  .fireflies i { animation: firefly var(--t) ease-in-out var(--d) infinite; }
  @keyframes firefly {
    0%, 100% { translate: 0 0; opacity: 0.15; }
    30% { opacity: 0.9; }
    50% { translate: 26px -34px; opacity: 0.5; }
    75% { translate: -14px -12px; opacity: 0.85; }
  }
  .foe:not(.is-3d) { animation: bob 2.6s ease-in-out infinite; }
  @keyframes bob { 50% { translate: -50% -1.2%; } }
  .quest-bg { animation: drift 30s ease-in-out infinite alternate; }
  /* The pitch arrives at once (it's above the fold — no scroll reveal). */
  .quest-copy > * { animation: quest-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .quest-copy > :nth-child(2) { animation-delay: 0.06s; }
  .quest-copy > :nth-child(3) { animation-delay: 0.12s; }
  .quest-copy > :nth-child(4) { animation-delay: 0.18s; }
  .quest-copy > :nth-child(5) { animation-delay: 0.24s; }
  @keyframes quest-in { from { opacity: 0; translate: 0 14px; } }
  @keyframes drift { to { scale: 1.06; } }

  /* The duel's map: the sweep turns, the raven flies its route, the bout
     trades a blow and a block. */
  .duel-map .sweep { animation: sweep 3.4s linear infinite; }
  @keyframes sweep { to { rotate: 360deg; } }
  .duel[data-step="0"] :is(.who-a, .who-b) img { animation: blip 3.4s ease-in-out infinite; }
  .duel[data-step="0"] .who-b img { animation-delay: -1.3s; }
  @keyframes blip { 0%, 60%, 100% { box-shadow: 0 0 0 2.5px rgba(255, 255, 255, 0.86), 0 8px 18px -6px rgba(0, 0, 0, 0.7), 0 0 0 0 rgba(140, 180, 255, 0.5); } 30% { box-shadow: 0 0 0 2.5px rgba(255, 255, 255, 0.86), 0 8px 18px -6px rgba(0, 0, 0, 0.7), 0 0 0 14px rgba(140, 180, 255, 0); } }
  .duel[data-step="1"] .route path { animation: march 0.9s linear infinite; }
  @keyframes march { to { stroke-dashoffset: -9.6; } }
  .duel[data-step="1"] .raven { animation: raven 2.6s cubic-bezier(0.4, 0, 0.3, 1) infinite; }
  @keyframes raven {
    0% { left: 50%; top: 78%; opacity: 0; scale: 0.5; }
    12% { opacity: 1; scale: 1; }
    45% { left: 37%; top: 52%; }
    82% { left: 29%; top: 33%; opacity: 1; scale: 1; }
    100% { left: 28%; top: 30%; opacity: 0; scale: 0.6; }
  }
  .duel[data-step="3"] .bar-foe i { animation: drain 4.2s ease-out infinite; }
  @keyframes drain { 0%, 10% { width: 100%; } 16%, 100% { width: 82%; } }
  .duel[data-step="3"] .bout-flash { animation: flash-a 4.2s ease-out infinite; }
  .duel[data-step="3"] .bout-flash.is-block { animation-name: flash-b; }
  @keyframes flash-a { 0%, 8% { opacity: 0; top: 52%; scale: 0.6; } 13% { opacity: 1; top: 44%; scale: 1.08; } 17%, 34% { opacity: 1; scale: 1; } 42%, 100% { opacity: 0; top: 40%; } }
  @keyframes flash-b { 0%, 54% { opacity: 0; top: 50%; scale: 0.6; } 59% { opacity: 1; top: 58%; scale: 1.08; } 63%, 80% { opacity: 1; scale: 1; } 88%, 100% { opacity: 0; top: 62%; } }
  .duel[data-step="3"] .who-a { animation: lunge-a 4.2s ease-in-out infinite; }
  .duel[data-step="3"] .who-me { animation: lunge-me 4.2s ease-in-out infinite; }
  @keyframes lunge-me { 0%, 6%, 20%, 100% { translate: -50% -50%; } 11% { translate: -50% -78%; } }
  @keyframes lunge-a { 0%, 12%, 26%, 52%, 66%, 100% { translate: -50% -50%; rotate: 0deg; } 15% { translate: -46% -58%; rotate: 5deg; } 57% { translate: -50% -24%; } }
  .road-steps .is-ready .tile { animation: ready 2.2s ease-in-out infinite; }
  @keyframes ready { 50% { translate: 0 -4px; } }
}
/* Still: the raven halfway, the blow landed. */
@media (prefers-reduced-motion: reduce) {
  .wave[open], .wave::backdrop { animation: none; }
  .duel-map .sweep { opacity: 0.5; }
  .duel[data-step="1"] .raven { left: 37%; top: 52%; opacity: 1; }
  .duel[data-step="3"] .bar-foe i { width: 82%; }
  .duel[data-step="3"] .bout-flash:not(.is-block) { opacity: 1; top: 44%; }
}

/* ── Responsive ────────────────────────────────────────────────────── */
@media (max-width: 1000px) {
  /* A stage, then its words under it. */
  .lair, .duel, .pair { grid-template-columns: minmax(0, 1fr); }
  .lair, .duel { gap: 36px; }
  .lair-info, .duel-copy { padding: 0 4px; }
  .lair-info { padding-top: 0; }
  /* The move's numbers over its name: side by side they ran out of the
     phone's half of the stage. */
  .dojo .stage-bar { flex-direction: column-reverse; align-items: flex-start; gap: 8px; }
}

/* ── A phone ──
   Less to scroll, and every block one thing: a section is its heading and
   ONE card about a screen tall — the training ground, the bestiary's
   card, the map — and the smaller blocks under them are cards too, so
   nothing floats loose between them. */
@media (max-width: 760px) {
  .nav-links { display: none; }
  .section { --air: 24px; --head-gap: 20px; padding-top: 76px; }
  .section-tight { padding-top: 64px; }
  .kicker { margin-bottom: 12px; }
  .display-m { font-size: clamp(32px, 9.6vw, 44px); }
  .lede { margin-top: 12px; font-size: 16px; line-height: 1.45; }
  .dojo-stage, .lair, .duel-map { border-radius: 28px; }
  .stage-bar { left: 12px; right: 12px; bottom: 12px; }
  /* The name capsule takes the stage's whole width: arrows at its ends,
     the name between them. */
  .stage-bar .pick { flex: 1; min-width: 0; align-self: stretch; }
  .stage-bar .pick-open { flex: 1; min-width: 0; justify-content: center; }
  .stage-bar .pick-step { width: 42px; height: 46px; flex: none; }
  .stage-bar .pick-label b { font-size: 16.5px; overflow: hidden; text-overflow: ellipsis; }
  .stage-bar .pick-menu, .pick-menu.pick-list { left: 0; right: 0; width: auto; }
  .pane-tag { left: 14px; top: 12px; font-size: 10.5px; }

  /* The training ground: your hand over the fight, one card. */
  .dojo-stage { --fight: clamp(250px, calc(40 * var(--svh)), 330px); grid-template-columns: minmax(0, 1fr); height: auto; }
  .dojo-hand { height: clamp(150px, calc(26 * var(--svh)), 200px); }
  .dojo-fight { height: var(--fight); --hud: clamp(4.6px, 1.5cqw, 6px); }
  .dojo-hand::after { inset: auto 0 0 0; width: auto; height: 1px; }
  .dojo-hp { top: 14px; }
  /* What the move costs: in the corner of the phone's own pane, just over
     the fight (the bar it belongs to hangs 12px off the stage's foot). */
  .dojo .pills { position: absolute; right: 0; bottom: calc(var(--fight) - 2px); }
  .dojo-steps { right: 10px; top: 8px; }
  .dojo-steps .tile { --tile: 30px; border-radius: 9px; }
  .pill { height: 40px; padding: 0 13px 0 10px; font-size: 15.5px; }
  .pill .glyph { width: 16px; }

  /* The bestiary: ONE screen. The stage, and over its foot a sheet with
     two lines about him; opened, the sheet takes the screen and he steps
     back, small, over it (--k: script.js, how small). */
  .lair {
    --H: min(calc(calc(100 * var(--svh)) - 92px), 680px);
    --peek: 136px;   /* of the sheet, while it's shut */
    --win: 190px;    /* of the stage, while it's open */
    position: relative;
    display: block;
    height: var(--H);
    overflow: hidden;
    background: #0b0c10;
    box-shadow: inset 0 0 0 1px var(--edge), 0 50px 90px -50px rgba(0, 0, 0, 0.9);
  }
  /* (Not clipping: the card does, and his list opens out over the sheet.) */
  .lair-stage { position: absolute; inset: 0 0 var(--peek); height: auto; border-radius: 0; box-shadow: none; overflow: visible; }
  .lair-figure { transition: transform 0.55s cubic-bezier(0.3, 1, 0.3, 1); }
  .lair.is-open .lair-figure { transform: scale(var(--k, 0.4)); }
  /* (Hidden, and not only see-through: what was faded out by opacity alone
     stayed under the keyboard and a screen reader — the switch, the ranks
     and his picker behind the open sheet, his attacks behind the shut one.) */
  .lair-stage > :is(.seg, .ranks, .stage-bar), .lair-hp { transition: opacity 0.25s, visibility 0s; }
  .lair.is-open .lair-stage > :is(.seg, .ranks, .stage-bar), .lair.is-open .lair-hp { opacity: 0; pointer-events: none; visibility: hidden; transition: opacity 0.25s, visibility 0s 0.25s; }
  .seg { left: 12px; top: 12px; }
  .seg button { padding: 8px 12px; font-size: 13.5px; }
  .ranks { right: 12px; }
  .ranks button { width: 36px; height: 36px; font-size: 16px; }
  .turn-hint { display: none; }
  /* The sheet. */
  .lair-info {
    position: absolute;
    inset: auto 0 0;
    display: block;
    height: var(--peek);
    padding: 0 16px 18px;
    border-radius: 26px 26px 0 0;
    background: #15161c;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
    overflow: hidden;
    cursor: pointer;
    transition: height 0.55s cubic-bezier(0.3, 1, 0.3, 1);
  }
  .lair.is-open .lair-info { height: calc(var(--H) - var(--win)); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; cursor: auto; }
  .lair-info::-webkit-scrollbar { display: none; }
  .lair-grip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    width: 100%;
    padding: 9px 0 7px;
    font-weight: 700;
    font-size: 11.5px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
    touch-action: none;
  }
  .lair-grip i { width: 38px; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.28); }
  .lair-info .tags { margin-top: 2px; }
  /* His name: in the capsule while the sheet is shut, here once it's open. */
  .lair-info h3 { margin: 0; max-height: 0; opacity: 0; overflow: hidden; font-size: 34px; transition: max-height 0.4s, opacity 0.3s, margin 0.4s; }
  .lair.is-open .lair-info h3 { max-height: 48px; margin-top: 10px; opacity: 1; }
  .lair-about { margin-top: 9px; font-size: 15.5px; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .lair.is-open .lair-about { display: block; }
  .lair-info > :is(.axes, .lair-trick, .lair-moves, .lair-dlc) { margin-top: 16px; opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0s 0.3s; }
  .lair.is-open .lair-info > :is(.axes, .lair-trick, .lair-moves, .lair-dlc) { opacity: 1; visibility: visible; transition: opacity 0.3s 0.12s, visibility 0s; }
  .axis { padding: 11px 13px 12px; border-radius: 18px; }
  .axis b { font-size: 16px; }
  .lair-trick p { font-size: 15.5px; }
  .lair-moves .chips { margin-top: 10px; gap: 6px; }
  .lair-moves .chip { padding: 9px 13px; font-size: 14px; }
  /* His whole list opens over the whole card — the stage and the sheet. */
  .lair .stage-bar .pick-menu { bottom: calc(-4px - var(--peek)); max-height: calc(var(--H) - 16px); }
  .lair-stage:has(.pick-menu:not([hidden])) { z-index: 2; }

  /* The map: to the screen's edges, about a screen tall, its trail a
     zigzag (--climb / --swing: script.js lays it out by them) so five waves
     show at once; its bar is the new-run button alone. */
  .map-wrap { --top: 70px; --node: 70px; margin-inline: calc(-1 * var(--gutter)); border-radius: 0; }
  .map-wrap::before { display: none; }
  .map-wrap::after { height: clamp(330px, calc(calc(100 * var(--svh)) - 340px), 420px); }
  .map-top { padding: 20px var(--gutter) 44px; }
  .map-head { max-width: calc(100% - 64px); }
  .node { font-size: 12.5px; }
  .node.is-boss { --node: 90px; }
  .node.is-mini, .node.is-mark { --node: 58px; }
  .map-nav { display: none; }
  .map-bar { left: 10px; right: 10px; top: 10px; gap: 8px; }
  .map-roll { flex: none; width: 50px; padding: 0; justify-content: center; }
  .map-roll span { display: none; }
  /* The opened wave: a sheet from the bottom edge. */
  .wave { width: 100vw; max-width: none; max-height: calc(88 * var(--svh)); margin: auto 0 0; border-radius: 30px 30px 0 0; overflow-y: auto; overscroll-behavior: contain; }
  .wave[open] { grid-template-columns: minmax(0, 1fr); transform-origin: 50% 100%; animation-name: sheet-in; animation-timing-function: cubic-bezier(0.2, 0.9, 0.2, 1); }
  .wave.is-closing { animation-name: sheet-out; }
  @keyframes sheet-in { from { translate: 0 100%; } }
  @keyframes sheet-out { to { translate: 0 100%; } }
  .wave-stage { min-height: 0; height: min(58vw, 250px); }
  .wave-stage .tile { --tile: 96px; }
  .wave-info { padding: 22px 20px max(26px, env(safe-area-inset-bottom)); gap: 14px; }
  .wave-info h3 { font-size: 36px; }
  .wave-info > p { font-size: 16.5px; }

  /* The duel, the workout, the road: three cards. */
  .duel, .fit, .road {
    padding: 14px 14px 18px;
    border-radius: 28px;
    background: var(--surface);
    box-shadow: inset 0 0 0 1px var(--edge);
  }
  .duel { gap: 16px; }
  .duel-copy { padding: 0 4px; }
  .duel-map { max-width: none; aspect-ratio: 1.3; border-radius: 20px; }
  /* A low map: in the bout the names would sit under the flashes. */
  .duel[data-step="3"] .who b, .duel[data-step="4"] .who b { opacity: 0; }
  .who img { width: 50px; }
  .duel-copy h3, .fit h3, .road h3 { font-size: 24px; }
  .duel-copy > p { margin-top: 8px; font-size: 15.5px; }
  /* Its five beats: a row of numbers, and the picked one's words under it. */
  .duel-steps { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin: 14px 0 0; padding-bottom: 96px; }
  .duel-steps button { position: static; display: grid; place-items: center; height: 40px; padding: 0; border-radius: 999px; background: rgba(255, 255, 255, 0.06); }
  .duel-steps button::before { position: static; background: none; font-size: 15px; }
  .duel-steps button.is-on { background: var(--g-blue); }
  .duel-steps button.is-on::before { background: none; }
  /* (A step's name is out of sight here, not out of the page: its button
     is still called by it — with nothing to read, a screen reader and an
     assistant had five buttons with no names.) */
  .duel-steps b { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .duel-steps button.is-on b { display: block; position: absolute; left: 2px; top: 52px; width: auto; height: auto; overflow: visible; clip-path: none; font-size: 17px; }
  .duel-steps button.is-on span { position: absolute; left: 2px; right: 2px; top: 77px; margin: 0; font-size: 14.5px; line-height: 1.4; }
  .pair { gap: 12px; margin-top: 12px; }
  .fit, .road { padding: 20px 18px 22px; }
  .figure { margin-top: 10px; }
  .figure b { font-size: 64px; }
  .figure span { font-size: 20px; }
  .figure small { font-size: 26px; }
  .figure-note { margin-top: 6px; font-size: 15.5px; }
  .fit-range { margin-top: 16px; }
  .road-steps { margin-top: 22px; }
  .road-steps .tile { --tile: 46px; border-radius: 14px; }
  .road-steps::before { top: 22px; }

  .faq { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .faq-list { gap: 8px; }
  .faq summary { padding: 17px 54px 17px 18px; font-size: 16.5px; }
  .faq details p { padding: 0 18px 18px; font-size: 15.5px; }
  .footer { margin-top: 64px; padding-top: 72px; }
  .footer-links { gap: 28px 48px; margin-top: 56px; }
  .footer-links .wordmark { flex-basis: 100%; }
}

/* ── A weak machine (html.q-lite, html.q-still — index.html's first script,
   or a 3D stage that found out it can't keep up: enemy3d.js) ──
   Besides the 3D itself, what costs a slow GPU most in a page like this is
   blur: every frosted capsule blurs what's under it again each frame
   anything moves there (and something always does: a model, the map
   sliding), and each section's backdrop is a screen-wide blurred layer.
   The capsules go solid — a little denser, to read as well over a
   picture — and the backdrops keep their picture, soft enough at a
   quarter's strength without the blur. */
:is(.q-lite, .q-still) :is(.kicker, .stage-link, #nav, .quest-cta .btn-glass, .beta, .pill, .seg, .ranks, .faq details),
:is(.q-lite, .q-still) .pick::before {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
:is(.q-lite, .q-still) #nav { background: rgba(10, 14, 11, 0.9); }
:is(.q-lite, .q-still) .kicker { background: rgba(0, 0, 0, 0.62); }
:is(.q-lite, .q-still) .quest-cta .btn-glass { background: rgba(20, 22, 21, 0.72); }
:is(.q-lite, .q-still) .quest-cta .beta { background: rgba(20, 22, 21, 0.72); }
:is(.q-lite, .q-still) .pick::before { background: rgba(8, 10, 9, 0.78); }
:is(.q-lite, .q-still) :is(.pill, .seg, .ranks) { background: rgba(8, 10, 9, 0.84); }

/* ══════════════════════════════════════════════════════════════════════
   One screen each
   ══════════════════════════════════════════════════════════════════════
   Every section after the hero is ONE block, a screen tall — the window
   less the menu (--screen) — and the block is the thing it's about, its
   heading standing inside it (.block-head): the training ground's floor,
   an open book, the dungeon's board, the lobby's radar, an activity ring
   and a road, a board with a scroll. (The dungeon's was built so first,
   the others after it.) What's above this in the file still draws their
   insides; this
   says how tall they are, where the heading goes, and what each is made
   to look like.

   And they are BANDS: each the window's whole width and height, one hard
   against the next — no air between them, no rounded corners — its ground
   running to the screen's edges while what's read keeps to the page's
   column (--side). Where two meet there's a line and nothing else
   (.section::before). */
:root {
  --nav-space: 86px;   /* the menu's capsule, and the air under it */
  --foot: clamp(24px, 2.8vw, 38px);   /* a band's air under what's in it */
  --band: clamp(640px, calc(100 * var(--svh)), 1080px);   /* a section: the window, whole */
  /* What a band's content stands in: the band less the menu and the foot. */
  --screen: calc(var(--band) - var(--nav-space) - var(--foot));
  /* The page column's margin — for a box as wide as the window (a
     percentage: it's worked out where it's used). */
  --side: max(var(--gutter), calc((100% - var(--page)) / 2));
  --head-top: calc(var(--nav-space) + 12px);   /* where a band's heading starts */
}
/* (A link to a section brings its band to the window's top: the menu
   floats over the band's own head room.) */
.section, .section-tight {
  position: relative;
  isolation: isolate;
  width: 100%;
  margin: 0;
  padding: 0;
  scroll-margin-top: 0;
}
/* The seams: a hair's line over the lower band's top edge, and nothing
   blended — each ground runs to the line and stops there. (The seams were
   blends at first, each band coming up out of the last one's colour.) */
:root { --seam: rgba(255, 255, 255, 0.16); }
.section::before {
  content: "";
  position: absolute;
  z-index: 6;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: var(--seam);
  pointer-events: none;
}
/* (A band is THERE — it doesn't fade or slide in: either would show the
   wall behind it through the seam while it did.) */
.js .section > .reveal { opacity: 1; translate: none; transition: none; }
/* The footer starts at a line too: its own dark from the first pixel, and
   its dots with it. */
.section + .footer { margin-top: 0; border-top: 1px solid var(--seam); background: var(--night); }
.section + .footer::before {
  -webkit-mask: linear-gradient(180deg, #000, rgba(0, 0, 0, 0.35) 70%, #000);
  mask: linear-gradient(180deg, #000, rgba(0, 0, 0, 0.35) 70%, #000);
}

/* A block's heading: the chip, the title, a line — sized by the block's
   height as much as by the page's width, so a low window keeps it all in. */
.block-head { position: relative; z-index: 2; }
.block-head .kicker { margin-bottom: 12px; }
.block-head .display { font-size: clamp(30px, min(4.4vw, calc(var(--screen) * 0.074)), 60px); }
.block-head .lede { max-width: 30em; margin-top: 12px; font-size: clamp(15.5px, 1.3vw, 18px); line-height: 1.45; }

/* ── The training ground ── */
/* The window in two: your hand's half and the fight's, each to its edge. */
.dojo { margin-top: 0; }
.dojo-stage { height: var(--band); border-radius: 0; box-shadow: none; }
/* (The page's margin, seen from a pane half the window wide.) */
.dojo-hand { --side-half: max(var(--gutter), calc(100% - var(--page) / 2)); display: flex; flex-direction: column; }
.dojo-hand .block-head { padding: var(--head-top) 24px 0 var(--side-half); pointer-events: none; }
/* The phone's own air: what's left of the pane under the heading. */
.dojo-air { position: relative; flex: 1; min-height: 0; }
.dojo-air .pane-tag { top: 14px; left: var(--side-half); }
.dojo .stage-bar { left: var(--side); right: var(--side); bottom: var(--foot); }
/* (The fight's own top row: under the menu.) */
.dojo-fight .pane-tag { top: calc(var(--head-top) + 4px); left: 26px; }
.dojo-hp { top: calc(var(--head-top) + 2px); }
/* (No 3D: the pane stays — the heading is in it — only the phone is gone.) */
.dojo-stage.no-phone { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.dojo-stage.no-phone .dojo-hand { display: flex; }
.dojo-stage.no-phone .dojo-air .pane-tag { display: none; }

/* ── The bestiary: a book, on a table ──
   The band is the table — its boards run the window's width
   (tools/wood-table.py), a lamp's light pooled on them, dark toward the
   ends — and the book lies on it with a little of the table showing all
   round. */
#bestiary {
  display: flex;
  flex-direction: column;
  height: var(--band);
  padding: calc(var(--nav-space) + 10px) var(--side) calc(var(--foot) + 6px);
  background:
    radial-gradient(64% 70% at 50% 52%, rgba(255, 190, 110, 0.2), transparent 74%),
    radial-gradient(ellipse at 50% 50%, transparent 42%, rgba(0, 0, 0, 0.58) 100%),
    url("assets/brand/wood-table.svg") center top / 1600px 600px,
    linear-gradient(180deg, #4a2f1b, #3a2414);
}
/* The book itself. Open on a creature: the cover showing round two pages,
   the spine's shade between them, the leaves' edges at the sides and the
   foot, a ribbon. Dark, as the page is — it's read by its shape. (An
   object on the table, so its corners stay a book's.) */
.book {
  --leather: linear-gradient(180deg, #2c1d14, #170f0a);
  position: relative;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  flex: 1;
  min-height: 0;
  margin-top: 0;
  padding: 12px 15px 18px;
  border-radius: 22px;
  background: var(--leather);
  /* (Its shade on the boards: close under it, and a longer one.) */
  box-shadow: inset 0 0 0 1px rgba(255, 214, 150, 0.2), inset 0 2px 0 rgba(255, 224, 180, 0.08), 0 3px 0 rgba(0, 0, 0, 0.45), 0 14px 22px -6px rgba(0, 0, 0, 0.7), 0 44px 70px -22px rgba(0, 0, 0, 0.85);
  perspective: 2400px;
}
/* The spine: both pages go down into it. */
.book::before {
  content: "";
  position: absolute;
  z-index: 5;
  left: 50%;
  top: 12px;
  bottom: 18px;
  width: 76px;
  translate: -50% 0;
  background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.5) 44%, rgba(255, 236, 200, 0.08) 50%, rgba(0, 0, 0, 0.5) 56%, transparent);
  pointer-events: none;
}
/* The left page: the plate. Its heading over the creature's own room. */
.book .lair-stage {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  height: auto;
  border-radius: 12px 3px 3px 12px;
  background:
    radial-gradient(60% 34% at 50% 86%, rgba(var(--tint), 0.3), transparent 72%),
    radial-gradient(40% 7% at 50% 87%, rgba(0, 0, 0, 0.5), transparent 70%),
    linear-gradient(90deg, #1c1712, #1a1510 78%, #100d0a);
  /* (The leaves under it, at the side and the foot.) */
  box-shadow: -2px 2px 0 #2d251b, -4px 4px 0 #1d1711, -6px 6px 0 #2d251b;
}
.book .page-head { padding: clamp(20px, 2.6vw, 34px) clamp(22px, 2.8vw, 38px) 0; pointer-events: none; }
.book .lair-figure { position: relative; inset: auto; }
/* The two sets: at the page's foot, over the name. (Not across from it,
   as they stood at first: the plate is never wider than 575px, and the
   name's row with a long name in it — «Древний Идол», "Garden Gnome" — is
   324px, the switch 266px, 301px in English: side by side they ran into
   each other at any width of the window.) */
.book .seg { left: 18px; top: auto; bottom: 80px; }
.book .turn-hint { margin: 0 0 14px; }
.book .ranks { top: auto; bottom: 84px; translate: none; }
/* (A book this narrow — a tablet held upright — has a left page some 340px
   across: the switch, 266px and 301 in English, ran under the ranks.) */
@media (min-width: 761px) and (max-width: 900px) { .book .ranks { bottom: 138px; } }
/* The right page: his entry. (It scrolls if a low window can't hold a long one.) */
.book .lair-info {
  position: relative;
  align-content: start;
  gap: clamp(13px, calc(var(--screen) * 0.027), 24px);
  padding: clamp(22px, 2.8vw, 40px) clamp(24px, 3vw, 44px) 52px clamp(42px, 3.8vw, 54px);
  border-radius: 3px 12px 12px 3px;
  background: linear-gradient(90deg, #100d0a, #1a1510 22%, #1c1712);
  box-shadow: 2px 2px 0 #2d251b, 4px 4px 0 #1d1711, 6px 6px 0 #2d251b;
  overflow-y: auto;
  scrollbar-width: none;
}
.book .lair-info::-webkit-scrollbar { display: none; }
.book .lair-info h3 { margin-top: -6px; font-size: clamp(34px, min(4vw, calc(var(--screen) * 0.07)), 54px); }
.book .lair-about { margin-top: -4px; font-size: clamp(15.5px, 1.35vw, 18px); line-height: 1.5; }
.book .axis { padding: 11px 16px 12px; border-radius: 18px; }
.book .lair-trick p { font-size: clamp(15px, 1.25vw, 16.5px); }
.book .lair-moves .chips { margin-top: 10px; }
.book .lair-moves .chip { padding: 9px 14px; font-size: 14.5px; }
/* The ribbon, down from the head of the spine. */
.book-ribbon {
  position: absolute;
  z-index: 6;
  left: calc(50% + 12px);
  top: 0;
  width: 20px;
  height: clamp(64px, calc(var(--screen) * 0.13), 100px);
  background: linear-gradient(90deg, #a3231f, #d8403a 45%, #b02a25);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% calc(100% - 12px), 0 100%);
  pointer-events: none;
}
/* Which page of how many: the right page's foot. */
.page-no {
  position: absolute;
  z-index: 6;
  right: 40px;
  bottom: 30px;
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.08em;
  color: rgba(255, 236, 200, 0.4);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
/* A leaf going over as the page is turned. Not a blank one — it was, and
   with nothing written on it the creature and his entry simply vanished and
   others stood there, and the turn was lost. On its face is the page
   being left, on its back the page being come to: copies of the real pages
   (script.js `turn`), so what's read goes over with the paper.
   Forward, the right page goes over onto the left; back, the left onto the
   right — there a still of the old right page lies under it (.book-cover)
   until it's down. */
.book-leaf, .book-cover {
  position: absolute;
  top: 12px;
  bottom: 18px;
  left: 50%;
  width: calc(50% - 15px);
  visibility: hidden;
  pointer-events: none;
}
.book-cover { z-index: 4; }
.book-leaf { z-index: 7; transform-origin: 0 50%; transform-style: preserve-3d; }
.leaf-face { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.leaf-back { transform: rotateY(180deg); }
/* (The copies: a page's own size, whatever the real one's place in the book gave it.) */
.leaf-face > *, .book-cover > * { width: 100%; height: 100% !important; margin: 0 !important; }
.leaf-face > * { box-shadow: 0 0 44px rgba(0, 0, 0, 0.7) !important; }
/* The leaf's own shade as it stands on edge: dark from the spine. */
.leaf-face::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.12) 55%, rgba(0, 0, 0, 0));
  opacity: 0;
  pointer-events: none;
}
.book.turn-prev .leaf-face::after { background: linear-gradient(270deg, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.12) 55%, rgba(0, 0, 0, 0)); }
/* (A creature caught as he stood, for the plate that's turned away: sections3d.js, the "snap" cue.) */
.beast-snap { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.lair-stage.has-snap .beast-img { opacity: 0; }
.book.is-turning .book-leaf { visibility: visible; }
.book.turn-prev .book-cover { visibility: visible; }
.book.turn-next .book-leaf { animation: leaf-next 0.74s cubic-bezier(0.45, 0.05, 0.3, 1) forwards; }
.book.turn-prev .book-leaf { left: 15px; transform-origin: 100% 50%; animation: leaf-prev 0.74s cubic-bezier(0.45, 0.05, 0.3, 1) forwards; }
.book.is-turning .leaf-face::after { animation: leaf-shade 0.74s ease-in-out; }
/* Down, and what it showed is the page under it now: it goes — its back
   alone (faded as a whole, a leaf of two faces is flattened, and the other
   face shows through it the wrong way round). */
.book.leaf-away .leaf-face:not(.leaf-back) { visibility: hidden; }
.book.leaf-away .leaf-back { opacity: 0; transition: opacity 0.3s ease; }
/* The plate's picture of him, and his health over it, where the model of
   him stands: the picture is what the leaf brings, and he steps out of it. */
@media (min-width: 761px) {
  .book .beast-img { height: 57%; bottom: 16%; }
  .book .lair-hp { top: max(74px, calc(var(--head, 0.3) * 100% - 38px)); }
}
@keyframes leaf-next { from { transform: rotateY(0); } to { transform: rotateY(-180deg); } }
@keyframes leaf-prev { from { transform: rotateY(0); } to { transform: rotateY(180deg); } }
@keyframes leaf-shade { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }

/* ── The dungeon: a screen of it ──
   The board runs under the whole window; the heading, the new-run button
   keep to the page's column. (padding-bottom isn't layout — the map is
   laid over the whole band — it's the foot script.js keeps the board
   clear of.) */
.map-wrap { height: var(--band); margin-inline: 0; padding-bottom: var(--foot); border-radius: 0; }
.map-wrap::before { display: none; }
.map-wrap::after { flex: 1; height: auto; min-height: 0; }
.map-top { padding: var(--head-top) var(--side) 60px; }
.map-bar { top: var(--head-top); left: var(--side); right: var(--side); }

/* ── The duel: the lobby's radar ──
   The band is the radar. Its rings go out across all of it from where
   YOU stand — and its light with them (.glow: on the map, so it's where
   you are whatever the window); the map that the five beats are played on
   is a square of it at the page column's right, nothing clipped at its
   edge. */
.duel {
  position: relative;
  isolation: isolate;
  display: block;
  height: var(--band);
  margin-top: 0;
  border-radius: 0;
  overflow: hidden;
  background:
    repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.028) 0 2px, transparent 2px 15px),
    linear-gradient(180deg, #121826, #0b0e17);
}
.duel-map .glow {
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 78%;
  width: 250%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(90, 150, 255, 0.3), rgba(90, 150, 255, 0.1) 46%, transparent);
  pointer-events: none;
}
/* (The words' side kept dark under them.) */
.duel::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(11, 14, 23, 0.92), rgba(11, 14, 23, 0.6) 36%, rgba(11, 14, 23, 0) 58%);
  pointer-events: none;
}
.duel-scene { position: absolute; inset: 0; z-index: -1; }
.duel-map {
  position: absolute;
  right: var(--side);
  /* (The middle of what's under the menu.) */
  top: calc(var(--nav-space) + (100% - var(--nav-space) - var(--foot)) / 2);
  /* (A square: as tall as the band lets it be, and no wider than leaves
     the words their side.) */
  width: min(calc((100% - 2 * var(--side)) * 0.54), calc(var(--screen) - 36px));
  max-width: none;
  margin: 0;
  translate: 0 -50%;
  border-radius: 0;
  overflow: visible;
  background: none;
  box-shadow: none;
}
/* Two rings more, for a radar the size of the block. */
.duel-map::before, .duel-map::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 78%;
  width: 196%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 1.5px solid rgba(140, 180, 255, 0.2);
  transition: opacity 0.4s;
  pointer-events: none;
}
.duel-map::after { width: 264%; border-color: rgba(140, 180, 255, 0.13); }
.duel .duel-map .ring { border-color: rgba(140, 180, 255, 0.32); }
.duel[data-step="2"] .duel-map::before, .duel[data-step="3"] .duel-map::before, .duel[data-step="4"] .duel-map::before,
.duel[data-step="2"] .duel-map::after, .duel[data-step="3"] .duel-map::after, .duel[data-step="4"] .duel-map::after { opacity: 0.35; }
.duel .who img { width: clamp(58px, calc(var(--screen) * 0.115), 92px); }
.duel .who b { font-size: 13.5px; }
.duel-copy {
  display: flex;
  flex-direction: column;
  width: min(calc((100% - 2 * var(--side)) * 0.47), 520px);
  height: 100%;
  margin-left: var(--side);
  padding: var(--head-top) 0 var(--foot);
}
.duel-steps { margin-top: clamp(14px, calc(var(--screen) * 0.034), 28px); }
.duel-steps button { padding: clamp(8px, calc(var(--screen) * 0.016), 11px) 14px clamp(8px, calc(var(--screen) * 0.016), 11px) 50px; }

/* ── For yourself: the hero's hall ──
   As the game's own profile: a stone wall under two lamps, a shelf of
   banners and cups, the hero under it in his rings; the workout's dials
   at the left turn the green one. Along the band's foot, from edge to edge
   of the page's column, the hero's road. (It was an activity ring and a row
   of tiles on a bare wall, a column each and a hole between.) */
.self {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: clamp(14px, calc(var(--screen) * 0.034), 30px) clamp(24px, 4vw, 64px);
  height: var(--band);
  padding: var(--head-top) var(--side) calc(var(--foot) + 4px);
  border-radius: 0;
  overflow: hidden;
  /* (The lamps' warmth on the wall behind the shelf; the page's wall.) */
  background:
    radial-gradient(46% 52% at calc(100% - var(--side) - 22%) 34%, rgba(255, 176, 86, 0.16), transparent 72%),
    radial-gradient(40% 40% at calc(100% - var(--side)) 100%, rgba(184, 121, 255, 0.13), transparent 70%),
    url("assets/brand/stone-wall.svg") center top / 720px 480px,
    linear-gradient(180deg, #17161a, #0c0d11);
}
.self-copy { display: flex; flex-direction: column; min-height: 0; }
/* (One line: the column is a hair narrower than the heading at its largest.) */
.self .block-head .display { white-space: nowrap; }
/* The workout: what's burnt, a line, the two dials. */
.self .fit { margin-top: auto; padding-top: clamp(14px, calc(var(--screen) * 0.04), 34px); max-width: 460px; }
.self .fit .figure { margin: 0; gap: 8px; }
.self .fit .figure b { font-size: clamp(64px, calc(var(--screen) * 0.15), 124px); }
.self .fit .figure span { font-size: clamp(20px, 2.2vw, 30px); }
.self .fit .figure small { font-size: clamp(26px, 3vw, 42px); }
.self .figure-note { margin-top: clamp(6px, 1vw, 12px); font-size: clamp(15.5px, 1.35vw, 18px); }
.self .fit-range {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 30px;
  margin-top: clamp(10px, calc(var(--screen) * 0.024), 20px);
  background: none;
  cursor: pointer;
}
.self .fit-range::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: linear-gradient(90deg, #a6ff3c var(--v, 29%), rgba(255, 255, 255, 0.16) var(--v, 29%)); }
.self .fit-range::-webkit-slider-thumb { -webkit-appearance: none; width: 24px; height: 24px; margin-top: -9px; border-radius: 50%; background: #f3f0e9; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55); }
.self .fit-range::-moz-range-track { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.16); }
.self .fit-range::-moz-range-progress { height: 6px; border-radius: 3px; background: #a6ff3c; }
.self .fit-range::-moz-range-thumb { width: 24px; height: 24px; border: 0; border-radius: 50%; background: #f3f0e9; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.55); }
.self .fit-pace { margin-top: clamp(6px, calc(var(--screen) * 0.014), 12px); }

/* The hall: the shelf, the hero under it, what his rings are. */
.hall { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 0; }
.hall-shelf { flex: 0 1 auto; display: block; width: min(100%, calc(var(--screen) * 0.7)); height: auto; min-height: 0; overflow: visible; }
.hero-coin {
  position: relative;
  flex: none;
  width: clamp(132px, calc(var(--screen) * 0.27), 224px);
  aspect-ratio: 1;
  margin-top: clamp(6px, calc(var(--screen) * 0.014), 14px);
}
.coin-rings { position: absolute; inset: 0; width: 100%; height: 100%; rotate: -90deg; }
.coin-rings circle { fill: none; stroke-width: 6; stroke-linecap: round; }
.coin-rings .ring-bg { stroke: rgba(166, 255, 60, 0.16); }
.coin-rings .ring-fg { stroke: #a6ff3c; stroke-dasharray: calc(var(--p, 0.3) * 100) 100; filter: drop-shadow(0 0 4px rgba(166, 255, 60, 0.6)); transition: stroke-dasharray 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.coin-rings .ring-bg.ring-xp { stroke: rgba(184, 121, 255, 0.18); }
.coin-rings .ring-fg.ring-xp { stroke: #b879ff; stroke-dasharray: 64 100; filter: drop-shadow(0 0 4px rgba(184, 121, 255, 0.6)); }
.hero-coin img {
  position: absolute;
  inset: 16%;
  width: 68%;
  height: 68%;
  max-width: none;
  border-radius: 50%;
  object-fit: cover;
  background: radial-gradient(circle at 50% 30%, rgb(var(--tint)), rgba(var(--tint), 0.6));
  box-shadow: 0 10px 26px -8px rgba(0, 0, 0, 0.8);
}
/* His level, on the rings' foot — as the app pins it. */
.coin-level {
  position: absolute;
  left: 50%;
  bottom: -3%;
  display: grid;
  place-items: center;
  min-width: 2.1em;
  height: 2.1em;
  padding: 0 0.4em;
  translate: -50% 0;
  border-radius: 999px;
  font-weight: 900;
  font-size: clamp(14px, calc(var(--screen) * 0.024), 19px);
  line-height: 1;
  color: #fff;
  background: var(--g-purple);
  box-shadow: 0 0 0 3px #131217, 0 6px 14px -4px rgba(0, 0, 0, 0.7);
}
.coin-legend { display: flex; gap: 18px; margin-top: clamp(12px, calc(var(--screen) * 0.028), 22px); font-weight: 600; font-size: 13.5px; color: rgba(255, 255, 255, 0.6); }
.coin-legend span { display: inline-flex; align-items: center; gap: 7px; }
.coin-legend span::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: #a6ff3c; }
.coin-legend .lg-xp::before { background: #b879ff; }

/* The road, along the band's foot: its name at the left, then the levels
   on a line — what each hands over standing on it, the level under. */
.self .road {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 250px) minmax(0, 1fr);
  align-items: center;
  gap: clamp(20px, 3vw, 48px);
  padding-top: clamp(14px, calc(var(--screen) * 0.03), 26px);
  border-top: 1px solid rgba(255, 255, 255, 0.09);
}
.road-head h3 { font-weight: 800; font-size: clamp(20px, 2vw, 26px); letter-spacing: -0.03em; line-height: 1.1; }
.road-head p { margin-top: 6px; font-weight: 500; font-size: 15px; line-height: 1.4; color: var(--muted); text-wrap: pretty; }
.self .road-steps { --tile: clamp(38px, min(calc(var(--screen) * 0.082), 4.4vw), 64px); --node: 26px; grid-template-columns: repeat(6, minmax(0, 1fr)) minmax(0, 0.7fr) minmax(0, 1fr); align-items: end; gap: 0; margin: 0; padding: 0; }
/* (The line the levels stand on: gone over as far as the one in hand.) */
.self .road-steps::before { display: block; left: calc(100% / 15.4); right: calc(100% / 15.4); top: auto; bottom: calc(var(--node) / 2 - 2px); height: 4px; border-radius: 2px; background: linear-gradient(90deg, #b879ff 0 29.9%, rgba(255, 255, 255, 0.13) 29.9% 83.2%, transparent 83.2% 91.4%, rgba(255, 255, 255, 0.13) 91.4%); }
.self .road-steps li { position: relative; display: grid; justify-items: center; gap: 5px; translate: none; }
.self .road-steps .tile { --tile: inherit; width: var(--tile); border-radius: 28%; }
.self .road-steps .chest-box { scale: 0.74; }
.t-wood { --grad: linear-gradient(145deg, #b98a52, #6b4524); }
.road-amt { font-weight: 800; font-size: 13px; line-height: 1; letter-spacing: 0.01em; color: rgba(255, 255, 255, 0.82); font-variant-numeric: tabular-nums; }
.self .road-steps li:not(.is-done):not(.is-ready):not(.is-goal) .road-amt { color: rgba(255, 255, 255, 0.42); }
/* (The level: a stud on the line.) */
.self .road-steps b {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--node);
  height: var(--node);
  margin-top: 5px;
  border-radius: 50%;
  font-weight: 800;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.6);
  background: #24232a;
  box-shadow: 0 0 0 3px #131217;
}
.self .road-steps .is-done b { color: #fff; background: #8a52f0; }
.self .road-steps .is-ready b { color: #2a1a00; background: #ffd24a; }
.self .road-steps li + li::before { display: none; }
/* (Between the seventh and the last: the rest of the way, in dots.) */
.self .road-steps .is-gap { align-self: end; height: var(--node); }
.self .road-steps .is-gap i { position: absolute; left: 10%; right: 10%; top: 50%; height: 8px; translate: 0 -50%; background: radial-gradient(circle, rgba(255, 255, 255, 0.34) 2.2px, transparent 2.8px) center / 13px 8px repeat-x; }
.self .road-steps .is-goal .tile { box-shadow: 0 0 0 2.5px rgba(184, 121, 255, 0.7), 0 0 26px -2px rgba(184, 121, 255, 0.8); filter: none !important; }
.self .road-steps .is-goal b { width: auto; min-width: var(--node); padding: 0 7px; border-radius: 999px; color: #fff; background: var(--g-purple); }
.self .road-steps .is-goal .road-amt { color: #d9bcff; }

/* ── The questions: a board, and a scroll ──
   The questions down the board's left; beside them a scroll unrolled on
   the answer to the one picked (script.js: .faq-ask, .faq-scroll). With no
   script the list is what there is, as it was. */
.faq { display: block; }
.faq-board {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  grid-template-rows: auto minmax(0, 1fr);
  gap: clamp(12px, calc(var(--screen) * 0.03), 26px) clamp(24px, 4vw, 60px);
  height: var(--band);
  padding: var(--head-top) var(--side) calc(var(--foot) + 4px);
  border-radius: 0;
  overflow: hidden;
  /* (Planks, upright.) */
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.22) 0 2px, transparent 2px 168px),
    repeating-linear-gradient(90deg, rgba(255, 230, 190, 0.016) 0 84px, transparent 84px 168px),
    linear-gradient(180deg, #1d1610, #130e0a);
}
.faq-board .block-head { grid-column: 1; }
.faq-board:not(.is-live) { height: auto; min-height: var(--band); grid-template-columns: minmax(0, 1fr); }
.faq-board.is-live .faq-list { display: none; }
.faq-ask { grid-column: 1; display: grid; align-content: start; gap: 3px; min-height: 0; overflow-y: auto; scrollbar-width: none; margin-left: -12px; }
.faq-ask::-webkit-scrollbar { display: none; }
.faq-ask button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  /* (Eleven of them in a low window: a row's own air gives.) */
  padding: clamp(6px, calc(var(--screen) * 0.0142), 12px) 14px clamp(6px, calc(var(--screen) * 0.0142), 12px) 12px;
  border-radius: 14px;
  text-align: left;
  font-weight: 700;
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.25;
  color: rgba(255, 244, 226, 0.66);
  transition: background 0.2s, color 0.2s;
}
.faq-ask button::after { content: "›"; flex: none; font-weight: 800; font-size: 20px; line-height: 1; opacity: 0; translate: -6px 0; transition: opacity 0.2s, translate 0.2s; }
.faq-ask button:hover { color: #fff; }
.faq-ask button[aria-selected="true"] { color: #fff; background: rgba(255, 228, 180, 0.09); }
.faq-ask button[aria-selected="true"]::after { opacity: 0.8; translate: 0 0; }
/* The scroll: two rods and the sheet between them. */
.faq-scroll {
  position: relative;
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: center;
  max-height: 100%;
  margin: 0 14px;
  padding: 16px 0;
}
.faq-scroll::before, .faq-scroll::after {
  content: "";
  position: absolute;
  z-index: 1;
  left: -14px;
  right: -14px;
  height: 20px;
  border-radius: 10px;
  background: linear-gradient(180deg, #a87a45, #6b4520 55%, #4a2e14);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35), 0 8px 14px -6px rgba(0, 0, 0, 0.8);
}
.faq-scroll::before { top: 0; }
.faq-scroll::after { bottom: 0; }
.faq-sheet {
  position: relative;
  max-height: calc(var(--screen) - 150px);
  padding: clamp(24px, 3vw, 40px) clamp(22px, 3vw, 40px);
  overflow-y: auto;
  scrollbar-width: none;
  background: linear-gradient(90deg, #17120d, #221b13 8%, #241d15 50%, #221b13 92%, #17120d);
  box-shadow: inset 0 14px 14px -10px rgba(0, 0, 0, 0.7), inset 0 -14px 14px -10px rgba(0, 0, 0, 0.7);
}
.faq-sheet::-webkit-scrollbar { display: none; }
.faq-sheet h3 { font-weight: 800; font-size: clamp(22px, 2.2vw, 30px); letter-spacing: -0.03em; line-height: 1.12; color: #ffe9c4; text-wrap: balance; }
.faq-sheet p { margin-top: 14px; font-weight: 500; font-size: clamp(16px, 1.35vw, 18px); line-height: 1.6; color: rgba(255, 244, 226, 0.78); text-wrap: pretty; }
.faq-sheet a { color: #fff; text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.35); text-underline-offset: 4px; }
.faq-sheet.swap > * { animation: swap-in 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.faq-back { display: none; }

@media (max-width: 760px) {
  :root { --nav-space: 72px; --foot: 16px; --band: clamp(600px, calc(100 * var(--svh)), 880px); --head-top: calc(var(--nav-space) + 2px); }
  .block-head .display { font-size: clamp(28px, min(8.6vw, calc(var(--screen) * 0.056)), 40px); }
  .block-head .lede { margin-top: 8px; font-size: 15.5px; line-height: 1.4; }
  .block-head .kicker { margin-bottom: 10px; padding: 6px 12px; font-size: 13px; }

  /* The training ground: the heading and the phone over the fight. */
  .dojo-stage { --fight: clamp(210px, calc(var(--screen) * 0.4), 320px); grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) var(--fight); height: var(--band); }
  .dojo-stage.no-phone { grid-template-columns: minmax(0, 1fr); }
  .dojo-hand { height: auto; }
  .dojo-hand .block-head { padding: var(--head-top) 16px 0; }
  .dojo .stage-bar { left: 12px; right: 12px; bottom: 14px; }
  /* (The fight is the lower half here: its row back at its own top.) */
  .dojo-fight .pane-tag { top: 12px; left: 14px; }
  .dojo-hp { top: 14px; }
  .dojo-air { min-height: 90px; }
  .dojo-air .pane-tag { left: 16px; top: 8px; }
  .dojo-fight { height: auto; }

  /* The book, one page of it: the plate, and his entry the sheet at its
     foot (as it was — only the creature's layer starts under the heading
     now: --head-h, script.js). */
  #bestiary { padding: calc(var(--nav-space) + 4px) 14px 18px 18px; }
  .book {
    --H: calc(var(--band) - var(--nav-space) - 22px);
    display: block;
    flex: none;
    height: var(--H);
    padding: 0;
    border-radius: 20px 28px 28px 20px;
    background: #1a1510;
    box-shadow: inset 0 0 0 1px rgba(255, 214, 150, 0.17), -3px 3px 0 #2d251b, -6px 6px 0 #1d1711, -6px 20px 30px -8px rgba(0, 0, 0, 0.8);
    perspective: none;
  }
  .book::before, .book-leaf, .book-cover, .page-no { display: none; }
  .book-ribbon { left: auto; right: 26px; width: 18px; height: 54px; }
  .book .lair-stage { position: absolute; inset: 0 0 var(--peek); grid-template-rows: auto auto minmax(0, 1fr); border-radius: 0; box-shadow: none; overflow: visible; background:
    radial-gradient(70% 30% at 50% 88%, rgba(var(--tint), 0.3), transparent 72%),
    linear-gradient(180deg, #1c1712, #17120e); }
  .book .page-head { padding: 18px 16px 0; transition: opacity 0.25s; }
  .book .seg { position: static; justify-self: start; margin: 10px 12px 0; transition: opacity 0.25s, visibility 0s; }
  .book .turn-hint { display: none; }
  .lair.is-open .page-head, .lair.is-open .seg { opacity: 0; pointer-events: none; }
  .lair.is-open .seg { visibility: hidden; transition: opacity 0.25s, visibility 0s 0.25s; }
  .lair.is-open .lair-figure { transform: translateY(calc(-1 * var(--head-h, 0px))) scale(var(--k, 0.4)); }
  .book .ranks { top: auto; bottom: 74px; translate: none; padding: 4px; }
  .book .ranks button { width: 32px; height: 32px; font-size: 15px; }
  .book .lair-hp { top: max(4px, calc(var(--head, 0.2) * 100% - 34px)); }
  .book .lair-info { position: absolute; inset: auto 0 0; display: block; gap: 0; padding: 0 16px 18px; border-radius: 26px 26px 0 0; background: #211a13; box-shadow: inset 0 1px 0 rgba(255, 226, 180, 0.14); overflow: hidden; }
  .book.is-open .lair-info { overflow-y: auto; }
  .book .lair-info h3 { margin: 0; font-size: 34px; }
  .book.is-open .lair-info h3 { margin-top: 10px; }
  .book .lair-about { margin-top: 9px; font-size: 15.5px; }

  .map-wrap { height: var(--band); }
  .map-wrap::after { height: auto; }
  .map-top { padding: var(--head-top) var(--gutter) 44px; }
  .map-bar { left: 10px; right: 10px; top: var(--head-top); }

  /* The duel: the heading, the radar, its five beats. */
  .duel { display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 0; }
  .duel::after { background: linear-gradient(180deg, rgba(11, 14, 23, 0.9), rgba(11, 14, 23, 0) 34%, rgba(11, 14, 23, 0) 62%, rgba(11, 14, 23, 0.86) 82%); }
  .duel-copy { display: contents; }
  .duel .block-head { order: 1; padding: var(--head-top) 16px 0; }
  .duel-scene { position: relative; inset: auto; order: 2; flex: 1; min-height: 150px; }
  .duel-map { left: 50%; right: auto; top: 50%; width: 54%; height: 100%; max-width: 100%; aspect-ratio: 1; translate: -50% -50%; border-radius: 0; }
  .duel-map .glow { width: 330%; }
  .duel .who img { width: 52px; }
  .duel-steps { order: 3; margin: 0; padding: 0 14px 104px; }
  .duel-steps button { padding: 0; }
  .duel-steps button.is-on b { left: 16px; top: 50px; }
  .duel-steps button.is-on span { left: 16px; right: 16px; top: 75px; }

  /* For yourself: the heading, the hero under his shelf, the dials, the
     road — one under another. */
  .self { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto auto; gap: 0; padding: var(--head-top) 16px 18px; }
  .self-copy { display: contents; }
  /* (Not cards, as a phone once drew them: parts of the one hall.) */
  .self .fit, .self .road { height: auto; padding: 0; border-radius: 0; background: none; box-shadow: none; }
  .self .block-head { order: 1; }
  .hall { order: 2; padding: 6px 0 2px; }
  .hall-shelf { width: min(84%, calc(var(--screen) * 0.44)); }
  .hero-coin { width: clamp(104px, calc(var(--screen) * 0.17), 132px); }
  .coin-legend { margin-top: 12px; font-size: 12.5px; }
  .self .fit { order: 3; margin: 0; padding: 6px 0 0; max-width: none; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 14px; }
  .self .fit .figure b { font-size: clamp(44px, calc(var(--screen) * 0.075), 58px); }
  .self .fit .figure span { font-size: 17px; }
  .self .fit .figure small { font-size: 22px; }
  .self .figure-note { margin: 0; font-size: 14px; line-height: 1.35; }
  .self .fit-range { grid-column: 1 / -1; margin-top: 2px; }
  .self .fit-pace { grid-column: 1 / -1; margin-top: 0; }
  .self .fit-pace button { padding: 9px 2px; font-size: 14px; }
  .self .road { order: 4; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 14px; padding: 12px 0 0; border-radius: 0; }
  .road-head { display: flex; align-items: baseline; gap: 10px; }
  .road-head h3 { font-size: 18px; white-space: nowrap; }
  .road-head p { margin: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .self .road-steps { --tile: 38px; --node: 22px; }
  .self .road-steps .tile { border-radius: 12px; }
  .self .road-steps .chest-box { scale: 0.56; }
  .road-amt { font-size: 11.5px; }
  .self .road-steps b { margin-top: 3px; font-size: 11.5px; }

  /* The questions fill the board; the scroll unrolls over them. */
  .faq-board { grid-template-columns: minmax(0, 1fr); gap: 12px; padding: var(--head-top) 16px 18px; }
  .faq-ask { margin-left: -10px; margin-right: -6px; }
  .faq-ask button { padding: clamp(8px, calc(var(--screen) * 0.017), 12px) 10px; font-size: 15.5px; }
  .faq-ask button::after { opacity: 0.4; translate: 0 0; }
  .faq-ask button[aria-selected="true"] { background: none; color: rgba(255, 244, 226, 0.66); }
  .faq-scroll {
    position: absolute;
    z-index: 3;
    inset: calc(var(--nav-space) - 6px) 18px 14px;
    grid-column: 1;
    margin: 0;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    opacity: 0;
    scale: 1 0.6;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.25s, scale 0.35s cubic-bezier(0.3, 1.2, 0.4, 1), visibility 0s 0.35s;
  }
  .faq-board.is-answer .faq-scroll { opacity: 1; scale: 1; pointer-events: auto; visibility: visible; transition: opacity 0.25s, scale 0.35s cubic-bezier(0.3, 1.2, 0.4, 1), visibility 0s; }
  .faq-board.is-answer .faq-ask, .faq-board.is-answer .block-head { opacity: 0.12; transition: opacity 0.25s; }
  .faq-sheet { flex: 1; max-height: none; padding: 20px 18px 24px; }
  .faq-back { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 14px; padding: 8px 14px 8px 10px; border-radius: 999px; font-weight: 700; font-size: 14px; color: #ffe9c4; background: rgba(255, 228, 180, 0.1); }
}

/* A short phone (the browser's bars up): the headings' lines of small
   words go — the blocks keep to the screen. */
@media (max-width: 760px) and (max-height: 700px) {
  .book .page-head .lede, .duel .block-head .lede { display: none; }
  .book { --peek: 118px; }
  .hall-shelf { display: none; }
  .hero-coin { margin-top: 0; }
}
