/* Stone Age Keno Public Website Mockup Styles */

@import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@600;700;800&family=Bree+Serif&family=Luckiest+Guy&display=swap');

:root {
  /* Game Typography System */
  --font-display: 'Luckiest Guy', cursive, sans-serif;
  --font-serif: 'Bree Serif', serif;
  --font-body: 'Barlow Condensed', -apple-system, BlinkMacSystemFont, sans-serif;

  /* In-Game Inspired Dark Charcoal & Light Cream Parchment Color Palette */
  /* Dark Charcoal / Gray Stone Base (Game Popup / Settings UI Theme) */
  --bg-charcoal-dark: #12161f;
  --bg-charcoal-section: #161b26;
  --bg-charcoal-panel: #222a3a;
  --bg-charcoal-card: #242b38;
  --border-charcoal-stone: #3a4659;

  /* Light Cream / Off-White Parchment Section Base */
  --bg-parchment-section: #f7f2e7;
  --bg-parchment-card: #ffffff;
  --border-parchment: #e2d7c3;

  /* Gold & Orange Accents */
  --gold: #f4b23b;
  --gold-bright: #ffe08a;
  --border-gold: #d99b32;
  --gold-glow: rgba(244, 178, 59, 0.25);
  --shadow-dark: #0a0d12;
  --shadow-brown: #5b2d0c;
  --purple: #a855f7;

  /* Text Colors */
  --text-cream: #fff0c8;
  --text-cream-muted: #d4c39e;
  --text-dark-charcoal: #1e2530;
  --text-dark-muted: #4a5568;

  /* Dimensions & Radius */
  --radius: 14px;
  --header-h: 78px;
  --max-w: 1140px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  background-color: var(--bg-charcoal-dark);
  color: var(--text-cream);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.relative-container {
  position: relative;
}

/* ===== Typography System ===== */
/* Game Heading Style with 3D Gold & Shadow */
.hero-title, .section-title, .hub-title, .emoji-showcase-title {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.03em;
  line-height: 1.2;
}

/* Dark Section Headings */
.section-dark-charcoal .section-title,
.hero-section .hero-title,
.site-footer h4,
.emoji-showcase-title {
  color: var(--gold-bright);
  text-shadow:
    0 3px 0 #3a1a05,
    0 6px 12px rgba(0, 0, 0, 0.7);
}

/* Light Cream Section Headings */
.section-cream-parchment .section-title {
  color: #c86e00;
  text-shadow:
    0 2px 0 #4a2800,
    0 4px 10px rgba(0, 0, 0, 0.15);
}

.step-title, .way-title, .module-title, .event-title, .feature-box h3, .footer-col h4, .comp-title, .reward-title {
  font-family: var(--font-serif);
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.3;
}

a { color: inherit; text-decoration: none; }

/* ===== Header & Top Menu Navigation ===== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  background-color: rgba(18, 22, 31, 0.95);
  backdrop-filter: blur(10px);
  border-bottom: 2px solid var(--border-charcoal-stone);
}

.header-container {
  max-width: var(--max-w);
  margin: 0 auto;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
}

.brand-link {
  display: flex;
  align-items: center;
}

.brand-logo {
  height: 56px;
  max-height: 82%;
  width: auto;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.75));
  transition: transform 0.15s ease;
}

.brand-link:hover .brand-logo {
  transform: scale(1.03);
}

/* Menu Navigation using Game Toggle Buttons */
.site-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
}

/* Width reduced 135px -> 124px (and type 0.88 -> 0.82rem) to make room for the
   new persistent .header-cta. At 135px the row was logo(102) + nav(840) +
   cta(189) = 1132px against a 1108px container, which would have flex-shrunk
   the stone toggle art at FULL desktop width. Longest label ("STONE AGE
   LOBBY") measures ~101px at 0.82rem, so it still clears with side padding. */
.nav-btn {
  width: 124px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-decoration: none;
  box-sizing: border-box;
  text-align: center;
  transition: transform 0.15s ease, filter 0.15s ease;
  white-space: nowrap;
}

/* Inactive Nav Toggle Button */
.nav-btn-inactive {
  background: url('assets/web_exports/toggle_button.webp') center / 100% 100% no-repeat;
  color: #d9bd86; /* Warm muted cream */
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}

.nav-btn-inactive:hover {
  transform: translateY(-1px);
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.6));
  color: #ffffff;
}

/* Active Nav Toggle Button — High Readability Bright Text & Shadow */
.nav-btn-active {
  background: url('assets/web_exports/toggle_button_active.webp') center / 100% 100% no-repeat;
  color: #fff0c8; /* Brighter cream text */
  text-shadow:
    0 2px 0 #5b2d0c,
    0 3px 6px rgba(0, 0, 0, 0.85);
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.5));
}

/* ===== Persistent Header Conversion CTA =====
   Green to match the in-game play_button.webp stone button family (colors
   sampled from that asset: #4c9904 highlight -> #2f8912 mid -> #1f740f base),
   but built in CSS rather than stretching the 384x140 art into a wide, short
   header slot — at header proportions the baked stone bevel distorts badly.
   Phase 1B option: export a wide green button plate and swap this for it. */
.header-cta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 46px;
  padding: 0 18px;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 0.86rem;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #ffffff;
  text-shadow: 0 2px 0 rgba(12, 40, 6, 0.9), 0 2px 6px rgba(0, 0, 0, 0.5);
  background: linear-gradient(180deg, #56a80c 0%, #2f8912 55%, #1d7010 100%);
  border: 2px solid #143a0a;
  border-top-color: #6cc21c;
  border-radius: 10px;
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.28),
    inset 0 -3px 0 rgba(0, 0, 0, 0.28),
    0 4px 12px rgba(0, 0, 0, 0.5);
  transition: transform 0.15s ease, filter 0.15s ease, box-shadow 0.15s ease;
}

.header-cta:hover {
  transform: translateY(-1px);
  filter: brightness(1.09);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.32),
    inset 0 -3px 0 rgba(0, 0, 0, 0.28),
    0 7px 18px rgba(0, 0, 0, 0.6);
}

.header-cta:active {
  transform: translateY(1px);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.45);
}

.header-cta:focus-visible,
.btn-game-play:focus-visible,
.nav-btn:focus-visible {
  outline: 3px solid var(--gold-bright);
  outline-offset: 3px;
}

/* ===== Action Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-serif);
  font-weight: 400;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  transition: all 0.15s ease-in-out;
  white-space: nowrap;
  text-decoration: none;
}

/* Hero primary CTA. Widened for the "PLAY FREE ON FACEBOOK" copy and held at a
   ~3:1 box against the 384x140 (2.74:1) native art — a gentler stretch than the
   previous 210x68. Typography matched to .header-cta so the site's two primary
   CTAs read as one system. */
.btn-game-play {
  flex: 0 0 auto;
  width: clamp(205px, 22vw, 240px);
  height: clamp(68px, 7.3vw, 80px);
  background: url('assets/web_exports/play_button.webp') center / 100% 100% no-repeat;
  color: #ffffff;
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: 0.045em;
  font-size: clamp(0.88rem, 1.05vw, 1rem);
  text-shadow: 0 2px 0 rgba(12, 40, 6, 0.85), 0 2px 6px rgba(0, 0, 0, 0.55);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.55));
  transition: transform 0.15s ease, filter 0.15s ease;
  text-transform: uppercase;
}

.btn-game-play:hover {
  transform: translateY(-2px) scale(1.03);
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.7));
}

.btn-game-arena {
  width: clamp(170px, 22vw, 210px);
  height: clamp(52px, 6vw, 68px);
  background: url('assets/web_exports/enter_arena_button.webp') center / 100% 100% no-repeat;
  color: #ffffff;
  font-size: clamp(0.95rem, 1.15vw, 1.1rem);
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.85);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.55));
  transition: transform 0.15s ease, filter 0.15s ease;
  text-transform: uppercase;
}

.btn-game-arena:hover {
  transform: translateY(-2px) scale(1.03);
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.7));
}

/* ===== 1. Hero Section ===== */
.hero-section {
  position: relative;
  width: 100%;
  background-color: #0b0f17;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-sizing: border-box;
}

.hero-video-stage {
  position: relative;
  width: 100%;
  max-width: 1920px;
  aspect-ratio: 2 / 1;
  max-height: calc(100vh - var(--header-h));
  margin: 0 auto;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #0b0f17;
  /* Must stay in sync with the <video poster> in index.html — this paints the
     stage behind the letterboxed video (Phase 1B re-pick, approved v5 clip 6). */
  background-image: url('assets/web_exports/hero_poster_v5_winner.webp');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

.hero-bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  z-index: 1;
  background-color: #0b0f17;
}

/* Edge vignette only — was a heavy bottom scrim ramping to 0.88 opacity, which
   existed to keep the overlaid text legible. With the copy moved out of the
   video that darkening bought nothing and cost gameplay visibility. */
.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(11, 15, 23, 0.30) 0%,
    rgba(11, 15, 23, 0.0) 18%,
    rgba(11, 15, 23, 0.0) 82%,
    rgba(11, 15, 23, 0.38) 100%
  );
  pointer-events: none;
  z-index: 2;
}

/* ===== Hero Action Band (below the video) ===== */
.hero-action-band {
  width: 100%;
  background: linear-gradient(180deg, #161b26 0%, var(--bg-charcoal-dark) 100%);
  border-top: 2px solid var(--border-gold);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  padding: 14px 20px 16px;
}

.hero-action-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.hero-action-copy {
  min-width: 0;
}

/* Now that it sits on a solid band rather than over video, the H1 can be a real
   headline instead of a caption (it was clamped to 1.25rem max — smaller than
   the 1.05rem body copy, which inverted the document hierarchy). */
.hero-title {
  font-size: clamp(1.15rem, 2.1vw, 1.75rem);
  color: var(--gold-bright);
  margin-bottom: 5px;
  letter-spacing: 0.03em;
  line-height: 1.15;
  text-shadow:
    0 2px 0 #3a1a00,
    0 3px 8px rgba(0, 0, 0, 0.6);
}

/* Trust microcopy directly beneath the hero CTA — answers the "is this real
   money gambling / do I have to install something / will it ask for my
   Facebook data" objection at the exact moment of the click decision. */
.hero-trust {
  margin-top: 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(0.72rem, 0.95vw, 0.88rem);
  letter-spacing: 0.04em;
  line-height: 1.35;
  color: var(--text-cream-muted);
}

/* ===== Un-Skewed Section Divider ===== */
.section-divider-wrap {
  width: 100%;
  overflow: hidden;
  line-height: 0;
  margin: -12px 0;
  position: relative;
  z-index: 30;
}

.section-divider-img {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.6));
}

/* ===== Alternating High-Contrast Section Backgrounds ===== */
.section {
  padding: 76px 20px;
}

/* Dark Charcoal Stone Section (In-Game Popup / Settings UI Theme) */
.section-dark-charcoal {
  background-color: var(--bg-charcoal-section); /* #161b26 */
}

.section-dark-charcoal .section-subtitle {
  color: var(--text-cream-muted);
}

/* Light Cream / Off-White Parchment Section */
.section-cream-parchment {
  background-color: var(--bg-parchment-section); /* #f7f2e7 */
  border-top: 1px solid var(--border-parchment);
  border-bottom: 1px solid var(--border-parchment);
}

.section-cream-parchment .section-subtitle {
  color: var(--text-dark-muted);
}

.section-container {
  max-width: var(--max-w);
  margin: 0 auto;
}

.section-head {
  margin-bottom: 44px;
}

.text-center { text-align: center; }

.section-title {
  font-size: clamp(1.9rem, 2.8vw, 2.6rem);
  margin-bottom: 8px;
}

.section-subtitle {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.18rem;
  letter-spacing: 0.02em;
}

/* ===== Raised Charcoal Stone Cards (High Contrast on Cream & Dark Sections) ===== */
.module-card, .comp-card, .reward-card, .feature-box, .step-card {
  background-color: var(--bg-charcoal-card); /* #242b38 */
  border: 2px solid var(--border-charcoal-stone); /* #3a4659 */
  border-top-color: #4f5f78; /* Subtle top edge light highlight */
  border-radius: var(--radius);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  color: var(--text-cream);
}

/* ===== 1. Game Worlds Collectible Mechanic Badges (56px-78px Desktop) ===== */
.mechanic-badge {
  position: absolute;
  bottom: -16px;
  right: 14px;
  width: clamp(56px, 6vw, 78px);
  height: clamp(56px, 6vw, 78px);
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.75));
  z-index: 20;
  transition: transform 0.25s ease;
}

.module-card:hover .mechanic-badge {
  transform: scale(1.1) rotate(6deg);
}

.modules-grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 26px;
}

.module-card {
  overflow: visible; /* Allows mechanic badges to overlap card edges cleanly */
  display: flex;
  flex-direction: column;
}

.module-banner {
  position: relative;
  height: 180px;
  background-color: #0f131a;
  overflow: visible;
  border-bottom: 3px solid var(--border-gold);
  border-top-left-radius: calc(var(--radius) - 2px);
  border-top-right-radius: calc(var(--radius) - 2px);
}

.module-art {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-top-left-radius: calc(var(--radius) - 2px);
  border-top-right-radius: calc(var(--radius) - 2px);
  transition: transform 0.3s ease;
}

/* Caveman world art only. The banner is ~2:1 but the art is 3:2, so
   `object-fit: cover` discards ~26% of the source height. Centred (the default
   50%), that took ~131px off the top — which is exactly where the caveman
   rider's head and raised fist sit, so he rendered headless.

   4% biases the crop toward the top: the rider clears the edge at every column
   count the auto-fit grid produces (3-col 363px, 2-col ~433px, 1-col ~586px),
   while the eggs and foreground at the bottom stay in frame. The image is
   NOT distorted — only the crop window moves.

   Cavegirl and Dino are correctly framed at the default 50% and are left alone. */
.module-art-top {
  object-position: 50% 4%;
}

.module-card:hover .module-art {
  transform: scale(1.04);
}

.module-logo-badge {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  max-width: 155px;
  max-height: 52px;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.9));
}

.module-body {
  padding: 24px 20px;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

.module-mascot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.module-mascot img {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid var(--gold);
}

.module-mascot span {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.04em;
  color: var(--gold-bright);
  text-transform: uppercase;
}

/* ===== Game Worlds — small looping mechanic animations (one per world label) =====
   Anchored to the right of the mascot/label row and absolutely positioned so they
   never shift the card layout, cover the avatar, title, body, tags, or card art.
   CSS-only (transform / opacity / filter / stepped background frames). */
.module-mascot { position: relative; }
.mechanic-anim {
  --mech-size: clamp(44px, 4.8vw, 56px);
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  width: var(--mech-size);
  height: var(--mech-size);
  background: center / contain no-repeat;
  pointer-events: none;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45));
  will-change: transform, filter;
}
.mechanic-anim span { all: unset; } /* guard: never inherit the label span styling */

/* 1. Caveman — EGG HATCH: intact egg rests, wobbles, then hatches (10-frame sequence).
   20% larger than the other mechanics; the extra height is added downward (center
   nudged down by half the growth) so the egg's TOP edge stays put. */
.mechanic-egg-hatch {
  width: calc(var(--mech-size) * 1.44);
  height: calc(var(--mech-size) * 1.44);
  top: calc(50% + var(--mech-size) * 0.22);
  background-image: url('assets/web_exports/egg_hatch1.webp');
  animation: mech-egg-frames 3.6s steps(1, end) infinite,
             mech-egg-motion 3.6s ease-in-out infinite;
}
@keyframes mech-egg-frames {
  0%, 50%   { background-image: url('assets/web_exports/egg_hatch1.webp'); }  /* rest */
  55%       { background-image: url('assets/web_exports/egg_hatch2.webp'); }
  61%       { background-image: url('assets/web_exports/egg_hatch3.webp'); }
  67%       { background-image: url('assets/web_exports/egg_hatch4.webp'); }
  73%       { background-image: url('assets/web_exports/egg_hatch5.webp'); }
  79%       { background-image: url('assets/web_exports/egg_hatch6.webp'); }
  84%       { background-image: url('assets/web_exports/egg_hatch7.webp'); }
  89%       { background-image: url('assets/web_exports/egg_hatch8.webp'); }
  94%       { background-image: url('assets/web_exports/egg_hatch9.webp'); }
  98%, 100% { background-image: url('assets/web_exports/egg_hatch10.webp'); }  /* hatched */
}
@keyframes mech-egg-motion {
  0%, 40%   { transform: translateY(-50%) rotate(0deg) scale(1);       filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
  44%       { transform: translateY(-50%) rotate(-6deg) scale(1); }
  48%       { transform: translateY(-50%) rotate(6deg) scale(1); }
  52%       { transform: translateY(-50%) rotate(-5deg) scale(1); }
  56%       { transform: translateY(-50%) rotate(4deg) scale(1.02); }
  62%       { transform: translateY(-50%) rotate(0deg) scale(1.07);    filter: drop-shadow(0 0 9px rgba(255, 210, 90, 0.95)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
  80%       { transform: translateY(-53%) rotate(0deg) scale(1.05);    filter: drop-shadow(0 0 6px rgba(255, 210, 90, 0.7)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
  100%      { transform: translateY(-50%) rotate(0deg) scale(1);       filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
}

/* 2. Cavegirl — CRYSTAL: rocks side to side, floats, and glows (magical/mining) */
.mechanic-crystal-spin {
  background-image: url('assets/web_exports/crystal.webp');
  animation: mech-crystal 4.2s ease-in-out infinite;
}
@keyframes mech-crystal {
  0%, 100% { transform: translateY(-50%) rotate(-11deg) scale(1);    filter: drop-shadow(0 0 4px rgba(168, 85, 247, 0.45)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
  50%      { transform: translateY(-54%) rotate(11deg) scale(1.06);  filter: drop-shadow(0 0 12px rgba(200, 130, 255, 0.95)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
}

/* 3. Dino — BONE: rocks side to side and floats, same motion as the crystal */
.mechanic-bone-spin {
  background-image: url('assets/web_exports/dino_bone.webp');
  animation: mech-bone 4.2s ease-in-out infinite;
}
@keyframes mech-bone {
  0%, 100% { transform: translateY(-50%) rotate(-11deg) scale(1);    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
  50%      { transform: translateY(-54%) rotate(11deg) scale(1.06);  filter: drop-shadow(0 0 7px rgba(255, 225, 150, 0.6)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.45)); }
}

/* Reduced motion: no animation — show the static asset (egg at rest, crystal, bone) */
@media (prefers-reduced-motion: reduce) {
  .mechanic-anim { animation: none !important; }
  .mechanic-egg-hatch { background-image: url('assets/web_exports/egg_hatch1.webp'); }
}

.module-title {
  font-size: 1.5rem;
  color: var(--gold-bright);
  margin-bottom: 8px;
}

.module-desc {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--text-cream-muted);
  margin-bottom: 18px;
  line-height: 1.45;
  flex: 1 1 auto;
}

.module-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding-top: 10px;
}

.stone-label {
  background: #181e28;
  border: 1px solid var(--border-charcoal-stone);
  color: var(--text-cream);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  padding: 4px 12px;
  border-radius: 6px;
  text-transform: uppercase;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}

.gold-label {
  background: rgba(244, 178, 59, 0.18);
  border: 1px solid var(--border-gold);
  color: var(--gold-bright);
}

/* ===== 2. THE STONE AGE LOBBY (Spilling Currency Stickers 48px-70px) ===== */
.hub-showcase-box {
  background: var(--bg-charcoal-panel); /* #222a3a */
  border: 2px solid var(--border-gold);
  border-radius: var(--radius);
  padding: 40px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 36px;
  align-items: center;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.65), 0 0 20px var(--gold-glow);
}

.hub-text-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.hub-title {
  font-size: clamp(2.2rem, 3.2vw, 3rem);
}

.hub-desc {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--text-cream);
  line-height: 1.5;
}

.hub-features-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 8px;
}

.hub-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #161b24;
  border: 1px solid var(--border-charcoal-stone);
  padding: 6px 14px;
  border-radius: 8px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--text-cream);
}

.hub-img-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  border-radius: var(--radius);
  overflow: visible; /* Allows currency stickers to spill outside frame */
  border: 2px solid var(--border-gold);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
  background: #090c12;
}

.hub-feature-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  border-radius: calc(var(--radius) - 2px);
}

/* Large Currency Stickers Spilling Around Lobby Frame (48px-70px) */
.currency-sticker {
  position: absolute;
  width: clamp(48px, 5vw, 68px);
  height: clamp(48px, 5vw, 68px);
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.8));
  z-index: 25;
}

.coin-sticker {
  top: -22px;
  left: -20px;
  transform: rotate(-12deg);
}

.bucks-sticker {
  bottom: -22px;
  left: 25%;
  transform: rotate(8deg);
}

.ruby-sticker {
  top: -22px;
  right: -18px;
  transform: rotate(15deg);
}

/* ===== 3. Stone Age Competitions (Large 90px-120px Rocky MaxBet Sticker) ===== */
.competitions-grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 26px;
}

.comp-card {
  overflow: visible;
  display: flex;
  flex-direction: column;
}

.comp-card-banner {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  background-color: #0f131a;
  overflow: hidden;
  border-bottom: 2px solid var(--border-charcoal-stone);
  border-top-left-radius: calc(var(--radius) - 2px);
  border-top-right-radius: calc(var(--radius) - 2px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  box-sizing: border-box;
}

.comp-card-img {
  max-width: 95%;
  max-height: 95%;
  width: auto;
  height: auto;
  object-fit: contain;
  object-position: center;
  display: block;
  margin: 0 auto;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.7));
  transition: transform 0.3s ease;
}

.comp-card-img-challenge {
  width: 85%;
  height: 130%;
  max-width: none;
  max-height: none;
  object-fit: contain;
  object-position: center 88%;
}

.comp-card:hover .comp-card-img {
  transform: scale(1.05);
}

/* Large Rocky MaxBet Personality Callout Sticker (90px-120px Desktop) */
.competition-sticker-lg {
  position: absolute;
  bottom: -28px;
  right: -14px;
  width: clamp(90px, 9vw, 120px);
  height: auto;
  max-height: 120px;
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.8));
  z-index: 25;
  transition: transform 0.25s ease;
}

.comp-card:hover .competition-sticker-lg {
  transform: scale(1.08) rotate(-4deg);
}

/* Medium Competition Prize Stickers (44px-64px) */
.competition-sticker {
  position: absolute;
  top: -14px;
  right: -12px;
  width: clamp(44px, 4.5vw, 64px);
  height: clamp(44px, 4.5vw, 64px);
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.75));
  z-index: 25;
}

.comp-img-placeholder {
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at 50% 50%, #242b38 0%, #12161f 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px dashed var(--border-gold);
}

.comp-placeholder-icon {
  font-size: 2.2rem;
}

.comp-placeholder-text {
  font-family: var(--font-display);
  font-size: 1.2rem;
  color: var(--gold-bright);
}

.comp-card-body {
  padding: 22px 20px;
  flex: 1 1 auto;
  position: relative;
}

.comp-title {
  font-size: 1.35rem;
  color: var(--gold-bright);
  margin-bottom: 8px;
}

.comp-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--text-cream-muted);
  line-height: 1.45;
}

/* ===== 4. How to Play — Miniature Dino Keno Demo ===== */
/* One faithful 80-tile board (10x8) autoplays the real gameplay loop:
   choose -> draw (20 stones, 3 bones, Golden Egg) -> in-game winner popup, then repeats.
   Tile aspect (969:803), bone height (~1.4x tile), tile-sized stone overlays, and
   ~60%-tile-height numerals mirror the live DinoMainScene keno board. JS toggles
   classes on a timeline; CSS does all the motion. */
.htp-demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.55fr); /* steps (left) + board (right) */
  gap: 34px;
  align-items: center;
  max-width: 960px;
  margin: 0 auto;
}

/* ----- Board stage ----- */
.dk-stage { position: relative; }

.dk-board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 3px;
  width: 100%;
  max-width: 470px;
  margin: 0 auto;
  padding: 12px;
  border-radius: 14px;
  /* dark stone/green Dino board surface */
  background:
    radial-gradient(130% 120% at 50% 0%, rgba(60, 96, 54, 0.5), rgba(0, 0, 0, 0) 62%),
    linear-gradient(160deg, #24331f 0%, #1a2417 55%, #131a11 100%);
  border: 3px solid #435a38;
  box-shadow: inset 0 2px 12px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(120, 160, 110, 0.14), 0 10px 26px rgba(0, 0, 0, 0.45);
}

/* Tile — native stone art is 969x803, so match that landscape aspect exactly.
   `container-type: size` lets the number scale to the tile height (cqh), matching
   the in-game FONT_DESIGN = 60% of tile height regardless of board size. */
.dk-tile {
  position: relative;
  aspect-ratio: 969 / 803;
  container-type: size;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: url('assets/web_exports/dino_blank_board_stone.webp') center / 100% 100% no-repeat;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.35);
}
.dk-num {
  position: relative;
  z-index: 2;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.66rem;   /* fallback if container queries are unavailable */
  font-size: 56cqh;     /* ~60% of tile height, as in-game */
  color: #eaf6e3;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
}

/* Any DRAWN number becomes the dark hit stone — whether it matched a pick or not.
   Matched tiles get the same hit-stone base with the glowing match stone on top. */
.dk-tile.drawn,
.dk-tile.matched { background-image: url('assets/web_exports/dino_hit_board_stone.webp'); }
.dk-tile.drawn .dk-num { color: #ccd5cc; opacity: 0.8; }

/* Selection + match stones fill the tile (same 969:803 aspect) via ::after */
.dk-tile.picked::after,
.dk-tile.matched::after {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: 1;
  background: center / contain no-repeat;
  transform: scale(0);
  animation: dk-pop 0.34s cubic-bezier(0.2, 0.8, 0.3, 1.45) forwards;
}
.dk-tile.picked::after  { background-image: url('assets/web_exports/dino_selection_stone.webp'); }
.dk-tile.matched::after { background-image: url('assets/web_exports/dino_match_selection_stone.webp'); }
/* Matched tiles glow in and out continuously (asset ships a baked glow; this pulses it) */
.dk-tile.matched { animation: dk-glow 1.5s ease-in-out infinite; }

/* Bone + Golden Egg drops on the board. */
.dk-drop {
  position: absolute;
  left: 50%;
  z-index: 3;
  opacity: 0;
  pointer-events: none;
}
/* Bone: center-anchored (so it can rotate cleanly on match) and tile-sized */
.dk-bone-drop {
  top: 50%;
  height: 98%;
  width: auto;
  transform: translate(-50%, -50%) scale(0);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
}
/* Golden Egg: the reserved final draw. egg.webp warmed toward the in-game #FFC83C
   gold tint, ~tile-sized, covering the number; bottom-anchored so it sits on the tile. */
.dk-egg-drop {
  bottom: 5%;
  height: 104%;
  width: auto;
  transform-origin: bottom center;
  transform: translateX(-50%) scale(0);
  filter: saturate(1.35) brightness(1.06) sepia(0.18) hue-rotate(-6deg)
          drop-shadow(0 0 7px rgba(255, 200, 60, 0.85)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}
/* The Golden Egg tile drops the green match glow so the egg's own gold glow reads clean */
.dk-tile.matched.has-egg { animation: none; }
/* Bone drops in first, then rests. When its tile is hit in the draw it HATCHES →
   slow continuous rotation (mirrors the in-game bone hatch spin, ~3.2s/rev). */
.dk-tile.has-bone .dk-bone-drop { animation: dk-bone-in 0.42s cubic-bezier(0.2, 0.8, 0.3, 1.5) forwards; }
.dk-tile.bone-hit .dk-bone-drop { opacity: 1; animation: dk-bone-spin 3.2s linear infinite; }
/* Egg flies down, then a gentle glow pulse holds (mirrors dropFinalEgg's landed pulse) */
.dk-tile.has-egg .dk-egg-drop { animation: dk-egg-in 0.5s cubic-bezier(0.2, 0.8, 0.3, 1.5) forwards, dk-egg-pulse 1.4s ease-in-out 0.5s infinite; }

/* ----- Step legend (highlights in sync with the board phase) ----- */
.dk-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.dk-step {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--bg-charcoal-card);
  border: 2px solid var(--border-charcoal-stone);
  opacity: 0.62;
  transition: opacity 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.dk-step.is-active {
  opacity: 1;
  border-color: var(--gold);
  transform: translateX(4px);
  box-shadow: 0 0 0 2px var(--gold-glow), 0 6px 18px rgba(0, 0, 0, 0.4);
}
.dk-step-badge {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--text-dark-charcoal);
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
}
.dk-step .step-title { font-size: 1.12rem; color: var(--gold-bright); margin: 0 0 3px; }
.dk-step .step-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.96rem;
  color: var(--text-cream-muted);
  line-height: 1.35;
  margin: 0;
}

/* ----- Winner popup: the in-game frame + result, scaled onto the board -----
   All content is sized as a fraction of the frame height (--fh), mirroring the
   ratios in dino_win_popup.js: amount ~11.5% H (high), egg/bone multipliers ~18% H
   (center, with the multiplier text overlaid on the symbols), YOUR BET ~6% H (low). */
.dk-winner {
  --fh: 320px;            /* winner-frame display height; drives every content size below */
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.htp-demo.is-win .dk-winner {
  visibility: visible;
  animation: dk-winner-in 0.42s cubic-bezier(0.2, 0.8, 0.3, 1.3) forwards;
}
.dk-winner-frame {
  height: var(--fh);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 22px rgba(0, 0, 0, 0.6));
}
/* Content box tracks the frame (922:1100). Each row is absolutely placed at the
   exact in-game y-position (dino_win_popup.js, relative to POPUP_H_DESIGN=538):
   amount at 33.6%, multipliers at 57.4%, YOUR BET at ~77% — centered on colCx
   (shifted slightly right so the peeking dino at bottom-left stays clear). */
.dk-winner-inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: calc(var(--fh) * 0.838);
  height: var(--fh);
  pointer-events: none;
  text-align: center;
}
/* Win amount + coin (high in the parchment, just under the WINNER banner) */
.dk-win-amount {
  position: absolute;
  top: 33.6%;
  left: 53%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--fh) * 0.02);
  white-space: nowrap;
}
.dk-win-coin { height: calc(var(--fh) * 0.095); width: auto; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5)); }
.dk-win-value {
  font-family: var(--font-display);
  font-size: calc(var(--fh) * 0.108);
  line-height: 1;
  white-space: nowrap;
  color: #fff3c4;
  text-shadow: 0 2px 0 #050302, 0 3px 4px rgba(0, 0, 0, 0.6);
}
/* Egg (10X) + bones (3x) multipliers — symbols at ~18% H, text overlaid on them */
.dk-win-mults {
  position: absolute;
  top: 57.4%;
  left: 53%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--fh) * 0.045);
}
.dk-mult {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  animation: dk-pulse-soft 1.2s ease-in-out infinite;
}
.dk-mult-egg { width: calc(var(--fh) * 0.17); height: calc(var(--fh) * 0.18); }
.dk-mult-matchstone { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.dk-mult-egg-img {
  position: relative;
  z-index: 1;
  height: calc(var(--fh) * 0.14);
  width: auto;
  filter: drop-shadow(0 0 4px rgba(255, 200, 60, 0.9));
}
.dk-mini-bone { height: calc(var(--fh) * 0.18); width: auto; }
.dk-mult-x {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  font-family: var(--font-display);
  font-size: calc(var(--fh) * 0.085);
  line-height: 1;
  color: #fff3c4;
  text-shadow: 0 0 3px #000, 0 2px 0 #050302, 0 2px 4px rgba(0, 0, 0, 0.85);
  pointer-events: none;
}
/* YOUR BET row (low in the parchment) */
.dk-win-bet {
  position: absolute;
  top: 77%;
  left: 53%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--fh) * 0.006);
}
.dk-bet-label {
  font-family: var(--font-display);
  font-size: calc(var(--fh) * 0.062);
  color: #fff3c4;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}
.dk-bet-amt {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--fh) * 0.014);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: calc(var(--fh) * 0.052);
  color: #fff3c4;
}
.dk-bet-coin { height: calc(var(--fh) * 0.06); width: auto; }

/* ----- Keyframes ----- */
@keyframes dk-pop {
  0%   { transform: scale(0); opacity: 0; }
  60%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
/* Bone flies in from above and settles centered on the tile */
@keyframes dk-bone-in {
  0%   { transform: translate(-50%, -140%) scale(0.6) rotate(-38deg); opacity: 0; }
  70%  { transform: translate(-50%, -50%) scale(1.06) rotate(6deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
}
/* Hatched bone: slow continuous rotation once its tile is hit in the draw */
@keyframes dk-bone-spin {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}
/* Golden Egg drops from the top onto the tile (bottom-anchored) */
@keyframes dk-egg-in {
  0%   { transform: translateX(-50%) translateY(-150%) scale(0.5); opacity: 0; }
  70%  { transform: translateX(-50%) translateY(0) scale(1.12); opacity: 1; }
  100% { transform: translateX(-50%) translateY(0) scale(1); opacity: 1; }
}
/* Landed golden egg: gentle brightness pulse (mirrors dropFinalEgg's alpha pulse) */
@keyframes dk-egg-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.72; }
}
@keyframes dk-glow {
  0%, 100% { filter: drop-shadow(0 0 2px rgba(150, 240, 90, 0.5)); }
  50%      { filter: drop-shadow(0 0 8px rgba(170, 255, 100, 0.95)); }
}
@keyframes dk-pulse-soft {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
@keyframes dk-winner-in {
  0%   { transform: scale(0.6); opacity: 0; }
  70%  { transform: scale(1.05); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Reduced motion: static, fully-resolved board + winner popup, no looping/animation */
@media (prefers-reduced-motion: reduce) {
  .dk-tile.picked::after,
  .dk-tile.matched::after,
  .dk-tile.matched,
  .dk-drop,
  .dk-mult,
  .htp-demo.is-win .dk-winner {
    animation: none !important;
  }
  .dk-tile.picked::after,
  .dk-tile.matched::after { transform: scale(1) !important; opacity: 1 !important; }
  .dk-tile.has-bone .dk-bone-drop { transform: translate(-50%, -50%) scale(1) !important; opacity: 1 !important; }
  .dk-tile.has-egg .dk-egg-drop { transform: translateX(-50%) scale(1) !important; opacity: 1 !important; }
  .dk-winner { opacity: 1 !important; visibility: visible !important; }
  .dk-step { transition: none !important; }
}

/* ===== 5. Rewards Section (3 Cards with Large Reward Stickers) ===== */
.rewards-section-wrap {
  display: flex;
  align-items: center;
  gap: 24px;
}

.rewards-grid-3 {
  flex: 1 1 720px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 22px;
}

.reward-card {
  overflow: visible;
  display: flex;
  flex-direction: column;
}

.reward-banner {
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 1;
  background-color: #0f131a;
  overflow: hidden;
  border-bottom: 2px solid var(--border-charcoal-stone);
  border-top-left-radius: calc(var(--radius) - 2px);
  border-top-right-radius: calc(var(--radius) - 2px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.reward-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-top-left-radius: calc(var(--radius) - 2px);
  border-top-right-radius: calc(var(--radius) - 2px);
  display: block;
  transition: transform 0.3s ease;
}

.reward-card:hover .reward-img {
  transform: scale(1.04);
}

.reward-icon-mode {
  width: 76px;
  height: 76px;
  object-fit: contain;
}

/* Layered Daily Wheelspin Visual Animation (In-Game Spec: 605/799 ratio, 5 turns, cubic ease-out) */
/* ── Daily Wheelspin — the two wheel layers are ONE composed visual group ──
   Previously each layer derived its own size from a percentage box (185% wide
   AND 185% tall) that was then squared off by `object-fit: contain`. That made
   the rendered diameter depend on THREE interacting systems — the banner's
   aspect-ratio, a percentage height resolving through a flex item, and contain
   — and it put the seating ratio inside `transform`, which the spin keyframes
   re-declare in full. Any one of those changing separates the layers.

   Now: both layers are the SAME square box, from ONE width-based size token,
   sharing one center and one transform-origin. The face's seating ratio lives
   in structural padding, so `transform` carries ONLY position + rotation and
   the animation cannot resize or de-center anything. */
.reward-banner.wheel-banner {
  overflow: hidden;
  background: radial-gradient(circle at 50% 100%, #1e2636 0%, #0d1117 100%);

  /* Single size basis for BOTH layers — % of the banner WIDTH only.
     92.5% reproduces the previous rendered diameter exactly. */
  --wheel-size: 92.5%;

  /* Face:frame seating ratio. AUTHORITATIVE — do not retune by eye. Taken from
     the game's own wheel layout (stone_age_keno/src/shared/daily_login_wheel_popup.js):
       faceDiameter: 605  /  frameDiameter: 799  = 0.757
     Verified against the exported art: the face's opaque disc is 600.3px at that
     scale and the ring's inner hole is 603.9px, i.e. it seats with ~3.7px of
     clearance, exactly as in-game. */
  --wheel-face-ratio: 0.757;

  /* Derived, never hand-entered, so the two can never drift apart. */
  --wheel-face-inset: calc(var(--wheel-size) * (1 - var(--wheel-face-ratio)) / 2);
}

.wheel-card-visual {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

/* SHARED GEOMETRY — identical square box, identical center, identical origin.
   `aspect-ratio` (not a percentage height) makes the box square from the width
   alone, so it no longer depends on the banner's aspect-ratio or on a
   percentage height resolving through the flex item. Both layers are pinned to
   the banner's bottom-centre, so only the wheel's top half shows. */
.wheel-frame,
.wheel-face {
  position: absolute;
  top: 100%;
  left: 50%;
  width: var(--wheel-size);
  height: auto;
  aspect-ratio: 1 / 1;
  max-width: none;
  max-height: none;
  object-fit: contain;
  transform: translate(-50%, -50%);
  transform-origin: 50% 50%;
  pointer-events: none;
}

/* Static ring + 12 o'clock pointer. Does NOT rotate — matches the game, where
   the frame owns the ticker and only the face spins beneath it. */
.wheel-frame {
  z-index: 2;
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.75));
}

/* Rotating face. The seating ratio is applied as PADDING inside the shared box
   rather than a transform scale: the border box (and therefore the centre and
   the rotation origin) stays identical to the frame's, and the spin keyframes
   below cannot touch the size. */
.wheel-face {
  z-index: 1;
  padding: var(--wheel-face-inset);
  animation: wheelSpinAutoplay 11.352s infinite;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
}

/* Keyframes carry position + rotation ONLY. `translate(-50%, -50%)` is repeated
   verbatim from the base rule (an animated `transform` replaces it wholesale),
   and no scale appears here, so the layers cannot separate mid-spin. */
@keyframes wheelSpinAutoplay {
  0% {
    transform: translate(-50%, -50%) rotate(0deg);
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
  }
  90.3% {
    transform: translate(-50%, -50%) rotate(-1800deg);
  }
  100% {
    transform: translate(-50%, -50%) rotate(-1800deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .wheel-face {
    animation: none;
  }
}

/* Reduced motion: the whole conversation is shown at once, static — no
   staggered arrival, no transition, no win-banner pulse. Matches how the Dino
   How-to-Play demo, the wheel and the Game Worlds mechanics already behave. */
@media (prefers-reduced-motion: reduce) {
  .cp-msg {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .cp-banner.cp-msg { transform: none; }
}

/* Large Reward Callout Stickers (70px-100px Desktop) */
.reward-sticker {
  position: absolute;
  top: -20px;
  right: -16px;
  width: clamp(70px, 7.5vw, 96px);
  height: clamp(70px, 7.5vw, 96px);
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.8));
  z-index: 25;
  transition: transform 0.25s ease;
}

.reward-card:hover .reward-sticker {
  transform: scale(1.08) rotate(5deg);
}

.reward-body {
  padding: 20px 16px;
  flex: 1 1 auto;
  position: relative;
}

.reward-title {
  font-size: 1.3rem;
  color: var(--gold-bright);
  margin-bottom: 6px;
}

.reward-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--text-cream-muted);
  line-height: 1.45;
}

.mascot-dino-wrap {
  flex: 0 0 190px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mascot-dino-img {
  max-height: 290px;
  width: auto;
  object-fit: contain;
  transform: scaleX(-1); /* Flips Dino horizontally to face inward toward content */
  filter: drop-shadow(0 10px 24px rgba(0, 0, 0, 0.7));
}

/* ===== 6. Community / Fair Play (Custom Chat Sticker Showcase Wall 72px-96px) ===== */
.emoji-showcase-bar {
  background: var(--bg-charcoal-panel);
  border: 2px solid var(--border-gold);
  border-radius: var(--radius);
  padding: 28px 24px;
  margin-bottom: 36px;
  text-align: center;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5), 0 0 16px var(--gold-glow);
}

.emoji-showcase-title {
  font-size: clamp(1.2rem, 1.8vw, 1.5rem);
  margin-bottom: 18px;
}

.emoji-showcase-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 3vw, 36px);
  flex-wrap: wrap;
}

.emoji-showcase-img {
  width: clamp(72px, 7vw, 96px);
  height: clamp(72px, 7vw, 96px);
  object-fit: contain;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.75));
  transition: transform 0.25s ease;
  pointer-events: none;
}

.emoji-showcase-img:hover {
  transform: scale(1.12) translateY(-4px);
}

/* ===== Chat / Social-Proof Component =====
   Replaces the old "Real-Time Live Chat" feature box. Panel chrome is built
   from the existing token set rather than a new art export. Contains NO live
   indicator, NO online count and NO timestamps — see the note in index.html. */
/* Left column is now a stack of three boxes, sized to sit against the full
   height of the chat stone — the stone is tall, and a short heading + paragraph
   left the section badly bottom-weighted. */
.chat-proof {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 34px;
  align-items: stretch;
  margin-bottom: 0;
}

.chat-proof-copy {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 18px;
  min-width: 0;
}

.chat-proof-copy .feature-box { margin: 0; }

/* The lead box carries the section's argument, so its heading runs larger. */
.feature-box-lead h3 {
  font-size: clamp(1.35rem, 2vw, 1.75rem);
  line-height: 1.2;
  margin-bottom: 10px;
}

/* Screen-reader equivalent for the aria-hidden feed. Not aria-live — nothing
   here is a real update. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ══ Panel + rows taken from the GAME ══
   CavegirlMainScene.js:337,345-347,368-370  stone 474.21 x 741.11 displayed
   CavegirlMainScene.js:995-999              content _chW 340.40 _chH 465.40,
                                             left offset 53.2
   chat_panel.js:437-438,466,553,558,578-581 row + bubble metrics
   chat_perfect_match.js:41-43,104-121,266,278  banner block

   PANEL IS 10% SHORTER than the previous pass: 741.11 * 0.9 = 667.0, so the
   aspect goes 0.6399 -> 0.7110. Width and the % content rect are unchanged.

   SIZING UNIT: container query units on .cp-inner. The previous pass used a
   custom property holding `min(100%, 470px)` — inside `font-size: calc(...)`
   that 100% resolves against the PARENT FONT-SIZE, not the width, which made
   every label ~0.5px. That is why the copy vanished. cqw is width-relative by
   definition and matches the container-query pattern already used by .dk-tile. */
.chat-proof-panel {
  container-type: inline-size;
  position: relative;
  width: min(100%, 470px);
  aspect-ratio: 474.21 / 667.0;
  margin: 0 auto;
  background: url('assets/web_exports/cavegirl_chat_stone.webp') center / 100% 100% no-repeat;
  filter: drop-shadow(0 16px 34px rgba(0, 0, 0, 0.6));
}

/* CHAT label — from the game, not invented.
   CavegirlMainScene.js:468,476 + gold_label.js:29-43
     addGoldLabel(..., 'CHAT', SIDE_TEXT_H, { bannerTitle: true, ox: 0, oy: 0 })
     SIDE_TEXT_H = 44*2/3 = 29.33 is the CAP height; gold_label converts it with
     CAP_RATIO 0.72 -> fontPx 40.74 = 8.59% of stone width.
     Face is Barlow Condensed BOLD — Luckiest Guy is an opt-in (opts.font) that
     this call does NOT pass; the previous pass used it by mistake.
     ox:0 / oy:0 = LEFT + TOP anchored at x 38.7% / y 9.75% of the stone, i.e.
     sitting on the wooden plank, not centred in the panel. */
.cp-head {
  position: absolute;
  left: 38.7%;
  top: 9.75%;
  transform: translateY(-50%);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 8.59cqw;
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: #FBDC8A;
  text-shadow: 0 2px 0 rgba(48, 22, 6, 0.95), 0 3px 6px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

/* The real chat container rect — and the cqw reference for everything inside. */
.cp-inner {
  container-type: inline-size;
  position: absolute;
  /* Game rect was left 11.2% / width 71.8% / top 20.8% / height 60.2%
     (CavegirlMainScene.js:995-999). Tuned for the site:
       - width -8% relative (71.8 -> 66.06), split evenly either side so the
         container's horizontal CENTRE does not drift
       - bottom edge up 3% of stone height (81.0 -> 78.0); top edge held
     Everything inside is sized in cqw and the track is bottom-anchored, so the
     messages rescale and reflow off these two values alone. */
  left: 14.07%;
  width: 66.06%;
  top: 20.8%;                 /* held — cleared off the wooden plank */
  height: 57.2%;
  overflow: hidden;           /* THE MASK — clipped message-list rect */
}

/* The scrolling row container. Flows top-to-bottom; JS translates it up so the
   newest message sits on the bottom edge, older ones ride off the top. */
.cp-track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.175cqw;              /* game row gap 4 */
  transform: translateY(0);
  transition: transform 0.42s cubic-bezier(0.2, 0.8, 0.3, 1);
  will-change: transform;
}

/* ── Win banner ──
   Native aspect preserved. Width capped to 72% — the same maxBubbleW the game
   uses for message bubbles — so it reads as the widest message in the feed
   rather than swallowing the panel. */
.cp-banner {
  flex: 0 0 auto;
  /* chat_perfect_match.js:52-54
       left = ctx.x + 6*S ; stoneW = ctx.width - 12*S ; stoneCx = left + stoneW/2
     -> inset 6px each side = 96.5% of the container, CENTRED (not left-aligned). */
  width: 96.5%;
  align-self: center;
  aspect-ratio: 768 / 503;
  background: url('assets/web_exports/perfectmatch_chat_banner.webp') center / 100% 100% no-repeat;
  /* Positioning context for the content group. Flex centring was used here
     before and lost: `.cp-msg` is declared LATER in this file (order 53685 vs
     51086) and its `align-items: flex-start` + `flex-direction: column` won the
     cascade, so the group ended up left-aligned and riding high inside the
     aspect-ratio box. Absolute centring cannot be overridden by row/column
     rules and is exact by construction. */
  position: relative;
  /* chat_perfect_match.js:310  groupTop = b.cy - groupH/2, where b.cy is the
     banner's GEOMETRIC centre — the group is centred with no offset. A previous
     pass added padding-bottom to lift it off the decorative rail; that was the
     vertical misalignment. Removed. */
}

/* chat_perfect_match.js:310 — groupTop = b.cy - groupH/2, b.cy being the
   banner's GEOMETRIC centre. translate(-50%,-50%) off the 50%/50% anchor is
   precisely that, on both axes, regardless of the parent's flex direction. */
.cp-banner-in {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 90%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.cp-banner-prof { display: inline-flex; align-items: center; gap: 1.2cqw; margin-bottom: 2.35cqw; }  /* game profGap 8 */
.cp-banner-prof .cp-av { width: 9.05cqw; }

.cp-banner-name {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 4.7cqw;
  line-height: 1.1;
  color: #e8d6b0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85);
}

.cp-banner-row {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 5.35cqw;           /* game 5.951%, eased so both rows clear the rail */
  line-height: 1.2;
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
  white-space: nowrap;
}

.cp-banner-amt { display: inline-flex; align-items: center; gap: 1.3cqw; margin-top: 0.8cqw; }

.cp-amt-num {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 8.4cqw;            /* game 9.406%, eased with the rows */
  line-height: 1;
  color: #FCE076;
  text-shadow:
    -1px 0 rgba(0,0,0,.8), 1px 0 rgba(0,0,0,.8), 0 -1px rgba(0,0,0,.8), 0 1px rgba(0,0,0,.8),
    0 2px 3px rgba(0, 0, 0, 0.75);
}

.cp-coin { width: 6.6cqw; height: auto; object-fit: contain; }

/* ── Feed ── */
.cp-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 1.175cqw;                /* game row gap 4 */
  overflow: hidden;
  /* A row riding off the top was being sliced mid-avatar. Fade the top instead
     so the clip reads as a scrolling feed, not a crop bug. */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 100%);
}

/* Row = header line, then the bubble beneath it (chat_panel.js:512-558). */
.cp-msg {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.175cqw;                /* game header -> bubble gap 4 */
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.cp-msg.is-in { opacity: 1; transform: translateY(0); }

/* Specificity guard: `.cp-msg` above would otherwise impose column layout and
   flex-start on the banner, which is not a header+bubble row. */
.cp-msg.cp-banner { display: block; align-items: initial; gap: 0; }

.cp-banner.cp-msg { flex-direction: row; transform: translateY(0) scale(0.97); }
.cp-banner.cp-msg.is-in { transform: translateY(0) scale(1); }

.cp-hdr { display: flex; align-items: center; gap: 1.763cqw; }   /* game avGap 6 */

.cp-av {
  flex: 0 0 auto;
  position: relative;
  width: 10.5cqw;               /* game AV = 9.048%; +16% for web legibility */
  aspect-ratio: 157 / 154;
  background: url('assets/web_exports/avatar_stone.webp') center / contain no-repeat;
  display: block;
}

.cp-av-img {
  position: absolute;
  left: 50%;
  bottom: 11%;
  width: 83.3%;                 /* AVATAR_STONE_RATIO 1/1.2 */
  height: auto;
  transform: translateX(-50%);
  object-fit: contain;
}

/* In-game the name is scaled to fill the avatar height (AV/1.2 = 8.75cqw here),
   but the message is reduced from the game's 9.755cqw to fit a fixed panel, and
   at 8.75 the name ends up LARGER than its own message — inverting the game,
   where message (33.2) > name (25.7). Name is therefore set to 5.6cqw, holding
   the game's message:name ratio (6.9/5.6 = 1.23 vs the game's 1.29). */
.cp-name {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 5.6cqw;
  line-height: 1;
  color: #e8d6b0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* iMessage bubble. padX/padY/radius are the game's exact values; max-width is
   the game's maxBubbleW (container * 0.72). Shrink-wraps its text. */
.cp-bubble {
  max-width: 72%;
  width: fit-content;
  padding: 2.056cqw 3.231cqw;
  border-radius: 4.113cqw;
  background: #3b3b3d;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 6.9cqw;            /* game 9.755% x chat text scale */
  line-height: 1.2;
  color: #ffffff;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.4);
}

/* isSelf: avatar, name and bubble all right, bubble blue. */
/* Consecutive messages from the same sender drop the header (game: showHeader
   false -> "tight gap between consecutive same-sender bubbles", y += 2*S). */
.cp-cont { margin-top: -0.6cqw; }

/* Emoji-only message: the game renders these bubbleless and large
   (chat_panel.js:557-559 isBanner -> padX 0, no bubble graphic). */
/* Emoji-only message. Sized from the game, not guessed:
     chat_rich_text.js:90,120-124
       emH = round(emojiFontSize * 1.15)          emojiFontSize = the message font
       h   = emH * CUSTOM_EMOJI_DISPLAY_SCALE(4)  <- normalized 2026-07-25 (owner);
                                                     supersedes the per-emoji
                                                     registry scale of 2 / 3
       w   = h * aspect, clamped to maxWidth (container - 16 = 95.3%)
     Design container 340.4: msg 33.21 -> emH 38 -> h 152 = 44.65% of container
     width. HEIGHT-driven with width auto, as the game does it, so each emoji
     keeps its own aspect ratio. */
.cp-sticker .cp-emo {
  height: 44.65cqw;
  width: auto;
  max-width: 95.3%;
  display: block;
  object-fit: contain;
}
.cp-sticker.cp-self { align-items: flex-end; }

.cp-self { align-items: flex-end; }
.cp-self .cp-hdr { flex-direction: row-reverse; }
.cp-self .cp-bubble { background: #0a84ff; }

.social-community-wrap {
  display: flex;
  align-items: center;
  gap: 30px;
}

.features-split {
  flex: 1 1 720px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 22px;
}

.feature-box {
  padding: 28px 22px;
  position: relative;
  overflow: visible;
}

.feature-icon {
  font-size: 2rem;
  margin-bottom: 12px;
}

.feature-box h3 {
  font-size: 1.35rem;
  color: var(--gold-bright);
  margin-bottom: 8px;
}

.feature-box p {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--text-cream-muted);
  line-height: 1.45;
}

/* Fair Play Support & Safeguards Sticker (56px-76px) */
.fair-play-help-sticker {
  position: absolute;
  top: -16px;
  right: -14px;
  width: clamp(56px, 5.5vw, 76px);
  height: clamp(56px, 5.5vw, 76px);
  object-fit: contain;
  pointer-events: none;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.75));
  z-index: 20;
}

/* ===== Final CTA Band =====
   Closing conversion section, NOT a second hero. Compact centred CTA framed by
   two grounded characters. Bottom fades to the footer ground so the two read as
   one closing block instead of a section pasted above the footer. */








/* Prominent but not oversized — smaller than the hero button. */


/* ===== Final CTA Band =====
   Closing conversion section, NOT a second hero. Compact centred CTA framed by
   two GROUNDED characters. Bottom fades to the footer ground so the band and
   footer read as one closing block. */
.final-cta {
  width: 100%;
  padding: 40px 20px 34px;
  background: linear-gradient(180deg, #1b2131 0%, #141926 62%, #0e121a 100%);
  border-top: 2px solid var(--border-gold);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
}

.final-cta-inner {
  max-width: 920px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 26px;
  align-items: end;
}

.final-cta-figure { display: flex; align-items: flex-end; }

.final-cta-mascot {
  height: auto;
  display: block;
  filter: drop-shadow(0 12px 22px rgba(0, 0, 0, 0.66));
}

/* Balanced on visual MASS, not figure height. Rocksie's spear is horizontal so
   her silhouette is wide and low; Rocky is upright and narrow. He stands ~1.3x
   her height, which is how a standing caveman reads beside a crouched pose. */
.cta-rocksie { width: 200px; transform: scaleX(-1); }
.cta-rocky   { width: 120px; }

.final-cta-copy { min-width: 0; text-align: center; padding-bottom: 6px; }

.final-cta-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 2.8vw, 2.4rem);
  line-height: 1.14;
  letter-spacing: 0.02em;
  color: var(--gold-bright);
  text-shadow: 0 3px 0 #3a1a05, 0 5px 11px rgba(0, 0, 0, 0.7);
  margin-bottom: 9px;
}

.final-cta-text {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.06rem;
  line-height: 1.42;
  color: var(--text-cream-muted);
  max-width: 44ch;
  margin: 0 auto 16px;
}

.final-cta-btn {
  width: clamp(212px, 22vw, 246px);
  height: clamp(70px, 7.4vw, 82px);
  font-size: clamp(0.88rem, 1.05vw, 1rem);
}

.final-cta-trust {
  margin: 13px auto 0;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.84rem;
  letter-spacing: 0.025em;
  line-height: 1.4;
  color: #93a1b6;
  max-width: 52ch;
}

/* ── Final CTA responsive ladder ──────────────────────────────────────────
   Each step is its own composition, not a scaled-down desktop.
     1280  characters ease in, copy column widens
     1024  characters step down again (tablet / narrow desktop)
      860  VERTICAL STACK: Rocksie only, above the copy; Rocky hidden so the
           section does not become a tall poster on a phone
      430  button goes near-full-width, type tightens
      360  smallest safe sizes; nothing may exceed the viewport            */
@media (max-width: 1280px) {
  .final-cta-inner { gap: 22px; }
  .cta-rocksie { width: 178px; }
  .cta-rocky   { width: 107px; }
}

@media (max-width: 1024px) {
  .final-cta { padding: 34px 18px 30px; }
  .final-cta-inner { gap: 16px; }
  .cta-rocksie { width: 150px; }
  .cta-rocky   { width: 90px; }
  .final-cta-text { font-size: 1rem; }
}

@media (max-width: 860px) {
  /* Vertical stack: art, then headline + copy, then button, then trust line. */
  .final-cta { padding: 28px 16px 26px; }
  .final-cta-inner {
    grid-template-columns: 1fr;
    gap: 12px;
    justify-items: center;
    align-items: center;
  }
  .final-cta-figure-left  { order: 1; }
  /* justify-items:center sizes grid items to MAX-CONTENT, so without an explicit
     width the copy box grows to the headline's unwrapped width and overflows the
     section (body{overflow-x:hidden} then silently cut it). Constrain to the track. */
  .final-cta-copy         { order: 2; padding-bottom: 0; width: 100%; max-width: 100%; }
  .final-cta-figure-right { display: none; }   /* one mascot only on phones */
  .cta-rocksie { width: 148px; }
  .final-cta-title { margin-bottom: 7px; }
  .final-cta-text { margin-bottom: 14px; max-width: 40ch; }
}

@media (max-width: 430px) {
  .final-cta-btn { width: 100%; max-width: 320px; height: 74px; font-size: 0.9rem; }
  .cta-rocksie { width: 132px; }
  .final-cta-text { font-size: 0.96rem; }
  .final-cta-trust { font-size: 0.79rem; }
}

@media (max-width: 360px) {
  .final-cta { padding: 24px 12px 22px; }
  .final-cta-title { font-size: 1.5rem; }   /* headroom on the narrowest phones */
  .cta-rocksie { width: 116px; }
  .final-cta-btn { height: 68px; font-size: 0.84rem; }
}



/* ===== 7. Footer ===== */
.site-footer {
  position: relative;
  width: 100%;
  background-image: url('assets/web_exports/footer.webp');
  background-position: center bottom;
  background-repeat: no-repeat;
  background-size: cover;
  background-color: #0e121a;
  border-top: 2px solid var(--border-charcoal-stone);
  padding: 90px 20px 60px 20px;
  box-sizing: border-box;
}

.footer-container {
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 36px;
  position: relative;
  z-index: 5;
}

.footer-brand-col {
  grid-column: span 1;
}

.footer-logo {
  height: 108px;
  width: auto;
  margin-bottom: 20px;
  display: block;
}

.footer-tagline {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--text-cream-muted);
  margin-bottom: 14px;
}

/* ===== Footer compliance strip ===== */
.footer-legal-bar {
  max-width: var(--max-w);
  margin: 30px auto 0;
  padding-top: 18px;
  border-top: 1px solid rgba(58, 70, 89, 0.75);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 28px;
  position: relative;
  z-index: 5;
}

/* Muted, but deliberately NOT dim-to-the-point-of-hiding: #9aa8bc on the footer
   ground is ~7.4:1, comfortably above AA. Compliance copy that can't be read
   doesn't count as disclosed. */
.footer-disclosure {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.92rem;
  line-height: 1.45;
  letter-spacing: 0.015em;
  color: #9aa8bc;
  margin: 0;
  max-width: 64ch;
}

.footer-copy {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  color: #708098;
  margin: 0;
  white-space: nowrap;
}

@media (max-width: 860px) {
  .footer-legal-bar { margin-top: 24px; gap: 10px; }
  .footer-disclosure { font-size: 0.86rem; }
  .footer-copy { white-space: normal; }
}

.footer-col h4 {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--gold);
  margin-bottom: 14px;
}

.footer-col ul {
  list-style: none;
}

.footer-col li {
  margin-bottom: 8px;
}

.footer-col a {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--text-cream-muted);
  transition: color 0.15s ease;
}

.footer-col a:hover {
  color: var(--text-cream);
}

/* Legal/support items that are NOT yet wired. These carry no href, so they are
   already unclickable and unfocusable; this dims them and kills the pointer
   affordance so nobody reads them as working links. Remove this class as each
   real page ships (Phase 3). */
.footer-col a.footer-link-pending {
  color: #5d6b80;
  cursor: default;
  font-style: italic;
}

.footer-col a.footer-link-pending::after {
  content: " (soon)";
  font-style: normal;
  font-size: 0.82em;
  letter-spacing: 0.04em;
  color: #4d5a6d;
}

.footer-col a.footer-link-pending:hover {
  color: #5d6b80;
}

/* ===== Responsive Breakpoints & Mobile Sticker Scaling ===== */

/* Header step 1 — logo + nav + CTA still share one row, nav compresses first. */
@media (max-width: 1180px) {
  .site-nav { gap: 5px; }
  .nav-btn { width: 112px; font-size: 0.8rem; }
  .header-cta { height: 44px; padding: 0 14px; font-size: 0.8rem; }
}

/* Header step 2 — below this width logo + nav + CTA can no longer share a row
   without the stone toggle art compressing under `white-space: nowrap` (this
   was the pre-existing ~860-980px squeeze). Rather than shrink further, the nav
   wraps onto its own second row and the CTA keeps its place beside the logo,
   so the primary conversion action stays visible at every width. */
@media (max-width: 1020px) {
  .site-header { height: auto; padding: 8px 0; }
  .header-container { flex-wrap: wrap; row-gap: 8px; }
  .brand-link { order: 1; }
  .header-cta { order: 2; }
  .site-nav {
    order: 3;
    flex-basis: 100%;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
  }
  .nav-btn { width: 118px; }
}

@media (max-width: 1280px) {
}

@media (max-width: 1040px) {

  .hub-showcase-box { grid-template-columns: 1fr; }
  .mascot-rocky-wrap { top: -65px; left: 10px; }
  .mascot-rocky-img { height: 110px; }
  .mascot-dino-wrap { flex: 0 0 150px; }
  .mascot-dino-img { max-height: 220px; }
  /* How to Play demo tightens up on narrower desktops/tablets */
  .htp-demo { gap: 22px; }
  .dk-step { padding: 12px 14px; }
  .dk-winner { --fh: 290px; }
}

@media (max-width: 860px) {
  .site-header { height: auto; padding: 10px 0; }
  /* NOTE: this was `flex-direction: column`, which stacked logo / nav / CTA into
     three full-width rows. It now keeps the wrapped layout from the 1020px step
     (logo + CTA on row 1, nav on row 2) so the play CTA is never pushed down. */
  .header-container { flex-wrap: wrap; row-gap: 8px; }
  .brand-logo { height: 46px; }
  .header-cta { height: 40px; padding: 0 12px; font-size: 0.74rem; letter-spacing: 0.03em; }
  .site-nav { flex-wrap: wrap; justify-content: center; }
  .nav-btn { width: 110px; height: 36px; font-size: 0.78rem; }
  .hero-section { width: 100%; height: auto; padding: 0; }
  .hero-video-stage { aspect-ratio: 2 / 1; min-height: 220px; }
  .hero-title { font-size: 0.8rem; margin-bottom: 6px; }
  .section-title { font-size: 1.8rem; }
  .mascot-rocky-wrap { display: none; }
  .mascot-dino-wrap { display: none; }

  .rewards-section-wrap { flex-direction: column; }
  .social-community-wrap { flex-direction: column; }

  /* Chat proof stacks: the three boxes above, panel below */
  .chat-proof { grid-template-columns: 1fr; gap: 20px; }
  .chat-proof-copy { justify-content: flex-start; }
  /* Stone keeps its native aspect; only the max width changes. */
  .chat-proof-panel { width: min(100%, 340px); }
  /* Band stacks and centres; the CTA no longer has to fit inside the 2:1 stage. */
  .hero-action-inner { flex-direction: column; text-align: center; gap: 12px; }
  .hero-action-band { padding: 14px 16px 16px; }
  .btn-game-play { width: 186px; height: 62px; font-size: 0.74rem; letter-spacing: 0.03em; }
  .hero-trust { margin-top: 6px; font-size: 0.66rem; }

  /* How to Play demo stacks: steps on top, board below */
  .htp-demo { grid-template-columns: 1fr; max-width: 470px; margin: 0 auto; gap: 22px; }
  .dk-board { max-width: 100%; }
  .dk-steps { flex-direction: column; }
  .dk-winner { --fh: 240px; }

  /* Game Worlds mechanic animations sit a touch smaller on mobile */
  .mechanic-anim { --mech-size: 42px; }
  
  /* Mobile Sticker Scaling — Retained on Mobile */
  .mechanic-badge { width: 48px; height: 48px; bottom: -12px; right: 10px; }
  .currency-sticker { width: 42px; height: 42px; }
  .coin-sticker { top: -14px; left: -10px; }
  .bucks-sticker { bottom: -14px; left: 20%; }
  .ruby-sticker { top: -14px; right: -10px; }
  .competition-sticker-lg { width: 70px; max-height: 70px; bottom: -18px; right: -8px; }
  .competition-sticker { width: 38px; height: 38px; top: -10px; right: -8px; }
  .reward-sticker { width: 54px; height: 54px; top: -14px; right: -10px; }
  .emoji-showcase-img { width: 54px; height: 54px; }
  .emoji-showcase-row { gap: 12px; }
  .fair-play-help-sticker { width: 44px; height: 44px; top: -12px; right: -8px; }
}

/* Mobile-only value strip + compliance note — shown at <=560px below. */
.mobile-value-strip, .mobile-value-note { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE PORTRAIT (<=560px) — conversion-first pass
   Measured before: 12.5 screens at 360px, with Game Worlds (2.36), Community
   (2.13), Competitions (1.76) and Rewards (1.70) making up 64% of the page.
   These rules compress art, tighten padding and shorten type so each section
   reads as a compact card rather than a desktop panel squeezed narrow.
   All sizes are fixed per breakpoint — no vw-based font scaling.
   Tablets (561-860px) keep the existing treatment.                          */
@media (max-width: 560px) {

  /* Nav was wrapping to 2 rows (430/390) and 3 rows (360), spending 60-100px of
     the first viewport on section links a phone user rarely taps. One
     horizontally-scrollable row keeps every link but returns that space to the
     hero and CTA. */
  .site-nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    justify-content: flex-start;
    gap: 7px;
    width: 100%;
    padding-bottom: 2px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .site-nav::-webkit-scrollbar { display: none; }
  .nav-btn { flex: 0 0 auto; width: auto; min-width: 96px; padding: 0 12px; height: 34px; font-size: 0.74rem; }

  /* value strip — visible only here */
  .mobile-value-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    list-style: none;
    margin: 0;
    padding: 14px 16px 4px;
    background: var(--bg-charcoal-dark);
  }
  .mobile-value-strip li {
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.86rem;
    letter-spacing: 0.03em;
    color: var(--text-cream);
    text-align: center;
    padding: 9px 6px;
    background: #161b24;
    border: 1px solid var(--border-charcoal-stone);
    border-top-color: #4f5f78;
    border-radius: 8px;
  }

  .mobile-value-note {
    display: block;
    margin: 0;
    /* the stone divider that follows uses margin:-12px + z-index:30, so it was
       riding over this line — clear it with padding and sit above it. */
    position: relative;
    z-index: 31;
    padding: 9px 16px 20px;
    background: var(--bg-charcoal-dark);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.76rem;
    letter-spacing: 0.02em;
    text-align: center;
    color: #8d9bb0;
  }

  /* Footer links were a ~29px pitch — below the 44px touch-target guidance.
     Padding turns each into a comfortable tap area without changing type size. */
  .footer-col li { margin-bottom: 2px; }
  .footer-col a { display: block; padding: 10px 0; font-size: 0.96rem; }
  .footer-col h4 { margin-bottom: 6px; }

  /* global section rhythm: 76px -> 32px top/bottom */
  .section { padding: 32px 16px; }
  .section-head { margin-bottom: 18px; }
  .section-title { font-size: 1.42rem; }
  .section-subtitle { font-size: 0.94rem; line-height: 1.4; }

  /* ── Game Worlds: compact scannable cards ── */
  .modules-grid-3 { gap: 13px; }
  .module-banner { height: 104px; }
  .module-body { padding: 13px 14px 15px; }
  .module-mascot { margin-bottom: 7px; }
  .module-mascot img { width: 26px; height: 26px; }
  .module-mascot span { font-size: 0.76rem; }
  .module-title { font-size: 1.12rem; margin-bottom: 4px; }
  .module-desc { font-size: 0.9rem; line-height: 1.38; margin-bottom: 0; }
  .module-tags { display: none; }       /* duplicated by the copy above */
  .mechanic-anim { display: none; }     /* decorative motion, not needed here */
  .module-logo-badge { max-height: 40px; bottom: 7px; }

  /* ── Lobby ── */
  .hub-showcase-box { padding: 18px 15px; gap: 15px; }
  .hub-title { font-size: 1.4rem; }
  .hub-desc { font-size: 0.94rem; line-height: 1.4; }
  .hub-features-chips { gap: 7px; }
  .hub-chip { font-size: 0.79rem; padding: 5px 10px; }

  /* ── Competitions ── */
  .competitions-grid-3 { gap: 13px; }
  .comp-card-banner { aspect-ratio: 5 / 2; }
  .comp-card-body { padding: 13px 14px 15px; }
  .comp-title { font-size: 1.1rem; margin-bottom: 5px; }
  .comp-text { font-size: 0.9rem; line-height: 1.38; }

  /* ── How to Play ── */
  .htp-demo { gap: 14px; }
  .dk-steps { gap: 9px; }
  .dk-step { padding: 10px 12px; gap: 11px; }
  .dk-step-badge { flex: 0 0 27px; width: 27px; height: 27px; font-size: 0.9rem; }
  .dk-step .step-title { font-size: 0.98rem; }
  .dk-step .step-text { font-size: 0.84rem; line-height: 1.3; }
  .dk-winner { --fh: 196px; }

  /* ── Rewards ── */
  .rewards-grid-3 { gap: 13px; }
  .reward-banner { aspect-ratio: 5 / 2; }
  .reward-body { padding: 12px 14px 14px; }
  .reward-title { font-size: 1.08rem; margin-bottom: 4px; }
  .reward-text { font-size: 0.89rem; line-height: 1.36; }

  /* ── Community: chat proof must not dominate ── */
  .chat-proof { gap: 14px; }
  .chat-proof-copy { gap: 12px; }
  .feature-box { padding: 15px 14px; }
  .feature-box h3 { font-size: 1.08rem; margin-bottom: 5px; }
  .feature-box p { font-size: 0.89rem; line-height: 1.38; }
  .feature-box-lead h3 { font-size: 1.16rem; }
  .feature-icon { font-size: 1.5rem; margin-bottom: 7px; }
  .chat-proof-panel { width: min(100%, 286px); }

  /* ── Final CTA: short and button-forward ── */
  .final-cta { padding: 24px 16px 26px; }
  .final-cta-inner { gap: 10px; }
  .cta-rocksie { width: 104px; }
  .final-cta-title { font-size: 1.46rem; margin-bottom: 6px; }
  .final-cta-text { font-size: 0.94rem; margin-bottom: 13px; }
  .final-cta-btn { width: 100%; max-width: 300px; height: 70px; font-size: 0.88rem; }
  .final-cta-trust { font-size: 0.78rem; margin-top: 11px; }

  /* ── Footer ── */
  .site-footer { padding: 46px 16px 34px; }
  .footer-container { gap: 22px; }
  .footer-logo { height: 76px; margin-bottom: 14px; }
  .footer-col h4 { font-size: 0.98rem; margin-bottom: 10px; }
  .footer-col a { font-size: 0.94rem; }
  .footer-disclosure { font-size: 0.82rem; }
  .footer-legal-bar { margin-top: 20px; padding-top: 14px; }
}
