/* ============================================================
 * AthenaSoftware storefront — self-contained, dark-first CSS.
 * Sections:
 *   1. Design tokens (palette, type, motion, per-game gradients)
 *   2. Base + reset
 *   3. Layout primitives (container, buttons, chips, alerts)
 *   4. Header / footer
 *   5. Hero
 *   6. Category ribbon (marquee)
 *   7. Catalog + product cards
 *   8. Trust band + FAQ
 *   9. Product detail page
 *  10. Success / cancel status pages
 *  11. Animations + reduced motion
 *  12. Responsive breakpoints
 * ============================================================ */

/* -----------------------------------------------------------
 * 1. Design tokens
 * ----------------------------------------------------------- */
:root {
  /* Ground / surfaces */
  --bg:            #070709;
  --bg-body:       #0e0515;
  --surface:       #141020;
  --surface-2:     #1c1428;
  --card:          #211830;
  --card-2:        #281634;
  --muted-fill:    #2c2630;
  --border:        #2f2740;
  --border-soft:   rgba(179, 45, 224, 0.14);

  /* Text */
  --text:          #f3ebf9;
  --text-muted:    #c2bac8;
  --text-dim:      #8f8698;

  /* Brand */
  --primary:       #B32DE0;
  --primary-2:     #ac57e2;
  --primary-hover: #c246ef;
  --accent:        #df76ff;
  --indigo:        #7a7af5;
  --cyan:          #00b5eb;
  --amber:         #de6200;

  /* Status */
  --success:       #22c55e;
  --success-soft:  rgba(34, 197, 94, 0.14);
  --warn:          #de6200;
  --warn-soft:     rgba(222, 98, 0, 0.14);
  --danger:        #ff614d;
  --danger-soft:   rgba(255, 97, 77, 0.14);

  /* Radii + shadows */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-full: 9999px;

  --shadow-card:  0 20px 40px -20px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.03) inset;
  --shadow-glow:  0 10px 40px -10px rgba(179, 45, 224, 0.45);
  --shadow-lift:  0 25px 50px -20px rgba(179, 45, 224, 0.35);

  /* Type */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Inter, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

  --tr-fast: 150ms cubic-bezier(.22, 1, .36, 1);
  --tr-med:  220ms cubic-bezier(.22, 1, .36, 1);

  /* Default game gradient (per-game override via data-game=…) */
  --g1: var(--primary);
  --g2: var(--indigo);
}

/* Per-game gradients + accent. --game-accent is used by ribbon tile labels
 * and the hover glow so each tile picks up its distinctive brand color. */
[data-game="default"]           { --g1:#B32DE0; --g2:#7a7af5; --game-accent:#B32DE0; }
/* Colours retuned to match the actual game hero images (purple/pink branding
 * overlays across the board, with red for the WWII / spoofer marks). */
[data-game="fortnite"]          { --g1:#E93D82; --g2:#6b1f4a; --game-accent:#FF7EC0; }
[data-game="gray-zone-warfare"] { --g1:#7C3AED; --g2:#301152; --game-accent:#C4A8FF; }
[data-game="battlefield-6"]     { --g1:#9333EA; --g2:#2a0e4e; --game-accent:#C4A8FF; }
[data-game="hell-let-loose"]    { --g1:#A73333; --g2:#3a0f0f; --game-accent:#F4A09E; }
[data-game="hwid-spoofer"]      { --g1:#C1272D; --g2:#3a0a0d; --game-accent:#F0898A; }
[data-game="rust"]              { --g1:#f97316; --g2:#7c2d12; --game-accent:#fb923c; }
[data-game="valorant"]          { --g1:#ff4655; --g2:#0f1923; --game-accent:#ff4655; }
[data-game="apex"]              { --g1:#e40007; --g2:#1a1a1a; --game-accent:#ff2937; }
[data-game="apex-legends"]      { --g1:#e40007; --g2:#1a1a1a; --game-accent:#ff2937; }
[data-game="fivem"]             { --g1:#f59e0b; --g2:#78350f; --game-accent:#fbbf24; }
[data-game="cs2"]               { --g1:#d97706; --g2:#3730a3; --game-accent:#fbbf24; }
[data-game="counter-strike-2"]  { --g1:#d97706; --g2:#3730a3; --game-accent:#fbbf24; }
[data-game="minecraft"]         { --g1:#22c55e; --g2:#166534; --game-accent:#22c55e; }
[data-game="gta5"]              { --g1:#facc15; --g2:#0891b2; --game-accent:#facc15; }
[data-game="gta-v"]             { --g1:#facc15; --g2:#0891b2; --game-accent:#facc15; }
[data-game="roblox"]            { --g1:#ef4444; --g2:#7f1d1d; --game-accent:#ef4444; }
[data-game="pubg"]              { --g1:#f59e0b; --g2:#1f2937; --game-accent:#f59e0b; }
[data-game="warzone"]           { --g1:#4b5563; --g2:#0b1220; --game-accent:#9ca3af; }
[data-game="tarkov"]            { --g1:#365314; --g2:#0e0f0a; --game-accent:#a3e635; }
[data-game="escape-from-tarkov"]{ --g1:#365314; --g2:#0e0f0a; --game-accent:#a3e635; }
[data-game="other"]             { --g1:#B32DE0; --g2:#7a7af5; --game-accent:#B32DE0; }

/* -----------------------------------------------------------
 * 2. Base + reset
 * ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* Background A/B test — four selectable page-atmosphere treatments, picked
   via ?bg=a|b|c|d (see shop_bg_variant() in _layout.php, which stamps the
   choice onto <body data-bg="...">). Defaults to "b" when no param is set.
   This is comparison tooling: once one is chosen, delete the other three
   variants and the switching mechanism, and bake the winner in as the
   plain, unconditional default.
     a = hero background photo, flat elsewhere
     b = static (non-animated) soft glow — the safe, calm default
     c = subtle film-grain texture
     d = faint technical grid pattern */
body {
  margin: 0;
  background: var(--bg-body);
  position: relative;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
}

/* --- a: purpose-generated 21:9 hero photo + grid overlay -----------------
   Take 10, using assets/hero/hero_duotone_21x9.png — an AI-generated shot
   made specifically for this hero, at 2520x1080 (~21:9), already in the
   site's exact duotone palette, no wordmark, no baked-in grid. Since the
   image's own aspect ratio now roughly matches the ultra-wide hero box
   (unlike the 16:9 sources used in takes 1-9), background-size:cover no
   longer swings wildly between "barely cropped" and "massive close-up"
   depending on the browser window shape — the mismatch that caused that
   was specifically a 16:9-into-21:9-ish-box problem.
   The hero's text is centered, which lands roughly over the main
   operator's face in this composition (not off to one side like earlier
   sources), so the readability treatment here is a centered radial
   vignette instead of the earlier left-to-right gradient — darkest right
   behind the text, fading out toward the edges so the more open sky/scene
   areas stay vivid. */
body[data-bg="a"] .hero {
  background-color: var(--bg-body);
  background-image:
    linear-gradient(0deg, var(--bg-body) 0%, transparent 20%),
    repeating-linear-gradient(0deg,  rgba(210,150,255,.09) 0 1px, transparent 1px 48px),
    repeating-linear-gradient(90deg, rgba(210,150,255,.09) 0 1px, transparent 1px 48px),
    radial-gradient(ellipse 65% 85% at 50% 42%, rgba(7,7,9,.7) 0%, rgba(7,7,9,.3) 50%, transparent 82%),
    url('hero/hero_duotone_21x9.png');
  background-size: 100% 100%, 48px 48px, 48px 48px, 100% 100%, cover;
  background-position: center, 0 0, 0 0, center, center;
  background-repeat: no-repeat, repeat, repeat, no-repeat, no-repeat;
}
/* The grid (see "d" below) applied across the whole page, not just the
   hero — ties the photo-backed hero together with a consistent texture on
   every section below it. */
body[data-bg="a"]::before {
  content: "";
  position: fixed;
  /* Overscanned past every edge, not inset:0 — see the "d" variant below
     for why (a line rendered exactly at the viewport clip boundary
     produces a seam/ghosting artifact if this pattern is ever animated). */
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  /* No mask — a previous version faded this to a soft central "spotlight"
     blob, which read as patchy/broken rather than a consistent page-wide
     texture. Uniform coverage everywhere is the point of this variant. */
}

/* --- b: static soft glow (no animation) ----------------------------------- */
body[data-bg="b"]::before,
body[data-bg="b"]::after {
  content: "";
  position: fixed;
  z-index: -1;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
}
body[data-bg="b"]::before {
  top: -15vh; left: -15vw;
  width: 55vw; height: 55vw;
  background: radial-gradient(circle, rgba(179,45,224,.28), transparent 70%);
}
body[data-bg="b"]::after {
  bottom: -20vh; right: -15vw;
  width: 50vw; height: 50vw;
  background: radial-gradient(circle, rgba(122,122,245,.22), transparent 70%);
}

/* --- c: subtle film-grain texture ------------------------------------------ */
body[data-bg="c"]::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .06;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
}
body[data-bg="c"]::after {
  content: "";
  position: fixed;
  z-index: -1;
  top: -10vh; left: -10vw;
  width: 60vw; height: 60vw;
  border-radius: 50%;
  filter: blur(100px);
  pointer-events: none;
  background: radial-gradient(circle, rgba(179,45,224,.16), transparent 70%);
}

/* --- d: faint technical grid ------------------------------------------------ */
body[data-bg="d"]::before {
  content: "";
  position: fixed;
  /* Overscanned 50px past every edge (not inset:0) — with the pattern
     flush against the viewport boundary, the animated topmost line was
     constantly being partially clipped right at that hard edge as it
     drifted, causing a seam/ghosting artifact. Padding the element beyond
     the viewport means no line is ever rendered exactly at a clip
     boundary — the seam has nowhere to happen. */
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  /* No mask — same fix as variant "a" above: a soft central spotlight blob
     read as patchy/broken rather than a consistent page-wide texture. */
  animation: gridDrift 22s linear infinite;
  will-change: background-position;
}
/* Diagonal scroll — the grid tiles seamlessly every 48px, so animating
   background-position by exactly one tile loops with zero visible jump. */
@keyframes gridDrift {
  from { background-position: 0 0; }
  to   { background-position: 48px 48px; }
}

/* --- shared grid mixin (copy-pasted, not @extend — plain CSS has no mixins)
   used identically as ::before on every "e" through "j" variant below, so
   each one keeps the exact same proven grid backdrop and only differs in
   what its ::after layer adds on top. --- */

/* --- e: grid + scan-line sweep ---------------------------------------------
   A soft horizontal band of light travels top-to-bottom down the page on a
   loop — classic "scanning" motion, fits the hacking/cheat-software theme. */
body[data-bg="e"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite;
  will-change: background-position;
}
body[data-bg="e"]::after {
  content: "";
  position: fixed;
  left: -50px; right: -50px;
  top: -250px;
  height: 220px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    transparent 0%, rgba(200,140,255,.06) 40%,
    rgba(223,118,255,.22) 50%,
    rgba(200,140,255,.06) 60%, transparent 100%);
  animation: scanSweep 7s linear infinite;
  will-change: transform;
}
@keyframes scanSweep {
  from { transform: translateY(0); }
  to   { transform: translateY(calc(100vh + 500px)); }
}

/* --- f: grid + breathing corner glows --------------------------------------
   Two soft glows in opposite corners slowly pulse in place — no position
   movement at all, just depth/life via opacity, so it can't repeat any of
   the "moving blob" problems from earlier attempts. */
body[data-bg="f"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite;
  will-change: background-position;
}
body[data-bg="f"]::after {
  content: "";
  position: fixed;
  inset: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle 420px at 8% 8%,   rgba(179,45,224,.28), transparent 70%),
    radial-gradient(circle 420px at 92% 92%, rgba(122,122,245,.22), transparent 70%);
  animation: cornerPulse 6s ease-in-out infinite;
}
@keyframes cornerPulse {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* --- g: grid + diagonal shine sweep ----------------------------------------
   A wide diagonal band of light slowly crosses the whole page — like light
   catching a brushed-metal surface. */
body[data-bg="g"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite;
  will-change: background-position;
}
body[data-bg="g"]::after {
  content: "";
  position: fixed;
  inset: -50px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent 42%, rgba(223,118,255,.16) 48%,
    rgba(223,118,255,.24) 50%,
    rgba(223,118,255,.16) 52%, transparent 58%);
  background-size: 320% 320%;
  animation: diagShine 12s linear infinite;
  will-change: background-position;
}
@keyframes diagShine {
  from { background-position: 0% 0%; }
  to   { background-position: 100% 100%; }
}

/* --- h: pulsing grid (brightness breathing, no extra layer) ---------------- */
body[data-bg="h"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite, gridPulse 4s ease-in-out infinite;
  will-change: background-position, opacity;
}
@keyframes gridPulse {
  0%, 100% { opacity: .65; }
  50%      { opacity: 1; }
}

/* --- i: dual-tone color-cycling grid ----------------------------------------
   Two identical grids, one purple one indigo, cross-fading — reads as the
   grid slowly shifting color rather than two separate layers. Avoids
   animating a gradient's own color stops directly (needs @property, which
   caused real problems earlier in this project) by cross-fading two
   already-colored layers instead. */
body[data-bg="i"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.18) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.18) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite, colorGridA 10s ease-in-out infinite;
  will-change: background-position, opacity;
}
body[data-bg="i"]::after {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(122,122,245,.2) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(122,122,245,.2) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite, colorGridB 10s ease-in-out infinite;
  will-change: background-position, opacity;
}
@keyframes colorGridA { 0%, 100% { opacity: 1; }  50% { opacity: .15; } }
@keyframes colorGridB { 0%, 100% { opacity: .15; } 50% { opacity: 1; } }

/* --- j: grid + rising particles ---------------------------------------------
   Tiny dots drift slowly upward through the grid, like embers or data
   particles. Pure CSS (no canvas/JS particle system) — a dot pattern tiled
   the same way the grid tiles, just moving the opposite direction. */
body[data-bg="j"]::before {
  content: "";
  position: fixed;
  top: -50px; left: -50px; right: -50px; bottom: -50px;
  z-index: -1;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(0deg,  rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px),
    repeating-linear-gradient(90deg, rgba(179,45,224,.16) 0 1.5px, transparent 1.5px 48px);
  animation: gridDrift 22s linear infinite;
  will-change: background-position;
}
body[data-bg="j"]::after {
  content: "";
  position: fixed;
  top: -100px; left: -100px; right: -100px; bottom: -100px;
  z-index: -1;
  pointer-events: none;
  background-image: radial-gradient(circle 1.6px, rgba(223,118,255,.55) 0, transparent 2.2px);
  background-size: 90px 90px;
  animation: particleRise 16s linear infinite;
  will-change: background-position;
}
@keyframes particleRise {
  from { background-position: 0 0; }
  to   { background-position: 0 -900px; }
}

/* --- k: connecting-node network (canvas, JS-driven — see shop_render_scripts()
   in _layout.php) ------------------------------------------------------------
   Real independent-particle motion instead of a repeating CSS tile: each dot
   has its own random velocity and bounces off the viewport edges, and lines
   are drawn between dots that happen to be near each other each frame. */
/* Reverted: a rigid grid and the organic dot network are two different
   "structural" visual languages competing for the same role — unlike the
   grid + soft glow/scan-line combos (those don't compete, since glows have
   no structure of their own). Flat background, network only. */
body[data-bg="k"],
body[data-bg="l"],
body[data-bg="m"],
body[data-bg="n"],
body[data-bg="o"],
body[data-bg="p"],
body[data-bg="q"],
body[data-bg="r"],
body[data-bg="s"],
body[data-bg="u"] {
  background-color: var(--bg-body);
}
/* --- t: aurora ribbons (CSS-only — no canvas needed for a slow soft drift) */
body[data-bg="t"] { background-color: var(--bg-body); }
body[data-bg="t"]::before,
body[data-bg="t"]::after {
  content: "";
  position: fixed;
  left: -20%; right: -20%;
  height: 60vh;
  z-index: -1;
  pointer-events: none;
  filter: blur(60px);
}
body[data-bg="t"]::before {
  top: -10vh;
  background: linear-gradient(100deg, transparent, rgba(179,45,224,.25), transparent, rgba(122,122,245,.2), transparent);
  animation: auroraDrift1 18s ease-in-out infinite;
}
body[data-bg="t"]::after {
  bottom: -20vh;
  background: linear-gradient(100deg, transparent, rgba(122,122,245,.2), transparent, rgba(223,118,255,.22), transparent);
  animation: auroraDrift2 22s ease-in-out infinite;
}
@keyframes auroraDrift1 {
  0%, 100% { transform: translateX(-5%) skewY(-2deg); }
  50%      { transform: translateX(5%) skewY(2deg); }
}
@keyframes auroraDrift2 {
  0%, 100% { transform: translateX(5%) skewY(1deg); }
  50%      { transform: translateX(-5%) skewY(-1deg); }
}
#bg-network-canvas {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  display: block;
}

/* main/footer are transparent so the single body-level atmosphere above
   shows through everywhere uniformly — no more seam between a solid black
   <main>/<footer> and a differently-toned <body>. */
main { flex: 1 0 auto; background: transparent; }

img, svg { max-width: 100%; height: auto; display: block; }

a {
  color: var(--primary-2);
  text-decoration: none;
  transition: color var(--tr-fast);
}
a:hover { color: var(--accent); text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

.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;
}

h1, h2, h3, h4 { margin: 0 0 .6em; letter-spacing: -0.01em; }
h1 { font-weight: 900; letter-spacing: -0.02em; line-height: 1.05; }
h2 { font-weight: 800; line-height: 1.15; }
h3 { font-weight: 700; line-height: 1.3; }

p  { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

.muted { color: var(--text-muted); }
.muted.small,
.small { font-size: 0.8125rem; letter-spacing: 0.01em; }

.grad-text {
  background: linear-gradient(90deg, var(--primary), var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Animated gradient shimmer on the hero's highlighted phrase — a slow
   left-to-right color sweep across the text itself (background-clip:text),
   not just a static tint. */
.hl {
  background: linear-gradient(90deg, var(--primary) 0%, var(--accent) 25%, var(--primary-2) 50%, var(--accent) 75%, var(--primary) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: hlShimmer 6s linear infinite;
}
@keyframes hlShimmer {
  from { background-position: 0% 50%; }
  to   { background-position: -250% 50%; }
}

/* -----------------------------------------------------------
 * 3. Layout primitives
 * ----------------------------------------------------------- */
.container {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 20px;
}

.section-title {
  font-size: clamp(1.6rem, 2vw + .8rem, 2.25rem);
  margin-bottom: .4em;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: .5em;
  padding: .35em .8em;
  border-radius: var(--radius-full);
  background: rgba(179, 45, 224, 0.08);
  border: 1px solid var(--border-soft);
  color: var(--primary-2);
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.icon { flex: 0 0 auto; }

/* Buttons */
.btn {
  --btn-bg: var(--surface-2);
  --btn-fg: var(--text);
  --btn-bd: var(--border);
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  padding: .7em 1.15em;
  border-radius: var(--radius-md);
  border: 1px solid var(--btn-bd);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  line-height: 1.1;
  transition: transform var(--tr-fast), box-shadow var(--tr-fast),
              background var(--tr-fast), border-color var(--tr-fast), color var(--tr-fast);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

.btn-lg  { padding: .9em 1.4em; font-size: 1.02rem; }
.btn-sm  { padding: .5em .9em; font-size: .875rem; }
.btn-block { width: 100%; }

.btn-primary {
  --btn-bg: linear-gradient(90deg, #6b21a8 0%, var(--primary) 100%);
  --btn-fg: #ffffff;
  --btn-bd: transparent;
  position: relative;
  overflow: hidden;
  background: var(--btn-bg);
  background-size: 200% 100%;
  background-position: 0% 50%;
  box-shadow: 0 10px 30px -12px rgba(179, 45, 224, 0.55);
}
.btn-primary:hover {
  background-position: 100% 50%;
  box-shadow: 0 14px 34px -10px rgba(179, 45, 224, 0.7);
  color: #ffffff;
}
/* Periodic light-streak sweep — plays on its own, not just on hover, so
   primary CTAs (Buy now, Browse the shop) draw the eye passively. */
.btn-primary::after {
  content: "";
  position: absolute;
  top: 0; left: -60%;
  width: 35%; height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255,255,255,.4), transparent);
  transform: skewX(-20deg);
  animation: btnShine 4.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes btnShine {
  0%   { left: -60%; }
  35%  { left: 130%; }
  100% { left: 130%; }
}

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-bd: var(--border);
  backdrop-filter: blur(8px);
}
.btn-ghost:hover {
  --btn-bg: rgba(179, 45, 224, 0.08);
  --btn-bd: var(--primary-2);
  color: var(--text);
}

.btn-discord {
  --btn-bg: #5865F2;
  --btn-fg: #ffffff;
  --btn-bd: #5865F2;
}
.btn-discord:hover {
  --btn-bg: #4752c4;
  --btn-bd: #4752c4;
  color: #ffffff;
}

/* Chips (small pill labels) */
.chip {
  display: inline-flex; align-items: center; gap: .35em;
  padding: .35em .7em;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: .8125rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}
.chip.chip--lg { padding: .55em 1em; font-size: .95rem; }
.chip.chip--primary { color: var(--primary-2); border-color: rgba(179,45,224,.35); background: rgba(179,45,224,.08); }
.chip.chip--success { color: var(--success); border-color: rgba(34,197,94,.35); background: var(--success-soft); }

/* Alerts */
.alert {
  display: flex; align-items: flex-start; gap: .6em;
  padding: .8em 1em;
  border-radius: var(--radius-md);
  border: 1px solid var(--danger-soft);
  background: var(--danger-soft);
  color: var(--text);
  font-size: .95rem;
  margin: 1em 0;
}
.alert .icon { color: var(--danger); margin-top: 2px; }
.alert-error { border-color: rgba(255, 97, 77, 0.4); }

/* Empty state */
.empty-state {
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
  padding: 3rem 1.5rem;
  text-align: center;
  background: rgba(255, 255, 255, 0.02);
}
.empty-state h2, .empty-state h3 { margin-bottom: .4em; }

/* -----------------------------------------------------------
 * 4. Header / footer
 * ----------------------------------------------------------- */
.header-sentinel {
  position: absolute; top: 0; left: 0; height: 40px; width: 1px;
  pointer-events: none;
}

.site-header {
  position: sticky; top: 0; z-index: 40;
  padding: 12px 0;
  background: transparent;
  /* NOTE: padding intentionally excluded — animating layout properties
     (padding/height) reflows every descendant and following block on scroll. */
  transition: background-color .3s ease,
              backdrop-filter .3s ease,
              border-color .3s ease;
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
  background: rgba(7, 7, 9, 0.75);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: var(--border);
}

.header-row {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
}

.brand {
  display: inline-flex; align-items: center; gap: .6em;
  color: var(--text);
  text-decoration: none;
  font-weight: 800;
}
.brand:hover { color: var(--text); text-decoration: none; }

.brand-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--border);
  color: var(--primary-2);
  font-size: 18px;
  overflow: hidden; /* the logo PNG carries its own background, unlike the old icon badge */
}
.brand-badge img { width: 100%; height: 100%; object-fit: cover; display: block; }

.wordmark { font-size: 1.05rem; letter-spacing: -.01em; }
.wordmark-accent { color: var(--primary-2); }

.site-nav {
  display: flex; align-items: center; gap: 16px;
}
.site-nav a {
  color: var(--text-muted);
  font-weight: 500;
  font-size: .95rem;
  padding: 6px 4px;
  transition: color var(--tr-fast);
}
.site-nav a:hover { color: var(--text); text-decoration: none; }
.site-nav .btn { padding: .5em .9em; }
.site-nav a:not(.btn) { position: relative; }
.site-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 4px; right: 4px; bottom: 2px;
  height: 2px;
  background: var(--primary-2);
  border-radius: 1px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s cubic-bezier(.22,1,.36,1);
}
.site-nav a:not(.btn):hover::after { transform: scaleX(1); }

/* Footer */
.site-footer {
  background: transparent;
  border-top: 1px solid var(--border);
  padding: 60px 0 30px;
  margin-top: 80px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--border);
}

.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-col a {
  color: var(--text-muted);
  font-size: .92rem;
}
.footer-col a:hover { color: var(--text); }
.footer-title { font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text); margin-bottom: 6px; }

.footer-brand .brand { margin-bottom: 4px; }

.pay-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pay-chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 42px; height: 26px;
  padding: 0 8px;
  border-radius: 6px;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .05em;
}

.footer-bar {
  padding-top: 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  flex-wrap: wrap;
}
.footer-legal { color: var(--text-dim); font-size: .78rem; margin: 0; }

/* -----------------------------------------------------------
 * 5. Hero
 * ----------------------------------------------------------- */
.hero {
  position: relative;
  padding: clamp(48px, 8vw, 96px) 0 clamp(64px, 10vw, 120px);
  overflow: hidden;
  isolation: isolate;
}
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  inset: auto;
  pointer-events: none;
  z-index: -1;
}
.hero::before {
  top: -30%; left: 50%;
  width: 120%; height: 90%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 0%, rgba(179, 45, 224, 0.18), transparent 72%);
  animation: heroGlow 12s ease-in-out infinite;
}
.hero::after {
  bottom: -20%; right: -10%;
  width: 60%; height: 60%;
  background: radial-gradient(circle at 80% 80%, rgba(179, 45, 224, 0.08), transparent 55%);
}
/* The a/b/c/d background system (body[data-bg]) supplies its own page-wide
   atmosphere now, applied uniformly everywhere. This original hero-only
   glow predates that system and, left active, adds EXTRA darkening/color
   only within .hero — which is exactly why the hero read as visibly darker/
   different from the flat, uniform grid everywhere else on the page. */
body[data-bg] .hero::before,
body[data-bg] .hero::after {
  display: none;
}

.hero-inner { position: relative; text-align: center; }

.hero-title {
  font-size: clamp(2.4rem, 4vw + 1rem, 4rem);
  /* Was 22ch, tuned for a shorter headline — longer copy at that width
     wrapped to 3+ stacked lines with an awkward orphan word on the last
     one. 30ch gives it room to settle into 2 lines instead. */
  max-width: 30ch;
  margin: 20px auto 20px;
}

.hero-lede {
  /* Was 60ch — the current copy wrapped to 3 lines with a short orphan
     line at the end (same "stacked" look the headline had at 22ch).
     68ch gives it enough room to settle into 2 more even lines. */
  max-width: 68ch;
  margin: 0 auto 30px;
  color: var(--text-muted);
  font-size: clamp(1rem, .5vw + .9rem, 1.15rem);
}

.hero-actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;
  margin-bottom: 30px;
}

/* Trust-chip marquee sitting at the top of the hero */
.chip-marquee {
  position: relative;
  overflow: hidden;
  padding: 6px 0;
  margin: 0 auto 26px;
  width: 100%;
  max-width: 100%;
  /* .chip-track shrinks to fit its content (width:max-content) rather than
     filling the marquee's full width, so without this it just sits
     left-anchored instead of centered. */
  display: flex;
  justify-content: center;
  /* Edge fades so the loop dissolves into the hero instead of a hard cut. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.chip-track {
  display: flex; gap: 12px;
  width: max-content;
  flex-wrap: nowrap;
  flex-shrink: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .chip-track  { animation: scrollX 40s linear infinite; }
  .chip-track:hover { animation-play-state: paused; }
}
.pill {
  display: inline-flex; align-items: center; gap: .5em;
  padding: .5em 1em;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: rgba(255,255,255,.03);
  color: var(--text);
  font-size: .85rem;
  font-weight: 500;
  white-space: nowrap;
  backdrop-filter: blur(12px);
}
.pill .dot {
  width: 6px; height: 6px; border-radius: 999px;
  background: var(--primary);
  box-shadow: 0 0 8px var(--primary);
  animation: dotPulse 2.4s ease-in-out infinite;
}
@keyframes dotPulse {
  0%, 100% { opacity: 1;   box-shadow: 0 0 6px var(--primary); }
  50%      { opacity: .55; box-shadow: 0 0 12px var(--primary); }
}

/* Payment row + scroll cue */
.hero-pay {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap;
  gap: 20px;
  margin: 20px auto 30px;
  color: var(--text-dim);
  font-size: .85rem;
  max-width: 640px;
}

/* Branded payment icons (inline SVG marks). Used in both hero + footer. */
.pay-icon {
  display: inline-flex; align-items: center; justify-content: center;
  height: 28px;
  line-height: 0;
  opacity: .9;
  transition: opacity var(--tr-fast), transform var(--tr-fast);
}
.pay-icon svg {
  display: block;
  height: 28px;
  width: auto;
  border-radius: 4px;
}
.pay-icon:hover { opacity: 1; transform: translateY(-1px); }
.footer-brand .pay-row { gap: 10px; }
.footer-brand .pay-icon { height: 24px; }
.footer-brand .pay-icon svg { height: 24px; }

.hero-cue {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  color: var(--text-muted);
  animation: bob 2s ease-in-out infinite;
}

/* Bottom-fade transition into content sections */
/* Disabled: this used to paint a flat, opaque fade at the bottom of the hero
   to blend into <main>'s old solid-black background. Now that <main> is
   transparent everywhere and the whole page shares one continuous ambient
   background (see body::before/::after below), this element's own flat
   fill was the thing creating a visible seam at the hero/ribbon boundary —
   there's nothing left for it to blend into. */
.hero-fade { display: none; }

/* -----------------------------------------------------------
 * 6. Category ribbon
 * ----------------------------------------------------------- */
.ribbon-section {
  position: relative;
  padding: 40px 0 20px;
  overflow: hidden;
}
.ribbon-section h2 {
  font-size: 1.4rem;
  text-align: center;
  color: var(--text-muted);
  margin-bottom: 24px;
  font-weight: 600;
}

.game-ribbon {
  position: relative;
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.ribbon-track {
  display: flex;
  gap: 16px;
  width: 100%;
  justify-content: center;
  flex-wrap: wrap;
  align-items: stretch;
  flex-wrap: nowrap;
}
@media (prefers-reduced-motion: no-preference) {
  /* Ribbon is now statically centered — no marquee animation needed for the
   * small game count. If the roster ever exceeds a screen row, re-enable
   * scrollX here and change .ribbon-track back to width:max-content. */
}
/* Hide the duplicate cycle emitted by the PHP loop — it exists purely for
 * marquee looping, which we no longer run on the ribbon. */
.ribbon-track [aria-hidden="true"] { display: none; }

.game-tile {
  position: relative;
  flex: 0 0 auto;
  width: 320px; height: 180px;   /* landscape 16:9 — matches standard game promo-art aspect so cover-crop trims almost nothing (titles like FORTNITE, HWID SPOOFER stay fully visible). */
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--card);
  text-decoration: none;
  color: var(--text);
  transition: transform var(--tr-fast), box-shadow var(--tr-fast), border-color var(--tr-fast);
}
.game-tile:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: var(--primary-2);
  text-decoration: none;
}
.game-tile-art {
  position: absolute; inset: 0;
  overflow: hidden;
  background: linear-gradient(135deg, var(--g1), var(--g2));
}
.game-tile-art .game-art-svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
/* File-based art (when shop/assets/games/<slug>.{jpg,png,webp} exists) */
.game-tile-art .game-art-img {
  position: absolute; inset: 0;
  display: block;
  background-position: center;
  background-size: cover;         /* fill the tile — tile aspect matches image aspect so cropping is minimal */
  background-repeat: no-repeat;
}
/* Card-art photo variant — landscape crop is fine here (16:9 aspect via .card-art). */
.card-art.card-art--photo {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.card-art.card-art--photo .card-art-label,
.card-art.card-art--photo .card-art-icon { display: none; }
/* Utility tiles (HWID Spoofer): drop the vignette + dot texture so the
   centered chip icon reads as an app icon, not game art. */
.game-tile[data-game="hwid-spoofer"] .game-tile-art::before,
.game-tile[data-game="hwid-spoofer"] .game-tile-art::after { display: none; }
/* HWID Spoofer's source photo is 2.49:1 vs the tile's 16:9. Keep the tile the
 * same size as the others (visual consistency was more important than aspect
 * accuracy) and stretch the image to fill — the small vertical stretch is
 * acceptable for a product-shot utility tile and keeps the whole "HWID
 * SPOOFER" wordmark visible. Overrides the inline shorthand via !important. */
.game-tile[data-game="hwid-spoofer"] {
  background-size: 100% 100% !important;
}
.game-tile[data-game="hwid-spoofer"] .game-tile-art {
  background: linear-gradient(160deg, #0d1620 0%, #04090f 100%);
}
.game-tile-art::before {
  /* Bottom-vignette so the tile name stays readable over the art. */
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, transparent 45%, rgba(0,0,0,.55) 100%);
  z-index: 1;
  pointer-events: none;
}
.game-tile-art::after {
  /* subtle dot-grid texture */
  content: "";
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.14) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: .18;
  mix-blend-mode: soft-light;
  z-index: 1;
  pointer-events: none;
}
.game-tile-name {
  position: absolute; left: 14px; bottom: 12px;
  font-weight: 800;
  font-size: 1.05rem;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,0,0,.6);
  z-index: 2;
  /* Left border accent using the game color. */
  padding-left: 10px;
  border-left: 3px solid var(--game-accent, #fff);
  line-height: 1.1;
}
.game-tile:hover {
  box-shadow: 0 25px 50px -20px color-mix(in oklab, var(--game-accent, var(--primary)) 60%, transparent);
  border-color: var(--game-accent, var(--primary-2));
}
.game-tile-hint {
  position: absolute; right: 14px; top: 12px;
  padding: .25em .7em;
  border-radius: var(--radius-full);
  background: rgba(0,0,0,.55);
  color: #fff;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .02em;
  z-index: 2;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--tr-med), transform var(--tr-med);
}
.game-tile:hover .game-tile-hint { opacity: 1; transform: translateY(0); }

/* Coming-soon variant */
.game-tile--soon {
  cursor: default;
  filter: grayscale(35%);
  opacity: .68;
}
.game-tile--soon:hover {
  transform: none;
  box-shadow: none;
  border-color: var(--border);
}
.game-tile-hint--soon {
  opacity: 1;
  transform: none;
  background: rgba(0,0,0,.72);
  color: var(--game-accent, #ffd67a);
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .68rem;
  border: 1px solid color-mix(in oklab, var(--game-accent, #ffd67a) 55%, transparent);
}

/* -----------------------------------------------------------
 * 7. Catalog + product cards
 * ----------------------------------------------------------- */
.catalog {
  padding: clamp(48px, 6vw, 96px) 20px;
  scroll-margin-top: 80px;
}

.catalog-header {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  margin-bottom: 32px;
  flex-wrap: wrap;
}

/* Currency segmented control */
.currency-filter {
  display: flex; align-items: center; gap: 10px;
}
.currency-filter-label,
.currency-filter label {
  color: var(--text-muted);
  font-size: .85rem;
}
.currency-seg {
  display: inline-flex;
  padding: 4px;
  border-radius: var(--radius-full);
  background: var(--surface);
  border: 1px solid var(--border);
}
.currency-seg-link {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-weight: 600;
  font-size: .85rem;
  padding: .45em 1em;
  border-radius: var(--radius-full);
  cursor: pointer;
  text-decoration: none;
  line-height: 1.1;
  transition: background var(--tr-fast), color var(--tr-fast);
}
.currency-seg-link:hover { color: var(--text); text-decoration: none; }
.currency-seg-link[aria-current="true"] {
  background: linear-gradient(90deg, #6b21a8, var(--primary));
  color: #fff;
  box-shadow: 0 6px 18px -8px rgba(179,45,224,.6);
}
.currency-filter noscript select {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
}

/* Product group (legacy per-tier card grid — kept for reference/rollback,
   no longer emitted by index.php once the feature-forward .plan-section
   layout shipped). */
.product-group { margin-top: 48px; }
.product-group:first-of-type { margin-top: 0; }

.group-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.group-header h3.group-title {
  font-size: 1.5rem;
  font-weight: 800;
  margin: 0;
}
.group-header h3.group-title::before {
  content: "";
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--g1, var(--primary)), var(--g2, var(--indigo)));
  margin-right: 10px;
  vertical-align: middle;
  box-shadow: 0 0 10px currentColor;
}

/* -----------------------------------------------------------
 * 7b. Feature-forward plan sections (one banner per game, feature
 *     bullets, tabbed duration switcher). This is what index.php
 *     actually renders in the catalog today.
 * ----------------------------------------------------------- */
.plan-section { margin-top: 56px; }
.plan-section:first-of-type { margin-top: 0; }

.plan-banner {
  position: relative;
  width: 100%;
  max-width: 100%;
  border-radius: var(--radius-lg);
  overflow: hidden;
  min-height: 150px;
  /* Went 21/5 (too cropped) -> 21/9 (too tall) -> contain at 21/5 (huge
     ugly pillarbox gaps either side, since the source photos are much
     closer to 16:9 than to this banner's wide shape — worse than either).
     21/7 (~3:1) with cover (no pillarbox, never was the problem) is the
     middle ground: taller than the original so cover crops less off the
     top/bottom, shorter than 21/9 so it doesn't dominate the layout. */
  aspect-ratio: 21 / 7;
  background: linear-gradient(135deg, var(--g1), var(--g2));
  margin-bottom: 18px;
  display: flex;
  align-items: flex-end;
  border: 1px solid var(--border);
}
.plan-banner::before {
  /* dot texture, matches the ribbon tile treatment */
  content: "";
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.12) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: .18;
  mix-blend-mode: soft-light;
  z-index: 1;
}
.plan-banner-inner {
  position: relative;
  z-index: 2;
  padding: 20px 26px;
}
.plan-banner-title {
  font-size: clamp(1.4rem, 1.1vw + 1.1rem, 2rem);
  color: #fff;
  text-shadow: 0 2px 10px rgba(0,0,0,.6);
  margin: 0 0 4px;
  font-weight: 800;
  border-left: 3px solid var(--game-accent, #fff);
  padding-left: 12px;
}
.plan-banner-sub {
  color: rgba(255,255,255,.82);
  font-size: .85rem;
  margin: 0 0 0 15px;
}

.plan-features {
  list-style: none;
  padding: 0; margin: 0 0 20px;
  display: flex; flex-wrap: wrap; gap: 10px;
}
.plan-feature {
  display: inline-flex; align-items: center; gap: .5em;
  padding: .5em .9em;
  border-radius: var(--radius-full);
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: .85rem;
  font-weight: 600;
}
.plan-feature .icon { color: var(--game-accent, var(--primary-2)); }

.plan-card {
  width: 100%;
  max-width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  box-shadow: var(--shadow-card);
  position: relative;
  overflow: hidden;
  transition: transform .4s cubic-bezier(.22,1,.36,1);
}

/* Cursor spotlight + magnetic tilt, shared with .buy-card — see the
   mousemove handler in shop_render_scripts(). --spot-x/--spot-y track the
   cursor always (harmless); the rotateX/rotateY transform itself is skipped
   under prefers-reduced-motion since it simulates real 3D movement. */
.plan-card::before,
.buy-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(260px circle at var(--spot-x, 50%) var(--spot-y, 50%), rgba(179, 45, 224, .14), transparent 70%);
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
.plan-card:hover::before,
.buy-card:hover::before { opacity: 1; }

.duration-tabs {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-bottom: 22px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border);
}
.duration-tab {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font: inherit; font-weight: 600; font-size: .875rem;
  padding: .6em 1.05em;
  border-radius: var(--radius-full);
  cursor: pointer;
  display: inline-flex; align-items: center; gap: .5em;
  transition: background var(--tr-fast), color var(--tr-fast), border-color var(--tr-fast), transform var(--tr-fast);
}
.duration-tab:hover { color: var(--text); border-color: var(--game-accent, var(--primary-2)); }
.duration-tab.is-active {
  background: linear-gradient(90deg, color-mix(in oklab, var(--game-accent, var(--primary)) 55%, #6b21a8), var(--game-accent, var(--primary)));
  border-color: transparent;
  color: #fff;
  box-shadow: 0 6px 18px -8px color-mix(in oklab, var(--game-accent, var(--primary)) 60%, transparent);
}
.duration-tab-badge {
  display: inline-flex; align-items: center; gap: .3em;
  font-size: .65rem;
  font-weight: 700;
  padding: .15em .55em;
  border-radius: var(--radius-full);
  background: rgba(255,255,255,.22);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.duration-tab:not(.is-active) .duration-tab-badge {
  background: rgba(179,45,224,.12);
  color: var(--primary-2);
}
.duration-tab:not(.is-active) .duration-tab-badge--deal {
  background: rgba(222,98,0,.14);
  color: var(--amber);
}

.plan-detail { display: none; }
.plan-detail.is-active { display: block; animation: popIn .25s cubic-bezier(.22,1,.36,1); }
.plan-detail-desc { color: var(--text-muted); margin: 0 0 18px; max-width: 65ch; }
.plan-price-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 16px;
}
.plan-price-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.plan-price-meta .product-price-lg { margin: 0; }

/* No-JS fallback: reveal every duration panel stacked (tabs become inert
   but harmless), so the plan is still fully browsable and purchasable. */
.no-js .plan-detail { display: block; margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--border); }
.no-js .plan-detail:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; }
.no-js .duration-tabs { display: none; }

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));   /* symmetric — no orphan cards on row 2 */
  grid-auto-rows: 1fr; /* equal-height rows so every card in a row matches */
  gap: 20px;
  align-items: stretch;
}
@media (max-width: 960px) {
  .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .product-grid { grid-template-columns: 1fr; }
}

.product-card {
  position: relative;
  display: flex; flex-direction: column;
  height: 100%;
  border: 1px solid var(--border);
  background: var(--card);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--tr-fast), box-shadow var(--tr-fast), border-color var(--tr-fast);
}
.product-card:hover {
  transform: translateY(-4px);
  border-color: color-mix(in oklab, var(--primary) 60%, var(--border));
  box-shadow: var(--shadow-lift);
}
.product-card--value { border-color: rgba(179, 45, 224, 0.4); }
.product-card--deal  { border-color: rgba(222, 98, 0, 0.45); }

/* Card art (top-of-card gradient panel) */
.card-art {
  position: relative;
  aspect-ratio: 16/9;
  background:
    radial-gradient(ellipse at 30% 20%, rgba(255,255,255,.15), transparent 55%),
    linear-gradient(135deg, var(--g1), var(--g2));
  overflow: hidden;
}
.card-art::after {
  content: "";
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.12) 1px, transparent 1px);
  background-size: 12px 12px;
  opacity: .18;
  mix-blend-mode: soft-light;
}
.card-art-label {
  position: absolute; left: 14px; bottom: 10px;
  color: #fff;
  font-weight: 700;
  font-size: .95rem;
  text-shadow: 0 2px 6px rgba(0,0,0,.55);
  letter-spacing: -.01em;
  z-index: 2;
}
.card-art-icon {
  position: absolute; right: 14px; bottom: 12px;
  color: rgba(255,255,255,.75);
  font-size: 22px;
  z-index: 2;
}

/* Ribbons */
.ribbon {
  position: absolute; top: 12px; left: 12px;
  z-index: 3;
  display: inline-flex; align-items: center; gap: .35em;
  padding: .35em .7em;
  border-radius: var(--radius-full);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #fff;
  box-shadow: 0 6px 16px -8px rgba(0,0,0,.7);
}
.ribbon--value { background: linear-gradient(90deg, var(--primary), var(--accent)); }
.ribbon--deal  { background: linear-gradient(90deg, var(--amber), #f59e0b); }

/* Card body */
.product-card-body {
  padding: 18px 18px 20px;
  display: flex; flex-direction: column; gap: 12px;
  flex: 1 0 auto;
}

.product-eyebrow {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text-dim);
  margin: 0;
  font-weight: 600;
}

.product-name {
  font-size: 1.125rem;
  font-weight: 700;
  margin: 0;
  color: var(--text);
}

.product-desc {
  color: var(--text-muted);
  font-size: .875rem;
  margin: 0;
}

.product-meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }

.product-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 6px;
}

.product-price {
  display: flex; align-items: baseline; gap: 3px;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  color: var(--text);
  margin: 0;
}
.price-currency { font-size: .95rem; color: var(--text-muted); font-weight: 600; }
.price-amount { font-size: 1.5rem; letter-spacing: -.01em; }

.product-price-lg { margin: 12px 0; }
.product-price-lg .price-amount { font-size: 2.2rem; color: var(--primary-2); }
.product-price-lg .price-currency { font-size: 1.1rem; color: var(--primary-2); opacity: .8; }

/* -----------------------------------------------------------
 * 8. Trust band + FAQ
 * ----------------------------------------------------------- */
.trust-band {
  padding: clamp(48px, 6vw, 96px) 0;
}
.trust-band h2 {
  text-align: center;
  margin-bottom: 40px;
}
.trust-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.trust-card {
  padding: 24px;
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--card) 85%, transparent);
  border: 1px solid var(--border-soft);
}
.trust-card .trust-icon {
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 12px;
  background: rgba(179, 45, 224, 0.12);
  color: var(--primary-2);
  font-size: 20px;
  margin-bottom: 14px;
}
.trust-card h3 { font-size: 1rem; font-weight: 700; margin-bottom: 6px; }
.trust-card p { color: var(--text-muted); font-size: .9rem; margin: 0; }

/* Original trust-row helper (used inside product page + hero fallback) */
.trust-row {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
}
.trust-row--compact {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
}
.trust-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: rgba(255,255,255,.02);
  border: 1px solid var(--border);
}
.trust-row--compact .trust-item {
  padding: 8px 12px;
  border-radius: var(--radius-full);
  background: rgba(179,45,224,.05);
  border-color: var(--border-soft);
}
.trust-icon { color: var(--primary-2); font-size: 18px; display: inline-flex; }
.trust-copy { display: flex; flex-direction: column; }
.trust-label { font-weight: 700; color: var(--text); font-size: .92rem; }
.trust-desc { color: var(--text-muted); font-size: .8125rem; margin-top: 2px; }
.trust-row--compact .trust-label { font-size: .82rem; }

/* FAQ */
.faq { padding: clamp(48px, 6vw, 96px) 20px; max-width: 900px; }
.faq h2 { text-align: center; margin-bottom: 32px; }
.faq-list { display: flex; flex-direction: column; gap: 12px; }
.faq-item {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.faq-item[open] { border-color: rgba(179,45,224,.3); }
.faq-item summary {
  cursor: pointer;
  list-style: none;
  padding: 16px 20px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  font-weight: 700;
  color: var(--text);
  font-size: 1rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-caret { transition: transform var(--tr-med); color: var(--text-muted); }
.faq-item[open] .faq-caret { transform: rotate(180deg); color: var(--primary-2); }
.faq-item p {
  padding: 0 20px 18px;
  color: var(--text-muted);
  margin: 0;
}

/* Catalog-level "view full feature list without buying" disclosure —
   shoppers were only seeing the full breakdown after clicking into a
   specific duration tier's product page; this surfaces it a step earlier. */
.feature-details {
  margin: 0 0 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.feature-details[open] { border-color: rgba(179,45,224,.3); }
/* Loads already-open with a clamped peek at the feature TEXT (see the click
   handler in shop_render_scripts()) instead of fully collapsed, so buyers
   see actual feature bullets without clicking. Clicking the summary while
   peeking lifts the clamp instead of closing — only removes .is-peek; a
   second click then behaves like a normal <details> toggle.
   Only .feature-groups--catalog is clamped — .feature-details-media is
   deliberately excluded: a 16:9 media box is already taller than any
   reasonable peek height, so clamping it just cropped the image instead of
   scaling it, and a screenshot is exactly the "good stuff" that should show
   in full rather than get cut off. */
.feature-details.is-peek .feature-groups--catalog {
  /* CSS columns + a height clamp don't combine predictably (content
     balances into the 2nd column instead of just clipping vertically,
     and the fade below would only mask one column) — force single-column
     while peeking so the clamp is a plain top-to-bottom crop. */
  columns: 1;
  max-height: 150px;
  overflow: hidden;
  position: relative;
  cursor: pointer; /* whole peeked area expands on click, not just the summary — see shop_render_scripts() */
}
.feature-details.is-peek .feature-groups--catalog::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 56px;
  background: linear-gradient(180deg, transparent, var(--card) 80%);
  pointer-events: none;
}
.feature-details summary {
  cursor: pointer;
  list-style: none;
  padding: 14px 18px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  font-weight: 600;
  color: var(--text);
  font-size: .9rem;
}
.feature-details summary::-webkit-details-marker { display: none; }
.feature-details[open] .faq-caret { transform: rotate(180deg); color: var(--primary-2); }
.feature-groups--catalog {
  margin: 0;
  padding: 0 18px 18px;
  columns: 2;
  column-gap: 24px;
}
.feature-details-media {
  padding: 0 18px 18px;
}
.feature-details-media .media-gallery {
  margin-bottom: 16px;
  /* Unconstrained, this fills the panel's full width — fine on product.php
     where a 2-column layout already caps it, but the catalog panel is much
     wider, so the same aspect-ratio-based sizing blew it up huge. Cap it to
     a compact slideshow size here instead. */
  max-width: 420px;
}
@media (max-width: 480px) {
  .feature-details-media .media-gallery { max-width: 100%; }
}
@media (max-width: 640px) {
  .feature-groups--catalog { columns: 1; }
}

/* -----------------------------------------------------------
 * 9. Product detail page
 * ----------------------------------------------------------- */
/* <main> itself stays full-width (its background must reach the viewport
   edges to match <body> — see .container.product-page-container below for
   why this page needs its own wrapper instead of combining .container
   directly on <main>, the way index.php's sections do it). */
.product-page { padding-top: 24px; padding-bottom: 60px; }
/* Wider than the default .container (1280px) — the two-column buy layout
   read as a thin strip on large monitors at the default width. Combined
   selector (not a bare class) so it wins over .container's max-width
   regardless of source order. */
.container.product-page-container { max-width: 1440px; }

.back-link {
  display: inline-flex; align-items: center; gap: .4em;
  color: var(--text-muted);
  font-size: .9rem;
  padding: 6px 0;
}
.back-link:hover { color: var(--primary-2); text-decoration: none; }

.product-detail-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 32px;
  margin-top: 20px;
  align-items: start;
}

.product-detail-main {
  padding: 28px;
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--border);
}
.product-detail-main .product-eyebrow { margin-bottom: 8px; }

.product-title {
  font-size: clamp(1.7rem, 2vw + 1rem, 2.4rem);
  font-weight: 800;
  line-height: 1.1;
  margin-bottom: 12px;
}

/* Hero art panel for the detail page */
.detail-art {
  position: relative;
  aspect-ratio: 16/9;
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: 22px;
  background:
    radial-gradient(ellipse at 30% 20%, rgba(255,255,255,.15), transparent 55%),
    linear-gradient(135deg, var(--g1), var(--g2));
}
.detail-art::after {
  content: "";
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.14) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: .18;
  mix-blend-mode: soft-light;
}
.detail-art .detail-art-badge {
  position: absolute; left: 16px; bottom: 14px;
  color: #fff;
  font-weight: 800;
  font-size: 1.05rem;
  text-shadow: 0 2px 6px rgba(0,0,0,.6);
  z-index: 2;
}

/* Screenshot / video gallery (shop_render_media_gallery output) — replaces
   .detail-art on products that have admin-uploaded media. */
.media-gallery { margin-bottom: 22px; }

.media-main {
  position: relative;
  aspect-ratio: 16/9;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
}
.media-main-item {
  position: absolute; inset: 0;
  display: none;
}
.media-main-item.is-active { display: block; }
.media-main-item img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.media-video-frame,
.media-video-native {
  width: 100%; height: 100%;
  display: block;
  border: 0;
  background: #000;
}
.media-video-native { object-fit: contain; }

.media-nav {
  position: absolute; top: 50%; z-index: 3;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(7,7,9,.55);
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--tr-fast), background var(--tr-fast), transform var(--tr-fast);
}
.media-main:hover .media-nav,
.media-nav:focus-visible { opacity: 1; }
.media-nav:hover { background: rgba(179,45,224,.55); }
.media-nav--prev { left: 12px; }
.media-nav--next { right: 12px; }

.media-expand {
  position: absolute; right: 12px; bottom: 12px; z-index: 3;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(7,7,9,.55);
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--tr-fast), background var(--tr-fast);
}
.media-main:hover .media-expand,
.media-expand:focus-visible { opacity: 1; }
.media-expand:hover { background: rgba(179,45,224,.55); }

.media-thumbs {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 10px;
}
.media-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 76px; height: 48px;
  border-radius: 8px;
  border: 2px solid var(--border);
  background: var(--surface) center/cover no-repeat;
  cursor: pointer;
  padding: 0;
  overflow: hidden;
  transition: border-color var(--tr-fast), opacity var(--tr-fast);
  opacity: .65;
}
.media-thumb:hover { opacity: .9; }
.media-thumb.is-active { border-color: var(--game-accent, var(--primary-2)); opacity: 1; }
.media-thumb-play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.35);
  color: #fff;
  font-size: 14px;
}

/* Lightbox — single reusable overlay, content injected by JS from data-media. */
.media-lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  padding: 40px 60px;
  background: rgba(5, 3, 8, .92);
  backdrop-filter: blur(6px);
}
.media-lightbox[hidden] { display: none; }
.media-lightbox-stage {
  width: 100%;
  max-width: 1100px;
  max-height: 80vh;
  aspect-ratio: 16/9;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #000;
}
.media-lightbox-stage img {
  width: 100%; height: 100%;
  object-fit: contain;
}
.media-lightbox-stage iframe,
.media-lightbox-stage video {
  width: 100%; height: 100%;
  border: 0;
}
.media-lightbox-caption {
  color: var(--text-muted);
  font-size: .9rem;
  margin: 0;
  text-align: center;
}
.media-lightbox-close {
  position: absolute; top: 20px; right: 20px; z-index: 3;
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(255,255,255,.06);
  color: #fff;
  cursor: pointer;
  transition: background var(--tr-fast);
}
.media-lightbox-close:hover { background: rgba(179,45,224,.55); }
.media-lightbox-nav {
  position: absolute; top: 50%; z-index: 3;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(255,255,255,.06);
  color: #fff;
  cursor: pointer;
  transition: background var(--tr-fast);
}
.media-lightbox-nav:hover { background: rgba(179,45,224,.55); }
.media-lightbox-nav--prev { left: 20px; }
.media-lightbox-nav--next { right: 20px; }

.detail-subhead {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 24px 0 4px;
}

.price-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
  margin: 14px 0 20px;
}

.product-desc-full {
  color: var(--text-muted);
  margin: 20px 0;
  line-height: 1.65;
}

.feature-list {
  list-style: none; padding: 0; margin: 20px 0 0;
  display: flex; flex-direction: column; gap: 8px;
}
.feature-list li {
  display: flex; align-items: center; gap: .6em;
  color: var(--text);
  font-size: .95rem;
}
.feature-list .icon { color: var(--success); }

/* Structured, categorized feature list (shop_game_features admin panel
   output) — replaces the plain .feature-list above when a game has one
   saved. Two-column on wide screens since these lists run long. */
.feature-groups {
  margin-top: 20px;
  columns: 2;
  column-gap: 28px;
}
.feature-group {
  break-inside: avoid;
  margin-bottom: 22px;
}
.feature-group-title {
  font-size: .95rem;
  font-weight: 700;
  color: var(--primary-2);
  margin: 0 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.feature-list--compact { margin-top: 0; gap: 5px; }
.feature-list--compact li {
  font-size: .875rem;
  color: var(--text-muted);
  gap: .5em;
}
.feature-list--compact .icon { color: var(--primary-2); width: .85em; height: .85em; }

/* Buy card */
.product-detail-side {
  display: flex; flex-direction: column; gap: 20px;
  position: sticky; top: 90px;
}
.buy-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-card);
  position: relative;
  overflow: hidden;
  transition: transform .4s cubic-bezier(.22,1,.36,1);
}
.buy-card-header { margin-bottom: 18px; }
.buy-badge {
  display: inline-flex; align-items: center; gap: .5em;
  padding: .35em .8em;
  border-radius: var(--radius-full);
  background: rgba(179, 45, 224, 0.1);
  color: var(--primary-2);
  border: 1px solid var(--border-soft);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.buy-card-title {
  font-size: 1.35rem;
  font-weight: 800;
  margin-bottom: 8px;
}

/* Verified chip */
.verified-chip {
  display: inline-flex; align-items: center; flex-wrap: wrap;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--radius-full);
  background: var(--success-soft);
  border: 1px solid rgba(34,197,94,.35);
  color: var(--success);
  font-size: .85rem;
  margin: 4px 0 16px;
  animation: popIn .35s cubic-bezier(.22,1,.36,1);
}
.verified-chip strong { color: var(--text); font-weight: 700; }
.verified-chip-sep { color: var(--text-dim); }
.verified-chip-form { margin: 0; }
.verified-chip-link { color: var(--text-muted); }
.verified-chip-link:hover { color: var(--text); }

/* Forms */
.buy-form { display: flex; flex-direction: column; gap: 14px; }
.form-row { display: flex; flex-direction: column; gap: 6px; }
.form-row label {
  font-size: .85rem;
  font-weight: 600;
  color: var(--text);
}
.form-row .req { color: var(--danger); }
.buy-form input[type="email"],
.buy-form input[type="text"] {
  background: rgba(255,255,255,.03);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  color: var(--text);
  font: inherit;
  transition: border-color var(--tr-fast), background var(--tr-fast);
}
.buy-form input:focus {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-color: var(--primary);
  background: rgba(255,255,255,.05);
}
.buy-form input::placeholder { color: var(--text-dim); }
.form-row--submit { margin-top: 6px; gap: 10px; }

.trust-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 24px;
}
.trust-panel-title {
  font-size: .8125rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text-muted);
  margin-bottom: 14px;
}

/* -----------------------------------------------------------
 * 10. Success / cancel status pages
 * ----------------------------------------------------------- */
/* <main> itself stays full-width (background reaches the viewport edges,
   matching .product-page above); the max-width/centering that used to come
   from combining .container directly on <main> now applies here instead,
   constraining just the inner content column. */
.success-page,
.cancel-page {
  padding: 60px 20px;
}
.success-page .container,
.cancel-page .container {
  max-width: 720px;
  padding: 0;
}

.status-card {
  padding: 32px;
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--border);
  text-align: center;
  margin-bottom: 24px;
}
.status-card h1 { font-size: 1.7rem; margin: 12px 0 10px; }
.status-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px;
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  font-size: 28px;
  margin: 0 auto;
}
.status-card--success .status-icon { color: var(--success); background: var(--success-soft); }
.status-card--warn    .status-icon { color: var(--warn);    background: var(--warn-soft); }
.status-card--error   .status-icon { color: var(--danger);  background: var(--danger-soft); }
.status-card--info    .status-icon { color: var(--primary-2); background: rgba(179,45,224,.12); }
.status-card--processing .status-icon { color: var(--primary-2); background: rgba(179,45,224,.12); }

.spinner { animation: spin 1.4s linear infinite; }

.license-box {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  margin: 20px 0;
}
.license-box label {
  display: block;
  font-size: .8125rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.license-key-row {
  display: flex; gap: 10px;
  flex-wrap: wrap;
}
.license-key-row input {
  flex: 1 1 260px;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  color: var(--text);
  font: 500 1rem var(--font-mono);
  letter-spacing: .02em;
}
.license-key-row input:focus { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Copy button icon morph: copy-icon and check-icon are stacked and
   crossfade/rotate into each other via .is-copied rather than swapping
   markup, so the transition is a CSS transition, not a DOM flash. */
.copy-icon-stack { position: relative; display: inline-flex; width: 1em; height: 1em; }
.copy-icon-stack .icon {
  position: absolute; inset: 0;
  transition: opacity .25s ease, transform .25s cubic-bezier(.34, 1.56, .64, 1);
}
.copy-icon-idle { opacity: 1; transform: scale(1) rotate(0deg); }
.copy-icon-done { opacity: 0; transform: scale(.5) rotate(-45deg); color: #22c55e; }
#license-copy-btn.is-copied .copy-icon-idle { opacity: 0; transform: scale(.5) rotate(45deg); }
#license-copy-btn.is-copied .copy-icon-done { opacity: 1; transform: scale(1) rotate(0deg); }

.next-steps {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  background: var(--card);
  margin: 20px 0;
}
.next-steps h2 { display: flex; align-items: center; gap: 10px; font-size: 1.2rem; margin-top: 0; }

.cancel-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 12px; }

/* -----------------------------------------------------------
 * 11. Animations
 * ----------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s cubic-bezier(.22,1,.36,1); }
.reveal.in-view { opacity: 1; transform: translateY(0); }

@keyframes scrollX {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes heroGlow {
  0%, 100% { opacity: .9; }
  50%      { opacity: .55; }
}
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes popIn {
  from { opacity: 0; transform: scale(.92); }
  to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  /* Large-scale / positional motion is suppressed here (vestibular safety —
     WCAG 2.3.3). Small decorative effects (text shimmer, dot pulse, button
     shine) are deliberately NOT in this list: they're subtle color/opacity
     changes on small elements, not the kind of motion reduced-motion users
     are opting out of, and suppressing every single animation on the site
     just because the OS-level toggle is on made the whole page look inert. */
  .chip-track,
  .ribbon-track,
  .hero-cue,
  .spinner,
  .site-header::before {
    animation: none !important;
  }
  /* Both marquees emit two identical cycles for a seamless scroll. In
     reduced-motion mode nothing animates, so the second cycle would show
     as a duplicate — hide it and let only the first cycle be visible. */
  .chip-track > [aria-hidden="true"],
  .ribbon-track > [aria-hidden="true"] { display: none !important; }
  /* The edge-fade mask on .chip-marquee exists to hide the scroll loop's
     seam — with the loop stopped (above), that seam no longer exists, but
     the mask was still cutting the first/last pill off mid-chip since they
     now sit statically right at the fade boundary. No scroll = no seam to
     hide, so drop the mask entirely here. */
  .chip-marquee {
    -webkit-mask-image: none;
            mask-image: none;
  }
  .hero::before { animation: none; opacity: .8; }
  .verified-chip { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  /* WCAG 2.3.3: dampen interaction-triggered motion. Keep border-color
     hover feedback but drop the lift transform and shadow shift. */
  .game-tile:hover,
  .product-card:hover {
    transform: none !important;
    box-shadow: none !important;
  }
  .game-tile-hint { opacity: 1; transform: none; transition: none; }
  * { scroll-behavior: auto !important; }
}

/* -----------------------------------------------------------
 * 12. Responsive
 * ----------------------------------------------------------- */
@media (max-width: 960px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
  .trust-grid { grid-template-columns: 1fr 1fr; }
  .product-detail-grid { grid-template-columns: 1fr; }
  .product-detail-side { position: static; }
}

@media (max-width: 640px) {
  .container { padding: 0 16px; }
  .feature-groups { columns: 1; }
  .hero-title { font-size: 2.1rem; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; justify-content: center; }
  .hero-pay { gap: 14px; }
  .pay-icon,
  .pay-icon svg { height: 24px; }
  .catalog-header { flex-direction: column; align-items: stretch; gap: 14px; }
  .catalog-header .currency-filter {
    justify-content: flex-start;
    flex-wrap: wrap;
    row-gap: 8px;
  }
  .currency-seg {
    display: flex;
    flex-wrap: nowrap;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .currency-seg-link {
    flex: 1 1 0;
    min-width: max-content;
    text-align: center;
  }
  .site-nav { gap: 8px; }
  .site-nav a:not(.btn) { font-size: .85rem; padding: 6px 2px; }
  .site-nav .btn-discord .icon { width: 1em; height: 1em; }
  .footer-grid { grid-template-columns: 1fr; gap: 28px; padding-bottom: 28px; }
  .footer-brand { grid-column: auto; }
  .footer-bar { flex-direction: column; align-items: flex-start; gap: 12px; }
  .trust-grid { grid-template-columns: 1fr; }
  .group-header { flex-direction: column; align-items: flex-start; gap: 4px; }
  .product-detail-main,
  .buy-card { padding: 22px; }
  .price-amount { font-size: 1.35rem; }
  .status-card { padding: 24px 20px; }
  /* Ribbon tiles fill the row on phones and each takes ~one card width. */
  .game-ribbon { -webkit-mask-image: none; mask-image: none; }
  .ribbon-track { gap: 12px; padding: 0 4px; flex-wrap: wrap; }
  .game-tile { flex: 1 1 calc(50% - 6px); width: calc(50% - 6px); height: auto; aspect-ratio: 16 / 9; }

  /* The 21:5 banner ratio is a thin, heavily-cropped strip at phone widths —
     ease it toward 16:9 so the game wordmark isn't zoomed/cut off, and tighten
     the card's padding so its content isn't visually narrower than the
     full-bleed banner above it (both boxes are the same outer width, but the
     22px inset made the card's content read as noticeably narrower). */
  .plan-banner { aspect-ratio: 16 / 8; min-height: 120px; }
  .plan-banner-inner { padding: 14px 16px; }
  .plan-card { padding: 16px; }
  .duration-tabs { gap: 6px; padding-bottom: 16px; margin-bottom: 16px; }
  .duration-tab { padding: .5em .85em; font-size: .8rem; }
}

@media (max-width: 480px) {
  .site-header { padding: 8px 0; }
  .wordmark { font-size: .95rem; }
  .brand-badge { width: 28px; height: 28px; font-size: 16px; }
  /* Collapse Discord button to icon-only on very narrow screens. */
  .site-nav .btn-discord span { display: none; }
  .site-nav .btn-discord { padding: .5em .6em; }
  /* Success-page copy card, license box, and buy card sit tight on the frame. */
  .success-page, .cancel-page { padding: 40px 12px; }
  .license-box, .next-steps { padding: 16px; }
  .license-key-row .btn { width: 100%; justify-content: center; }
  .license-key-row input { width: 100%; }
  /* No hover on touch devices — gallery/lightbox controls must stay visible. */
  .media-nav, .media-expand { opacity: 1; }
  .media-lightbox { padding: 20px 16px; gap: 10px; }
  .media-lightbox-nav { width: 40px; height: 40px; }
  .media-lightbox-nav--prev { left: 8px; }
  .media-lightbox-nav--next { right: 8px; }
  .media-lightbox-close { top: 10px; right: 10px; width: 38px; height: 38px; }
}

@media (max-width: 400px) {
  .hero-actions .btn { width: 100%; }
  /* One-per-row tiles at the smallest sizes so the game titles stay legible. */
  .game-tile { flex: 1 1 100%; width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .site-nav a:not(.btn) { display: none; }   /* fall back to icon-only nav here */
}
