/* ============================================================
   Robux Clicker — stylesheet
   Theme: dark navy background (matching the launcher), Roblox red
   accents, green for affordable prices. All three columns share
   the same dark background — no split-fill layouts.
   ============================================================ */

/* ---------- 1. RESET ---------- */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ---------- 2. BASE PAGE ---------- */
html, body {
  /* Lock page to viewport — no document scroll. Panels scroll internally. */
  height: 100%;
  overflow: hidden;
}

body {
  /* Same dark navy as the launcher index.html */
  background: #0a0a14;
  /* Subtle radial vignette so the center feels like a stage */
  background-image:
    radial-gradient(circle at 50% 40%, #15152e 0%, #0a0a14 70%);
  color: #ddd;
  font-family: 'Segoe UI', 'Roboto', 'Courier New', sans-serif;
  /* Prevent text selection so rapid clicking doesn't highlight text */
  user-select: none;
  -webkit-user-select: none;
  /* Mobile: prevent the iOS double-tap-zoom delay */
  touch-action: manipulation;
}

/* ---------- 3. NEWS TICKER (top bar) ---------- */
#news-bar {
  height: 32px;
  background: #1a1a30;
  border-bottom: 2px solid #2a2a4e;
  overflow: hidden;
  display: flex;
  align-items: center;
  /* Hide overflow so text scrolls cleanly */
  white-space: nowrap;
}

#news-text {
  /* The ticker is animated in JS by translating this element */
  display: inline-block;
  padding-left: 100%;
  font-size: 0.85rem;
  letter-spacing: 1px;
  color: #c0c0d8;
  font-style: italic;
}

/* ---------- 4. MAIN 3-COLUMN LAYOUT ---------- */
#game {
  /* Fill viewport minus the news bar (32px) and brand footer (28px) */
  height: calc(100vh - 32px - 28px);
  display: grid;
  /* Left panel | Center stage | Right panel */
  grid-template-columns: 280px 1fr 360px;
  gap: 0;
}

/* Shared style for the left/right panels */
.panel {
  background: #0e0e1f;
  border-color: #1a1a30;
  border-style: solid;
  border-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

#stats-panel {
  /* Single divider on the right edge — separates from center stage */
  border-right-width: 1px;
  padding: 16px;
  overflow-y: auto;
}

#shop-panel {
  /* Single divider on the left edge */
  border-left-width: 1px;
}

/* Section titles inside panels */
.panel-title {
  font-size: 0.75rem;
  letter-spacing: 3px;
  color: #8888aa;
  text-transform: uppercase;
  margin-top: 16px;
  margin-bottom: 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid #1f1f3a;
}
.panel-title:first-child {
  margin-top: 0;
}

/* ---------- 5. STATS PANEL CONTENT ---------- */
#stats-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.8rem;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  padding: 4px 0;
  color: #aaa;
}
.stat-row .stat-label {
  color: #8888aa;
}
.stat-row .stat-value {
  color: #fff;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---------- 5a. PROGRESS HINTS PANEL (rc-13) ----------
   Up to 3 small rows showing the next reachable milestones (building
   tier unlocks, click upgrades, prestige threshold, etc.). Sits in the
   stats column between the stats list and the achievements grid. The
   bar uses a CSS transition so changes animate smoothly even though the
   container's innerHTML is rewritten every frame (the .progress-hint
   element is recreated each tick, so the transition only takes effect
   on stable hints whose width inline-style changes between frames). */
#progress-hints {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}
.progress-hint {
  background: #15152e;
  border: 1px solid #1f1f3a;
  border-radius: 4px;
  padding: 8px 10px;
}
.progress-hint-title {
  font-size: 0.78rem;
  color: #fff;
  margin-bottom: 4px;
}
.progress-hint-bar {
  height: 4px;
  background: #0a0a14;
  border-radius: 2px;
  overflow: hidden;
}
.progress-hint-fill {
  height: 100%;
  background: linear-gradient(90deg, #1ea050, #4ee07a);
  transition: width 0.4s ease-out;
}
.progress-hint-status {
  font-size: 0.7rem;
  color: #8888aa;
  margin-top: 4px;
}
.progress-hint-empty {
  color: #4a4a7a;
  font-size: 0.78rem;
  font-style: italic;
}

/* Achievements grid: small badges */
#achievements-content {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  margin-bottom: 16px;
}

.achievement-badge {
  aspect-ratio: 1;
  background: #15152e;
  border: 1px solid #2a2a4e;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: help;
  transition: transform 0.1s, border-color 0.2s;
}
.achievement-badge:hover {
  transform: scale(1.08);
  border-color: #4a4a7a;
}
.achievement-badge.unlocked {
  background: #2a1a05;
  border-color: #d4a017;
  /* Gold glow for unlocked achievements */
  box-shadow: 0 0 8px rgba(212, 160, 23, 0.3);
}
.achievement-badge.locked svg {
  opacity: 0.18;
}

/* ---------- 5b. PRESTIGE SECTION ----------
   Sits between the Achievements heading and grid. It is hidden by
   default — main.js removes .prestige-hidden once StateManager
   .canPrestige() is true. The button uses the Beanstalk green
   gradient (#1e7a3a -> #4ee07a) so it stands apart from the
   settings buttons and from the Roblox-green click button.
   The yield value is right-aligned in gold (#ffd040) so the
   reward is the most prominent thing on the button. */
.prestige-hidden {
  /* When the player is below the prestige threshold the entire
     section collapses to zero height. */
  display: none;
}

#prestige-section {
  /* Tiny vertical breathing room around the button. */
  margin-bottom: 16px;
}

.prestige-btn {
  /* Wider and taller than .settings-btn to feel like a milestone. */
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 14px;
  border-radius: 8px;
  /* Beanstalk gradient — green left to brighter green right. */
  background: linear-gradient(90deg, #1e7a3a 0%, #4ee07a 100%);
  border: 1px solid #5dff90;
  color: #fff;
  font-family: inherit;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  /* Slight glow + drop shadow so the button feels lifted. */
  box-shadow:
    0 4px 12px rgba(78, 224, 122, 0.25),
    0 0 0 0 rgba(78, 224, 122, 0);
  transition: transform 0.15s ease-out, box-shadow 0.2s, filter 0.15s;
}

.prestige-btn:hover {
  /* Lift and brighten on hover. */
  transform: translateY(-1px);
  filter: brightness(1.08);
  box-shadow:
    0 6px 18px rgba(78, 224, 122, 0.45),
    0 0 0 1px rgba(255, 208, 64, 0.35);
}

.prestige-btn:active {
  /* Press feedback — settle back down. */
  transform: translateY(0);
  filter: brightness(0.95);
}

.prestige-btn-label {
  /* Left-aligned label. Slightly shadowed so it reads on the gradient. */
  font-size: 0.78rem;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  flex: 1;
  text-align: left;
}

.prestige-btn-yield {
  /* Right-aligned reward — biggest text on the button, gold colour. */
  font-size: 1.0rem;
  font-weight: 800;
  color: #ffd040;
  font-variant-numeric: tabular-nums;
  /* Dark text shadow so the gold pops on the green gradient. */
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
  white-space: nowrap;
  letter-spacing: 0.5px;
}

/* Settings buttons at the bottom of the stats panel */
#settings-buttons {
  margin-top: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding-top: 16px;
  border-top: 1px solid #1f1f3a;
}

.settings-btn {
  background: #1a1a30;
  border: 1px solid #2a2a4e;
  color: #ccc;
  font-family: inherit;
  font-size: 0.7rem;
  letter-spacing: 1px;
  padding: 8px 4px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  text-transform: uppercase;
}
.settings-btn:hover {
  background: #22224a;
  border-color: #4a4a7a;
  color: #fff;
}
.settings-btn-danger:hover {
  border-color: #e2231a;
  color: #ff6650;
}

/* ---------- 6. CENTER CLICK AREA ---------- */
#click-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 16px;
}

/* ---------- 6a. CLICK-AREA TITLE BLOCK ----------
   Big "RobuxClicker.com" wordmark over a small disclaimer-flavoured
   subtitle, at the very top of the click-area stack. Decorative
   only — JS does not read or update this block.

   Visual choices:
   - Title uses the same brand-green (#4ee07a) as the footer brand
     name, so the wordmark inside the click view and the footer
     logo speak with one voice.
   - Subtitle uses the muted-lavender + italic style already used
     for the footer tagline so it sits quietly under the headline.
   - No coloured side stripes on the block (project Rule 5):
     typography alone carries the hierarchy.
   - Soft text-shadow + green glow lifts the wordmark off the
     dark navy stage, matching the treatment on the big counter
     number below it. */
#click-title {
  /* Center-align both lines under the click stack. */
  text-align: center;
  line-height: 1.15;
  /* DESKTOP: pin the title to the top of #click-area as a banner,
     instead of letting it sit in the centered click stack. This
     lifts the wordmark visibly above the big counter and the
     Robux button without pushing them down. The parent
     #click-area already has position: relative, so the absolute
     positioning resolves against the click column.
     The mobile (<= 980px) override below restores in-flow layout
     so the title scrolls naturally with the rest of the click view. */
  position: absolute;
  top: 28px;
  left: 0;
  right: 0;
  /* Bottom margin only matters in the in-flow (mobile) layout —
     the absolute desktop positioning ignores it. */
  margin-bottom: 14px;
}

.click-title-name {
  /* Big wordmark — sized to dominate the click view's top band.
     Mobile/small-phone font-sizes are scaled down in the media
     queries further below. */
  font-size: 3.5rem;
  font-weight: 800;
  /* Brand green — the project's accent colour throughout. */
  color: #4ee07a;
  letter-spacing: 0.5px;
  /* Drop shadow for legibility on dark navy + soft outer glow
     so the wordmark feels lit. Matches .big-robux-num shadow. */
  text-shadow:
    0 2px 0 #000,
    0 0 22px rgba(78, 224, 122, 0.30);
  /* Override the user-agent <h1> margins so the subtitle sits
     tight below. (The * { margin:0 } reset already neutralises
     this, but we re-state it explicitly for safety against
     future resets.) */
  margin: 0;
  /* Keep the wordmark on a single line at all viewports — it is
     16 characters which fits comfortably even at the smallest
     320px-class phone with the mobile font-size below. */
  white-space: nowrap;
}

.click-title-subtitle {
  /* Tiny gap between title and subtitle. */
  margin: 6px 0 0;
  font-size: 1rem;
  font-style: italic;
  letter-spacing: 0.5px;
  /* Muted lavender — same colour as the footer tagline so the
     visual hierarchy stays consistent across the page. */
  color: #8888aa;
}

#big-counter {
  text-align: center;
  margin-bottom: 8px;
}

.big-robux-num {
  font-size: 3.5rem;
  font-weight: 800;
  /* Roblox-y bright green for the main number */
  color: #4ee07a;
  text-shadow: 0 2px 0 #000, 0 0 24px rgba(78, 224, 122, 0.25);
  font-variant-numeric: tabular-nums;
  letter-spacing: -1px;
  /* The number pops briefly when clicked */
  transition: transform 0.08s ease-out;
}
.big-robux-num.bump {
  transform: scale(1.04);
}

#big-rps {
  font-size: 0.9rem;
  color: #8888aa;
  letter-spacing: 1px;
  margin-top: 4px;
}

/* The button wrapper holds the SVG + floating number layer */
#robux-wrap {
  position: relative;
  width: 320px;
  height: 320px;
  /* Generous click target on mobile */
  margin: 24px 0;
}

/* The big clickable Robux itself */
#robux-btn {
  /* Reset native button look */
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Slight drop shadow so it sits on top of the stage */
  filter: drop-shadow(0 8px 24px rgba(78, 224, 122, 0.18));
  transition: transform 0.08s ease-out, filter 0.2s;
}

#robux-btn:hover {
  filter: drop-shadow(0 8px 32px rgba(78, 224, 122, 0.32));
}

/* Press animation: shrink slightly */
#robux-btn:active,
#robux-btn.pressed {
  transform: scale(0.94);
}

#robux-svg-host {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Floating-number layer sits on top of the button without intercepting clicks */
#fx-layer,
#golden-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
}

/* +N text that floats up and fades out */
.float-num {
  position: absolute;
  font-size: 1.4rem;
  font-weight: 800;
  color: #4ee07a;
  text-shadow: 0 2px 0 #000;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  /* Animation handled by inline transform updated each frame */
  will-change: transform, opacity;
}

/* Floating number for critical clicks (rc-08): bigger, gold, glow.
   Inherits position/animation behavior from .float-num — only the
   look-and-feel is overridden. ~70% larger than the base 1.4rem. */
.float-num.crit {
  font-size: 2.4rem;
  color: #ffd040;
  text-shadow: 0 0 12px rgba(255, 208, 64, 0.7), 0 2px 0 #000;
}

/* One spark in the crit-burst ring (rc-08). The element is a small
   round glowing dot; particles.js translates it outward each frame
   via inline transform, and CSS handles the visual style. */
.crit-spark {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff8a0 0%, #ffd040 50%, #ff8800 100%);
  box-shadow: 0 0 8px #ffd040;
  pointer-events: none;
  will-change: transform, opacity;
}

/* ---------- Click juice (rc-09): screen shake on big-payout clicks ----------
   Each strength level translates the #game container by a few pixels in
   alternating directions. We animate #game (not body) so position:fixed
   chrome — the news bar, brand footer, mobile tab bar — stays still
   while the play area shakes. JS adds shake-N for ~280ms, then removes.
*/
@keyframes shake-1 {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(-1px, 1px); }
  50%      { transform: translate(1px, -1px); }
  75%      { transform: translate(-1px, -1px); }
}
@keyframes shake-2 {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-2px, 2px); }
  40%      { transform: translate(2px, -1px); }
  60%      { transform: translate(-1px, 2px); }
  80%      { transform: translate(2px, 1px); }
}
@keyframes shake-3 {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-3px, 2px); }
  40%      { transform: translate(3px, -2px); }
  60%      { transform: translate(-2px, 3px); }
  80%      { transform: translate(3px, 2px); }
}
@keyframes shake-4 {
  0%, 100% { transform: translate(0, 0); }
  15%      { transform: translate(-4px, 3px); }
  30%      { transform: translate(4px, -3px); }
  45%      { transform: translate(-3px, 4px); }
  60%      { transform: translate(4px, 2px); }
  80%      { transform: translate(-2px, -3px); }
}
@keyframes shake-5 {
  0%, 100% { transform: translate(0, 0); }
  15%      { transform: translate(-5px, 4px); }
  30%      { transform: translate(5px, -4px); }
  45%      { transform: translate(-4px, 5px); }
  60%      { transform: translate(5px, 3px); }
  80%      { transform: translate(-3px, -4px); }
}

/* Apply each keyframe to #game when the matching class is set by JS. */
#game.shake-1 { animation: shake-1 280ms ease-out; }
#game.shake-2 { animation: shake-2 280ms ease-out; }
#game.shake-3 { animation: shake-3 280ms ease-out; }
#game.shake-4 { animation: shake-4 280ms ease-out; }
#game.shake-5 { animation: shake-5 280ms ease-out; }

/* Honour the user's reduced-motion preference: suppress the animation
   entirely so motion-sensitive players still get the floating-number
   feedback without the screen jitter. */
@media (prefers-reduced-motion: reduce) {
  #game.shake-1,
  #game.shake-2,
  #game.shake-3,
  #game.shake-4,
  #game.shake-5 {
    animation: none;
  }
}

/* Click sparkle ring */
.click-ring {
  position: absolute;
  border: 3px solid rgba(78, 224, 122, 0.8);
  border-radius: 50%;
  pointer-events: none;
  will-change: transform, opacity;
}

/* Golden Robux drifting across the screen — clickable for power-ups */
.golden-robux {
  position: absolute;
  width: 80px;
  height: 80px;
  cursor: pointer;
  pointer-events: auto;
  filter: drop-shadow(0 0 16px rgba(255, 200, 40, 0.7));
  /* Pulse animation */
  animation: goldenPulse 1.2s ease-in-out infinite;
}
.golden-robux:hover {
  filter: drop-shadow(0 0 24px rgba(255, 220, 80, 1));
}
@keyframes goldenPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

/* Lifetime stats line below the click area */
#lifetime-stats {
  display: flex;
  gap: 32px;
  font-size: 0.8rem;
  color: #8888aa;
  letter-spacing: 1px;
  margin-top: 16px;
}

/* ---------- 7. SHOP PANEL (right side) ---------- */
#shop-tabs {
  display: flex;
  border-bottom: 1px solid #1f1f3a;
}

.shop-tab {
  flex: 1;
  background: #0e0e1f;
  border: none;
  color: #8888aa;
  font-family: inherit;
  font-size: 0.75rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 12px 8px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  border-bottom: 2px solid transparent;
}
.shop-tab:hover {
  color: #ccc;
  background: #15152e;
}
.shop-tab.active {
  color: #fff;
  /* Active tab uses a bottom underline (NOT a left stripe) */
  border-bottom-color: #4ee07a;
}

#buy-amount {
  display: flex;
  gap: 4px;
  padding: 8px 12px;
  border-bottom: 1px solid #1f1f3a;
}

/* Hidden on the upgrades and beanstalk tabs — both are single-purchase
   so the X1/X10/X100/MAX selector has nothing to do there. The sticky
   shop header just gets shorter when this is hidden. */
#buy-amount.hidden-on-upgrades {
  display: none;
}

/* ---------- 7b. UPGRADES FILTER ROW (rc-12) ---------- */
/* The filter row is part of the shop sticky header but only matters
   while the upgrades tab is active. We keep it out of the layout
   (display:none) on every other tab and re-enable it when ui-shop.js
   tags the panel with .tab-upgrades. The flex layout puts the filter
   pill group on the left and the sort toggle on the right. */
#upgrade-filter-row {
  display: none;
  /* rc-16: stack the filter pills row above the sort toggle so the
     four pills + the "Cheapest first" / "Priciest first" label always
     fit cleanly in the 360px (desktop) and 390px (mobile) shop
     columns. The previous side-by-side layout wrapped awkwardly with
     the sort hovering between two pill rows. */
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 8px 12px;
  border-bottom: 1px solid #1f1f3a;
}
#shop-panel.tab-upgrades #upgrade-filter-row {
  display: flex;
}

/* The four filter pills sit in their own group on the left so the
   sort toggle can be flush right via justify-content:space-between. */
.upgrade-filter-group {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

/* Compact, monospace-feel pill — small and dim by default; the
   active one gets a green border + green text to match the buy-btn
   active state and the .shop-tab.active underline. No left/right
   accent stripe (per project design rules).
   Padding/letter-spacing trimmed in rc-16 so all four pills + the
   sort toggle share a single row inside the 360px shop column on
   desktop and the 390px shop on mobile (was wrapping into 2 rows). */
.upgrade-filter-btn {
  background: #15152e;
  border: 1px solid #2a2a4e;
  color: #aaa;
  font-family: inherit;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  padding: 4px 8px;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  text-transform: uppercase;
}
.upgrade-filter-btn:hover {
  background: #1f1f3a;
  color: #fff;
}
.upgrade-filter-btn.active {
  background: #224428;
  border-color: #4ee07a;
  color: #4ee07a;
}

/* Sort toggle is link-style — subtle, smaller, no border. The
   intent is "secondary control" so it doesn't fight the filter pills
   for attention. */
.upgrade-sort-btn {
  background: transparent;
  border: none;
  color: #8888aa;
  font-family: inherit;
  font-size: 0.65rem;
  letter-spacing: 0.5px;
  padding: 2px 4px;
  cursor: pointer;
  text-transform: uppercase;
  transition: color 0.15s;
  white-space: nowrap;
  /* Sit on its own line below the pill row, flush right so the eye
     finishes scanning the pills and naturally lands on the sort. */
  align-self: flex-end;
}
.upgrade-sort-btn:hover {
  color: #4ee07a;
  text-decoration: underline;
}

/* Beanstalk tab button — hidden by default; only shown after the
   player has earned the right to prestige (or already has tokens). */
.shop-tab.beanstalk-tab {
  display: none;
}
body.beanstalk-unlocked .shop-tab.beanstalk-tab {
  display: block;
}

.buy-btn {
  flex: 1;
  background: #15152e;
  border: 1px solid #2a2a4e;
  color: #aaa;
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 1px;
  padding: 6px 4px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  text-transform: uppercase;
}
.buy-btn:hover {
  background: #1f1f3a;
  color: #fff;
}
.buy-btn.active {
  background: #224428;
  border-color: #4ee07a;
  color: #4ee07a;
}

/* Tab content scroll containers */
.shop-content {
  flex: 1;
  overflow-y: auto;
  display: none;
  padding: 8px;
}
.shop-content.active {
  display: block;
}

/* Custom scrollbar for the shop and stats panels */
.shop-content::-webkit-scrollbar,
#stats-panel::-webkit-scrollbar {
  width: 8px;
}
.shop-content::-webkit-scrollbar-track,
#stats-panel::-webkit-scrollbar-track {
  background: #0a0a14;
}
.shop-content::-webkit-scrollbar-thumb,
#stats-panel::-webkit-scrollbar-thumb {
  background: #2a2a4e;
  border-radius: 4px;
}
.shop-content::-webkit-scrollbar-thumb:hover,
#stats-panel::-webkit-scrollbar-thumb:hover {
  background: #4a4a7a;
}

/* Building card: icon + name + cost. NO colored side stripe (Rule 5). */
.building-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #15152e;
  border: 1px solid #2a2a4e;
  border-radius: 6px;
  padding: 10px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
  position: relative;
}

.building-card:hover {
  background: #1f1f3a;
  border-color: #4a4a7a;
}

/* Affordable: green border tint via filter (still all-around, not a stripe) */
.building-card.affordable {
  border-color: #2a5a3a;
}
.building-card.affordable:hover {
  border-color: #4ee07a;
}

/* Locked: dim and not clickable */
.building-card.locked {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Click animation on purchase */
.building-card.bought {
  animation: cardFlash 0.4s ease-out;
}
@keyframes cardFlash {
  0% { background: #4ee07a; }
  100% { background: #15152e; }
}

.building-icon {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  background: #0a0a14;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.building-icon svg {
  width: 100%;
  height: 100%;
}

.building-info {
  flex: 1;
  min-width: 0;
}

.building-name {
  font-size: 0.85rem;
  font-weight: 600;
  color: #fff;
  margin-bottom: 2px;
}

.building-cost {
  font-size: 0.85rem;
  font-weight: 700;
  color: #ff8866;
  font-variant-numeric: tabular-nums;
}
.building-card.affordable .building-cost {
  color: #4ee07a;
}

.building-owned {
  font-size: 1.6rem;
  font-weight: 800;
  color: #4a4a7a;
  font-variant-numeric: tabular-nums;
  min-width: 36px;
  text-align: right;
}
.building-card.affordable .building-owned {
  color: #6f6fa0;
}

/* Tier dots row: one dot per per-building upgrade tier, filled green
   when the upgrade is owned. Lets the player see at a glance which
   buildings still have upgrades to buy.
   The empty/locked state must read clearly on the card background —
   we use the page bg colour (darker than the card) plus a thicker,
   brighter border so the dot is always visible. */
.building-tier-dots {
  display: flex;
  gap: 5px;
  margin-top: 5px;
}
.tier-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  /* Empty dot: darker than card bg + brighter border = visible. */
  background: #050510;
  border: 2px solid #4a4a7a;
  box-sizing: border-box;
  transition: background 0.2s, border-color 0.2s, box-shadow 0.2s;
  flex-shrink: 0;
}
.tier-dot.owned {
  background: #4ee07a;
  border-color: #5dff90;
  box-shadow: 0 0 6px rgba(78, 224, 122, 0.65);
}
.tier-dot.available {
  /* Pulsing bright-green ring draws attention to a tier the player
     can buy right now. The pulse is subtle so a row of available
     dots doesn't get noisy. */
  border-color: #4ee07a;
  background: #0d3a1c;
  animation: tierDotPulse 1.6s ease-in-out infinite;
}
@keyframes tierDotPulse {
  0%, 100% { box-shadow: 0 0 0 rgba(78, 224, 122, 0.4); }
  50%      { box-shadow: 0 0 8px rgba(78, 224, 122, 0.85); }
}

/* When the parent building card is dimmed (.locked), force the tier
   dots back to readable contrast so the player can still count them. */
.building-card.locked .tier-dot {
  border-color: #5a5a8a;
  background: #08081a;
}

/* Upgrade card: square tile with icon + corner badge.
   The card is *always* full opacity now (we only ever render
   already-unlocked upgrades). Affordability is communicated by the
   border colour, NOT by dimming the icon.

   IMPORTANT: `display: grid` lives on the `.active` rule below, NOT
   on the bare #upgrades-list rule. Otherwise the ID specificity
   (1,0,0) overrides the .shop-content `display: none` (0,1,0) and
   the grid renders even when the tab is not active — bug observed
   in earlier builds where buildings + upgrades rendered together.
   The grid-template/gap/align-content properties below are inert
   until display: grid kicks in. */
#upgrades-list {
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  align-content: start;
}
#upgrades-list.active {
  display: grid;
}

.upgrade-card {
  /* Card lays out as a column: square icon area on top, price strip
     at the bottom. We don't lock aspect-ratio on the card itself
     because the price strip adds fixed vertical space; aspect-ratio
     lives on .upgrade-card-icon below so the icon stays square. */
  background: #15152e;
  border: 1px solid #2a2a4e;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  transition: background 0.15s, border-color 0.15s, transform 0.1s, box-shadow 0.2s;
  /* Position context for the absolutely-positioned tier badge. */
  position: relative;
  overflow: hidden;
}

.upgrade-card:hover {
  background: #1f1f3a;
  border-color: #4a4a7a;
  transform: scale(1.05);
}

/* Affordable: green border + soft outer glow. Icon stays full-colour. */
.upgrade-card.affordable {
  border-color: #4ee07a;
  box-shadow: 0 0 8px rgba(78, 224, 122, 0.25);
}
.upgrade-card.affordable:hover {
  box-shadow: 0 0 14px rgba(78, 224, 122, 0.45);
}

/* The icon area: keeps a square 1:1 ratio so all icons look consistent. */
.upgrade-card-icon {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  flex: none;
}
.upgrade-card-icon svg {
  width: 100%;
  height: 100%;
}

/* Price strip at the bottom of each upgrade card. Colour-coded:
   green text when the player can afford it, warm orange when not.
   Solid dark band beneath the icon so the number reads cleanly. */
.upgrade-price {
  text-align: center;
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.3px;
  padding: 4px 2px 5px;
  background: #0a0a14;
  border-top: 1px solid #1f1f3a;
  /* Insufficient funds is the default state. */
  color: #ff8866;
}
/* Sufficient funds: bright Roblox-green and a hairline green divider. */
.upgrade-card.affordable .upgrade-price {
  color: #4ee07a;
  border-top-color: #2a5a3a;
}

/* Tier / kind corner badge — disambiguates upgrades that share an
   icon (like the five Roblox Avatar tiers). */
.upgrade-tier-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  background: #0a0a14;
  color: #aaa;
  font-size: 0.62rem;
  font-weight: 800;
  padding: 1px 4px;
  border-radius: 3px;
  border: 1px solid #2a2a4e;
  pointer-events: none;
  z-index: 2;
  letter-spacing: 0.5px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.upgrade-card.affordable .upgrade-tier-badge {
  color: #4ee07a;
  border-color: #4ee07a;
}
/* Click-upgrade badges use a yellow accent so they're easy to scan
   apart from building-tier upgrades. */
.upgrade-card.upgrade-click .upgrade-tier-badge {
  color: #ffd040;
  border-color: #4a3a1a;
}
.upgrade-card.upgrade-click.affordable .upgrade-tier-badge {
  border-color: #ffd040;
}
/* Synergy upgrades use a pink/magenta accent — they're rare. */
.upgrade-card.upgrade-synergy .upgrade-tier-badge {
  color: #ff88dd;
  border-color: #4a1a3a;
  font-size: 0.78rem;
  padding: 0 4px;
}
.upgrade-card.upgrade-synergy.affordable .upgrade-tier-badge {
  border-color: #ff88dd;
}

/* When the upgrades list is empty, show a hint */
.shop-empty {
  padding: 32px 16px;
  text-align: center;
  color: #4a4a7a;
  font-size: 0.8rem;
  font-style: italic;
}

/* ---------- 7b. BEANSTALK TAB (perma-upgrades) ---------- */

/* Beanstalk list: 2-column grid (cards have more text than the icon
   tiles in #upgrades-list, so a wider card reads better). Grid only
   activates when the tab is .active so it doesn't fight the
   .shop-content `display: none` rule above. */
#beanstalk-list {
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  align-content: start;
}
#beanstalk-list.active {
  display: grid;
}

/* Each perma-upgrade card: small gold-tinted icon on the left, text
   block in the middle, token cost on the right. Mirrors the
   horizontal layout of building cards. */
.beanstalk-card {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 8px;
  align-items: center;
  background: #15152e;
  border: 1px solid #2a2a4e;
  border-radius: 6px;
  padding: 8px;
  cursor: pointer;
  position: relative;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.beanstalk-card:hover {
  background: #1f1f3a;
  border-color: #4a4a7a;
}

/* Affordable: gold border + soft glow (gold = the token currency colour). */
.beanstalk-card.affordable {
  border-color: #ffd040;
  box-shadow: 0 0 6px rgba(255, 208, 64, 0.25);
}
.beanstalk-card.affordable:hover {
  box-shadow: 0 0 12px rgba(255, 208, 64, 0.45);
}

/* Owned: muted card with no hover glow. */
.beanstalk-card.owned {
  background: #0e0e1f;
  border-color: #2a4a3a;
  cursor: default;
  opacity: 0.85;
}
.beanstalk-card.owned:hover {
  background: #0e0e1f;
  border-color: #2a4a3a;
}

/* Locked-by-prestige: heavy dim, lock overlay handled by .beanstalk-lock. */
.beanstalk-card.locked-prestige {
  opacity: 0.45;
  cursor: not-allowed;
}
.beanstalk-card.locked-prestige:hover {
  background: #15152e;
  border-color: #2a2a4e;
}

/* Icon column: square gold-tinted upgrade arrow. */
.beanstalk-card-icon {
  width: 36px;
  height: 36px;
  background: #0a0a14;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Gold tint on the SVG by recolouring fill via CSS filter is not
     reliable across renderers — instead we override the polygon fill
     directly using a child-selector below. */
}
.beanstalk-card-icon svg {
  width: 80%;
  height: 80%;
}
.beanstalk-card-icon svg polygon {
  fill: #ffd040;
}

/* Text column: name on top, effect line, then flavor text. */
.beanstalk-card-info {
  min-width: 0;
}
.beanstalk-card-name {
  font-size: 0.82rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 1px;
}
.beanstalk-card-effect {
  font-size: 0.72rem;
  color: #ffd040;
  margin-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.beanstalk-card-flavor {
  font-size: 0.68rem;
  color: #8888aa;
  font-style: italic;
  /* Clamp to two lines so cards stay roughly the same height. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Cost column: token amount with a small token glyph. Gold colour
   means cost; affordable cards keep the same gold (already legible
   on the gold border), unaffordable cards reduce opacity. */
.beanstalk-card-cost {
  font-size: 0.85rem;
  font-weight: 800;
  color: #ffd040;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
  white-space: nowrap;
}
.beanstalk-card:not(.affordable):not(.owned):not(.locked-prestige) .beanstalk-card-cost {
  opacity: 0.55;
}

/* Owned badge replaces the cost. */
.beanstalk-card-owned-badge {
  font-size: 0.7rem;
  font-weight: 800;
  color: #4ee07a;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

/* Lock requirement text replaces the cost on locked cards. */
.beanstalk-card-lock {
  font-size: 0.66rem;
  color: #ff8866;
  text-align: right;
  max-width: 90px;
  line-height: 1.3;
}

/* ---------- 8. TOOLTIP ---------- */
#tooltip {
  position: fixed;
  background: #0a0a14;
  border: 1px solid #4a4a7a;
  border-radius: 6px;
  padding: 12px;
  max-width: 280px;
  font-size: 0.78rem;
  line-height: 1.5;
  color: #ddd;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
}
.tooltip-hidden {
  display: none;
}

.tooltip-title {
  font-size: 0.95rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 4px;
}

.tooltip-cost {
  color: #4ee07a;
  font-weight: 600;
  margin-top: 6px;
}
.tooltip-cost.expensive {
  color: #ff8866;
}

.tooltip-flavor {
  font-style: italic;
  color: #8888aa;
  margin-top: 8px;
  border-top: 1px solid #1f1f3a;
  padding-top: 6px;
}

.tooltip-each {
  color: #6f6fa0;
  font-size: 0.72rem;
  margin-top: 4px;
}

/* Tier label under the upgrade name in tooltips — small caps look. */
.tooltip-tier {
  font-size: 0.68rem;
  letter-spacing: 1.5px;
  color: #4ee07a;
  text-transform: uppercase;
  margin-top: -2px;
  margin-bottom: 6px;
}

/* The list of tier upgrades shown inside a building tooltip. */
.tooltip-upgrades-list {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid #1f1f3a;
  font-size: 0.72rem;
  color: #6f6fa0;
}
.tooltip-upgrade-row {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding: 1px 0;
  font-size: 0.72rem;
  line-height: 1.35;
}
.tooltip-upgrade-mark {
  display: inline-block;
  width: 12px;
  text-align: center;
  font-weight: 700;
}
.tooltip-upgrade-row.owned {
  color: #4ee07a;
}
.tooltip-upgrade-row.available {
  color: #ffe080;
}
.tooltip-upgrade-row.locked {
  color: #4a4a7a;
}

/* ---------- 9. MODAL DIALOG ---------- */
.modal-hidden {
  display: none !important;
}

#modal-host {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
}

#modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
}

#modal-box {
  position: relative;
  background: #15152e;
  border: 1px solid #4a4a7a;
  border-radius: 8px;
  padding: 24px;
  min-width: 320px;
  max-width: 480px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
}

#modal-title {
  font-size: 1.1rem;
  color: #fff;
  margin-bottom: 12px;
  letter-spacing: 1px;
}

#modal-body {
  font-size: 0.85rem;
  color: #ccc;
  line-height: 1.6;
  margin-bottom: 20px;
}

#modal-body textarea {
  width: 100%;
  min-height: 120px;
  background: #0a0a14;
  border: 1px solid #2a2a4e;
  border-radius: 4px;
  color: #ccc;
  padding: 8px;
  font-family: 'Courier New', monospace;
  font-size: 0.75rem;
  resize: vertical;
}

#modal-buttons {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.modal-btn {
  background: #1a1a30;
  border: 1px solid #2a2a4e;
  color: #ccc;
  font-family: inherit;
  font-size: 0.8rem;
  letter-spacing: 1px;
  padding: 10px 18px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  text-transform: uppercase;
}
.modal-btn:hover {
  background: #22224a;
  border-color: #4a4a7a;
  color: #fff;
}
.modal-btn-primary {
  background: #224428;
  border-color: #4ee07a;
  color: #4ee07a;
}
.modal-btn-primary:hover {
  background: #2a5a30;
  color: #fff;
}
.modal-btn-danger:hover {
  border-color: #e2231a;
  color: #ff6650;
}

/* ---------- 9b. LEGAL FOOTER ----------
   Always visible. Hosts the short fan-game disclosure plus the
   four legal-info buttons (Privacy, Terms, Cookies, Disclaimer).
   On desktop sits at the bottom of the page; on mobile it sticks
   above the bottom tab bar.

   Height responds to viewport: 28px on desktop (single row),
   ~50px on mobile (the disclosure wraps to a row of its own so
   it is never truncated). The mobile calc()s for #game height,
   the body bottom-padding, the #click-area min-height, and the
   #mobile-tab-bar bottom-offset are all updated to match.

   The selector stays #brand-footer (rather than #legal-footer)
   to avoid a churn-only HTML rename — see the matching comment
   in index.html.
*/
#brand-footer {
  /* min-height (not fixed height) so the footer can grow when
     flex-wrap pushes the .footer-actions block to a second row
     on narrow screens. Desktop content fits in one row at 28px. */
  min-height: 28px;
  background: #12122a;
  border-top: 1px solid #2a2a4e;
  display: flex;
  align-items: center;
  /* Disclosure left, buttons right on desktop. The mobile media
     query below switches this to "center" so the wrapped rows
     sit nicely in the middle on phone widths. */
  justify-content: space-between;
  /* flex-wrap lets the buttons drop to a new row when the row
     becomes too narrow to hold both the disclosure and the
     button group. Without wrap the buttons would overflow or
     compress the disclosure with ellipsis — neither acceptable
     since the disclosure must stay fully readable. */
  flex-wrap: wrap;
  /* No vertical padding on desktop so the footer keeps its
     historical 28px height — the #game calc(100vh - 32px - 28px)
     and other layout calcs depend on that exact value. The
     mobile media query adds 4px vertical padding for the 2-row
     wrapped layout (and updates the mobile calcs to 50px). */
  padding: 0 14px;
  /* Row-gap is the gap between wrapped rows on mobile (small);
     column-gap is the gap between siblings on desktop. */
  gap: 4px 14px;
  font-size: 0.7rem;
  letter-spacing: 0.5px;
  /* Sit firmly at the page bottom — combined with html { height: 100% }
     and #game height calc() this anchors the footer to the viewport. */
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 40;
}

/* The fan-game disclosure text. Muted lavender + italic to read
   as a quiet caption, not a primary control. white-space: nowrap
   guarantees the legally meaningful sentence never breaks mid-
   word; if it cannot fit on a row it wraps to the next row (via
   #brand-footer's flex-wrap rule) but stays a single line. */
.footer-disclaimer {
  color: #8888aa;
  font-style: italic;
  white-space: nowrap;
}

/* Wrapper around the four legal-info buttons. Keeps them together
   as one flex child of #brand-footer so they wrap as a group
   rather than individually. */
.footer-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.brand-disclaimer-btn {
  background: transparent;
  border: 1px solid #2a2a4e;
  color: #ccc;
  font-family: inherit;
  font-size: 0.68rem;
  letter-spacing: 1px;
  padding: 3px 10px;
  border-radius: 3px;
  cursor: pointer;
  text-transform: uppercase;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.brand-disclaimer-btn:hover {
  background: #1f1f3a;
  border-color: #4a4a7a;
  color: #fff;
}

/* ---------- 9c. BRAND LEGAL LINKS ----------
   Three small text-link buttons in the footer — Privacy, Terms,
   Cookies — that open informational modals. Styled as low-contrast
   text links (no border, transparent background) so the bordered
   Disclaimer button stays the visual anchor of the footer. Tied
   to JS in js/legal-modals.js. Remove that file + this CSS block
   + the three <button>s in index.html to remove the feature.
*/
.brand-legal-link {
  background: transparent;
  border: 0;
  color: #8888aa;
  font-family: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.5px;
  padding: 3px 4px;
  cursor: pointer;
  flex-shrink: 0;
  /* Hover transitions match .brand-disclaimer-btn timing so the
     four footer buttons feel like one cohesive control group. */
  transition: color 0.15s, text-decoration-color 0.15s;
}
.brand-legal-link:hover {
  color: #4ee07a;
  text-decoration: underline;
}

/* Disclaimer modal body styling — multiple paragraphs of small text.
   Also styles the Privacy / Terms / Cookies modal bodies, which
   wrap their content in the same .disclaimer-body class to share
   one stylesheet. The h4 / ul rules below are unused by the
   original Disclaimer modal (which uses only <p> tags) but make
   the longer legal modals readable. */
.disclaimer-body p {
  margin-bottom: 10px;
  line-height: 1.55;
}
.disclaimer-body p:last-child {
  margin-bottom: 0;
}
.disclaimer-body strong {
  color: #fff;
}
.disclaimer-body em {
  color: #4ee07a;
  font-style: normal;
  font-weight: 600;
}
/* Subheadings inside legal modals (Privacy / Terms / Cookies).
   Green to echo the brand accent + bold to step away from body
   copy. Tightened top margin on the first heading so the modal
   does not start with a big gap below the "Last updated" line. */
.disclaimer-body h4 {
  color: #4ee07a;
  font-size: 0.92rem;
  font-weight: 700;
  margin: 14px 0 6px 0;
  letter-spacing: 0.4px;
}
.disclaimer-body h4:first-child {
  margin-top: 4px;
}
/* Bullet lists for the policies. Modest left indent so the
   bullets do not crowd the modal's edge; green marker dots so
   the lists feel native to the dark-green theme without using
   a forbidden coloured side-stripe pattern. */
.disclaimer-body ul {
  margin: 0 0 10px 0;
  padding-left: 22px;
}
.disclaimer-body li {
  margin-bottom: 4px;
  line-height: 1.5;
}
.disclaimer-body li::marker {
  color: #4ee07a;
}

/* ---------- 10. MOBILE-ONLY ELEMENTS (default hidden on desktop) ---------- */

/* The bottom tab bar only appears on mobile widths. */
#mobile-tab-bar {
  display: none;
}

/* The in-shop balance pill only appears on mobile widths. */
#shop-balance {
  display: none;
}

/* ---------- 11. MOBILE LAYOUT ----------
   Below 980px the 3-column desktop layout doesn't fit comfortably,
   so we switch to a tabbed mobile pattern: news bar (fixed top),
   one full-screen view at a time (click / shop / stats), and a tab
   bar (fixed bottom) for switching. The body scrolls naturally —
   no nested overflow containers, which fixes the iOS scroll quirks.
*/
@media (max-width: 980px) {

  /* Body scrolls naturally; padding leaves room for the fixed bars.
     We deliberately do NOT set `overflow-x: hidden` here because in
     Chrome/Safari that creates a containing block which breaks
     `position: sticky` further down the tree. The news ticker
     already clips its own overflow inside #news-bar, so the body
     never overflows horizontally. */
  html, body {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
    overflow: visible;
  }
  body {
    padding-top: 32px;     /* news bar height */
    /* Reserve space for: tab bar (64px) + legal footer (50px on
       mobile — 2-row layout with disclosure on top, buttons below)
       + safe area. */
    padding-bottom: calc(64px + 50px + env(safe-area-inset-bottom, 0px));
  }

  /* News bar: fixed to viewport top. */
  #news-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
  }

  /* Game container becomes a vertical stack (no grid). */
  #game {
    display: block;
    height: auto;
    grid-template-columns: none;
    grid-template-rows: none;
  }

  /* All panels go full-width; remove inner max-heights and overflow. */
  #stats-panel,
  #shop-panel,
  #click-area {
    width: 100%;
    height: auto;
    min-height: 0;
    border: 0 !important;
    max-height: none !important;
    overflow: visible;
    padding: 16px;
  }

  /* Hide the inactive views so only the chosen tab renders. */
  body[data-mobile-view="click"] #stats-panel,
  body[data-mobile-view="click"] #shop-panel,
  body[data-mobile-view="shop"] #stats-panel,
  body[data-mobile-view="shop"] #click-area,
  body[data-mobile-view="stats"] #shop-panel,
  body[data-mobile-view="stats"] #click-area {
    display: none !important;
  }

  /* Click view fills the available viewport height and centers content.
     Subtract news bar (32) + tab bar (64) + legal footer (50 on
     mobile, 2-row) = 146. */
  body[data-mobile-view="click"] #click-area {
    min-height: calc(100vh - 146px);
    min-height: calc(100dvh - 146px);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding: 24px 16px;
  }

  /* Inner shop content panes: no inner scroll, full natural height. */
  .shop-content {
    overflow: visible;
    height: auto;
    flex: none;
    padding: 12px;
  }

  /* The settings buttons area sits at the bottom of the stats view
     (no margin-top: auto needed since body height is natural). */
  #settings-buttons {
    margin-top: 16px;
    grid-template-columns: repeat(4, 1fr);
  }

  /* Tooltip is awkward on touch devices — hide it entirely on mobile. */
  #tooltip {
    display: none !important;
  }

  /* Larger tap targets and clearer info on building cards. */
  .building-card {
    padding: 14px 12px;
    margin-bottom: 8px;
  }
  .building-icon {
    width: 56px;
    height: 56px;
  }
  .building-name {
    font-size: 1rem;
  }
  .building-cost {
    font-size: 0.95rem;
  }
  .building-owned {
    font-size: 1.8rem;
  }

  /* Mobile: bump the prestige button up to a comfortable thumb-tap
     size. Larger padding + bigger label/yield text. */
  .prestige-btn {
    padding: 16px 16px;
    border-radius: 10px;
  }
  .prestige-btn-label {
    font-size: 0.9rem;
  }
  .prestige-btn-yield {
    font-size: 1.15rem;
  }

  /* Achievement grid: 8 columns at tablet, 5 at phone. */
  #achievements-content {
    grid-template-columns: repeat(8, 1fr);
  }
  .achievement-badge {
    /* Slightly larger so they're easy to tap for tooltips on iOS hover. */
    min-height: 44px;
  }

  /* Upgrades grid: roomier on mobile. */
  #upgrades-list {
    grid-template-columns: repeat(5, 1fr);
    gap: 10px;
  }

  /* Beanstalk grid: stack to a single column on phones so the
     full description text reads clearly at 390px width. */
  #beanstalk-list {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .beanstalk-card {
    padding: 10px;
  }
  .beanstalk-card-name {
    font-size: 0.95rem;
  }
  .beanstalk-card-effect {
    font-size: 0.8rem;
  }
  .beanstalk-card-flavor {
    font-size: 0.74rem;
  }
  .beanstalk-card-cost {
    font-size: 1rem;
  }

  /* Click-area title scales down on mobile so the wordmark + the
     big Robux button + the counters all fit comfortably inside
     the click-view min-height (calc(100dvh - 146px)).
     Also restore in-flow positioning (the desktop rule pins the
     title absolutely to the top of #click-area; on mobile we want
     it in the centered flex stack with the rest). */
  #click-title {
    position: static;
    top: auto;
    left: auto;
    right: auto;
    margin-bottom: 10px;
  }
  .click-title-name {
    font-size: 1.7rem;
    letter-spacing: 0.3px;
  }
  .click-title-subtitle {
    font-size: 0.75rem;
  }

  /* Big Robux: comfortable size on phones. */
  #robux-wrap {
    width: 240px;
    height: 240px;
    margin: 8px 0;
  }
  .big-robux-num {
    font-size: 2.6rem;
  }
  #big-rps {
    font-size: 0.95rem;
  }
  #lifetime-stats {
    margin-top: 12px;
    flex-wrap: wrap;
    justify-content: center;
    gap: 16px;
    font-size: 0.85rem;
  }

  /* Mobile tab bar: visible, fixed to bottom. */
  #mobile-tab-bar {
    display: flex;
    position: fixed;
    /* Sit above the legal footer (50px on mobile — 2-row layout)
       plus iOS safe-area inset. */
    bottom: calc(50px + env(safe-area-inset-bottom, 0px));
    left: 0;
    right: 0;
    height: 64px;
    background: #0a0a14;
    border-top: 1px solid #2a2a4e;
    z-index: 50;
    /* Subtle shadow so it lifts visually off the page content. */
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.4);
  }

  /* Legal footer on mobile: pinned at the very bottom, below the
     tab bar (so it doesn't take up valuable thumb-zone real estate).
     The tab bar is the primary nav so it stays above.

     The footer becomes a 2-row layout: the disclosure on row 1
     (forced to full width via flex: 0 0 100%) and the four
     buttons on row 2 (centered as a group). Total height grows
     to ~50px — calc() values below in this media query are
     updated to match. */
  #brand-footer {
    min-height: 50px;
    padding: 4px 10px;
    gap: 2px 6px;
    font-size: 0.62rem;
    /* Override the desktop space-between: with the disclosure on
       its own row, both rows look better centered on a phone. */
    justify-content: center;
  }
  /* Force the disclosure onto its own row so it is always shown
     in full (never truncated, never sharing a row with buttons). */
  .footer-disclaimer {
    flex: 0 0 100%;
    text-align: center;
    font-size: 0.6rem;
  }
  /* Centered, slightly tighter button row on mobile. */
  .footer-actions {
    gap: 6px;
  }
  .brand-disclaimer-btn {
    font-size: 0.6rem;
    padding: 3px 8px;
    letter-spacing: 0.5px;
  }
  /* Mobile-tight version of the three legal text-links. Slightly
     smaller font keeps all four buttons (Privacy, Terms, Cookies,
     Disclaimer) comfortably centered on a 390px iPhone width. */
  .brand-legal-link {
    font-size: 0.6rem;
    padding: 3px 4px;
    letter-spacing: 0.3px;
  }

  /* Each mobile tab: equal-flex column with icon over label. */
  .mobile-tab {
    flex: 1;
    background: transparent;
    border: 0;
    color: #6f6fa0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
    font-family: inherit;
    font-size: 0.7rem;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    padding: 8px 4px;
    /* Suppress iOS tap highlight; we have our own active styles. */
    -webkit-tap-highlight-color: transparent;
    /* Borders separate tabs without using a colored stripe. */
    border-right: 1px solid #1a1a30;
  }
  .mobile-tab:last-child {
    border-right: 0;
  }
  .mobile-tab:active {
    background: rgba(78, 224, 122, 0.05);
  }
  .mobile-tab.active {
    color: #4ee07a;
    background: rgba(78, 224, 122, 0.08);
  }

  .mobile-tab-icon {
    width: 24px;
    height: 24px;
    line-height: 0;
    /* Inner SVG sized to match. */
  }
  .mobile-tab-icon svg {
    width: 100%;
    height: 100%;
  }
  .mobile-tab-label {
    font-weight: 600;
  }

  /* SHOP STICKY HEADER — wraps balance + tabs + buy-amount on mobile
     so they stay grouped at the top while the buildings list scrolls.
     Single sticky container avoids overlap between the three rows. */
  .shop-sticky-header {
    position: sticky;
    top: 32px;            /* sit just below the fixed news bar */
    z-index: 10;
    background: #0e0e1f;  /* opaque so scrolling content passes UNDER */
    border-bottom: 1px solid #1f1f3a;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  }

  /* In-shop balance pill: visible on mobile shop view. Single-line
     layout so it stays compact (no flex-wrap to a second row). */
  #shop-balance {
    display: flex;
    align-items: baseline;
    gap: 8px;
    background: #15152e;
    padding: 10px 16px;
  }
  .shop-balance-label {
    font-size: 0.7rem;
    letter-spacing: 2px;
    color: #8888aa;
    text-transform: uppercase;
  }
  #shop-balance-num {
    font-size: 1.4rem;
    font-weight: 800;
    color: #4ee07a;
    font-variant-numeric: tabular-nums;
    flex: 1;
    text-align: right;
  }
  #shop-balance-rps {
    font-size: 0.78rem;
    color: #8888aa;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* Modal sizing on small screens. */
  #modal-box {
    min-width: 0;
    width: calc(100vw - 32px);
    max-width: 480px;
  }
}

/* ---------- 12. SMALL PHONES ---------- */
@media (max-width: 480px) {
  /* 5 achievement columns is the right density for narrow phones. */
  #achievements-content {
    grid-template-columns: repeat(5, 1fr);
  }
  /* Upgrades: 4 cols so each is tappable. */
  #upgrades-list {
    grid-template-columns: repeat(4, 1fr);
  }
  /* Shrink the click button a bit more so the counters fit. */
  #robux-wrap {
    width: 200px;
    height: 200px;
  }
  .big-robux-num {
    font-size: 2.2rem;
  }
  /* Title shrinks again so "RobuxClicker.com" still reads as one
     line on iPhone-SE-class screens (~320px wide). */
  .click-title-name {
    font-size: 1.45rem;
  }
  .click-title-subtitle {
    font-size: 0.7rem;
  }
  /* Tighter tab labels at very small widths. */
  .mobile-tab {
    font-size: 0.65rem;
    letter-spacing: 1px;
  }
}

/* ============================================================
   EVENT BANNER (rc-06)
   Centered above the click button. Two tinted backgrounds —
   green for good events, red for bad — with no left/right
   accent stripe. The banner is fully hidden when no event is
   active so it doesn't reserve layout space.
   ============================================================ */

#event-banner {
  /* Box layout — sits in the natural flow above #robux-wrap. */
  width: 100%;
  max-width: 480px;
  margin: 0 auto 12px auto;
  padding: 10px 16px;
  border-radius: 10px;
  border: 2px solid transparent;
  text-align: center;
  /* Drop shadow for depth above the dark stage. */
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
  /* Smooth reveal/hide tinting transition. */
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

/* Title line — the headline of the active event. */
.event-banner-title {
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: 1px;
  margin-bottom: 2px;
}

/* Body line — short description below the title. */
.event-banner-body {
  font-size: 0.85rem;
  color: #e0e0ec;
  margin-bottom: 4px;
}

/* Timer line — live countdown injected by EVENTS.update(). */
.event-banner-timer {
  font-size: 0.75rem;
  letter-spacing: 2px;
  color: #f0f0ff;
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

/* Good-event tint: green-glow palette, full-width fill (no side stripe). */
#event-banner.event-good {
  background: linear-gradient(180deg, #1a3a25 0%, #0f2418 100%);
  border-color: #4ee07a;
  color: #b8f5c8;
}

/* Bad-event tint: red-glow palette, full-width fill. */
#event-banner.event-bad {
  background: linear-gradient(180deg, #3a1a1f 0%, #240f12 100%);
  border-color: #e2231a;
  color: #ffc0bb;
}

/* Hidden state — collapses to zero footprint. */
#event-banner.event-hidden {
  display: none;
}

/* Mobile (<= 700px) tighten the banner so it fits a 390px viewport
   with comfortable side padding and slightly smaller text. */
@media (max-width: 700px) {
  #event-banner {
    max-width: calc(100% - 16px);
    padding: 8px 12px;
    margin: 0 8px 10px 8px;
  }
  .event-banner-title {
    font-size: 1rem;
  }
  .event-banner-body {
    font-size: 0.78rem;
  }
}

/* ============================================================
   34. ANIMATED BACKGROUND CANVAS (rc-10)
   Full-viewport canvas pinned behind every other UI element.
   The drawing is done by js/background.js; CSS just owns the
   placement, layering, and reduced-motion opt-out.
   ============================================================ */
#bg-canvas {
  /* Pin to the viewport so the canvas covers the entire window
     regardless of scroll position. */
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  /* z-index:-1 puts it behind everything else, including the
     news bar, click area, panels, and modals. */
  z-index: -1;
  /* Never swallow clicks meant for the big Robux button or the
     panels above. */
  pointer-events: none;
  /* Keep the animation subtle so it doesn't compete with the
     foreground click target. */
  opacity: 0.55;
}

/* Users who prefer reduced motion get NO animated background. */
@media (prefers-reduced-motion: reduce) {
  #bg-canvas {
    display: none;
  }
}

/* ============================================================
   FIRST-RUN TUTORIAL OVERLAY (rc-11).
   - The overlay itself uses pointer-events: none so the player
     can still click the highlighted target through it. The
     dimming is done by the spotlight's huge box-shadow (a
     "spread" the size of the viewport that wraps darkness around
     the spotlight rectangle).
   - The tooltip box re-enables pointer-events:auto so its Skip /
     Got it buttons receive clicks.
   - z-index 1500 — above all gameplay UI, below MODAL (2000)
     so a confirm dialog (e.g. hard reset) opens above it.
   ============================================================ */
#tutorial-overlay {
  /* Cover the entire viewport. */
  position: fixed;
  inset: 0;
  z-index: 1500;
  /* Pass clicks through by default so the player can interact
     with the underlying game. The tooltip re-enables
     pointer-events for itself below. */
  pointer-events: none;
}

/* Hidden state — used by TUTORIAL.finish() to take the overlay
   out of the layout entirely. */
.tutorial-hidden { display: none !important; }

/* The bright rectangle around the current target. The huge
   box-shadow creates the dim wash outside the rectangle. */
#tutorial-spotlight {
  position: absolute;
  border: 3px solid #4ee07a;
  border-radius: 12px;
  /* Inner glow + a viewport-sized opaque ring outside that does
     all the dimming. */
  box-shadow:
    0 0 30px rgba(78, 224, 122, 0.7),
    0 0 0 9999px rgba(0, 0, 0, 0.6);
  /* Decorative — never absorbs clicks. */
  pointer-events: none;
  /* Smoothly slide from one target to the next instead of
     teleporting. */
  transition: top 0.25s ease, left 0.25s ease,
              width 0.25s ease, height 0.25s ease;
}

/* Speech-bubble panel with the step copy + buttons. */
#tutorial-tooltip {
  position: absolute;
  background: #15152e;
  border: 1px solid #4a4a7a;
  border-radius: 8px;
  padding: 16px 20px;
  max-width: 320px;
  font-size: 0.85rem;
  color: #fff;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
  /* Re-enable pointer events here so the Skip / Got it buttons
     can be clicked even though the parent overlay disables them. */
  pointer-events: auto;
}

/* "Step N of 4" small caps label above the title. */
#tutorial-step {
  font-size: 0.7rem;
  color: #4ee07a;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-bottom: 6px;
}

/* Bold title line for the current step. */
#tutorial-title {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 6px;
}

/* Body copy, slightly muted so the title stands out. */
#tutorial-body {
  color: #ccc;
  line-height: 1.5;
  margin-bottom: 12px;
}

/* Right-aligned button row at the bottom of the tooltip. */
#tutorial-buttons {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Shared button base — Skip and Got it both use the same shape;
   colour rules below distinguish them. */
.tutorial-btn-skip,
.tutorial-btn-next {
  background: #1a1a30;
  border: 1px solid #2a2a4e;
  color: #ccc;
  padding: 8px 16px;
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.78rem;
  letter-spacing: 1px;
  cursor: pointer;
  text-transform: uppercase;
}

/* Primary action — green-tinted to match the spotlight. */
.tutorial-btn-next {
  background: #224428;
  border-color: #4ee07a;
  color: #4ee07a;
}

/* Hover affordance for both buttons. */
.tutorial-btn-next:hover { background: #2a5a30; color: #fff; }
.tutorial-btn-skip:hover { color: #fff; }

/* ============================================================
   GAMES MENU — More Games button + modal grid.
   This whole block is removable; deleting it disables the
   feature without touching anything else. See
   js/games-menu.js for the matching JS module.
   ============================================================ */

/* The "More Games" pill at the bottom of the click area. Deliberately
   understated — green outline on dark background so it reads as a
   secondary CTA, not competing with the giant Robux button above it. */
.games-menu-button {
  /* Block layout under the lifetime-stats row. */
  display: block;
  margin: 18px auto 4px;
  /* Pill shape, generous tap target for mobile (44x44 minimum). */
  padding: 10px 22px;
  min-height: 44px;
  border-radius: 999px;
  /* Dark fill matching the panel/card palette; green outline tones it
     to the brand. */
  background: #15152e;
  border: 1px solid #2a5a3a;
  color: #4ee07a;
  /* Same monospace stack used elsewhere — feels consistent with the
     stats and tooltip text. */
  font: 600 0.85rem/1 'Courier New', monospace;
  letter-spacing: 1px;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s,
              box-shadow 0.15s;
}

/* Hover lights the border to brand green and adds a subtle glow.
   Affordance via border + glow, never by dimming or stripe. */
.games-menu-button:hover {
  background: #1f1f3a;
  border-color: #4ee07a;
  color: #fff;
  box-shadow: 0 0 12px rgba(78, 224, 122, 0.25);
}

/* Keyboard accessibility: same affordance on focus as hover. */
.games-menu-button:focus-visible {
  outline: none;
  border-color: #4ee07a;
  box-shadow: 0 0 0 2px rgba(78, 224, 122, 0.45);
}

/* Inside the modal: a responsive grid of card links. minmax(220px,1fr)
   gives 1 column on phones (390px modal body), 2-3 columns on desktop
   modals (typically 600-720px wide). */
.games-menu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  /* Cap so very wide screens don't stretch cards uncomfortably wide. */
  max-width: 920px;
  margin: 0 auto;
}

/* Individual game card. Anchor element so a click is a real link
   (works with middle-click "open in new tab", keyboard activation,
   and screen-reader semantics). */
.games-menu-card {
  /* Reset the default link look. */
  text-decoration: none;
  color: inherit;
  /* Same dark-card palette as building-card so the menu feels native
     to the rest of the UI rather than imported. */
  background: #15152e;
  border: 1px solid #2a2a4e;
  border-radius: 6px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 0.15s, background 0.15s, transform 0.1s,
              box-shadow 0.15s;
}

/* Hover: brand-green border + subtle lift + glow. Mirrors the
   affordable building-card hover state. */
.games-menu-card:hover {
  background: #1f1f3a;
  border-color: #4ee07a;
  transform: translateY(-2px);
  box-shadow: 0 4px 18px rgba(78, 224, 122, 0.18);
}

/* Keyboard focus mirrors hover for accessibility. */
.games-menu-card:focus-visible {
  outline: none;
  border-color: #4ee07a;
  box-shadow: 0 0 0 2px rgba(78, 224, 122, 0.45);
}

/* Genre badge — small, brand green, ALL CAPS to read as a label. */
.games-menu-genre {
  font-size: 0.65rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #4ee07a;
}

/* Game title — the focal text on each card. */
.games-menu-title {
  font-size: 1rem;
  letter-spacing: 1.5px;
  color: #fff;
  margin: 0;
}

/* Body copy describing the game. Two-three sentences, easy to scan. */
.games-menu-desc {
  font-size: 0.78rem;
  line-height: 1.45;
  color: #aab;
  margin: 0;
}

/* Tech notes — muted, separated by a top divider so the eye knows
   the description block ended and meta information started. */
.games-menu-tech {
  font-size: 0.68rem;
  line-height: 1.4;
  color: #556;
  border-top: 1px solid #222;
  padding-top: 8px;
  /* margin-top:auto pins this to the card bottom even when descriptions
     differ in length, keeping the row of tech-notes baseline-aligned. */
  margin-top: auto;
}

/* Mobile: collapse the grid to one column at narrow widths.
   The modal body itself shrinks on mobile so cards already wrap, but
   we tighten the gap and font sizes a touch for phone screens. */
@media (max-width: 600px) {
  .games-menu-grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .games-menu-card { padding: 12px; }
  .games-menu-title { font-size: 0.95rem; }
  .games-menu-desc { font-size: 0.76rem; }
}
/* ============================================================
   /GAMES MENU
   ============================================================ */

/* ============================================================
   HOMEPAGE CONTENT SECTION (ITEM-24 — AdSense content layer)

   The idle game above is rendered by JS into #game and is locked
   to a single viewport. To give the homepage real, crawlable text
   for the Google AdSense review, index.html appends a static
   content section (.homepage-content) and a shared site footer
   (.site-footer) AFTER the game.

   This block does three jobs:
     1. Releases the one-viewport scroll lock so the new content
        below the game is reachable by scrolling.
     2. Un-pins the in-game legal footer on desktop so it flows
        with the document instead of floating over the new content
        as the visitor scrolls (mobile keeps it pinned — the
        mobile layout calc()s depend on that).
     3. Styles the new content section and footer to match the
        site's dark-navy / green theme.

   Scoping: every rule below either targets html / body /
   #brand-footer explicitly, or is prefixed with .homepage-content
   or .site-footer. Nothing here can leak into #game, .panel, or
   any other game element. The class names used (.homepage-*,
   .site-footer, .footer-links, .footer-disclaimer-text,
   .footer-copyright, .btn-primary) are not used anywhere else in
   this stylesheet, so there is no collision with game CSS.

   Removable feature: delete this block plus the matching
   <section class="site-content homepage-content"> and
   <footer class="site-footer"> in index.html.
   ============================================================ */

/* 1. Release the one-viewport scroll lock. The base rule (top of
   this file) sets html, body { height: 100%; overflow: hidden }
   so the desktop document never scrolls. Here we let the document
   grow to its natural height and scroll normally, which is what
   makes the content section below the game reachable. #game keeps
   its own calc() height, so a visitor who does not scroll still
   sees exactly the same game as before. On mobile the document
   already scrolls (the max-width: 980px block sets the same
   values), so this rule simply agrees with it there. */
html, body {
  height: auto;
  overflow: visible;
}

/* 2. Desktop only (the mobile breakpoint is max-width: 980px):
   let the in-game legal footer flow inside the document instead
   of being pinned to the viewport bottom. Pinned, it would float
   on top of the content section the whole time the visitor
   scrolls; static, it sits right at the bottom edge of the game
   (visually identical at the top of the page) and then scrolls
   away as the visitor moves into the content. The mobile layout
   keeps the footer fixed because its bottom-bar calc()s rely on
   that — so this override is scoped to desktop widths only. */
@media (min-width: 981px) {
  #brand-footer {
    position: static;
  }
}

/* 3a. The content section itself — a centred reading column that
   sits below the game. position: relative + z-index keep it
   cleanly above the fixed background canvas (#bg-canvas, z-index
   -1). user-select is re-enabled because the game body disables
   text selection; article copy should be selectable like normal
   text. */
.homepage-content {
  position: relative;
  z-index: 1;
  max-width: 860px;
  margin: 0 auto;
  padding: 8px 18px 24px;
  line-height: 1.7;
  user-select: text;
  -webkit-user-select: text;
}

/* Intro link row — the four section links as pill-style buttons. */
.homepage-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin: 18px 0 26px;
}
.homepage-nav a {
  display: inline-block;
  padding: 9px 16px;
  background: #1a1a30;
  border: 1px solid #2a2a4e;
  border-radius: 8px;
  color: #c0c0d8;
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
}
.homepage-nav a:hover {
  color: #fff;
  border-color: #4ee07a;
}

/* Article typography, scoped to the content section so it cannot
   touch the game UI. Headings use the same scale as css/site.css
   (the content-layer stylesheet) so the homepage reads as part of
   the same site as the other content pages. */
.homepage-content h2 {
  font-size: 1.35rem;
  color: #fff;
  margin: 30px 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid #1f1f3a;
}
.homepage-content h3 {
  font-size: 1.1rem;
  color: #4ee07a;
  margin: 20px 0 8px;
}
.homepage-content p {
  margin: 0 0 16px;
  color: #ddd;
}
.homepage-content ul {
  margin: 0 0 16px;
  padding-left: 24px;
  color: #ddd;
}
.homepage-content li {
  margin-bottom: 6px;
}
/* In-text links: brand green, underlined for a clear affordance. */
.homepage-content a {
  color: #4ee07a;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.homepage-content a:hover {
  color: #7dff9f;
}

/* Teaser panel — an evenly-bordered card for the Arcade and Guides
   cross-links. A normal full-border panel: no split fill and no
   coloured side stripe (CLAUDE.md rule 5). */
.homepage-teaser {
  background: #0e0e1f;
  border: 1px solid #2a2a4e;
  border-radius: 10px;
  padding: 18px 20px;
  margin: 14px 0 18px;
}
.homepage-teaser p {
  margin-bottom: 12px;
}
/* Primary call-to-action button inside a teaser — solid brand
   green with dark text, matching .btn-primary in css/site.css. */
.homepage-teaser .btn-primary {
  display: inline-block;
  padding: 11px 20px;
  background: #4ee07a;
  border: 1px solid #4ee07a;
  border-radius: 8px;
  color: #06210f;
  font-size: 0.95rem;
  font-weight: 700;
  text-decoration: none;
}
.homepage-teaser .btn-primary:hover {
  background: #7dff9f;
  border-color: #7dff9f;
  color: #06210f;
}

/* FAQ — each item is an evenly-bordered panel; the question is set
   off by weight and colour, never by a coloured side stripe. */
.homepage-faq {
  margin: 14px 0 8px;
}
.homepage-faq-item {
  background: #0e0e1f;
  border: 1px solid #2a2a4e;
  border-radius: 8px;
  padding: 14px 18px;
  margin-bottom: 12px;
}
.homepage-faq-q {
  font-weight: 700;
  color: #fff;
  margin-bottom: 6px;
}
.homepage-faq-a {
  color: #c0c0d8;
  margin-bottom: 0;
}

/* 3b. The shared site footer appended below the content section.
   It mirrors the .site-footer used on every other content page
   (see css/site.css) so the homepage carries the same crawlable
   legal links and trademark disclaimer. */
.site-footer {
  position: relative;
  z-index: 1;
  margin-top: 20px;
  background: #0e0e1f;
  border-top: 1px solid #2a2a4e;
  padding: 26px 16px;
}
.site-footer-inner {
  max-width: 1100px;
  margin: 0 auto;
  text-align: center;
}
/* Legal links row — centred, wraps on narrow phones. */
.site-footer .footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px 4px;
  margin-bottom: 14px;
}
.site-footer .footer-links a {
  display: inline-block;
  padding: 8px 12px;
  color: #c0c0d8;
  text-decoration: none;
  font-size: 0.9rem;
  border-radius: 6px;
}
.site-footer .footer-links a:hover {
  color: #4ee07a;
  background: #1a1a30;
}
/* The permanent trademark-safety disclaimer — always legible. */
.site-footer .footer-disclaimer-text {
  color: #8888aa;
  font-size: 0.82rem;
  line-height: 1.6;
  max-width: 640px;
  margin: 0 auto 10px;
}
/* Copyright line — the dimmest text in the footer. */
.site-footer .footer-copyright {
  color: #66667e;
  font-size: 0.8rem;
}

/* Desktop: a little more breathing room and a larger heading in
   the reading column, matching the content-page scale. */
@media (min-width: 760px) {
  .homepage-content {
    padding: 16px 24px 32px;
  }
  .homepage-content h2 {
    font-size: 1.5rem;
  }
}
/* ============================================================
   /HOMEPAGE CONTENT SECTION
   ============================================================ */
