/* ==========================================================================
   Dig, Melt, Sell! - marketing page
   --------------------------------------------------------------------------
   The page is built out of the game's own UI kit:
     - cream cards inside rounded steel frames        -> .panel
     - deep blue header plates with a gold underline  -> .plate
     - chunky bevelled orange buttons                 -> .btn
     - a conveyor belt running down the page          -> .spine

   CONTENTS
     01. Design tokens (colours, spacing, type)
     02. Reset and base
     03. Utilities (wrap, sr-only, skip link)
     04. Buttons
     05. Chips
     06. Panels and header plates
     07. Conveyor spine (the animated flourish)
     08. Hero
     09. Key facts strip
     10. How it plays
     11. Screenshot frames (with missing-image placeholder)
     12. Playable WebGL block
     13. Sliders (screenshots + videos)
     14. Where it bites
     15. Technical status table
     16. Monetization
     17. Footer
     18. Responsive (tablet and desktop)
     19. Reduced motion and print
   ========================================================================== */


/* ==========================================================================
   01. DESIGN TOKENS
   Change a colour here and it changes everywhere on the page.
   ========================================================================== */
:root {
  /* Palette, taken straight from the game art */
  --sky-1:        #3BA7F0;
  --sky-2:        #1E6FD9;
  --blue:         #1C4FA1;   /* panels and header plates */
  --blue-dark:    #133A7A;
  --gold:         #F5C518;
  --gold-deep:    #E8A317;
  --orange:       #FF8A1F;   /* primary call to action */
  --orange-deep:  #C25E00;
  --cream:        #F2E8D5;   /* card bodies */
  --cream-soft:   #FBF6EC;
  --steel:        #8D99A6;   /* frames */
  --steel-dark:   #5A6673;
  --green:        #6FBF3F;
  --rock:         #2B2A2E;   /* footer and deep backgrounds */
  --red:          #E84A4A;

  --ink:          #23262B;   /* body text on cream */
  --ink-soft:      #5A6673;

  /* Type */
  --font-display: "Fredoka", "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  /* Rhythm */
  --gap:      1rem;
  --gap-lg:   1.75rem;
  --section:  clamp(2.5rem, 6vw, 4.5rem);
  --wrap:     1120px;

  /* Shape */
  --r-lg: 28px;
  --r-md: 18px;
  --r-sm: 12px;

  --shadow-card: 0 18px 40px rgba(19, 58, 122, .16);
  --focus: 0 0 0 3px #fff, 0 0 0 6px var(--orange);
  --pop: cubic-bezier(.34, 1.56, .64, 1);   /* overshoot, the mobile-game bounce */
}


/* ==========================================================================
   02. RESET AND BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.62;
  color: var(--ink);
  background: var(--sky-2);
  /* Sky gradient behind everything, so a failed image never shows a void */
  background-image: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 34%, #14539f 100%);
  background-attachment: fixed;
  overflow-x: hidden;
}

img, video { max-width: 100%; display: block; }
[hidden] { display: none !important; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.12;
  margin: 0;
  letter-spacing: .1px;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--blue); }

/* One visible focus style for the whole page */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--focus);
  border-radius: 8px;
}


/* ==========================================================================
   03. UTILITIES
   ========================================================================== */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(1.5rem, 4vw, 2.5rem); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: absolute; left: 50%; top: 0; z-index: 100;
  transform: translate(-50%, -120%);
  background: var(--cream); color: var(--blue);
  font-family: var(--font-display); font-weight: 600;
  padding: .7rem 1.2rem; border-radius: 0 0 12px 12px;
  text-decoration: none;
}
.skip-link:focus { transform: translate(-50%, 0); }

/* Intro copy inside a panel */
.lede {
  font-size: 1.06rem;
  color: var(--ink-soft);
  max-width: 60ch;
  margin-bottom: var(--gap-lg);
}

.note {
  margin-top: var(--gap-lg);
  padding: 1rem 1.15rem;
  border-left: 5px solid var(--gold);
  background: rgba(245, 197, 24, .1);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--ink-soft);
  font-size: .96rem;
}

.sub {
  font-size: clamp(1.05rem, 2.4vw, 1.3rem);
  color: var(--blue);
  margin: var(--gap-lg) 0 .85rem;
}
.sub:first-of-type { margin-top: .5rem; }


/* ==========================================================================
   04. BUTTONS
   Chunky, with a hard bottom bevel like the in-game orange button.
   ========================================================================== */
.btn {
  --btn-face:  var(--orange);
  --btn-bevel: var(--orange-deep);
  --btn-text:  #fff;

  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem;
  min-height: 56px;
  padding: .85rem 1.6rem;
  font-family: var(--font-display);
  font-size: 1.05rem; font-weight: 600;
  color: var(--btn-text);
  text-decoration: none;
  text-align: center;
  /* flat colour first, so old browsers without color-mix still get a solid button */
  background: var(--btn-face);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .3) 0%, rgba(255, 255, 255, 0) 52%, rgba(0, 0, 0, .16) 100%);
  border: 3px solid rgba(255, 255, 255, .55);
  border-radius: 16px;
  box-shadow: 0 6px 0 var(--btn-bevel), 0 12px 22px rgba(0, 0, 0, .22);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .08s ease, filter .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { filter: brightness(1.06); }
.btn:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 var(--btn-bevel), 0 6px 14px rgba(0, 0, 0, .22);
}

.btn--primary { --btn-face: var(--orange); --btn-bevel: var(--orange-deep); }

.btn--ghost {
  --btn-face: var(--blue);
  --btn-bevel: var(--blue-dark);
  border-color: rgba(255, 255, 255, .4);
}

.btn--gold { --btn-face: var(--gold); --btn-bevel: var(--gold-deep); --btn-text: #4a3400; }

.btn--sm { min-height: 46px; padding: .55rem 1.1rem; font-size: .95rem; border-radius: 13px; }


/* ==========================================================================
   05. CHIPS
   Small cream plates with a steel edge, used for facts and tags.
   ========================================================================== */
.chips {
  display: flex; flex-wrap: wrap; gap: .6rem;
  list-style: none; margin: 0; padding: 0;
  justify-content: center;
}

.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .6rem 1rem;
  background: var(--cream);
  border: 2px solid var(--steel);
  border-bottom-width: 4px;
  border-radius: 999px;
  font-size: .95rem;
  color: var(--ink-soft);
  box-shadow: 0 6px 16px rgba(19, 58, 122, .18);
  white-space: nowrap;
}
.chip b {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--blue);
}
.chip--sm { font-size: .85rem; padding: .4rem .8rem; border-bottom-width: 3px; }

.chips--facts { justify-content: center; }
.chips--tech { justify-content: flex-start; margin-top: var(--gap-lg); }


/* ==========================================================================
   06. PANELS AND HEADER PLATES
   .panel is the steel frame, .panel__inner is the cream card body,
   .plate is the deep blue header that sits across the top of the card.
   ========================================================================== */
.panel {
  position: relative;
  padding: 7px;
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, #b7c0c9 0%, var(--steel) 45%, var(--steel-dark) 100%);
  box-shadow: var(--shadow-card), inset 0 2px 0 rgba(255, 255, 255, .55);
}

.panel__inner {
  position: relative;
  /* top padding must clear the header plate, which is positioned over it */
  padding: 4.75rem clamp(1.1rem, 4vw, 2.4rem) clamp(1.6rem, 4vw, 2.4rem);
  border-radius: calc(var(--r-lg) - 8px);
  background: var(--cream);
  background-image: linear-gradient(180deg, var(--cream-soft) 0%, var(--cream) 220px);
  overflow: hidden;
}

/* Deep blue header plate, pinned across the top of the card */
.plate {
  --plate-1: #2C68C4;
  --plate-2: var(--blue);
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: min(92%, 560px);
  padding: .7rem 1.5rem .95rem;
  text-align: center;
  background: linear-gradient(180deg, var(--plate-1) 0%, var(--plate-2) 100%);
  border-radius: 0 0 18px 18px;
  box-shadow: 0 6px 0 rgba(0, 0, 0, .18), 0 10px 20px rgba(19, 58, 122, .25);
}
.plate h2 {
  color: #fff;
  font-size: clamp(1.25rem, 4.2vw, 1.75rem);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .28);
}
/* the gold bar under the plate, straight from BGCard */
.plate::after {
  content: "";
  position: absolute; left: 8%; right: 8%; bottom: -7px;
  height: 8px;
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  border-radius: 999px;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .18);
}
/* rivets on the plate shoulders */
.plate::before {
  content: "";
  position: absolute; left: 12px; right: 12px; top: 12px;
  height: 7px;
  background:
    radial-gradient(circle at left center, #cfd6dd 0 3px, transparent 3.5px),
    radial-gradient(circle at right center, #cfd6dd 0 3px, transparent 3.5px);
}

.plate--gold { --plate-1: var(--gold); --plate-2: var(--gold-deep); }
.plate--gold h2 { color: #4a3400; text-shadow: 0 2px 0 rgba(255, 255, 255, .35); }
.plate--red  { --plate-1: #F06A6A; --plate-2: var(--red); }

/* One gold frame on the page, saved for the monetization panel.
   Every other panel keeps the steel frame so the page stays calm. */
.panel--gold { background: linear-gradient(180deg, #f3d97a 0%, var(--gold-deep) 100%); }


/* ==========================================================================
   07. CONVEYOR SPINE
   A thin vertical belt between sections, carrying an ore that becomes a ring.
   Purely decorative, hidden from screen readers in the HTML.
   ========================================================================== */
.spine {
  position: relative;
  display: flex;
  justify-content: center;
  height: 92px;
  pointer-events: none;
}

.spine__belt {
  position: relative;
  width: 26px; height: 100%;
  border-radius: 13px;
  background:
    repeating-linear-gradient(180deg,
      rgba(255, 255, 255, .18) 0 3px,
      rgba(255, 255, 255, 0) 3px 15px),
    linear-gradient(90deg, #3f4954 0%, #6d7a88 45%, #39424c 100%);
  box-shadow:
    inset 0 0 0 3px rgba(255, 255, 255, .16),
    0 6px 16px rgba(0, 0, 0, .22);
  animation: spine-tread 1.1s linear infinite;
}
@keyframes spine-tread {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 0 15px, 0 0; }
}

/* gold guide rails either side of the belt */
.spine__belt::before,
.spine__belt::after {
  content: "";
  position: absolute; top: 6px; bottom: 6px; width: 4px;
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  border-radius: 4px;
  opacity: .9;
}
.spine__belt::before { left: -7px; }
.spine__belt::after  { right: -7px; }

.spine__cargo {
  position: absolute;
  top: 0; left: 50%;
  width: 42px; height: auto;
  margin-left: -21px;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .35));
  animation: spine-ride 3.6s linear infinite;
}
@keyframes spine-ride {
  0%   { transform: translateY(-46px) rotate(-6deg); opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { transform: translateY(96px) rotate(8deg); opacity: 0; }
}


/* ==========================================================================
   08. HERO
   Full-bleed video with a key-art background behind it, so the section still
   looks finished if the video file is missing.
   ========================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(3.5rem, 8vh, 5rem) clamp(3rem, 8vh, 4.5rem);
  background: linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 100%);
}
@supports not (min-height: 100svh) { .hero { min-height: 100vh; } }

/* Blurred key art, far behind, so the video plate reads crisply on top of it.
   The negative inset overscans so the blur never shows a soft edge. */
.hero__bg {
  position: absolute; inset: -8%;
  z-index: -2;
  background-color: var(--sky-2);
  background-image: url("../img/deco-keyart.jpg");
  background-size: cover;
  background-position: center 28%;
  filter: blur(26px) saturate(1.15);
  transform: scale(1.08);
}

/* Veil keeps the copy readable and stops the background competing with the video. */
.hero__veil {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(125% 85% at 50% 32%, rgba(13, 39, 84, .10) 0%, rgba(13, 39, 84, .58) 66%, rgba(11, 30, 66, .86) 100%),
    linear-gradient(180deg, rgba(19, 58, 122, .42) 0%, rgba(19, 58, 122, 0) 32%);
}

.hero__inner {
  display: grid;
  gap: clamp(1.25rem, 4vh, 2.25rem);
  width: 100%;
  text-align: center;
}

/* -------- the video player: first element, first thing on screen -------- */
.player { width: 100%; max-width: 900px; margin-inline: auto; }

.player__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #0C1524;
  border: 3px solid rgba(255, 255, 255, .18);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, .20),
    0 10px 0 rgba(9, 28, 66, .38),
    0 30px 64px rgba(6, 20, 48, .58);
  transition: transform .4s var(--pop), box-shadow .4s ease;
}
.player:hover .player__frame,
.player:focus-within .player__frame {
  transform: translateY(-5px);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, .24),
    0 14px 0 rgba(9, 28, 66, .40),
    0 38px 74px rgba(6, 20, 48, .62);
}

.player__video,
.player__preview {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
}
.player__video { background: #0C1524; }

/* The preview covers the video until the visitor presses play. */
.player__preview {
  z-index: 1;
  transition: opacity .45s ease, transform .6s var(--pop);
}
.player--playing .player__preview {
  opacity: 0; transform: scale(1.04); pointer-events: none;
}
.player--playing .player__play {
  opacity: 0; transform: translate(-50%, -50%) scale(.82); pointer-events: none;
}
.player--novideo .player__play { display: none; }

/* Play button, deliberately large and obvious */
.player__play {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  display: grid; gap: .85rem; justify-items: center;
  padding: 0; border: 0; background: none; cursor: pointer;
  transition: opacity .3s ease, transform .35s var(--pop);
}
.player__play-ring {
  position: relative;
  width: clamp(68px, 14vw, 92px); aspect-ratio: 1;
  border-radius: 50%;
  background: linear-gradient(180deg, #FFA23F 0%, var(--orange) 46%, var(--orange-deep) 100%);
  box-shadow:
    inset 0 3px 0 rgba(255, 255, 255, .50),
    inset 0 -4px 0 rgba(0, 0, 0, .18),
    0 10px 26px rgba(0, 0, 0, .42);
  display: grid; place-items: center;
  transition: transform .3s var(--pop);
}
/* the triangle */
.player__play-ring::after {
  content: "";
  width: 0; height: 0;
  margin-left: 18%;
  border-left: clamp(20px, 4.2vw, 27px) solid #fff;
  border-top: clamp(13px, 2.7vw, 17px) solid transparent;
  border-bottom: clamp(13px, 2.7vw, 17px) solid transparent;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .25));
}
/* soft outward pulse so the eye lands on it */
.player__play-ring::before {
  content: "";
  position: absolute; inset: -10px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .55);
  animation: play-pulse 2.4s ease-out infinite;
}
@keyframes play-pulse {
  0%        { transform: scale(.90); opacity: .75; }
  70%, 100% { transform: scale(1.22); opacity: 0; }
}
.player__play:hover  .player__play-ring { transform: scale(1.09); }
.player__play:active .player__play-ring { transform: scale(.95); }
.player__play-text {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(.95rem, 2.6vw, 1.1rem);
  color: #fff;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .65);
}

/* Replaces the button when hero.mp4 is not on the server yet */
.player__soon {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 2; margin: 0;
  display: grid; gap: .4rem;
  width: min(88%, 34ch);
  padding: 1.15rem 1.35rem;
  border-radius: var(--r-md);
  background: rgba(12, 21, 36, .72);
  border: 2px solid rgba(255, 255, 255, .20);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.player__soon-title { font-family: var(--font-display); font-weight: 600; color: #fff; font-size: 1.05rem; }
.player__soon-note  { color: rgba(255, 255, 255, .78); font-size: .9rem; }

/* --------------------------- logo and hook --------------------------- */
.hero__intro { display: grid; gap: .85rem; justify-items: center; }
.hero__title { margin: 0; }

.hero__logo {
  width: min(62vw, 340px); height: auto; margin-inline: auto;
  filter: drop-shadow(0 12px 26px rgba(0, 0, 0, .50));
}

/* Text wordmark shown only if logo.png fails to load */
.hero__wordmark {
  display: flex; flex-direction: column; align-items: center;
  font-family: var(--font-display); font-weight: 700; line-height: .95;
  font-size: clamp(2.4rem, 12vw, 4.4rem);
  text-shadow: 0 4px 0 rgba(0, 0, 0, .35);
}
.wm--dig  { color: var(--orange); }
.wm--melt { color: #CFE9FF; }
.wm--sell { color: var(--green); }

.hero__hook {
  margin: 0 auto; max-width: 34ch; color: #fff;
  font-size: clamp(1rem, 3.6vw, 1.22rem); font-weight: 500;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .62);
}

.hero__actions { display: flex; justify-content: center; margin: .25rem 0 0; }
.hero__actions .btn { min-width: 15rem; }

/* Scroll cue */
.hero__scroll {
  position: absolute; left: 50%; bottom: .5rem;
  transform: translateX(-50%);
  width: 44px; height: 44px;
  display: grid; place-items: center;
  z-index: 2;
}
.hero__scroll span {
  width: 14px; height: 14px;
  border-right: 3px solid rgba(255, 255, 255, .85);
  border-bottom: 3px solid rgba(255, 255, 255, .85);
  transform: rotate(45deg);
  animation: hero-bob 1.9s ease-in-out infinite;
}
@keyframes hero-bob {
  0%, 100% { transform: rotate(45deg) translate(0, 0); opacity: .55; }
  50%      { transform: rotate(45deg) translate(3px, 3px); opacity: 1; }
}
@keyframes hero-bob {
  0%, 100% { transform: rotate(45deg) translate(0, 0); opacity: .55; }
  50%      { transform: rotate(45deg) translate(3px, 3px); opacity: 1; }
}


/* ==========================================================================
   09. KEY FACTS STRIP
   ========================================================================== */
#facts .chips { max-width: 900px; margin-inline: auto; }


/* ==========================================================================
   10. HOW IT PLAYS
   ========================================================================== */
.steps {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: clamp(1.25rem, 4vw, 2rem);
}

.step {
  display: grid;
  /* phone: a small portrait thumbnail beside the text, so the page stays short */
  grid-template-columns: 104px 1fr;
  gap: 1rem;
  align-items: center;
  background: var(--cream-soft);
  border: 2px solid rgba(141, 153, 166, .5);
  border-radius: var(--r-md);
  padding: clamp(.9rem, 3vw, 1.25rem);
  box-shadow: 0 6px 0 rgba(141, 153, 166, .35);
}

.step__body { min-width: 0; }

.step__num {
  display: inline-grid; place-items: center;
  width: 36px; height: 36px;
  margin-bottom: .5rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.2rem;
  color: #4a3400;
  background: radial-gradient(circle at 35% 30%, #ffe27a 0%, var(--gold) 45%, var(--gold-deep) 100%);
  border: 3px solid #fff;
  border-radius: 50%;
  box-shadow: 0 4px 0 rgba(0, 0, 0, .18);
}

.step h3 {
  font-size: clamp(1.15rem, 4vw, 1.4rem);
  color: var(--blue);
  margin-bottom: .35rem;
}
.step p { color: var(--ink-soft); margin: 0; }


/* ==========================================================================
   11. SCREENSHOT FRAMES
   .shot draws its own placeholder. If the <img> inside is missing or hidden
   the frame still reads as a deliberate empty screen, never a broken icon.
   ========================================================================== */
.shot {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background:
    repeating-linear-gradient(135deg,
      rgba(255, 255, 255, .06) 0 12px,
      rgba(255, 255, 255, 0) 12px 24px),
    linear-gradient(180deg, #2f5fa8 0%, var(--blue) 60%, var(--blue-dark) 100%);
  border: 3px solid var(--steel-dark);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, .25);
}
.shot--portrait { aspect-ratio: 9 / 16; }

/* the placeholder label, painted under the image */
.shot::after {
  content: "Screenshot coming";
  position: absolute; inset: auto 0 0 0;
  padding: .6rem;
  text-align: center;
  font-family: var(--font-display); font-size: .8rem; letter-spacing: .04em;
  color: rgba(255, 255, 255, .72);
  background: linear-gradient(0deg, rgba(0, 0, 0, .28), transparent);
  z-index: 0;
}
/* the label has to survive inside the narrow step thumbnails too */
.step .shot::after { font-size: .62rem; line-height: 1.25; padding: .35rem .2rem; }

.shot img {
  position: relative; z-index: 1;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center top;
}


/* ==========================================================================
   12. PLAYABLE WEBGL BLOCK
   ========================================================================== */
.playable {
  display: grid;
  gap: clamp(1.25rem, 4vw, 2rem);
  align-items: center;
}

/* Phone-shaped frame */
.phone {
  --phone-w: min(320px, 84vw);
  width: var(--phone-w);
  margin-inline: auto;
  padding: 10px;
  border-radius: 38px;
  background: linear-gradient(180deg, #7c8896 0%, var(--steel-dark) 60%, #3d454e 100%);
  box-shadow: 0 22px 44px rgba(19, 58, 122, .3), inset 0 2px 0 rgba(255, 255, 255, .4);
}

.phone__screen {
  position: relative;
  aspect-ratio: 9 / 19.5;
  overflow: hidden;
  border-radius: 28px;
  background: linear-gradient(180deg, #2f5fa8 0%, var(--blue-dark) 100%);
}
/* the phone screen expands once the Unity build is running */
.phone.is-running { --phone-w: min(420px, 92vw); }

.phone__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Big play button over the poster */
.playable__start {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem;
  width: 100%;
  padding: 1rem;
  font-family: var(--font-body);
  color: #fff;
  background: linear-gradient(180deg, rgba(10, 32, 68, .45) 0%, rgba(10, 32, 68, .84) 100%);
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.playable__play {
  width: 78px; height: 78px;
  border-radius: 50%;
  background: linear-gradient(180deg, #ffa54d 0%, var(--orange) 55%, var(--orange-deep) 100%);
  border: 4px solid #fff;
  box-shadow: 0 8px 0 var(--orange-deep), 0 14px 26px rgba(0, 0, 0, .35);
  position: relative;
  transition: transform .1s ease;
}
.playable__play::after {
  content: "";
  position: absolute; top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-left: 24px solid #fff;
  border-top: 15px solid transparent;
  border-bottom: 15px solid transparent;
}
.playable__start:hover .playable__play { transform: scale(1.05); }
.playable__start:active .playable__play { transform: translateY(4px); box-shadow: 0 3px 0 var(--orange-deep); }

.playable__label {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.25rem;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .55);
}
.playable__sub { font-size: .82rem; color: rgba(255, 255, 255, .82); }

/* Loading / unavailable state */
.playable__status {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .7rem;
  padding: 1.5rem;
  text-align: center;
  color: #fff;
  background: linear-gradient(180deg, rgba(19, 58, 122, .82) 0%, rgba(10, 32, 68, .95) 100%);
}
.playable__status-title { font-family: var(--font-display); font-size: 1.1rem; margin: 0; }
.playable__status-note { font-size: .85rem; color: rgba(255, 255, 255, .78); margin: 0; }

.bar {
  width: 78%; height: 12px;
  background: rgba(0, 0, 0, .35);
  border: 2px solid rgba(255, 255, 255, .45);
  border-radius: 999px;
  overflow: hidden;
}
.bar__fill {
  display: block; width: 0%; height: 100%;
  background: linear-gradient(90deg, var(--gold) 0%, var(--orange) 100%);
  transition: width .2s ease;
}

/* Unity canvas, injected by main.js */
.phone__screen canvas {
  position: absolute; inset: 0;
  width: 100% !important; height: 100% !important;
  display: block;
  background: var(--blue-dark);
}

.playable__aside h3 { color: var(--blue); font-size: 1.2rem; margin-bottom: .5rem; }
.playable__aside p { color: var(--ink-soft); font-size: .96rem; }
.playable__hint { font-size: .86rem; color: var(--steel-dark); }


/* ==========================================================================
   13. SLIDERS
   CSS scroll-snap does the scrolling and the touch swipe. The JS only adds
   the arrows, the dots and the keyboard control.
   ========================================================================== */
.slider { position: relative; }

.slider__stage {
  position: relative;
  display: flex;
  align-items: center;
  gap: .5rem;
}

.slider__track {
  list-style: none;
  margin: 0;
  padding: 4px;
  display: flex;
  gap: clamp(.6rem, 2.5vw, 1rem);
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.slider__track::-webkit-scrollbar { display: none; }

/* Slides are a little narrower than the track so the next one peeks in,
   which is what tells a phone user the strip can be swiped. */
.slider__slide {
  flex: 0 0 auto;
  scroll-snap-align: center;
  width: clamp(140px, 42vw, 220px);
}
.slider__track--clips .slider__slide { width: clamp(150px, 44vw, 260px); }

/* video slides */
.clip {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 3px solid var(--steel-dark);
  background: linear-gradient(180deg, #2f5fa8 0%, var(--blue-dark) 100%);
  aspect-ratio: 9 / 16;
}
.clip video {
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--blue-dark);
}
.clip__title {
  position: absolute; left: 0; right: 0; bottom: 0;
  margin: 0;
  padding: .5rem .7rem;
  font-size: .82rem; color: #fff;
  background: linear-gradient(0deg, rgba(0, 0, 0, .68), transparent);
  pointer-events: none;
}

/* arrows */
.slider__nav {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  background: linear-gradient(180deg, #2C68C4 0%, var(--blue) 100%);
  border: 3px solid #fff;
  border-radius: 50%;
  box-shadow: 0 4px 0 var(--blue-dark), 0 8px 16px rgba(0, 0, 0, .2);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .08s ease;
}
.slider__nav:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--blue-dark); }
.slider__nav::before {
  content: "";
  width: 11px; height: 11px;
  border-top: 3px solid #fff;
  border-right: 3px solid #fff;
}
.slider__nav--prev::before { transform: rotate(-135deg); margin-left: 4px; }
.slider__nav--next::before { transform: rotate(45deg); margin-right: 4px; }
.slider__nav[disabled] { opacity: .35; cursor: default; }

/* dots */
.slider__dots {
  display: flex; justify-content: center; flex-wrap: wrap;
  gap: .45rem;
  margin-top: .9rem;
}
/* The visible dot is small, the tap target around it is 28px. */
.slider__dot {
  width: 28px; height: 28px;
  padding: 0;
  display: grid; place-items: center;
  border: 0;
  background: none;
  cursor: pointer;
}
.slider__dot::before {
  content: "";
  width: 11px; height: 11px;
  border: 2px solid var(--steel-dark);
  border-radius: 50%;
  background: var(--cream);
  transition: transform .12s ease, background-color .12s ease;
}
.slider__dot[aria-current="true"]::before {
  background: var(--orange);
  border-color: var(--orange-deep);
  transform: scale(1.3);
}

.slider__empty {
  margin: 1rem 0 0;
  padding: 1.5rem;
  text-align: center;
  color: var(--ink-soft);
  background: rgba(141, 153, 166, .14);
  border: 2px dashed var(--steel);
  border-radius: var(--r-md);
  font-size: .95rem;
}


/* ==========================================================================
   14. WHERE IT BITES
   ========================================================================== */
.bites {
  display: grid;
  gap: clamp(1.25rem, 4vw, 2rem);
  align-items: start;
}
.bites__art .shot { max-width: 280px; margin-inline: auto; }

.bites__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }

.bite {
  background: var(--cream-soft);
  border: 2px solid rgba(141, 153, 166, .5);
  border-radius: var(--r-md);
  padding: 1.1rem;
  box-shadow: 0 6px 0 rgba(141, 153, 166, .32);
}
.bite h3 {
  display: flex; align-items: center; gap: .6rem;
  font-size: 1.15rem;
  color: var(--blue);
  margin-bottom: .4rem;
}
.bite p { color: var(--ink-soft); margin: 0; font-size: .96rem; }

.bite__tag {
  flex: 0 0 auto;
  width: 16px; height: 16px;
  border-radius: 5px;
  border: 2px solid #fff;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .2);
}
.bite__tag--orange { background: var(--orange); }
.bite__tag--red    { background: var(--red); }

.verdict {
  margin-top: var(--gap-lg);
  padding: 1.1rem 1.25rem;
  background: linear-gradient(180deg, rgba(232, 74, 74, .12) 0%, rgba(232, 74, 74, .06) 100%);
  border: 2px solid rgba(232, 74, 74, .45);
  border-radius: var(--r-md);
  color: var(--ink);
  font-size: 1rem;
}
.verdict b { color: #a92e2e; }


/* ==========================================================================
   15. TECHNICAL STATUS TABLE
   ========================================================================== */
.status {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: .95rem;
}
.status thead { display: none; }

.status tr { display: block; }

.status th[scope="row"],
.status td {
  display: block;
  text-align: left;
  font-weight: 400;
}

.status tbody tr {
  padding: .95rem 1.05rem;
  margin-bottom: .6rem;
  background: var(--cream-soft);
  border: 2px solid rgba(141, 153, 166, .5);
  border-radius: var(--r-md);
  box-shadow: 0 4px 0 rgba(141, 153, 166, .28);
}

.status th[scope="row"] {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--blue);
}

.status__detail {
  display: block;
  margin-top: .3rem;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: .9rem;
  color: var(--ink-soft);
}

.status td { margin-top: .6rem; }

.pill {
  display: inline-block;
  padding: .3rem .8rem;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: .82rem; font-weight: 600;
  border: 2px solid;
}
.pill--ready {
  color: #2c5b12;
  background: rgba(111, 191, 63, .2);
  border-color: var(--green);
}
.pill--open {
  color: #6b4a00;
  background: rgba(245, 197, 24, .22);
  border-color: var(--gold-deep);
}
.status__row--open { border-style: dashed !important; }


/* ==========================================================================
   16. MONETIZATION
   ========================================================================== */
.money {
  list-style: none;
  margin: 0; padding: 0;
  display: grid; gap: .85rem;
}
.money li {
  position: relative;
  padding: .9rem 1rem .9rem 2.6rem;
  background: var(--cream-soft);
  border: 2px solid rgba(232, 163, 23, .5);
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font-size: .97rem;
}
.money li::before {
  content: "";
  position: absolute; left: 1rem; top: 1.25rem;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe27a 0%, var(--gold) 50%, var(--gold-deep) 100%);
  border: 2px solid #fff;
}
.money b { color: var(--blue); font-family: var(--font-display); font-weight: 600; }

.note--honest { border-left-color: var(--blue); background: rgba(28, 79, 161, .08); }

.deco-coin {
  position: absolute;
  top: 5.2rem; right: 1rem;
  width: 54px; height: auto;
  opacity: .9;
  pointer-events: none;
}


/* ==========================================================================
   17. FOOTER
   ========================================================================== */
.footer {
  background: var(--rock);
  color: #d8d5cf;
  padding-block: clamp(2rem, 6vw, 3rem) 1.25rem;
  border-top: 6px solid var(--gold-deep);
}
.footer__inner {
  display: flex; flex-wrap: wrap; gap: 1.25rem;
  align-items: center; justify-content: space-between;
}
.footer__name {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.3rem; color: #fff;
  margin: 0;
}
.footer__role { margin: .1rem 0 .35rem; font-size: .9rem; color: #9a968f; }
.footer__mail { margin: 0; }
.footer__mail a {
  display: inline-block;
  padding: .3rem 0;          /* keeps the tap target comfortable on a phone */
  color: var(--gold);
  font-weight: 600;
}

.footer__fine {
  max-width: var(--wrap);
  margin: 1.75rem auto 0;
  padding-inline: clamp(1rem, 4vw, 2rem);
  font-size: .8rem;
  color: #7d7a75;
}


/* ==========================================================================
   18. RESPONSIVE
   Mobile first. Everything above is the phone layout.
   ========================================================================== */

/* --- 640px and up: two-column cards ------------------------------------ */
@media (min-width: 640px) {
  .step {
    grid-template-columns: 150px 1fr;
    gap: 1.25rem;
    align-items: center;
  }
  .bites { grid-template-columns: 260px 1fr; }
  .status tbody tr {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 1rem;
  }
  .status td { margin-top: 0; text-align: right; }
  .slider__slide { width: 220px; }
  .slider__track--clips .slider__slide { width: 260px; }
}

/* --- 900px and up: wider frames and side-by-side playable --------------- */
@media (min-width: 900px) {
  .spine { height: 120px; }
  .spine__cargo { width: 52px; margin-left: -26px; }
  @keyframes spine-ride {
    0%   { transform: translateY(-56px) rotate(-6deg); opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { transform: translateY(124px) rotate(8deg); opacity: 0; }
  }

  .playable { grid-template-columns: minmax(0, 340px) 1fr; align-items: center; }
  .phone { margin-inline: 0; }

  .steps { grid-template-columns: repeat(3, 1fr); }
  .step { grid-template-columns: 1fr; text-align: left; align-items: start; }
  .step .shot { max-width: none; }
  .step .shot::after { font-size: .8rem; padding: .6rem; }

  .hero__hook { max-width: 46ch; }
  .hero__actions .btn { flex: 0 1 16rem; }
}

/* --- 1200px and up: a little more air ---------------------------------- */
@media (min-width: 1200px) {
  .panel__inner { padding: 5.5rem 3rem 3rem; }
  .hero__logo { width: min(46vw, 520px); }
}


/* ==========================================================================
   19. REDUCED MOTION AND PRINT
   The conveyor stops, the video does not autoplay, nothing slides.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .spine__belt { animation: none; }
  .btn:hover, .btn:active,
  .panel:hover, .chip:hover, .pill:hover,
  .shot:hover, .step:hover, .step:hover .step__num,
  .slider__nav:hover, .slider__nav:active,
  .player:hover .player__frame { transform: none; }
  .btn:hover::after { animation: none; }
  .pill--ready::after { animation: none; opacity: 0; }
  .player__play-ring::before { animation: none; opacity: 0; }
  .hero__scroll span { animation: none; }
  .spine__cargo {
    animation: none;
    top: 50%;
    transform: translateY(-50%);
    opacity: 1;
  }
  .hero__scroll span { animation: none; opacity: .8; }
  .slider__track { scroll-behavior: auto; }
}

@media print {
  .hero { min-height: auto; }
  .spine, .hero__scroll, .slider__nav { display: none; }
  body { background: #fff; }
}
/* ==========================================================================
   20. JUICE
   The game's menus bounce, so the page should too. This layer sits on top of
   the components above and only adds motion, depth and press feedback. It is
   deliberately last so it overrides earlier transitions, and every rule here
   is switched off under prefers-reduced-motion at the bottom of the file.
   ========================================================================== */

/* ---- reveal: overshoot instead of a flat fade ---- */
.reveal {
  transition:
    opacity .55s ease,
    transform .7s var(--pop);
}

/* ---- buttons: lift, press, and a shine that sweeps on hover ---- */
.btn {
  position: relative;
  overflow: hidden;
  transition:
    transform .25s var(--pop),
    box-shadow .25s ease,
    filter .25s ease;
}
.btn::after {
  content: "";
  position: absolute; top: 0; bottom: 0; left: -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, .42) 50%, transparent 100%);
  transform: skewX(-18deg);
  opacity: 0;
  pointer-events: none;
}
.btn:hover  { transform: translateY(-3px); filter: saturate(1.08); }
.btn:active { transform: translateY(1px) scale(.985); }
.btn:hover::after { animation: btn-shine .75s ease-out; }
@keyframes btn-shine {
  0%   { left: -60%; opacity: 0; }
  18%  { opacity: 1; }
  100% { left: 115%; opacity: 0; }
}

/* ---- panels: a little physical lift on approach ---- */
.panel {
  transition: transform .35s var(--pop), box-shadow .35s ease;
}
.panel:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 54px rgba(19, 58, 122, .22);
}

/* ---- chips and pills: springy hover, gold gets a slow gloss ---- */
.chip, .pill {
  transition: transform .28s var(--pop), box-shadow .28s ease, background-color .28s ease;
}
.chip:hover, .pill:hover {
  transform: translateY(-2px) scale(1.03);
  box-shadow: 0 8px 18px rgba(19, 58, 122, .20);
}
.pill--ready { position: relative; overflow: hidden; }
.pill--ready::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, .40) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: gloss 5.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes gloss {
  0%, 62% { transform: translateX(-120%); }
  78%     { transform: translateX(120%); }
  100%    { transform: translateX(120%); }
}

/* ---- screenshots: tilt up slightly, as if picked off the table ---- */
.shot {
  transition: transform .4s var(--pop), box-shadow .4s ease;
}
.shot:hover {
  transform: translateY(-6px) rotate(-.6deg);
  box-shadow: 0 30px 60px rgba(19, 58, 122, .28);
}

/* ---- how-it-plays: the step number pops when its card is approached ---- */
.step { transition: transform .35s var(--pop); }
.step:hover { transform: translateY(-4px); }
.step__num {
  transition: transform .35s var(--pop), box-shadow .3s ease;
}
.step:hover .step__num {
  transform: scale(1.12) rotate(-4deg);
  box-shadow: 0 10px 22px rgba(0, 0, 0, .28);
}

/* ---- slider arrows: grow into the press ---- */
.slider__nav {
  transition: transform .25s var(--pop), background-color .25s ease, box-shadow .25s ease;
}
.slider__nav:hover  { transform: scale(1.12); }
.slider__nav:active { transform: scale(.94); }

/* ---- header plates catch a highlight along the top edge ---- */
.plate { position: relative; }
.plate::after {
  content: "";
  position: absolute; left: 8%; right: 8%; top: 3px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent);
  pointer-events: none;
}


/* ==========================================================================
   20. CONDENSED LAYOUT
   The page was nine sections and felt long. It is now four, the video sits
   at the very top with only a slim bar above it, and the header plates sit
   much closer to the top of their cards. These rules come last so they win.
   ========================================================================== */

/* ---- tighter vertical rhythm throughout ---- */
:root { --section: clamp(1.5rem, 3vw, 2.5rem); }

/* ---- header plates: much less air above the title ---- */
.panel__inner {
  padding: 3.3rem clamp(1rem, 3.2vw, 1.9rem) clamp(1.15rem, 3vw, 1.8rem);
}
.plate { padding: .48rem 1.35rem .6rem; }
.plate h2 { font-size: clamp(1.15rem, 3.6vw, 1.5rem); }

/* ---- the top block: bar, then video, nothing else above it ---- */
.hero {
  display: block;
  min-height: 0;
  align-items: initial;
  padding-block: clamp(.7rem, 2vh, 1.2rem) clamp(1.1rem, 3vh, 1.9rem);
}
.hero__inner { display: block; }

/* the blur was far too heavy */
.hero__bg {
  inset: -4%;
  filter: blur(9px) saturate(1.08);
  transform: scale(1.04);
}
.hero__veil {
  background:
    radial-gradient(130% 90% at 50% 30%, rgba(13, 39, 84, .06) 0%, rgba(13, 39, 84, .42) 70%, rgba(11, 30, 66, .68) 100%);
}

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  margin-bottom: clamp(.55rem, 1.6vh, .95rem);
}
.topbar__logo {
  width: clamp(104px, 25vw, 168px); height: auto;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .45));
}
.topbar__wordmark {
  font-family: var(--font-display); font-weight: 700; color: #fff;
  font-size: 1.15rem; text-shadow: 0 2px 8px rgba(0, 0, 0, .6);
}

/* the player carries the first screen, so let it be big */
.player { max-width: none; }
.player__frame { border-radius: var(--r-md); }

.hero__hook {
  margin: clamp(.7rem, 2vh, 1rem) auto clamp(.55rem, 1.6vh, .8rem);
  max-width: 46ch;
  font-size: clamp(.98rem, 3.2vw, 1.14rem);
  text-align: center;
}
.chips--facts { justify-content: center; margin: 0; }

/* ---- two-up layout used by the merged sections ---- */
.duo {
  display: grid;
  gap: clamp(1rem, 3vw, 1.7rem);
  align-items: start;
}
@media (min-width: 880px) {
  .duo       { grid-template-columns: minmax(0, 310px) minmax(0, 1fr); }
  .duo--even { grid-template-columns: 1fr 1fr; }
}

/* ---- the fail states, now folded into "How it plays" ---- */
.bites {
  display: grid;
  gap: clamp(.9rem, 3vw, 1.5rem);
  margin-top: clamp(1.1rem, 3vw, 1.7rem);
  padding-top: clamp(.9rem, 2.4vw, 1.35rem);
  border-top: 2px dashed rgba(90, 102, 115, .28);
}
@media (min-width: 760px) {
  .bites { grid-template-columns: minmax(0, 180px) minmax(0, 1fr); }
}
.bites__list { list-style: none; margin: 0 0 .8rem; padding: 0; display: grid; gap: .5rem; }
.bite { font-size: .95rem; line-height: 1.5; color: var(--ink); }
.bite b { color: var(--blue); }
.verdict { margin: 0; font-size: .95rem; line-height: 1.5; }

/* ---- build status, a list now rather than a table ---- */
ul.status {
  list-style: none; margin: 0 0 .9rem; padding: 0;
  display: grid; gap: .5rem;
}
ul.status li {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .55rem;
  align-items: start;
  font-size: .92rem; line-height: 1.45; color: var(--ink);
}

.sub { margin: 0 0 .6rem; font-size: 1rem; }
.sub--danger { color: var(--red); }
.sub--gold   { color: var(--gold-deep); }

.lede { margin: 0 0 clamp(.85rem, 2.4vw, 1.25rem); }
.money { margin: 0 0 .8rem; }
.money li { font-size: .92rem; line-height: 1.5; }

/* ---- 20b. Height control.
   Portrait screenshots are 9:16, so at full column width a single one eats
   half a phone screen. Inside the steps and the fail-state block they become
   small cropped thumbnails instead, which is all they need to be. ---- */

.steps { display: grid; gap: .55rem; margin: 0 0 .4rem; padding: 0; }
.step {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: .85rem;
  align-items: center;
}
.step .shot,
.step .shot--portrait {
  width: 84px; height: 126px;
  margin: 0; padding: 0;
  overflow: hidden;
  aspect-ratio: auto;
}
.step .shot img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 22%;
  display: block;
}
.step__body { display: block; }
.step__body h3 { margin: 0 0 .2rem; font-size: 1rem; }
.step__body p  { margin: 0; font-size: .9rem; line-height: 1.45; }
.step__num {
  display: inline-block; margin-right: .4rem;
  font-family: var(--font-display); font-weight: 700; color: var(--gold-deep);
}

.bites__art,
.bites__art .shot,
.bites__art .shot--portrait {
  width: 122px; height: 183px;
  margin: 0; padding: 0;
  overflow: hidden;
  aspect-ratio: auto;
}
.bites__art .shot img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
  display: block;
}
@media (min-width: 760px) {
  .bites { grid-template-columns: 122px minmax(0, 1fr); }
}

/* the playable frame does not need to be a full phone tall */
.phone { max-width: 240px; margin-inline: auto; }
.phone__screen { max-height: 420px; }
.phone__poster { width: 100%; height: 100%; object-fit: cover; object-position: center top; }

/* denser text blocks */
ul.status li { font-size: .875rem; line-height: 1.4; }
.money li { font-size: .875rem; line-height: 1.42; margin-bottom: .35rem; }
.note--honest { font-size: .85rem; }
.chips--tech { margin-top: .5rem; }

/* ---- 20c. Guarantee the video fits the first screen on every phone.
   The frame takes its aspect ratio from the real video, so a portrait clip
   would otherwise push the fold. Capping the height keeps it visible on a
   small handset without letterboxing, because the video covers the frame. ---- */
.player__frame { max-height: 56svh; }
@supports not (height: 1svh) { .player__frame { max-height: 56vh; } }
.player__video, .player__preview { object-fit: cover; }

/* Trim so the video, the hook and the fact chips all land on the first screen. */
.player__frame { max-height: 48svh; }
@supports not (height: 1svh) { .player__frame { max-height: 48vh; } }
.hero__hook { margin: .6rem auto .5rem; }

/* ---- 20d. The title plate.
   Something later in the cascade forces .plate to position:relative, so the
   old absolute "pinned to the top" trick left the title sitting below a
   4.75rem gap. Rather than fight it, the plate now genuinely caps the card:
   flush with the top edge, no padding above it. ---- */
.panel__inner { padding-top: 0; }
.plate {
  position: relative;
  top: 0; left: auto;
  transform: none;
  margin: 0 auto clamp(.85rem, 2.2vw, 1.15rem);
  width: min(92%, 560px);
  border-radius: 0 0 18px 18px;
}

/* ---- 20e. Centre the video frame.
   max-height plus the video's own aspect ratio shrinks the frame narrower
   than its column, and a block element does not centre itself, so it was
   sitting hard left. Also give it more height on a desktop screen, where
   48svh leaves a portrait clip looking like a postage stamp. ---- */
.player__frame { margin-inline: auto; }

@media (min-width: 900px) {
  .player__frame { max-height: 66vh; }
  .player { max-width: 760px; }
}

/* ---- 20f. Make the play control readable over a busy poster.
   The preview frame is a game screenshot full of its own buttons and text,
   so the label was colliding with the in-game START button. A soft vignette
   plus a pill behind the label separates the control from the artwork. ---- */
.player__preview { filter: brightness(.86) saturate(1.02); }

.player__frame::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(62% 46% at 50% 50%,
              rgba(6, 14, 28, .52) 0%, rgba(6, 14, 28, .22) 58%, rgba(6, 14, 28, 0) 100%);
  transition: opacity .45s ease;
}
.player--playing .player__frame::after { opacity: 0; }

.player__play-text {
  padding: .32rem .8rem;
  border-radius: 999px;
  background: rgba(9, 17, 30, .74);
  border: 1px solid rgba(255, 255, 255, .18);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  text-shadow: none;
}

/* ---- 20g. Drop the label from over the artwork.
   A play triangle needs no caption, and the poster is a game screenshot with
   its own buttons, so any text on top reads as clutter. The label stays in
   the markup for screen readers. ---- */
.player__play-text {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0; background: none;
}
.player__play { gap: 0; }

/* ---- 20h. Step number badges.
   The badge is a 36px circle originally designed to sit above the heading.
   In the new compact row it now sits inline with the title instead. ---- */
.step__body h3 {
  display: flex; align-items: center; gap: .45rem;
  margin: 0 0 .25rem;
  font-size: clamp(.95rem, 3.2vw, 1.08rem);
}
.step__num {
  width: 26px; height: 26px;
  flex: 0 0 26px;
  margin: 0;
  font-size: .82rem;
  border-width: 2px;
}

/* An earlier override set this to gold-deep, which is invisible on a gold
   circle. Back to the dark brown the badge was designed with. */
.step__num {
  display: grid;
  place-items: center;
  color: #4a3400;
  line-height: 1;
}

/* ---- 20i. Stop the sliders blowing out their grid column.
   A grid item defaults to min-width:auto, so the slider track (a flex row of
   every slide) forced the column to its full content width, roughly 1748px.
   The phone is centred in that column, so it was being pushed off-screen,
   and .panel__inner{overflow:hidden} hid the evidence instead of scrolling. ---- */
.duo > *,
.duo__media,
.slider,
.slider__stage,
.slider__track {
  min-width: 0;
  max-width: 100%;
}

/* ---- 20j. Size the phone the way the design intends.
   The frame is driven by --phone-w and the screen takes its height from
   aspect-ratio 9/19.5. Setting max-width and max-height separately left the
   screen narrower than its own body, showing a grey band down one side. ---- */
.phone {
  --phone-w: min(215px, 72vw);
  max-width: none;
}
.phone__screen { max-height: none; }
.phone.is-running { --phone-w: min(420px, 92vw); }

/* ---- 20k. Same treatment for the playable poster: the screenshot has its
   own START button, so the real call to action needs separating from it. ---- */
.phone__poster { filter: brightness(.84) saturate(1.02); }
.phone__screen::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(62% 46% at 50% 46%,
              rgba(6, 14, 28, .50) 0%, rgba(6, 14, 28, .20) 60%, rgba(6, 14, 28, 0) 100%);
}
.phone.is-running .phone__screen::after,
.phone.is-loading .phone__screen::after { display: none; }
.playable__start { z-index: 2; }
.playable__label { text-shadow: 0 2px 8px rgba(0, 0, 0, .8); }
.playable__sub   { text-shadow: 0 1px 6px rgba(0, 0, 0, .8); }

/* ==========================================================================
   21. LOGO ABOVE, BUTTON BELOW, STACKED PLAY SECTION, LIGHTBOX
   ========================================================================== */

/* ---- hero: logo centred above the video, call to action under it ---- */
.hero__mark {
  display: flex; justify-content: center;
  margin-bottom: clamp(.5rem, 1.6vh, .9rem);
}
.hero__mark .hero__logo {
  width: clamp(150px, 42vw, 250px); height: auto;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, .5));
}
.hero__cta {
  display: flex; justify-content: center;
  margin: clamp(.7rem, 2vh, 1rem) 0 0;
}
.hero__cta .btn { min-width: 14rem; }

/* ---- play section: playable, then screenshots, then videos ---- */
.stack { display: grid; gap: clamp(1rem, 3vw, 1.6rem); }
.stack__media { min-width: 0; display: grid; gap: .4rem; }
.stack .phone { margin-inline: auto; }

/* the playable poster reads as a button */
.phone__screen { cursor: pointer; }

/* ---- every screenshot is clickable ---- */
.shot img,
.slider__track--shots img { cursor: zoom-in; }

/* ---- fullscreen image viewer ---- */
body.has-lightbox { overflow: hidden; }

.lightbox {
  position: fixed; inset: 0;
  z-index: 999;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: .5rem;
  padding: clamp(.75rem, 3vw, 2rem);
  background: rgba(6, 12, 24, .92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  animation: lb-in .18s ease-out;
}
.lightbox[hidden] { display: none; }
@keyframes lb-in { from { opacity: 0; } to { opacity: 1; } }

.lightbox__img {
  grid-column: 2;
  justify-self: center;
  max-width: 100%;
  max-height: 88vh;
  width: auto; height: auto;
  border-radius: var(--r-md);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .6);
  cursor: zoom-out;
}

.lightbox__close {
  position: absolute; top: clamp(.5rem, 2vw, 1rem); right: clamp(.5rem, 2vw, 1rem);
  width: 44px; height: 44px;
  display: grid; place-items: center;
  font-size: 1.9rem; line-height: 1;
  color: #fff;
  background: rgba(255, 255, 255, .12);
  border: 2px solid rgba(255, 255, 255, .35);
  border-radius: 50%;
  cursor: pointer;
}
.lightbox__close:hover { background: rgba(255, 255, 255, .22); }

.lightbox__nav {
  width: 44px; height: 64px;
  background: rgba(255, 255, 255, .10);
  border: 2px solid rgba(255, 255, 255, .28);
  border-radius: var(--r-sm);
  cursor: pointer;
  position: relative;
}
.lightbox__nav:hover { background: rgba(255, 255, 255, .2); }
.lightbox__nav::before {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 12px; height: 12px;
  border-right: 3px solid #fff; border-bottom: 3px solid #fff;
}
.lightbox__nav--prev::before { transform: translate(-40%, -50%) rotate(135deg); }
.lightbox__nav--next::before { transform: translate(-60%, -50%) rotate(-45deg); }
.lightbox__nav--prev { grid-column: 1; }
.lightbox__nav--next { grid-column: 3; }

.lightbox__caption {
  grid-column: 1 / -1;
  margin: 0; text-align: center;
  color: rgba(255, 255, 255, .8);
  font-size: .9rem;
}

@media (max-width: 560px) {
  .lightbox__nav { width: 38px; height: 54px; }
}

/* ==========================================================================
   22. CUSTOM VIDEO PLAYER
   The caption used to sit absolutely over the bottom of the video, which read
   as part of the picture. It is now a real line of text under the frame, and
   the native controls are replaced with a bar that matches the game UI.
   ========================================================================== */
.clip {
  aspect-ratio: auto;          /* the stage owns the ratio now, not the card */
  border: 0;
  background: none;
  overflow: visible;
  border-radius: 0;
}

.clip__stage {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 3px solid var(--steel-dark);
  background: linear-gradient(180deg, #2f5fa8 0%, var(--blue-dark) 100%);
  box-shadow: 0 10px 24px rgba(19, 58, 122, .25);
}

.clip__stage video {
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--blue-dark);
  display: block;
}

/* caption, now genuinely under the video */
.clip__title {
  position: static;
  margin: .5rem 0 0;
  padding: 0;
  background: none;
  color: var(--ink);
  font-size: .86rem;
  font-weight: 600;
  text-align: center;
  pointer-events: auto;
}

/* ---- big centre play, hidden once it is running ---- */
.clip__big {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: grid; place-items: center;
  border: 0; background: rgba(6, 14, 28, .28);
  cursor: pointer;
  transition: opacity .25s ease;
}
.clip__big::after {
  content: "";
  width: 0; height: 0;
  margin-left: 6px;
  border-left: 22px solid #fff;
  border-top: 14px solid transparent;
  border-bottom: 14px solid transparent;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .5));
}
.clip__big::before {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 62px; height: 62px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: linear-gradient(180deg, #FFA23F 0%, var(--orange) 50%, var(--orange-deep) 100%);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, .45), 0 8px 20px rgba(0, 0, 0, .4);
}
.clip.is-playing .clip__big { opacity: 0; pointer-events: none; }

/* ---- control bar ---- */
.clip__bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: .4rem;
  padding: .45rem .5rem;
  background: linear-gradient(0deg, rgba(6, 12, 24, .88) 0%, rgba(6, 12, 24, .55) 60%, transparent 100%);
  opacity: 0;
  transition: opacity .25s ease;
}
.clip__stage:hover .clip__bar,
.clip__stage:focus-within .clip__bar,
.clip.is-playing .clip__bar,
.clip__stage.is-fullscreen .clip__bar { opacity: 1; }

.clip__btn {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  padding: 0;
  border: 0; border-radius: 8px;
  background: rgba(255, 255, 255, .14);
  cursor: pointer;
  position: relative;
}
.clip__btn:hover { background: rgba(255, 255, 255, .28); }

.clip__seek {
  flex: 1 1 auto;
  min-width: 0;
  height: 4px;
  -webkit-appearance: none; appearance: none;
  background: rgba(255, 255, 255, .3);
  border-radius: 999px;
  cursor: pointer;
}
.clip__seek::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--gold);
  border: 2px solid #fff;
}
.clip__seek::-moz-range-thumb {
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--gold);
  border: 2px solid #fff;
}

.clip__time {
  flex: 0 0 auto;
  font-size: .68rem;
  color: rgba(255, 255, 255, .9);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- fullscreen: letterbox rather than crop, so the shape stays true ---- */
.clip__stage:fullscreen,
.clip__stage:-webkit-full-screen {
  aspect-ratio: auto;
  width: 100vw; height: 100vh;
  border: 0; border-radius: 0;
  background: #000;
}
.clip__stage:fullscreen video,
.clip__stage:-webkit-full-screen video {
  object-fit: contain;
  background: #000;
}
.clip__stage:fullscreen .clip__bar,
.clip__stage:-webkit-full-screen .clip__bar {
  padding: 1rem 1.25rem;
  gap: .7rem;
}
.clip__stage:fullscreen .clip__btn,
.clip__stage:-webkit-full-screen .clip__btn { width: 40px; height: 40px; }
.clip__stage:fullscreen .clip__time,
.clip__stage:-webkit-full-screen .clip__time { font-size: .85rem; }

/* Standalone copies of the fullscreen rules. A grouped selector is thrown
   away wholesale by any browser that does not recognise one part of it, so
   pairing :fullscreen with :-webkit-full-screen above would silently break
   fullscreen in Firefox. These duplicates keep each engine covered. */
.clip__stage:fullscreen {
  aspect-ratio: auto;
  width: 100vw; height: 100vh;
  border: 0; border-radius: 0;
  background: #000;
}
.clip__stage:fullscreen video {
  object-fit: contain;
  background: #000;
}
.clip__stage:fullscreen .clip__bar { padding: 1rem 1.25rem; gap: .7rem; }
.clip__stage:fullscreen .clip__btn { width: 40px; height: 40px; }
.clip__stage:fullscreen .clip__time { font-size: .85rem; }
.clip__stage:fullscreen .clip__big::before { width: 84px; height: 84px; }

/* ==========================================================================
   23. VOLUME, SPEED, DOWNLOAD, AND THE SHARED HERO BAR
   ========================================================================== */

/* the hero frame is a stage too, so it gets the same bar */
.player__frame:hover .clip__bar,
.player__frame:focus-within .clip__bar,
.player__frame.is-playing .clip__bar,
.player__frame.is-fullscreen .clip__bar { opacity: 1; }

.clip__bar { flex-wrap: nowrap; }

/* ---- volume: button plus a slider that opens beside it ---- */
.clip__vol { position: relative; display: flex; align-items: center; flex: 0 0 auto; }
.clip__btn--vol.is-muted { background: rgba(232, 74, 74, .55); }

.clip__vol-slider {
  width: 0; opacity: 0;
  height: 4px;
  margin-left: 0;
  -webkit-appearance: none; appearance: none;
  background: rgba(255, 255, 255, .32);
  border-radius: 999px;
  cursor: pointer;
  transition: width .22s var(--pop), opacity .18s ease, margin-left .22s var(--pop);
}
.clip__vol:hover .clip__vol-slider,
.clip__vol:focus-within .clip__vol-slider { width: 56px; opacity: 1; margin-left: .35rem; }
.clip__vol-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
}
.clip__vol-slider::-moz-range-thumb {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
}

/* ---- speed: a text button that cycles ---- */
.clip__btn--speed {
  width: auto; min-width: 34px;
  padding: 0 .35rem;
  font-family: var(--font-display); font-weight: 600;
  font-size: .72rem; color: #fff;
  font-variant-numeric: tabular-nums;
}

/* ---- download ---- */
.clip__btn--dl { text-decoration: none; }

/* narrow phones: drop the speed label rather than crowd the bar */
@media (max-width: 400px) {
  .clip__btn--speed { min-width: 30px; font-size: .66rem; }
  .clip__time { font-size: .62rem; }
}

/* ---- footer studio name ---- */
.footer__studio {
  margin: 0 0 .1rem;
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.35rem; line-height: 1.1;
  color: var(--gold);
  letter-spacing: .01em;
}

/* ==========================================================================
   24. TITLE JUICE
   The logo pops in on load and then breathes, and each section plate drops
   in with a small overshoot when it is scrolled to.
   ========================================================================== */
.hero__mark .hero__logo {
  animation: logo-pop .7s var(--pop) both, logo-float 5.5s ease-in-out 1s infinite;
  transform-origin: 50% 60%;
}
@keyframes logo-pop {
  0%   { opacity: 0; transform: scale(.72) translateY(-14px) rotate(-3deg); }
  60%  { opacity: 1; transform: scale(1.05) translateY(2px) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) translateY(0) rotate(0); }
}
@keyframes logo-float {
  0%, 100% { transform: translateY(0) rotate(0); }
  50%      { transform: translateY(-7px) rotate(-1.2deg); }
}

.plate { animation: plate-drop .5s var(--pop) both; }
@keyframes plate-drop {
  0%   { opacity: 0; transform: translateY(-16px) scaleX(.9); }
  100% { opacity: 1; transform: translateY(0) scaleX(1); }
}
.plate h2 {
  background: linear-gradient(100deg, #fff 30%, #ffe9a8 50%, #fff 70%) 0 0 / 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: plate-shine 6s ease-in-out 1.2s infinite;
}
@keyframes plate-shine {
  0%, 65%, 100% { background-position: 120% 0; }
  80%           { background-position: -20% 0; }
}
.plate--gold h2 { -webkit-text-fill-color: #4a3400; background: none; animation: none; }

@media (prefers-reduced-motion: reduce) {
  .hero__mark .hero__logo,
  .plate,
  .plate h2 { animation: none; }
  .plate h2 { -webkit-text-fill-color: #fff; }
}

/* ==========================================================================
   25. CONTROL BAR, REBUILT
   The old icons were pseudo-element shapes that read as random glyphs, and
   the seek slider shared one flex row with everything else so it collapsed
   to zero width on a narrow slide. Icons are now SVG and the seek gets a
   row to itself.
   ========================================================================== */

/* never crop a video: letterbox it against black instead */
.clip__stage video,
.player__video { object-fit: contain; background: #06101f; }

.clip__bar {
  display: grid;
  grid-template-rows: auto auto;
  gap: .3rem;
  padding: .45rem .55rem .5rem;
  align-items: center;
}
.clip__row {
  display: flex; align-items: center; gap: .25rem;
  min-width: 0;
}
.clip__spacer { flex: 1 1 auto; }

/* ---- buttons ---- */
.clip__btn {
  width: 30px; height: 30px;
  flex: 0 0 auto;
  display: inline-grid; place-items: center;
  padding: 0;
  border: 0; border-radius: 8px;
  background: rgba(255, 255, 255, .13);
  color: #fff;
  cursor: pointer;
  transition: background-color .18s ease, transform .18s var(--pop);
}
.clip__btn:hover { background: rgba(255, 255, 255, .3); }
.clip__btn:active { transform: scale(.92); }

/* every icon is an svg now, so one rule styles them all */
.clip__btn svg {
  width: 17px; height: 17px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* the play and pause glyphs are solid, not outlines */
.clip__btn--play svg { fill: currentColor; stroke: none; }

.clip__btn--vol.is-muted { background: rgba(232, 74, 74, .5); }

.clip__btn--speed {
  width: auto; min-width: 32px;
  padding: 0 .3rem;
  font-family: var(--font-display); font-weight: 600;
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
}

.clip__btn--dl { text-decoration: none; }

/* ---- sliders ---- */
.clip__seek {
  grid-row: 1;
  width: 100%;
  height: 5px;
  margin: 0;
  -webkit-appearance: none; appearance: none;
  background: rgba(255, 255, 255, .28);
  border-radius: 999px;
  cursor: pointer;
}
.clip__seek::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.clip__seek::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
}

.clip__vol { position: relative; display: flex; align-items: center; flex: 0 0 auto; }
.clip__vol-slider {
  width: 0; opacity: 0; margin-left: 0;
  height: 4px;
  -webkit-appearance: none; appearance: none;
  background: rgba(255, 255, 255, .32);
  border-radius: 999px;
  cursor: pointer;
  transition: width .2s var(--pop), opacity .16s ease, margin-left .2s var(--pop);
}
.clip__vol:hover .clip__vol-slider,
.clip__vol:focus-within .clip__vol-slider { width: 52px; opacity: 1; margin-left: .3rem; }
.clip__vol-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
}
.clip__vol-slider::-moz-range-thumb {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--gold); border: 2px solid #fff;
}

.clip__time {
  flex: 0 0 auto;
  font-size: .66rem;
  color: rgba(255, 255, 255, .92);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* very narrow slides: hide speed and the volume slider, keep the essentials */
@media (max-width: 430px) {
  .clip__stage .clip__btn--speed { display: none; }
  .clip__stage .clip__vol:hover .clip__vol-slider,
  .clip__stage .clip__vol:focus-within .clip__vol-slider { width: 40px; }
}

/* fullscreen: roomier controls */
.clip__stage:fullscreen .clip__btn { width: 40px; height: 40px; }
.clip__stage:fullscreen .clip__btn svg { width: 21px; height: 21px; }
.clip__stage:fullscreen .clip__btn--speed { display: inline-grid; }
.clip__stage:fullscreen .clip__time { font-size: .85rem; }

/* The playing class is set on the stage, not the outer card, so these two
   rules were never matching for carousel clips: the bar stayed hidden and
   the big play button stayed on screen during playback. */
.clip__stage.is-playing .clip__bar { opacity: 1; }
.clip__stage.is-playing .clip__big { opacity: 0; pointer-events: none; }

/* download button while it is buffering the file */
.clip__btn--dl.is-busy { opacity: .55; pointer-events: none; }
.clip__btn--dl.is-busy svg { animation: dl-nudge .8s ease-in-out infinite; }
@keyframes dl-nudge {
  0%, 100% { transform: translateY(-2px); }
  50%      { transform: translateY(2px); }
}
@media (prefers-reduced-motion: reduce) {
  .clip__btn--dl.is-busy svg { animation: none; }
}

/* ==========================================================================
   26. PLAYABLE: FIT THE VIEWPORT, FULLSCREEN, LOADING
   The running phone was sized only by width. With a 9/19.5 screen, 420px wide
   is 910px tall, which overflows most laptops and every phone. The third term
   below derives a width from the height actually available, so the frame can
   never be taller than the viewport.
   ========================================================================== */

.phone {
  position: relative;
  --phone-w: min(215px, 72vw, calc((100svh - 14rem) * 9 / 19.5));
}
.phone.is-running {
  --phone-w: min(420px, 92vw, calc((100svh - 11rem) * 9 / 19.5));
}
@supports not (height: 1svh) {
  .phone            { --phone-w: min(215px, 72vw, calc((100vh - 14rem) * 9 / 19.5)); }
  .phone.is-running { --phone-w: min(420px, 92vw, calc((100vh - 11rem) * 9 / 19.5)); }
}

/* ---- fullscreen control, only present once the build is running ---- */
.playable__fs {
  position: absolute;
  right: 50%;
  bottom: -0.9rem;
  transform: translateX(50%);
  z-index: 3;
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .45rem .85rem;
  border: 2px solid #fff;
  border-radius: 999px;
  background: linear-gradient(180deg, #2C68C4 0%, var(--blue) 100%);
  color: #fff;
  font-family: var(--font-display); font-weight: 600; font-size: .82rem;
  cursor: pointer;
  box-shadow: 0 4px 0 var(--blue-dark), 0 8px 18px rgba(0, 0, 0, .3);
  transition: transform .18s var(--pop), box-shadow .18s ease;
}
.playable__fs:hover { transform: translateX(50%) translateY(-2px); }
.playable__fs:active {
  transform: translateX(50%) translateY(3px);
  box-shadow: 0 1px 0 var(--blue-dark);
}
.playable__fs svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* give the button room so it does not collide with the next section */
.stack .phone.is-running { margin-bottom: 1.4rem; }

/* ---- loading readout ---- */
.playable__status-title { font-variant-numeric: tabular-nums; }

.bar {
  overflow: hidden;
  border-radius: 999px;
}
.bar__fill {
  transition: width .25s ease;
}
/* a moving sheen so a slow download still looks alive */
.bar__fill::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .45), transparent);
  animation: bar-sheen 1.3s linear infinite;
}
@keyframes bar-sheen {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .bar__fill::after { animation: none; }
}

/* ==========================================================================
   27. FULLSCREEN THAT KEEPS THE GAME'S SHAPE
   The frame goes fullscreen, not the canvas. The canvas is then sized by CSS
   to the game's real 9/19.5 ratio and centred, so a portrait game letterboxes
   against black instead of being stretched across a landscape monitor.
   Written as separate rules per prefix: a grouped selector is discarded whole
   by any browser that does not recognise one part of it.
   ========================================================================== */

.phone__screen:fullscreen {
  width: 100vw; height: 100vh;
  max-width: none; max-height: none;
  aspect-ratio: auto;
  border-radius: 0;
  background: #000;
  display: grid;
  place-items: center;
}
.phone__screen:fullscreen canvas {
  height: 100%;
  width: auto;
  aspect-ratio: 9 / 19.5;
  max-width: 100vw;
  max-height: 100vh;
  display: block;
}
/* the poster and any overlay must not reappear over the game */
.phone__screen:fullscreen > *:not(canvas) { display: none; }

.phone__screen:-webkit-full-screen {
  width: 100vw; height: 100vh;
  max-width: none; max-height: none;
  aspect-ratio: auto;
  border-radius: 0;
  background: #000;
  display: grid;
  place-items: center;
}
.phone__screen:-webkit-full-screen canvas {
  height: 100%;
  width: auto;
  aspect-ratio: 9 / 19.5;
  max-width: 100vw;
  max-height: 100vh;
  display: block;
}
.phone__screen:-webkit-full-screen > *:not(canvas) { display: none; }

/* On a phone held upright the screen is already portrait, so fill the width
   and let the height follow rather than leaving side bars. */
@media (orientation: portrait) {
  .phone__screen:fullscreen canvas {
    width: 100%;
    height: auto;
    max-height: 100vh;
  }
  .phone__screen:-webkit-full-screen canvas {
    width: 100%;
    height: auto;
    max-height: 100vh;
  }
}

/* ---- 27b. Beat the base canvas rule.
   .phone__screen canvas pins the canvas with position:absolute, inset:0 and
   width/height 100% !important, so it always fills its box and can never be
   letterboxed. In fullscreen it has to become a normal centred grid item, and
   only !important can undo !important. ---- */
.phone__screen:fullscreen canvas {
  position: static !important;
  inset: auto !important;
  height: 100% !important;
  width: auto !important;
  aspect-ratio: 9 / 19.5;
  max-width: 100vw !important;
  max-height: 100vh !important;
  margin: 0 auto;
}
.phone__screen:-webkit-full-screen canvas {
  position: static !important;
  inset: auto !important;
  height: 100% !important;
  width: auto !important;
  aspect-ratio: 9 / 19.5;
  max-width: 100vw !important;
  max-height: 100vh !important;
  margin: 0 auto;
}

@media (orientation: portrait) {
  .phone__screen:fullscreen canvas {
    width: 100% !important;
    height: auto !important;
  }
  .phone__screen:-webkit-full-screen canvas {
    width: 100% !important;
    height: auto !important;
  }
}
