/* CloudRift - marketing site
   Palette, type scale and shape language taken from the game's UI theme. */

@font-face {
  font-family: 'MotionControl';
  src: url('../fonts/MotionControl-Bold.otf?v=1d7367317423') format('opentype');
  font-weight: 400 900;
  font-display: swap;
}

:root {
  /* sky */
  --sky-top: #101A35;
  --sky-mid: #3A2C55;
  --sky-bottom: #6E3F58;

  /* dusk UI system */
  --cream: #F5E9D3;
  --purple-shadow: #3A2C55;
  --rift-orange: #F2A02C;
  --pill-bg: #252548;
  --pill-border: rgba(244, 201, 93, 0.7);
  --gold: #F4C95D;
  --lavender: #A89BC4;
  --peach: #E8A87C;
  --peach-text: #2D2E5F;
  --dusty-purple: #5C5980;
  --teal: #4A8E9B;
  --green: #A4D8A8;
  --mint: #B8E0A8;
  --card-center: #4A3B6B;
  --card-edge: #252548;
  --card-border: rgba(212, 165, 116, 0.6);
  --scrim: rgba(11, 14, 19, 0.8);

  /* rarity */
  --common: #94A0B5;
  --rare: #5BA0E0;
  --epic: #AE6BE0;
  --legendary: #F4C95D;

  /* bamboo */
  --bamboo: #6FB04A;
  --bamboo-light: #BDE48A;
  --bamboo-dark: #3E7530;
  --node: #BFA86A;

  --gem: #A040D8;

  --max: 1180px;
  --r-sm: 8px;
  --r: 12px;
  --r-md: 14px;
  --r-lg: 16px;
  --r-xl: 20px;
}

*, *::before, *::after { box-sizing: border-box; }

/* Type scale is percentage-based from here down. Percentages resolve against
   the PARENT's size, so the base has to be predictable: html sets the root,
   and form controls are forced to inherit (a <button> otherwise falls back to
   the UA's ~13px, which would silently shrink every % inside the roster,
   powerup and map/trail buttons). */
html { font-size: 118.75%; }        /* 19px root */
button, input, select, textarea { font: inherit; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  font-family: 'MotionControl', 'Segoe UI', system-ui, sans-serif;
  background: var(--sky-top);
  color: var(--cream);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 2000;
  padding: 10px 14px;
  border-radius: 8px;
  background: var(--cream);
  color: #11182D;
  font-weight: 800;
  transform: translateY(-160%);
}
.skip-link:focus { transform: translateY(0); }

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 24px; }

/* ---------- shared type ---------- */
.h2 {
  font-size: clamp(30px, 5vw, 46px);
  font-weight: 900;
  letter-spacing: 2px;
  text-transform: uppercase;
  margin: 0 0 10px;
  text-shadow: 3px 4px 0 var(--purple-shadow);
}
.sub {
  color: var(--lavender);
  font-weight: 500;
  font-size: 112%;
  line-height: 1.65;
  max-width: 700px;
  margin: 0 auto 44px;
  letter-spacing: .3px;
}
.section { padding: 92px 0; position: relative; }
/* Adjacent sections can end and begin on the same colour (Maps → Collect &
   Share did), which erases the boundary. A hairline makes every seam read. */
.section + .section { border-top: 1px solid rgba(168, 155, 196, .13); }
.section-head { text-align: center; max-width: 760px; margin: 0 auto; }

.eyebrow {
  display: inline-block;
  font-size: 80%;
  font-weight: 800;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold);
  border: 2px solid var(--pill-border);
  background: var(--pill-bg);
  border-radius: var(--r-md);
  padding: 6px 14px;
  margin-bottom: 18px;
}

/* ---------- nav ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Was rgba(16, 26, 53, .82) - the exact value of --sky-top, which is the
     colour the hero starts on. The bar was painting itself onto its own
     backdrop, so it read as nothing. Sits several stops darker now so it
     separates from the hero at the top of the page and from the near-black
     sections further down. */
  background: rgba(6, 11, 24, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 2px solid rgba(244, 201, 93, 0.42);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
}
.nav-in {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 66px;
}
.nav-logo { display: flex; align-items: center; gap: 10px; }
.nav-logo img { width: 38px; height: 38px; border-radius: 10px; }
.nav-word { font-size: 21px; font-weight: 900; letter-spacing: 1px; }
.nav-word .rift { color: var(--rift-orange); }
.nav-links { margin-left: auto; display: flex; gap: 4px; align-items: center; }
.nav-links a {
  font-size: 76%;
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--lavender);
  padding: 9px 13px;
  border-radius: var(--r);
  transition: color .18s, background .18s;
}
.nav-links a:hover { color: var(--cream); background: rgba(255, 255, 255, .06); }
/* The nav's only action now that "Get the game" is gone. Filled rather than
   outlined, since it no longer shares the bar with a second button. */
.nav-play {
  background: var(--gold) !important;
  color: var(--peach-text) !important;
  border: 2px solid rgba(255, 255, 255, .22);
}
.nav-play:hover { filter: brightness(1.07); }
/* The section anchors collapse on small screens; Play stays at every width. */
@media (max-width: 860px) { .nav-links .hide-sm { display: none; } }
@media (max-width: 420px) {
  .nav-links { gap: 2px; }
  .nav-play { padding: 8px 10px; font-size: 70%; }
}

/* ---------- hero ---------- */
.hero {
  position: relative;
  padding: 64px 0 88px;
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 55%, var(--sky-bottom) 100%);
  overflow: hidden;
}
.hero::after {
  /* Horizon silhouette, echoing the game's near-mountain layer.
     Two things made this read as a hard shard before:
       1. It ended on `#02050C 88%`, so the bottom 12% was flat solid and the
          ramp had to cover the whole fade in 120px.
       2. A plain two-stop ramp changes slope abruptly at each end, and the eye
          exaggerates that into a visible edge (Mach banding).
     So: taller, and the stops follow a smoothstep curve instead of a straight
     line, which removes the corners at both ends of the fade. */
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 260px;
  background: linear-gradient(180deg,
    rgba(2, 5, 12, 0)    0%,
    rgba(2, 5, 12, .02) 12%,
    rgba(2, 5, 12, .07) 24%,
    rgba(2, 5, 12, .16) 36%,
    rgba(2, 5, 12, .29) 47%,
    rgba(2, 5, 12, .45) 57%,
    rgba(2, 5, 12, .62) 67%,
    rgba(2, 5, 12, .77) 76%,
    rgba(2, 5, 12, .89) 85%,
    rgba(2, 5, 12, .96) 93%,
    rgba(2, 5, 12, 1)  100%);
  pointer-events: none;
}
/* Dither layer. A smooth gradient across this much dark area quantises to
   8 bits and steps visibly; a faint noise texture breaks the steps up. The
   SVG is inline so it costs no request. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
.hero-in {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: 54px;
  align-items: center;
  position: relative;
  z-index: 2;
}
@media (max-width: 940px) {
  .hero-in { grid-template-columns: 1fr; gap: 40px; }
  .hero-copy { text-align: center; }
  .hero-copy .sub { margin-left: auto; margin-right: auto; }
  .badges { justify-content: center; }
}

.wordmark {
  font-size: clamp(58px, 11vw, 104px);
  font-weight: 900;
  letter-spacing: 1px;
  line-height: .95;
  margin: 0 0 14px;
  text-shadow: 4px 5px 0 var(--purple-shadow);
}
.wordmark-sub {
  display: block;
  margin-top: 8px;
  color: var(--cream);
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: clamp(15px, 1.8vw, 21px);
  font-weight: 800;
  letter-spacing: .12em;
  line-height: 1.25;
  text-shadow: none;
  text-transform: uppercase;
}
.wordmark .rift { color: var(--rift-orange); }
.tagline {
  font-size: 140%;
  font-weight: 700;
  color: var(--cream);
  letter-spacing: .5px;
  margin: 0 0 14px;
  line-height: 1.45;
}
.hero-copy .sub { margin: 0 0 28px; max-width: 560px; }

.badges { display: flex; flex-wrap: wrap; gap: 12px; }
.store {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 20px;
  border-radius: var(--r-md);
  border: 2px solid transparent;
  font-weight: 800;
  transition: transform .18s, filter .18s;
}
.store:hover { transform: translateY(-2px); }
/* Slot for an official store badge image once each store is live. Sized to
   respect the minimum-height rules in the brand guidelines; never restyle,
   recolour, or redraw the supplied artwork. */
.store .ico { width: 24px; height: 24px; flex: 0 0 24px; }
.store-badge img { height: 48px; width: auto; display: block; }
.store .lines { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.store .small { font-size: 62%; letter-spacing: 2px; text-transform: uppercase; opacity: .8; }
.store .big { font-size: 92%; letter-spacing: .5px; }
.store-live { background: var(--peach); color: var(--peach-text); border-color: rgba(255, 255, 255, .25); }
.store-soon {
  background: var(--pill-bg);
  color: var(--lavender);
  border-color: rgba(168, 155, 196, .35);
  cursor: default;
}
.store-soon:hover { transform: none; }

/* phone / demo */
.phone {
  position: relative;
  width: 100%;
  max-width: 340px;
  margin: 0 auto;
  border-radius: 34px;
  padding: 12px;
  background: linear-gradient(160deg, #3b3a63, #1a1a30);
  border: 2px solid rgba(244, 201, 93, .35);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .55);
}
.phone::before {
  content: '';
  position: absolute;
  top: 20px; left: 50%;
  transform: translateX(-50%);
  width: 74px; height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .18);
  z-index: 3;
}
.screen {
  position: relative;
  border-radius: 24px;
  overflow: hidden;
  aspect-ratio: 9 / 16;
  background: var(--sky-top);
}
#game { display: block; width: 100%; height: 100%; cursor: pointer; touch-action: manipulation; }
.demo-tag {
  text-align: center;
  margin-top: 14px;
  font-size: 80%;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--lavender);
}

/* ---------- generic card ---------- */
.card {
  background: radial-gradient(circle at 50% 42%, var(--card-center), var(--card-edge) 78%);
  border: 2px solid var(--card-border);
  border-radius: var(--r-lg);
  padding: 22px;
}

.grid { display: grid; gap: 16px; }
.g3 { grid-template-columns: repeat(3, 1fr); }
.g4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .g3, .g4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .g3, .g4 { grid-template-columns: 1fr; } }

/* ---------- modes ---------- */
.modes { background: #0D1428; }
.mode {
  position: relative;
  transition: transform .2s, border-color .2s;
}
.mode:hover { transform: translateY(-4px); border-color: var(--gold); }
.mode h3 {
  font-size: 145%;
  font-weight: 900;
  letter-spacing: 1px;
  margin: 12px 0 8px;
  text-shadow: 2px 3px 0 var(--purple-shadow);
}
.mode p { font-size: 100%; line-height: 1.65; color: var(--lavender); font-weight: 500; margin: 0 0 18px; }
.mode-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  border-radius: 6px;
  background: #C56B3A;
  color: #FFF1D6;
  font-size: 92%;
  font-weight: 900;
}
.chip {
  display: inline-block;
  font-size: 74%;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: var(--r-sm);
  border: 2px solid;
}
.chip-lock { background: #2E2E36; border-color: #55555F; color: #9095A2; }
.chip-open { background: rgba(184, 224, 168, .12); border-color: var(--mint); color: var(--mint); }

/* ---------- roster ---------- */
.roster { background: linear-gradient(180deg, #0D1428, #1A0E2E); }
.char {
  display: block;
  width: 100%;
  text-align: center;
  padding: 20px 14px;
  border-radius: var(--r-lg);
  background: #1B2236;
  border: 2px solid #2E3245;
  transition: transform .2s, border-color .2s, box-shadow .2s;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
}
.char:hover { transform: translateY(-5px); }
.char[aria-pressed="true"] { background: #212a44; }
/* Square, like the store's Canvas - a circular mask clips ear tufts, horns
   and Hina's comb, all of which sit near the top of the 88-unit box. */
.char-art {
  width: 96px; height: 96px;
  margin: 0 auto 12px;
  border-radius: var(--r-lg);
  display: grid;
  place-items: center;
  border: 2px solid;
  overflow: hidden;
}
.char-art canvas { width: 92px; height: 92px; display: block; }
.pick {
  display: block;
  margin-top: 12px;
  font-size: 72%;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--lavender);
}
.char[aria-pressed="true"] .pick { color: var(--mint); }
.char[aria-pressed="true"] .pick::before { content: '● '; }
.char h3 { margin: 0 0 3px; font-size: 115%; font-weight: 900; letter-spacing: .6px; }
.char .tag {
  display: block;
  font-size: 88%; color: var(--lavender); font-weight: 500;
  line-height: 1.5;
  margin: 0 0 14px; min-height: 3em; letter-spacing: .2px;
}
.rar {
  font-size: 72%;
  font-weight: 800;
  letter-spacing: 2px;
  text-transform: uppercase;
  display: block;
  margin-bottom: 10px;
}
.price {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 86%;
  font-weight: 800;
  background: #141826;
  border: 2px solid #2E3245;
  border-radius: var(--r-sm);
  padding: 5px 12px;
  color: var(--gold);
}
.price.free { color: var(--mint); border-color: rgba(184, 224, 168, .4); }

/* ---------- trails ---------- */
.trails { background: #150A28; }
.trail-wrap { display: grid; grid-template-columns: 300px 1fr; gap: 24px; align-items: start; }
@media (max-width: 820px) { .trail-wrap { grid-template-columns: 1fr; } }
.trail-list { display: flex; flex-direction: column; gap: 8px; }
.trail-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  font-family: inherit;
  font-size: 100%;
  font-weight: 800;
  letter-spacing: .5px;
  color: var(--cream);
  background: #1B2236;
  border: 2px solid #2E3245;
  border-radius: var(--r);
  padding: 14px 16px;
  cursor: pointer;
  transition: background .18s, border-color .18s;
}
.trail-btn:hover { border-color: #4a5170; }
.trail-btn[aria-selected="true"] { border-color: #FFB66B; background: rgba(255, 182, 107, .2); }
.trail-btn.soon { opacity: .6; }
.trail-btn.soon[aria-selected="true"] { opacity: 1; }
.trail-btn .dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 12px; }
.trail-btn .cost { margin-left: auto; font-size: 84%; color: var(--gold); }
.trail-stage {
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 2px solid var(--card-border);
  background: var(--sky-top);
  aspect-ratio: 16 / 9;
  position: relative;
}
/* Both preview canvases must be sized purely by their stage - if they size to
   their own backing store, the ResizeObserver below feeds back and runs away. */
#trailCanvas, #mapCanvas { display: block; width: 100%; height: 100%; }
.trail-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 16px 20px;
  background: linear-gradient(180deg, transparent, rgba(11, 14, 19, .92));
  font-size: 97%;
  line-height: 1.55;
  color: #C8BFDC;
  font-weight: 500;
}
/* 126% of the caption's own size, not the root - percentages compound. */
.trail-caption b { color: var(--cream); display: block; font-size: 126%; letter-spacing: .5px; margin-bottom: 4px; }

/* Maps caption sits below the preview rather than over it - the scene is
   busy enough without text on top of it. */
.map-col { min-width: 0; }
.map-caption {
  margin-top: 16px;
  padding: 18px 20px;
  background: #1B2236;
  border: 1px solid rgba(168, 155, 196, .18);
  border-radius: var(--r-sm);
  font-size: 97%;
  line-height: 1.55;
  color: #C8BFDC;
  font-weight: 500;
}
.map-caption b {
  color: var(--cream);
  display: block;
  font-size: 126%;
  letter-spacing: .5px;
  margin-bottom: 5px;
}

/* ---------- powerups ---------- */
.powerups { background: #0D1428; }
.pu-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
@media (max-width: 900px) { .pu-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .pu-grid { grid-template-columns: repeat(2, 1fr); } }
.pu {
  background: #1B2236;
  border: 2px solid #2E3245;
  border-radius: var(--r);
  padding: 16px 10px;
  text-align: center;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  transition: transform .18s, border-color .18s, background .18s;
}
.pu:hover, .pu[aria-expanded="true"] { transform: translateY(-3px); border-color: #FFB66B; background: rgba(255, 182, 107, .12); }
.pu img { width: 42px; height: 42px; margin: 0 auto 9px; image-rendering: auto; }
.pu .n { font-size: 88%; font-weight: 800; letter-spacing: .5px; display: block; margin-bottom: 6px; }
.pu .c { font-size: 82%; font-weight: 700; color: var(--gold); }
.pu .c.gem { color: #D8C5FF; }
.pu-detail {
  margin-top: 18px;
  min-height: 74px;
  border-radius: var(--r);
  border: 2px solid var(--pill-border);
  background: var(--pill-bg);
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.pu-detail img { width: 40px; height: 40px; flex: 0 0 40px; }
.pu-detail .txt b { font-size: 120%; letter-spacing: .5px; display: block; margin-bottom: 5px; }
.pu-detail .txt span { font-size: 100%; color: var(--lavender); font-weight: 500; line-height: 1.6; }
.pu-note {
  margin-top: 16px;
  font-size: 88%;
  color: var(--lavender);
  font-weight: 600;
  letter-spacing: .5px;
  text-align: center;
}

/* ---------- unlock ladder ---------- */
.ladder { background: linear-gradient(180deg, #1A0E2E, #101A35); }
.ladder-ui { max-width: 780px; margin: 0 auto; }
.score-readout { text-align: center; margin-bottom: 8px; }
.score-readout .v {
  font-size: 68px;
  font-weight: 900;
  letter-spacing: 2px;
  text-shadow: 3px 4px 0 var(--purple-shadow);
  line-height: 1;
}
.score-readout .l {
  font-size: 80%;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--lavender);
}
.slider-row { padding: 26px 4px 34px; }
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 10px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--rift-orange) var(--fill, 0%), #2E3245 var(--fill, 0%));
  outline: none;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--peach);
  border: 3px solid var(--sky-top);
  cursor: grab;
}
input[type="range"]::-moz-range-thumb {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--peach);
  border: 3px solid var(--sky-top);
  cursor: grab;
}
.unlock-list { display: grid; gap: 10px; }
.unlock {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  border-radius: var(--r);
  border: 2px solid #55555F;
  background: #2E2E36;
  color: #9095A2;
  transition: all .28s ease;
}
.unlock.on {
  background: rgba(184, 224, 168, .1);
  border-color: var(--mint);
  color: var(--cream);
}
.unlock .req {
  font-size: 82%;
  font-weight: 900;
  min-width: 46px;
  text-align: center;
  padding: 4px 0;
  border-radius: 6px;
  background: rgba(0, 0, 0, .3);
}
.unlock.on .req { background: var(--mint); color: #1F3A1A; }
.unlock .nm { font-size: 104%; font-weight: 800; letter-spacing: .5px; line-height: 1.6; }
.unlock .ds { font-size: 94%; font-weight: 500; opacity: .85; line-height: 1.55; }
.unlock .mult {
  margin-left: auto;
  font-size: 74%;
  font-weight: 800;
  letter-spacing: 1px;
  padding: 4px 9px;
  border-radius: 6px;
  border: 2px solid currentColor;
  white-space: nowrap;
}
@media (max-width: 560px) {
  .unlock { flex-wrap: wrap; }
  .unlock .mult { margin-left: 0; }
}

/* ---------- bonus maps ---------- */
.bonus { background: #150A28; }
.luck {
  text-align: center;
  max-width: 620px;
  margin: -20px auto 34px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .4px;
  color: var(--gold);
}
.portal-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 44px 0 0; }
@media (max-width: 700px) { .portal-row { grid-template-columns: repeat(2, 1fr); } }
.portal {
  text-align: center;
  padding: 26px 12px;
  border-radius: var(--r-lg);
  border: 2px solid;
  position: relative;
  overflow: hidden;
}
.portal .ring {
  width: 56px; height: 56px;
  border-radius: 50%;
  margin: 0 auto 12px;
  border: 3px solid;
  animation: pulse 2.6s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { transform: scale(1); opacity: .85; } 50% { transform: scale(1.09); opacity: 1; } }
.portal .t { font-size: 26px; font-weight: 900; letter-spacing: 1px; }
.portal .s { font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--lavender); }

.roll { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; max-width: 640px; margin: 0 auto; }
@media (max-width: 560px) { .roll { grid-template-columns: 1fr; } }
.roll div {
  padding: 18px;
  border-radius: var(--r);
  border: 2px solid;
  text-align: center;
}
.roll .pct { font-size: 28px; font-weight: 900; letter-spacing: 1px; }
.roll .k { font-size: 12px; font-weight: 800; letter-spacing: 2px; text-transform: uppercase; }

/* ---------- how to play ---------- */
/* Sits directly under the hero now - carry the hero's dark horizon down into
   the Modes section's flat navy. */
.how { background: linear-gradient(180deg, #02050C 0%, #0D1428 100%); }
.how-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 800px) { .how-grid { grid-template-columns: 1fr; } }
.how-step { display: flex; gap: 14px; align-items: flex-start; }
.how-step .n {
  flex: 0 0 42px;
  height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--pill-bg);
  border: 2px solid var(--pill-border);
  font-size: 105%;
  font-weight: 900;
  color: var(--gold);
}
.how-step h3 { margin: 6px 0 6px; font-size: 110%; font-weight: 900; letter-spacing: .5px; }
.how-step p { margin: 0; font-size: 100%; line-height: 1.7; color: var(--lavender); font-weight: 500; }

/* ---------- achievements + sharing ---------- */
.achieve { background: linear-gradient(180deg, #0D1428, #150A28); }
.achieve-wrap {
  display: grid;
  grid-template-columns: minmax(0, 430px) 330px;
  gap: 40px;
  align-items: start;
  justify-content: center;
}
@media (max-width: 920px) { .achieve-wrap { grid-template-columns: minmax(0, 430px); } }

/* Four tiers stacked beside the share card. */
.tiers { display: grid; grid-template-columns: 1fr; gap: 14px; align-content: start; }
.tier {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  border: 2px solid;
  border-radius: var(--r);
  padding: 20px 22px;
  background: rgba(255, 255, 255, .03);
}
.tier .t {
  font-size: 105%;
  font-weight: 900;
  letter-spacing: 3px;
  text-transform: uppercase;
}
.tier .r { font-size: 110%; font-weight: 900; color: var(--gold); white-space: nowrap; }

/* Share card - mirrors the 1080² PNG the game hands to the share sheet:
   logo art under a NEW BEST pill, the score numeral, and the CTA line. */
/* width:100% is load-bearing - container-type makes the intrinsic width
   resolve to 0, so any shrink-to-fit context (e.g. the auto margins below)
   would collapse the card entirely. */
.share-col { container-type: inline-size; position: sticky; top: 90px; width: 100%; }
@media (max-width: 920px) { .share-col { position: static; max-width: 340px; margin: 0 auto; } }
.share-card {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #1F1B3A url('../img/cloudrift-logo.webp?v=1d7367317423') center / cover no-repeat;
  border: 2px solid var(--card-border);
}
/* Metrics are the source's fractions of the 1080px card: badge type .038,
   score .22, tagline .05; badge padding .025/.012, radius .015. */
.share-card .newbest {
  position: absolute; left: 50%; top: 67%; transform: translate(-50%, -50%);
  background: #B8E0A8; color: #1F3A1A;
  font-size: 3.8cqw; font-weight: 900; letter-spacing: .073em;
  padding: 1.2cqw 2.5cqw; border-radius: 1.5cqw;
  white-space: nowrap;
}
.share-card .score {
  position: absolute; left: 50%; top: 81%; transform: translate(-50%, -50%);
  color: var(--cream); font-size: 22cqw; font-weight: 900; line-height: 1;
  text-shadow: 0.9cqw 1.2cqw 0 var(--purple-shadow);
}
.share-card .beat {
  position: absolute; left: 50%; top: 95%; transform: translate(-50%, -50%);
  color: var(--cream); font-size: 5cqw; font-weight: 900; letter-spacing: .093em;
  text-shadow: 0.5cqw 0.5cqw 0 rgba(26, 31, 38, .8);
  white-space: nowrap;
}
.share-cap {
  margin: 12px 0 0;
  text-align: center;
  font-size: 78%;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--lavender);
}
.share-msg {
  margin-top: 14px;
  background: var(--pill-bg);
  border: 2px solid var(--pill-border);
  border-radius: var(--r-md);
  padding: 13px 16px;
  font-size: 88%;
  font-weight: 500;
  line-height: 1.5;
  color: var(--cream);
}
.share-to { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; justify-content: center; }
.share-to span {
  font-size: 74%;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--lavender);
  border: 2px solid #2E3245;
  border-radius: var(--r-sm);
  padding: 5px 10px;
}

.cta-inline { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
.cta-inline:hover { color: var(--cream); }

/* ---------- FAQ ----------
   <details>/<summary> rather than JS: the answers are in the DOM and
   crawlable whether or not an item is open, and it works with no script. */
.faq { background: linear-gradient(180deg, #150A28, #0D1428); }
.faq-list { max-width: 820px; margin: 0 auto; display: grid; gap: 12px; }
.faq-item {
  background: #1B2236;
  border: 1px solid rgba(168, 155, 196, .18);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.faq-item[open] { border-color: rgba(244, 201, 93, .38); }
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 18px 22px;
  display: flex;
  align-items: center;
  gap: 14px;
  transition: background .16s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { background: rgba(255, 255, 255, .04); }
.faq-item summary h3 {
  margin: 0;
  flex: 1;
  font-size: 104%;
  font-weight: 800;
  letter-spacing: .4px;
  color: var(--cream);
}
/* Chevron drawn in CSS so there's no icon font or image to load. */
.faq-item summary::after {
  content: '';
  flex: 0 0 10px;
  width: 10px; height: 10px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .2s;
}
.faq-item[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq-item p {
  margin: 0;
  padding: 0 22px 20px;
  font-size: 100%;
  line-height: 1.7;
  color: var(--lavender);
  font-weight: 500;
}
@media (max-width: 560px) {
  .faq-item summary { padding: 15px 16px; }
  .faq-item summary h3 { font-size: 98%; }
  .faq-item p { padding: 0 16px 17px; }
}

/* ---------- CTA ---------- */
.cta {
  padding: 100px 0;
  text-align: center;
  background: linear-gradient(180deg, #101A35 0%, #3A2C55 55%, #6E3F58 100%);
  position: relative;
  overflow: hidden;
}
.cta .badges { justify-content: center; margin-top: 30px; }
.platform-note {
  margin-top: 26px;
  font-size: 88%;
  font-weight: 600;
  letter-spacing: 1px;
  color: rgba(245, 233, 211, .7);
}

/* ---------- footer ---------- */
.footer { background: #02050C; padding: 42px 0; border-top: 2px solid rgba(244, 201, 93, .15); }
.footer-in { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
/* The badge is round, so height is left to follow the source aspect rather
   than being pinned to a square - pinning it squashed the circle into an
   ellipse. object-fit is a belt-and-braces guard if the art is ever swapped
   for something non-square. */
.footer img { width: 46px; height: auto; object-fit: contain; }
.footer .fine { font-size: 88%; color: var(--lavender); font-weight: 500; line-height: 1.7; }
.footer .links { margin-left: auto; display: flex; gap: 18px; }
.footer .links a { font-size: 74%; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--lavender); }
.footer .links a:hover { color: var(--gold); }
@media (max-width: 620px) { .footer .links { margin-left: 0; } }

/* ---------- information pages ---------- */
/* Info pages (about / help / privacy) are text-first, so they keep a single
   readable column rather than the home page's centered section rhythm - but
   every visual token is the site's, so they read as the same product:
   the same sky-to-dark background, the same uppercase drop-shadow headings,
   the same radial-gradient cards, the same nav and footer. */
.info-body {
  min-height: 100vh;
  /* Same descent the home page makes from hero sky into its dark lower
     sections, using site tokens instead of one-off hexes. */
  background: linear-gradient(180deg, var(--sky-top) 0%, #0D1428 55%, #02050C 100%);
}
.info-main { width: min(900px, calc(100% - 32px)); margin: 0 auto; padding: 70px 0 90px; }
.info-hero { margin-bottom: 30px; }
/* Matches the site heading treatment (see .h2 / .wordmark): uppercase with
   the purple drop-shadow, so an info h1 reads like a home-page section title. */
.info-hero h1 {
  margin: 5px 0 16px;
  font-size: clamp(42px, 9vw, 76px);
  line-height: .95;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-shadow: 3px 4px 0 var(--purple-shadow);
}
.info-hero .sub { max-width: 720px; }
/* Same radial-gradient body and gold-tinted 2px border as the home .card. */
.info-card {
  padding: clamp(22px, 5vw, 42px);
  border: 2px solid var(--card-border);
  border-radius: var(--r-xl);
  background: radial-gradient(circle at 50% 42%, var(--card-center), var(--card-edge) 78%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .3);
}
.info-card + .info-card { margin-top: 18px; }
.info-card h2 {
  margin: 0 0 12px;
  color: var(--cream);
  font-size: clamp(24px, 4vw, 34px);
  font-weight: 900;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-shadow: 2px 3px 0 var(--purple-shadow);
}
.info-card h3 { margin: 25px 0 8px; color: var(--gold); font-size: 116%; letter-spacing: .4px; }
.info-card p, .info-card li { color: var(--lavender); line-height: 1.75; }
.info-card a { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
.info-card a:hover { color: var(--cream); }
.info-card ul, .info-card ol { padding-left: 22px; }
.info-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
.info-actions a { padding: 11px 18px; border-radius: 999px; background: var(--gold); color: var(--peach-text); font-weight: 900; text-decoration: none; border: 2px solid rgba(255, 255, 255, .22); transition: filter .18s; }
.info-actions a:hover { filter: brightness(1.07); }
.info-actions a.secondary { background: var(--pill-bg); color: var(--cream); border: 2px solid var(--pill-border); }

/* ---------- play page (play.html) ---------- */
.play-body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: #0A0F1F;
}
.play-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;          /* the Play CTA drops to its own row on phones */
  gap: 10px 16px;
  padding: 12px 20px;
  /* Same fix as .nav: this was rgba(16, 26, 53, .9) sitting on a #0A0F1F
     page, close enough that the bar barely separated from the playfield
     behind it. Solid rather than translucent, since nothing scrolls under
     this one - it's the first row of a flex column, not sticky. */
  border-bottom: 2px solid rgba(244, 201, 93, .42);
  background: #060B18;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .45);
  position: relative;   /* lift it above the playfield so the shadow lands */
  z-index: 5;
}
.play-get {
  margin-left: auto;
  background: var(--peach);
  color: var(--peach-text);
  border: 2px solid rgba(255, 255, 255, .22);
  border-radius: var(--r);
  padding: 9px 15px;
  font-size: 82%;
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.play-get:hover { filter: brightness(1.07); }
/* Non-interactive variant: there is no live listing to link to yet. */
.play-get-soon {
  background: var(--pill-bg);
  color: var(--lavender);
  border-color: rgba(168, 155, 196, .35);
  cursor: default;
}
.play-get-soon:hover { filter: none; }

/* Ad slots - reserved space only. Replace the inner <span> with your ad tag,
   or delete the element to reclaim the space. */
.ad {
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .025);
  border: 1px dashed rgba(168, 155, 196, .3);
  border-radius: var(--r-sm);
  color: rgba(168, 155, 196, .55);
  font-size: 70%;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.ad-top { width: min(970px, calc(100% - 32px)); height: 90px; margin: 14px auto 0; }
.ad-side { width: 160px; height: 600px; position: sticky; top: 16px; }

.play-grid {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 840px);
  gap: 0;
  align-items: start;
  justify-content: center;
  padding: 16px 20px 28px;
}
/* Backdrop renders the selected map across the whole window; everything else
   sits above it, so the portrait playfield reads as a window into the scene
   instead of a phone floating on a flat page. */
.play-bg { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; }
/* Lift page content above the backdrop - but never the fixed overlays, whose
   position:fixed would be clobbered by position:relative.
   .play-bar is excluded too: it needs to sit ABOVE its later siblings so its
   drop shadow lands on the playfield, and it sets its own position/z-index.
   Three :not() clauses make this selector (0,4,0), so it silently beat the
   plain .play-bar rule until the bar was excluded here. */
.play-body > *:not(.play-bg):not(.bag):not(.ovl):not(.play-bar):not(.skip-link) { position: relative; z-index: 1; }
.play-body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  background: rgba(6, 9, 18, .62);
  pointer-events: none;
}

.play-stage { display: flex; justify-content: center; }

/* The promo intro and the controls guide sit side by side in a row below the
   playfield. Both were standalone centered cards; inside .play-below they
   become equal-height grid items. Stacks on narrow screens. */
/* One merged panel below the game: the promo sits on top, the how-to-play
   guide directly below it, split by a divider inside a single card. */
.play-below {
  width: min(1040px, calc(100% - 32px));
  margin: 24px auto 30px;
  padding: 30px clamp(20px, 4vw, 40px);
  border: 1px solid rgba(244, 201, 93, .22);
  border-radius: var(--r-lg);
  background: rgba(6, 11, 24, .9);
  box-shadow: 0 16px 42px rgba(0, 0, 0, .32);
}
/* The inner sections drop their own frames - the panel is the frame now. */
.play-below .play-intro,
.play-below .play-guide {
  width: auto;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}
/* Divider between the promo and the guide. */
.play-below .play-guide {
  margin-top: 26px;
  padding-top: 26px;
  border-top: 1px solid rgba(168, 155, 196, .18);
}
.play-below .play-guide-grid { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
/* The play-bar isn't sticky, but leave a little breathing room when the
   header link jumps here. */
#how-to-play { scroll-margin-top: 20px; }

.play-intro {
  width: min(900px, calc(100% - 32px));
  margin: 24px auto 0;
  padding: 22px 26px;
  border: 1px solid rgba(244, 201, 93, .28);
  border-radius: var(--r-lg);
  background: rgba(6, 11, 24, .88);
  box-shadow: 0 16px 42px rgba(0, 0, 0, .32);
}
.play-intro .eyebrow, .play-guide .eyebrow { margin: 0 0 5px; }
.play-intro h1, .play-guide h2 {
  margin: 0 0 8px;
  color: var(--cream);
  font-size: clamp(28px, 5vw, 48px);
  line-height: 1.05;
}
.play-intro > p:not(.eyebrow) { max-width: 760px; margin: 0; color: var(--lavender); line-height: 1.65; }
.play-facts { display: flex; flex-wrap: wrap; gap: 8px; margin: 15px 0 0; padding: 0; list-style: none; }
.play-facts li {
  padding: 7px 11px;
  border: 1px solid rgba(244, 201, 93, .25);
  border-radius: 999px;
  background: var(--pill-bg);
  color: var(--gold);
  font-size: 76%;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.play-guide {
  width: min(1040px, calc(100% - 32px));
  margin: 0 auto 28px;
  padding: 30px;
  border: 1px solid rgba(168, 155, 196, .26);
  border-radius: var(--r-lg);
  background: rgba(6, 11, 24, .9);
}
.play-guide h2 { font-size: clamp(26px, 4vw, 40px); }
.play-guide-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 20px; }
.play-guide-grid article { padding: 18px; border-radius: var(--r); background: rgba(255, 255, 255, .045); }
.play-guide-grid h3 { margin: 0 0 7px; color: var(--gold); font-size: 108%; }
.play-guide-grid p, .play-save-note { margin: 0; color: var(--lavender); line-height: 1.65; }
.play-save-note { margin-top: 18px; }
.play-save-note a { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
.play-footer {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 18px max(20px, calc((100% - 1040px) / 2));
  border-top: 1px solid rgba(168, 155, 196, .18);
  background: #060B18;
  color: var(--lavender);
  font-size: 78%;
}
.play-footer nav { display: flex; flex-wrap: wrap; gap: 16px; }
.play-footer a:hover { color: var(--gold); }
.play-screen {
  position: relative;            /* anchors the main-menu chrome */
  height: min(80vh, 840px);
  aspect-ratio: 1;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 2px solid rgba(244, 201, 93, .35);
  background: var(--sky-top);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
}
.play-screen canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: pointer;
  touch-action: manipulation;
}


.play-icon-btn {
  background: var(--pill-bg);
  border: 2px solid var(--pill-border);
  color: var(--cream);
  border-radius: var(--r);
  padding: 8px 14px;
  font-size: 78%;
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
}
.play-icon-btn:hover { border-color: var(--gold); }
.btn-ico { display: none; }          /* phone view swaps this in for .btn-label */

/* ---- main-menu chrome over the playfield ---- */
/* Mirrors MenuScreen's stacked chrome cards: tap target on top (48dp icon +
   gold label), currency balance beneath, both PillBg with a 2dp gold rim. */
.menu-chrome {
  position: absolute;
  top: 20px; left: 16px;
  width: 124px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: opacity .2s;
}
.menu-chrome[hidden] { display: none; }
.chrome-card {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 6px 8px;
  background: var(--pill-bg);
  border: 2px solid var(--pill-border);
  border-radius: 14px;
  cursor: pointer;
  transition: transform .16s, border-color .16s;
}
.chrome-card:hover { transform: translateY(-2px); border-color: var(--gold); }
.chrome-card img { width: 48px; height: 48px; }
.chrome-card span {
  color: var(--gold);
  font-size: 106%;
  font-weight: 900;
  letter-spacing: .5px;
}
.chrome-balance {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  background: var(--pill-bg);
  border: 2px solid var(--pill-border);
  border-radius: 12px;
  color: var(--gold);
  font-size: 92%;
  font-weight: 900;
}
/* Painted by R.coinGlyph so the menu balance shows the same coin as the
   playfield and the buy buttons, rather than a flat CSS approximation. */
/* Selector beats `.play-screen canvas`, which stretches the playfield canvas
   to 100% and would otherwise swallow this one. */
/* Watch-ad-for-coins button, sits under the balance on the menu chrome.
   Gold fill so it reads as the one earn action in the pre-run menu. */
.chrome-ad {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
  padding: 6px 9px;
  background: var(--gold);
  color: var(--peach-text);
  border: 2px solid rgba(255, 255, 255, .22);
  border-radius: 12px;
  cursor: pointer;
  font-weight: 900;
  font-size: 78%;
  letter-spacing: .02em;
  transition: filter .16s;
}
.chrome-ad:hover:not(:disabled) { filter: brightness(1.07); }
.chrome-ad:disabled { opacity: .5; cursor: default; }
.chrome-ad[hidden] { display: none; }   /* flex display would otherwise defeat the hidden attribute */
.chrome-ad-label { text-transform: uppercase; }
.chrome-ad-reward { font-weight: 900; }

.chrome-balance .coin-dot {
  display: block;
  width: 22px; height: 22px;
  margin: 0 10px 0 0;
  flex: 0 0 22px;
}

/* ---- game over ----
   Ported from ui/GameOverScreen.kt. Sizes are the source's dp/sp values times
   --gs, the playfield's scale against the game's 640dp reference height, so
   the whole screen keeps its phone proportions at any canvas size. */
.go {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(14px * var(--gs, 1));
  background: rgba(11, 14, 19, .8);
  padding: calc(20px * var(--gs, 1));
}
.go[hidden] { display: none; }
/* Menu wordmark - mirrors the mobile MenuScreen title (MenuScreen.kt): two-tone
   CloudRift ("Cloud" cream, "Rift" orange) over a single purple drop-shadow,
   scaled to the playfield via --gs like the other overlays. Sits top-centre,
   above the TAP TO FLY hint, and is toggled off the moment a run starts. */
.play-wordmark {
  position: absolute;
  top: calc(24px * var(--gs, 1));
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  font-family: 'MotionControl', 'Segoe UI', system-ui, sans-serif;
  font-size: calc(48px * var(--gs, 1));
  font-weight: 900;
  letter-spacing: calc(1px * var(--gs, 1));
  line-height: 1;
  color: var(--cream);
  text-shadow: calc(4px * var(--gs, 1)) calc(5px * var(--gs, 1)) 0 var(--purple-shadow);
  pointer-events: none;
  white-space: nowrap;
}
.play-wordmark .rift { color: var(--rift-orange); }
.play-wordmark[hidden] { display: none; }

.go-title {
  margin: 0;
  font-size: calc(52px * var(--gs, 1));
  font-weight: 900;
  letter-spacing: calc(4px * var(--gs, 1));
  color: var(--cream);
  text-shadow: calc(4px * var(--gs, 1)) calc(5px * var(--gs, 1)) 0 var(--purple-shadow);
}
.go-card {
  width: calc(320px * var(--gs, 1));
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(2px * var(--gs, 1));
  padding: calc(18px * var(--gs, 1)) calc(22px * var(--gs, 1));
  border-radius: calc(18px * var(--gs, 1));
  background: radial-gradient(circle at 50% 50%, #4A3B6B, #252548);
  border: calc(2px * var(--gs, 1)) solid rgba(212, 165, 116, .6);
}
.go-label {
  font-size: calc(13px * var(--gs, 1));
  font-weight: 700;
  letter-spacing: calc(2px * var(--gs, 1));
  text-transform: uppercase;
  color: var(--lavender);
}
.go-num {
  font-size: calc(30px * var(--gs, 1));
  font-weight: 900;
  letter-spacing: calc(1px * var(--gs, 1));
  color: var(--cream);
  text-shadow: calc(2px * var(--gs, 1)) calc(3px * var(--gs, 1)) 0 var(--purple-shadow);
}
.go-bestrow {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--gs, 1));
  margin-top: calc(10px * var(--gs, 1));
}
.go-new {
  background: #B8E0A8;
  color: #1F3A1A;
  border-radius: calc(4px * var(--gs, 1));
  padding: calc(2px * var(--gs, 1)) calc(6px * var(--gs, 1));
  font-size: calc(9px * var(--gs, 1));
  font-weight: 900;
  letter-spacing: calc(.5px * var(--gs, 1));
  text-transform: uppercase;
}
.go-new[hidden] { display: none; }
.go-chip {
  display: flex;
  align-items: center;
  gap: calc(12px * var(--gs, 1));
  padding: calc(12px * var(--gs, 1)) calc(18px * var(--gs, 1));
  background: var(--pill-bg);
  border: calc(2px * var(--gs, 1)) solid var(--pill-border);
  border-radius: calc(14px * var(--gs, 1));
}
.go-chip[hidden] { display: none; }
.go-chip canvas {
  width: calc(34px * var(--gs, 1));
  height: calc(34px * var(--gs, 1));
  display: block;
}
.go-earned { font-size: calc(28px * var(--gs, 1)); font-weight: 900; color: var(--gold); }
.go-wallet {
  font-size: calc(17px * var(--gs, 1));
  font-weight: 600;
  letter-spacing: calc(.5px * var(--gs, 1));
  color: var(--lavender);
}
.go-row {
  display: flex;
  gap: calc(12px * var(--gs, 1));
  width: calc(320px * var(--gs, 1));
  max-width: 100%;
  margin-top: calc(4px * var(--gs, 1));
}
.go-btn {
  /* No flex-grow here - .go-retry is a child of the column and would stretch
     to fill the leftover height. Only the two buttons in .go-row share width. */
  flex: 0 0 auto;
  border: 0;
  cursor: pointer;
  border-radius: calc(12px * var(--gs, 1));
  padding: calc(11px * var(--gs, 1)) calc(16px * var(--gs, 1));
  font-size: calc(15px * var(--gs, 1));
  font-weight: 600;
  transition: filter .16s;
}
.go-btn:hover { filter: brightness(1.08); }
.go-row .go-btn { flex: 1 1 0; }
.go-menu { background: #5C5980; color: var(--cream); }
.go-share { background: #4A8E9B; color: var(--cream); }
.go-retry {
  width: calc(320px * var(--gs, 1));
  max-width: 100%;
  background: var(--peach);
  color: var(--peach-text);
}

/* Mode select - stacked full-width rows, name left / best right, per
   ui/MenuScreen.kt: 21sp ExtraBold, 14dp radius, h17/v16 padding, 85% width. */
/* Fireballs mechanic: circular fire button in the lower-right of the playfield.
   Scales with the playfield via --gs, sits above the canvas so taps fire
   instead of flapping. */
.fire-btn {
  position: absolute;
  right: calc(16px * var(--gs, 1));
  bottom: calc(16px * var(--gs, 1));
  z-index: 4;
  width: calc(60px * var(--gs, 1));
  height: calc(60px * var(--gs, 1));
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 11, 24, 0.7);
  border: 2px solid rgba(255, 150, 60, 0.85);
  box-shadow: 0 0 calc(14px * var(--gs, 1)) rgba(255, 120, 40, 0.45);
  cursor: pointer;
  transition: transform .1s, filter .12s;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.fire-btn[hidden] { display: none; }
.fire-btn:active { transform: scale(0.9); filter: brightness(1.2); }
.fire-btn img { width: 64%; height: 64%; object-fit: contain; pointer-events: none; }
/* Cooldown state: dim the flame, dark border, show the remaining seconds. */
.fire-btn.cooling { border-color: rgba(120, 130, 150, 0.7); box-shadow: none; cursor: default; }
.fire-btn.cooling:active { transform: none; filter: none; }
.fire-cd {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: calc(22px * var(--gs, 1));
  color: var(--cream);
  pointer-events: none;
}
.fire-cd[hidden] { display: none; }

.mode-row {
  position: absolute;
  left: 50%; bottom: calc(20px * var(--gs, 1));
  transform: translateX(-50%);
  /* fillMaxWidth(0.85f) of the game 360dp-wide screen, not of our square
     canvas - otherwise the buttons stretch to the full playfield width. */
  width: calc(306px * var(--gs, 1));
  max-width: 88%;
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--gs, 1));
}
.mode-row[hidden] { display: none; }
.mode-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  border: 0;
  border-radius: calc(14px * var(--gs, 1));
  padding: calc(16px * var(--gs, 1)) calc(17px * var(--gs, 1));
  font-size: calc(21px * var(--gs, 1));
  font-weight: 800;
  letter-spacing: calc(1px * var(--gs, 1));
  cursor: pointer;
  transition: filter .16s, transform .16s;
}
.mode-btn:hover:not(.locked) { filter: brightness(1.06); transform: translateY(-1px); }
.mode-best { opacity: .82; text-transform: uppercase; }

.mode-classic { background: var(--peach); color: var(--peach-text); }
/* Ported from MenuScreen.kt: Classic stays flat peach; Challenge is the deep
   navy pill (PillBg) with a warm-gold rim (PillBorder), cream label and
   lavender best - reads as "advanced" without looking secondary. Scoped to
   :not(.locked) so a locked Challenge keeps its muted grey state below. */
.mode-challenge:not(.locked) {
  background: var(--pill-bg);
  color: var(--cream);
  border: 2px solid var(--pill-border);
}
.mode-challenge:not(.locked) .mode-best { color: var(--lavender); }
/* Locked Challenge: LoadoutTheme locked chip, with a padlock before the goal */
.mode-btn.locked { background: #2E2E36; color: #9095A2; box-shadow: inset 0 0 0 2px #55555F; }
/* Padlock before the goal, as a literal glyph: a CSS unicode escape
   needs a terminating space and is easy to mangle. */
.mode-btn.locked .mode-best::before { content: "🔒"; margin-right: 6px; }

/* Achievements */
.ach-count {
  margin-left: auto;
  font-size: 74%;
  font-weight: 800;
  letter-spacing: 1px;
  color: var(--gold);
}
.ach { gap: 12px; }
.ach.on { border-color: rgba(255, 182, 107, .45); }
.ach-tick {
  width: 26px; height: 26px;
  flex: 0 0 26px;
  border-radius: 8px;
  border: 2px solid;
  display: grid;
  place-items: center;
  font-size: 68%;
  font-weight: 900;
  color: #12172A;
}

/* ---- bag ----
   Ported from ui/CustomizeScreen.kt + ui/LoadoutTheme.kt. */
.bag {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(8, 10, 14, .9);      /* ScrimDim #E6080A0E */
  backdrop-filter: blur(4px);
}
.bag[hidden] { display: none; }
.bag-card {
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 14px;
}
.bag-head { display: flex; align-items: center; gap: 10px; }
.bag-head h2 { margin: 0; font-size: 158%; font-weight: 900; color: #fff; }
.bag-x {
  margin-left: auto;
  background: #1F232C;                  /* SecondaryButton */
  border: 0;
  color: #fff;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 74%;
  font-weight: 700;
  cursor: pointer;
}
.bag-x:hover { background: #2B3041; }

/* CoinBalanceRow - CardBg, 12dp radius, coin + count */
.bag-wallet {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: #1B2236;
  border-radius: 12px;
  color: #fff;
  font-size: 95%;
  font-weight: 800;
}
.bag-wallet canvas { width: 22px; height: 22px; display: block; }

/* Tab row - equal widths, 12dp radius, 14sp ExtraBold */
.bag-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.bag-tab {
  padding: 10px 6px;
  border-radius: 12px;
  background: #1B2236;                  /* CardBg */
  border: 1px solid #2E3245;            /* NeutralBorder */
  color: #E9EDF8;                       /* NeutralText */
  font-size: 74%;
  font-weight: 800;
  cursor: pointer;
  white-space: nowrap;
}
.bag-tab[aria-selected="true"] {
  background: #E8B97E;                  /* TitleBarBg */
  border-color: transparent;
  color: #1B1F27;                       /* TitleBarText */
}

/* Tab content card - SectionBg with the 2dp clay border */
.bag-panel {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border-radius: 16px;
  background: #12172A;                  /* SectionBg */
  border: 2px solid #C97A48;            /* SectionBorder */
}

/* TierHeader - 10x18 accent bar + uppercase rarity label */
.tier-head { display: flex; align-items: center; gap: 10px; padding: 4px 0 2px; }
.tier-bar { width: 10px; height: 18px; border-radius: 3px; flex: 0 0 10px; }
.tier-name { font-size: 74%; font-weight: 900; letter-spacing: 3px; }
.bag-caption {
  padding: 0 0 2px 4px;
  color: #98A0B3;                       /* SubtleText */
  font-size: 74%;
  font-weight: 600;
  letter-spacing: 1px;
}

/* CosmeticRow */
.cos {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border-radius: 14px;
  background: #1B2236;                  /* CardBg */
  border: 1px solid #2E3245;
}
.cos-icon {
  width: 72px; height: 72px;
  flex: 0 0 72px;
  display: grid;
  place-items: center;
  padding: 4px;
  border-radius: 12px;
  background: #141826;                  /* CardBgDim */
}
.cos-icon canvas,
.cos-icon img { width: 64px; height: 64px; display: block; object-fit: contain; }
.cos-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cos-name { font-size: 96%; font-weight: 700; color: #E9EDF8; }
.cos-tag { font-size: 68%; color: #98A0B3; line-height: 1.35; }
.cos-btn {
  flex: 0 0 auto;
  border: 0;
  border-radius: 10px;
  padding: 10px 18px;
  font-size: 78%;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
}
.cos-btn canvas { width: 16px; height: 16px; display: block; }
.cos-equipped {                          /* not a button - a static chip */
  background: #141826;
  border: 1px solid #2E3245;
  color: #98A0B3;
  padding: 10px 14px;
  font-size: 72%;
  font-weight: 600;
  border-radius: 10px;
  cursor: default;
}
.cos-equip { background: #FFB66B; color: #1A1F26; }      /* PrimaryButton */
.cos-buy { background: #E89B5C; color: #1B1F27; font-weight: 900; }
.cos-buy.locked { background: #2B3041; color: #98A0B3; cursor: not-allowed; }
/* Mechanics tab toggle: dark pill when Off, gold when On (min-width so the
   row doesn't reflow as the label changes between Off and On). */
.cos-toggle {
  min-width: 56px;
  justify-content: center;
  background: var(--pill-bg);
  color: var(--lavender);
  border: 2px solid var(--pill-border);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.cos-toggle.on { background: var(--gold); color: var(--peach-text); border-color: var(--gold); }
/* Intro line at the top of a Bag tab panel. */
.bag-note { margin: 2px 2px 12px; font-size: 84%; line-height: 1.5; color: var(--lavender); }

@media (max-width: 560px) {
  .bag-card { padding: 12px 8px; }
  .cos { gap: 10px; padding: 10px; }
  .cos-icon { width: 56px; height: 56px; flex-basis: 56px; }
  .cos-icon canvas,
  .cos-icon img { width: 48px; height: 48px; }
  .bag-tabs { grid-template-columns: repeat(2, 1fr); }
}


/* =====================================================================
   PLAY PAGE - RESPONSIVE
   Every media query for play.html lives here, at the end of the section,
   so it sits below the base rules it overrides. This is deliberate: at
   equal specificity the LAST declaration wins, and when these blocks were
   scattered above their components (.play-icon-btn, .mode-btn) the
   overrides were parsed, matched, and then silently discarded.
   Keep new play-page media queries in this block.
   ===================================================================== */

/* Below ~1180px the skyscrapers no longer fit beside the playfield, so drop
   them rather than squeezing the game. Below 720px the square playfield has
   to size off width, not viewport height, or it overflows. */
@media (max-width: 1180px) {
  .play-grid { grid-template-columns: minmax(0, 1fr); }
  .ad-side { display: none; }
}

/* ---- phones ----
   Measured at 390x844, 360x780 and 414x896. Three things made the page hard
   to actually play on a handset:
     1. The header wrapped onto three rows (157px, a fifth of the screen).
     2. .play-screen kept its 1:1 desktop ratio, so a 390px phone got a
        350x350 playfield and left ~250px of empty page below it. Phones are
        portrait; the game is portrait; the playfield now is too.
     3. The menu chrome is sized in fixed px, so on a 320px playfield the
        Bag card covered a third of the width and collided with TAP TO FLY. */

@media (max-width: 720px) {
  .ad-top { height: 50px; }          /* 50 is a real mobile banner height; 60 was not */

  .play-bar { gap: 6px 8px; padding: 8px 12px; }
  .play-bar .nav-word { font-size: 17px; }
  .play-bar .nav-logo img { width: 30px; height: 30px; }
  /* Icon-only controls. Five text buttons wrapped onto two rows and ate a
     fifth of the screen; as square icons they fit one row with room spare.
     The text label stays in the DOM as the accessible name via aria-label. */
  .play-icon-btn {
    padding: 0;
    width: 44px;
    min-width: 44px;
    /* Height is set here as well as in the (pointer: coarse) block. Relying
       on pointer detection alone left these 44x26 anywhere that reports a
       fine pointer at a phone width. */
    height: 44px;
    min-height: 44px;
    font-size: 118%;
    letter-spacing: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .play-icon-btn .btn-label { display: none; }
  .play-icon-btn .btn-ico { display: block; line-height: 1; }

  /* The store CTA is the widest item in the bar and forces the wrap. The
     game itself is the point of this page on a phone. */
  .play-get { display: none; }

  /* Portrait playfield that uses the height a phone actually has. */
  .play-screen {
    height: auto;
    width: 100%;
    max-width: 460px;
    aspect-ratio: 3 / 4;
  }
  .play-grid { padding: 10px 10px 16px; gap: 12px; }
  .play-intro { margin-top: 14px; padding: 18px; }
  .play-guide { padding: 22px 18px; }
  .play-guide-grid { grid-template-columns: 1fr; }
  .play-footer { flex-direction: column; }

  /* menu chrome scales with the playfield instead of holding 124px */
  .menu-chrome { width: 96px; top: 12px; left: 10px; gap: 4px; }
  .chrome-card { padding: 4px 6px; gap: 4px; border-radius: 11px; }
  .chrome-card img { width: 32px; height: 32px; }
  .chrome-card span { font-size: 88%; }
  .chrome-balance { padding: 3px 6px; font-size: 80%; }
  .chrome-balance .coin-dot { width: 17px; height: 17px; flex: 0 0 17px; margin-right: 7px; }
}

/* Very narrow handsets: the header still has five items to place. */
@media (max-width: 400px) {
  .play-bar .nav-word { display: none; }   /* the icon still identifies the game */
  .play-icon-btn { padding: 5px 7px; font-size: 62%; }
  .play-get { padding: 5px 8px; font-size: 62%; }
}

/* Touch targets. Measured on a 390x844 frame the header buttons came out at
   35px and the CTA buttons at 25px, well under the ~44px a fingertip needs.
   Keyed on (pointer: coarse) rather than width so mouse users keep the
   compact bar and only touch devices pay the extra height. */
@media (pointer: coarse) {
  /* .play-get is intentionally excluded: it's a non-interactive "Coming soon"
     label (no tap target needed) and is hidden on phones by the max-width:720px
     rule. Listing it here re-applied display:inline-flex and, being later in the
     file, defeated that hide - so the button reappeared on touch phones. */
  .play-icon-btn,
  .mode-btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .mode-btn { justify-content: space-between; }
}

/* ---------- run-end overlay ---------- */
.ovl {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(11, 14, 19, .82);
  backdrop-filter: blur(4px);
  animation: ovlIn .22s ease;
}
.ovl[hidden] { display: none; }
@keyframes ovlIn { from { opacity: 0; } to { opacity: 1; } }
.ovl-card {
  width: 100%;
  max-width: 420px;
  text-align: center;
  padding: 34px 30px 28px;
  border-radius: var(--r-xl);
  background: radial-gradient(circle at 50% 30%, var(--card-center), var(--card-edge) 78%);
  border: 2px solid var(--card-border);
  animation: ovlPop .26s cubic-bezier(.2, .9, .3, 1.2);
}
@keyframes ovlPop { from { transform: translateY(14px) scale(.96); } to { transform: none; } }
.ovl-eyebrow {
  margin: 0 0 8px;
  font-size: 76%;
  font-weight: 800;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold);
}
.ovl-title {
  margin: 0 0 10px;
  font-size: 190%;
  font-weight: 900;
  letter-spacing: 1px;
  text-shadow: 3px 4px 0 var(--purple-shadow);
}
.ovl-body { margin: 0 0 20px; font-size: 96%; line-height: 1.6; color: var(--lavender); font-weight: 500; }
.ovl-score { display: flex; justify-content: center; gap: 34px; margin-bottom: 24px; }
.ovl-score .k {
  display: block;
  font-size: 72%;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--lavender);
  margin-bottom: 2px;
}
.ovl-score .v { display: block; font-size: 175%; font-weight: 900; text-shadow: 2px 3px 0 var(--purple-shadow); }
.ovl-score .v.gold { color: var(--gold); }
.ovl-cta {
  display: block;
  padding: 15px 20px;
  border-radius: var(--r-md);
  background: var(--peach);
  color: var(--peach-text);
  border: 2px solid rgba(255, 255, 255, .25);
  font-size: 108%;
  font-weight: 900;
  letter-spacing: 1px;
  transition: filter .18s, transform .18s;
}
.ovl-cta:hover { filter: brightness(1.07); transform: translateY(-2px); }
.ovl-close {
  margin-top: 12px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--lavender);
  font-size: 84%;
  font-weight: 700;
  letter-spacing: 1px;
  padding: 8px;
}
.ovl-close:hover { color: var(--cream); }
body.ovl-open { overflow: hidden; }

/* Content must remain visible without scrolling or JavaScript. */
.reveal, .reveal.in { opacity: 1; transform: none; }
