/* Alpaca Arcade — neon arcade-cabinet theme. */
:root {
  --bg0: #07030f;
  --bg1: #120826;
  --panel: #160b2e;
  --panel2: #1e0f3a;
  --border: #3b1d6e;
  --text: #f3efff;
  --muted: #a793d6;
  --gold: #ffd23e;
  --pink: #ff2d95;
  --cyan: #22d3ee;
  --lime: #a3e635;
  --red: #ff4d5e;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  color: var(--text);
  font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  background:
    radial-gradient(1200px 500px at 50% -10%, rgba(255, 45, 149, 0.16), transparent 60%),
    radial-gradient(1000px 600px at 85% 110%, rgba(34, 211, 238, 0.12), transparent 60%),
    linear-gradient(var(--bg0), var(--bg1));
  min-height: 100vh;
}

/* ---------- Marquee header ---------- */
.arcade-header { text-align: center; padding: 2.2rem 1rem 1.4rem; }
.marquee {
  display: inline-block;
  background: linear-gradient(#241040, #150826);
  border: 3px solid var(--gold);
  border-radius: 18px;
  padding: 0.9rem 2.6rem 1.1rem;
  box-shadow: 0 0 24px rgba(255, 210, 62, 0.45), 0 0 70px rgba(255, 45, 149, 0.25), inset 0 0 30px rgba(0, 0, 0, 0.6);
}
.marquee h1 {
  margin: 0;
  font-size: clamp(1.8rem, 5vw, 3rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 0 6px var(--pink), 0 0 18px var(--pink), 0 0 42px var(--pink);
  animation: marqueeFlicker 4.5s infinite;
}
.marquee p { margin: 0.4rem 0 0; color: var(--muted); font-size: 0.9rem; letter-spacing: 0.06em; }
.bulbs { display: flex; justify-content: center; gap: 14px; margin: 0 0 0.7rem; }
.bulbs i {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 8px var(--gold), 0 0 16px var(--gold);
  animation: bulbChase 1.2s infinite;
}
.bulbs i:nth-child(even) { animation-delay: 0.6s; }
@keyframes bulbChase { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes marqueeFlicker {
  0%, 100% { opacity: 1; } 3% { opacity: 0.6; } 5% { opacity: 1; }
  52% { opacity: 1; } 53% { opacity: 0.7; } 54% { opacity: 1; }
}
.arcade-header.slim { display: flex; align-items: center; gap: 1rem; text-align: left; padding: 1rem 1.5rem; border-bottom: 2px solid var(--border); background: rgba(10, 4, 24, 0.7); }
.arcade-header.slim h1 { font-size: 1.25rem; margin: 0; letter-spacing: 0.08em; text-transform: uppercase; text-shadow: 0 0 10px var(--cyan), 0 0 26px var(--cyan); }
.arcade-header a { color: var(--gold); text-decoration: none; font-weight: 700; }
.arcade-header a:hover { text-shadow: 0 0 12px var(--gold); }
.arcade-error { color: var(--red); margin-top: 0.5rem; }
.tagline { color: var(--cyan); letter-spacing: 0.28em; font-size: 0.72rem; text-transform: uppercase; margin-top: 0.9rem; animation: pulseGlow 2.4s ease-in-out infinite; }
/* ---------- Header navigation (Players / My player card) ---------- */
.arcade-nav { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.7rem; margin-top: 1rem; }
.arcade-nav a {
  color: var(--cyan); text-decoration: none; font-weight: 700; letter-spacing: 0.06em;
  background: var(--panel); border: 2px solid var(--border); border-radius: 999px; padding: 0.42rem 1rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.arcade-nav a:hover { border-color: var(--cyan); box-shadow: 0 0 12px rgba(34, 211, 238, 0.5); }
.arcade-nav a[data-my-card] { color: var(--gold); }
.arcade-nav a[data-my-card]:hover { border-color: var(--gold); box-shadow: 0 0 12px rgba(255, 210, 63, 0.5); }
@keyframes pulseGlow { 0%, 100% { opacity: 0.65; } 50% { opacity: 1; text-shadow: 0 0 14px var(--cyan); } }

/* ---------- Game grid / cards ---------- */
.game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.3rem; padding: 1.5rem 1.5rem 3.5rem; max-width: 1220px; margin: 0 auto; }
.game-card {
  position: relative; display: block; overflow: hidden;
  background: linear-gradient(160deg, var(--panel2), var(--panel));
  border: 2px solid var(--border); border-radius: 14px; padding: 1.1rem 1.1rem 1rem;
  color: var(--text); text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.game-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
  background: linear-gradient(90deg, var(--pink), var(--gold), var(--cyan));
}
.game-card:hover { transform: translateY(-4px) scale(1.01); border-color: var(--pink); box-shadow: 0 0 18px rgba(255, 45, 149, 0.55), 0 10px 30px rgba(0, 0, 0, 0.5); }
.game-title { font-weight: 800; font-size: 1.15rem; letter-spacing: 0.04em; margin-bottom: 0.35rem; text-shadow: 0 0 12px rgba(34, 211, 238, 0.6); }
.game-stars { color: var(--gold); font-size: 1.15rem; font-weight: 800; text-shadow: 0 0 10px rgba(255, 210, 62, 0.8); }
.game-rating { margin: 0.25rem 0; font-size: 0.9rem; }
.game-meta { font-size: 0.78rem; color: var(--muted); margin-top: 0.35rem; }
.game-top { margin-top: 0.5rem; font-size: 0.88rem; font-weight: 700; color: var(--gold); }
.muted { color: var(--muted); }
.play-now {
  display: inline-block; margin-top: 0.7rem; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.14em;
  color: #0a0418; background: linear-gradient(90deg, var(--gold), #ff9d3e);
  border-radius: 999px; padding: 0.35rem 0.9rem;
  box-shadow: 0 0 12px rgba(255, 210, 62, 0.7);
}
.empty-cabinet { grid-column: 1 / -1; text-align: center; padding: 3rem 1rem; border: 2px dashed var(--border); border-radius: 14px; color: var(--muted); }

/* ---------- Category grouping & filters ---------- */
.arcade-filters { max-width: 1220px; margin: 0 auto; padding: 0 1.5rem; display: flex; flex-direction: column; gap: 0.8rem; }
.arcade-filters input#arcade-search {
  background: #120826; color: var(--text); border: 2px solid var(--border); border-radius: 12px;
  padding: 0.6rem 0.9rem; font-size: 0.95rem; width: 100%;
}
.arcade-filters input#arcade-search:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 10px rgba(34, 211, 238, 0.5); }
.category-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.category-chip {
  background: var(--panel); color: var(--muted); border: 2px solid var(--border); border-radius: 999px;
  padding: 0.35rem 0.85rem; font-size: 0.8rem; font-weight: 700; cursor: pointer; letter-spacing: 0.04em;
}
.category-chip:hover { border-color: var(--cyan); color: var(--text); }
.category-chip.is-active { background: linear-gradient(90deg, var(--pink), var(--cyan)); color: #0a0418; border-color: transparent; }
.game-category { max-width: 1220px; margin: 0 auto 1rem; padding: 0 1.5rem; }
.game-category-title {
  margin: 1.4rem 0 0.7rem; font-size: 1rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--cyan);
  text-shadow: 0 0 10px rgba(34, 211, 238, 0.6);
}
.game-category .game-grid { margin: 0; padding: 0; }
.game-tag {
  display: inline-block; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--lime); background: rgba(163, 230, 53, 0.12); border: 1px solid rgba(163, 230, 53, 0.4);
  padding: 0.1rem 0.5rem; border-radius: 6px; margin-bottom: 0.3rem;
}

/* ---------- Play layout / cabinet ---------- */
.play-layout { display: grid; grid-template-columns: 1fr 350px; gap: 1.2rem; padding: 1.2rem 1.5rem 3rem; max-width: 1420px; margin: 0 auto; align-items: start; }
@media (max-width: 1000px) { .play-layout { grid-template-columns: 1fr; } }
/* Grid-blowout guard: a collapsed 1fr track may only shrink if its items
allow it. Without this, wide content (game frames, code viewer) forces the
track to content width and the whole page overflows the viewport. */
.play-layout > * { min-width: 0; }
.cabinet {
  background: linear-gradient(#2a1150, #170a30);
  border: 3px solid var(--pink);
  border-radius: 20px;
  padding: 14px;
  box-shadow: 0 0 26px rgba(255, 45, 149, 0.5), inset 0 0 40px rgba(0, 0, 0, 0.55);
}
.cabinet-marquee {
  text-align: center; font-weight: 800; letter-spacing: 0.2em; text-transform: uppercase;
  color: #fff; font-size: 0.95rem; margin-bottom: 10px;
  text-shadow: 0 0 8px var(--cyan), 0 0 22px var(--cyan);
}
.screen { position: relative; border-radius: 12px; overflow: hidden; background: #000; line-height: 0; }
.screen iframe { width: 100%; height: 76vh; min-height: 480px; border: 0; background: #000; }
.cabinet-hint { margin: 0.6rem 0.2rem 0; font-size: 0.82rem; color: var(--arcade-muted, #b8a6e8); text-align: center; }
.cabinet-hint kbd { background: #1a1033; border: 1px solid #6d28d9; border-radius: 4px; padding: 0 0.35rem; font-family: inherit; }
.screen::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; line-height: normal;
  background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.045) 0 1px, transparent 1px 3px);
  box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.75);
}
.pane-block {
  background: linear-gradient(165deg, var(--panel2), var(--panel));
  border: 2px solid var(--border); border-radius: 14px; padding: 1rem; margin-bottom: 1rem;
}
.pane-block.neon-cyan { border-color: var(--cyan); box-shadow: 0 0 16px rgba(34, 211, 238, 0.35); }
.pane-block.neon-gold { border-color: var(--gold); box-shadow: 0 0 16px rgba(255, 210, 62, 0.3); }
.pane-block.neon-pink { border-color: var(--pink); box-shadow: 0 0 16px rgba(255, 45, 149, 0.35); }
.pane-block h3 { margin: 0 0 0.6rem; font-size: 0.95rem; letter-spacing: 0.1em; text-transform: uppercase; }
.pane-block.neon-cyan h3 { color: var(--cyan); text-shadow: 0 0 10px rgba(34, 211, 238, 0.8); }
.pane-block.neon-gold h3 { color: var(--gold); text-shadow: 0 0 10px rgba(255, 210, 62, 0.8); }
.pane-block.neon-pink h3 { color: var(--pink); text-shadow: 0 0 10px rgba(255, 45, 149, 0.8); }
.bench-stars { color: var(--gold); font-size: 1.5rem; font-weight: 800; margin-bottom: 0.5rem; text-shadow: 0 0 14px rgba(255, 210, 62, 0.9); }
.meta-list { list-style: none; padding: 0; margin: 0.4rem 0; font-size: 0.82rem; }
.meta-list li { margin: 0.2rem 0; word-break: break-word; }
details { font-size: 0.82rem; margin-top: 0.5rem; }
summary { cursor: pointer; color: var(--cyan); }
.prompt-box { white-space: pre-wrap; font-size: 0.72rem; max-height: 220px; overflow: auto; background: #090412; padding: 0.6rem; border-radius: 8px; border: 1px solid var(--border); }

/* ---------- Scoreboard ---------- */
.score-list { list-style: none; padding: 0; margin: 0.4rem 0; counter-reset: rank; }
.score-list li {
  counter-increment: rank; display: flex; align-items: center; gap: 0.6rem;
  padding: 0.35rem 0.5rem; font-size: 0.92rem; border-radius: 8px; margin-bottom: 0.25rem;
  background: rgba(255, 255, 255, 0.03); border: 1px solid transparent;
}
.score-list li::before {
  content: counter(rank); min-width: 1.5em; height: 1.5em; line-height: 1.5em; text-align: center;
  font-size: 0.75rem; font-weight: 800; border-radius: 6px;
  background: #2a1a4d; color: var(--muted);
}
.score-list li:nth-child(1) { border-color: var(--gold); background: rgba(255, 210, 62, 0.08); box-shadow: 0 0 12px rgba(255, 210, 62, 0.35); }
.score-list li:nth-child(1)::before { content: "🥇"; background: none; font-size: 1rem; }
.score-list li:nth-child(2)::before { content: "🥈"; background: none; font-size: 1rem; }
.score-list li:nth-child(3)::before { content: "🥉"; background: none; font-size: 1rem; }
.score-list li span { flex: 1; font-weight: 700; letter-spacing: 0.08em; }
.score-list li strong { color: var(--lime); font-variant-numeric: tabular-nums; text-shadow: 0 0 8px rgba(163, 230, 53, 0.6); }
.score-form { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.6rem; }
.score-form input { background: #0d0618; color: #fff; border: 1px solid var(--border); border-radius: 8px; padding: 0.45rem 0.55rem; font-size: 0.85rem; }
.score-form input:focus { outline: none; border-color: var(--cyan); box-shadow: 0 0 10px rgba(34, 211, 238, 0.5); }
#score-initials { width: 64px; text-transform: uppercase; }
#score-value { width: 110px; }
.arcade-btn {
  background: linear-gradient(#ff5fa8, #d61674); color: #fff; font-weight: 800; letter-spacing: 0.06em;
  border: 0; border-radius: 999px; padding: 0.5rem 1rem; cursor: pointer; font-size: 0.85rem;
  box-shadow: 0 4px 0 #7c0b40, 0 0 14px rgba(255, 45, 149, 0.6);
  transition: transform 0.06s ease, box-shadow 0.06s ease;
}
.arcade-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 #7c0b40; }
.arcade-btn.ghost { background: #241344; box-shadow: none; border: 1px solid var(--border); color: var(--text); font-weight: 600; }
.arcade-btn.ghost:hover { border-color: var(--cyan); color: var(--cyan); }
.candidates button { display: block; width: 100%; margin-top: 0.3rem; background: #0d0618; color: var(--text); border: 1px dashed var(--border); border-radius: 8px; padding: 0.35rem; cursor: pointer; font-size: 0.8rem; }
.candidates button:hover { border-color: var(--lime); color: var(--lime); }
.form-msg { font-size: 0.8rem; min-height: 1.2em; margin-top: 0.3rem; color: var(--lime); }
.rating-widget { font-size: 1.3rem; color: var(--gold); text-shadow: 0 0 12px rgba(255, 210, 62, 0.8); }
.rate-buttons { display: flex; gap: 0.3rem; margin-top: 0.4rem; }
.rate-buttons button { background: #241344; color: var(--muted); border: 1px solid var(--border); border-radius: 8px; padding: 0.35rem 0.6rem; cursor: pointer; font-size: 1rem; transition: transform 0.08s ease; }
.rate-buttons button:hover { transform: scale(1.2); color: var(--gold); border-color: var(--gold); }
.rate-buttons button.rated { color: var(--gold); border-color: var(--gold); box-shadow: 0 0 10px rgba(255, 210, 62, 0.5); }
.arcade-footer { text-align: center; color: var(--muted); font-size: 0.78rem; padding: 1.5rem; border-top: 2px solid var(--border); letter-spacing: 0.2em; text-transform: uppercase; }
.arcade-footer .coin { color: var(--gold); animation: pulseGlow 2s infinite; }

/* ---------- Cross-device polish ---------- */
::selection { background: var(--pink); color: #fff; }
a, button { -webkit-tap-highlight-color: transparent; }
button, .play-now, .game-card { touch-action: manipulation; }
a:focus-visible, button:focus-visible, input:focus-visible, summary:focus-visible {
  outline: 2px solid var(--cyan); outline-offset: 2px; border-radius: 6px;
}
.prompt-box::-webkit-scrollbar { width: 8px; }
.prompt-box::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

/* Twinkling starfield behind everything (desktop eye-candy, cheap). */
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    radial-gradient(1px 1px at 12% 22%, #fff, transparent),
    radial-gradient(1px 1px at 68% 8%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 84% 34%, var(--cyan), transparent),
    radial-gradient(1px 1px at 32% 62%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 52% 82%, var(--pink), transparent),
    radial-gradient(1px 1px at 6% 78%, #fff, transparent),
    radial-gradient(1px 1px at 92% 66%, var(--gold), transparent),
    radial-gradient(1px 1px at 44% 12%, #fff, transparent);
  animation: starTwinkle 5s ease-in-out infinite;
}
body > * { position: relative; z-index: 1; }
@keyframes starTwinkle { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }

/* Breathing glow on the marquee frame. */
.marquee { animation: marqueeGlow 3.2s ease-in-out infinite; }
@keyframes marqueeGlow {
  0%, 100% { box-shadow: 0 0 24px rgba(255, 210, 62, 0.45), 0 0 70px rgba(255, 45, 149, 0.25), inset 0 0 30px rgba(0, 0, 0, 0.6); }
  50% { box-shadow: 0 0 34px rgba(255, 210, 62, 0.7), 0 0 100px rgba(255, 45, 149, 0.4), inset 0 0 30px rgba(0, 0, 0, 0.6); }
}

/* Sticky score rail on wide screens. */
@media (min-width: 1001px) {
  .score-pane { position: sticky; top: 1rem; }
}
/* Modern viewport units so mobile browser chrome doesn't clip the screen. */
.screen iframe { height: 76vh; }
@supports (height: 1dvh) {
  .screen iframe { height: 76dvh; }
}

/* ---------- Mobile (award-worthy small screens) ---------- */
@media (max-width: 640px) {
  .arcade-header { padding: 1.2rem 0.75rem 1rem; }
  .marquee { padding: 0.7rem 1.1rem 0.9rem; border-radius: 14px; max-width: 100%; }
  .marquee h1 { letter-spacing: 0.06em; }
  .marquee p { font-size: 0.78rem; }
  .bulbs { gap: 8px; margin-bottom: 0.5rem; }
  .bulbs i { width: 8px; height: 8px; }
  .tagline { letter-spacing: 0.14em; font-size: 0.62rem; }
  .arcade-header.slim { flex-wrap: wrap; gap: 0.4rem 0.8rem; padding: 0.8rem 1rem; }
  .arcade-header.slim h1 {
    font-size: 1rem; flex: 1 1 100%; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
  }
  .game-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1rem; padding: 1rem 1rem 2.5rem; }
  .play-now { padding: 0.55rem 1.2rem; font-size: 0.85rem; }
  .play-layout { padding: 0.75rem 0.75rem 2rem; gap: 0.9rem; }
  .cabinet { padding: 8px; border-radius: 14px; }
  .cabinet-marquee { font-size: 0.75rem; letter-spacing: 0.12em; }
  .screen iframe { height: 62vh; min-height: 340px; }
  @supports (height: 1dvh) {
    .screen iframe { height: 62dvh; }
  }
  .pane-block { padding: 0.85rem; }
  .bench-stars { font-size: 1.25rem; }
  .score-form { gap: 0.5rem; }
  .score-form input { flex: 1 1 40%; min-height: 44px; font-size: 1rem; }
  #score-initials, #score-value { width: auto; }
  .arcade-btn { min-height: 44px; padding: 0.6rem 1.2rem; font-size: 0.9rem; }
  .score-form .arcade-btn { flex: 1 1 100%; }
  .rate-buttons { gap: 0.45rem; }
  .rate-buttons button { min-width: 48px; min-height: 48px; font-size: 1.25rem; }
  .rating-widget { font-size: 1.5rem; }
  .arcade-footer { font-size: 0.65rem; letter-spacing: 0.12em; }
}
@media (max-width: 400px) {
  .game-grid { grid-template-columns: 1fr; }
  .bulbs { gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  .marquee h1, .marquee, .bulbs i, .tagline, .arcade-footer .coin, body::before { animation: none; }
}

/* ---------- Family-hub embed ---------- */
/* The Jarvis Family hub opens a game in a full-screen modal. Give the game
   the whole viewport there: no site header, score rail, marquee or hints. */
body.arcade-embed .arcade-header,
body.arcade-embed .score-pane,
body.arcade-embed .cabinet-marquee,
body.arcade-embed .cabinet-hint,
body.arcade-embed .fs-toggle {
  display: none;
}
body.arcade-embed .play-layout {
  display: block;
  max-width: none;
  padding: 0;
}
body.arcade-embed .cabinet {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  height: 100dvh;
}
body.arcade-embed .screen,
body.arcade-embed .screen iframe {
  height: 100%;
  min-height: 0;
  border-radius: 0;
}

/* ---------- Player card ---------- */
.player-wrap { max-width: 1060px; margin: 0 auto; padding: 1.2rem 1.2rem 3rem; display: flex; flex-direction: column; gap: 1.4rem; }
.player-hero {
  text-align: center; padding: 2rem 1rem 1.6rem; border-radius: 18px;
  background: linear-gradient(160deg, #2b0a4e 0%, #3b0f63 45%, #0e2a5e 100%);
  border: 2px solid var(--neon-pink, #ff2fb3);
  box-shadow: 0 0 26px rgba(255, 47, 179, 0.45), inset 0 0 60px rgba(34, 211, 238, 0.12);
  position: relative; overflow: hidden;
}
.player-callsign {
  font-size: clamp(3rem, 10vw, 5.2rem); font-weight: 900; letter-spacing: 0.18em; line-height: 1;
  background: linear-gradient(180deg, #fff 20%, #ffd23f 55%, #ff2fb3 95%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 14px rgba(255, 210, 63, 0.65));
}
.player-title { font-size: 1.15rem; margin-top: 0.5rem; color: #fff; text-shadow: 0 0 12px var(--neon-cyan, #22d3ee); }
.player-unlock-count { margin-top: 0.3rem; color: var(--muted, #9aa4c7); font-size: 0.85rem; letter-spacing: 0.1em; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.8rem; }
.stat-card {
  background: rgba(10, 8, 30, 0.85); border: 1px solid var(--neon-cyan, #22d3ee); border-radius: 12px;
  padding: 0.9rem 0.5rem; text-align: center; box-shadow: 0 0 14px rgba(34, 211, 238, 0.25);
}
.stat-num { font-size: 1.7rem; font-weight: 800; color: #fff; text-shadow: 0 0 10px var(--neon-cyan, #22d3ee); }
.stat-label { font-size: 0.72rem; letter-spacing: 0.08em; color: var(--muted, #9aa4c7); margin-top: 0.25rem; }

/* ---------- Trophy room ---------- */
.trophy-room h2, .player-games h2 { color: #ffd23f; text-shadow: 0 0 14px rgba(255, 210, 63, 0.7); letter-spacing: 0.1em; }
.trophy-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0.8rem; }
.trophy {
  border-radius: 12px; padding: 1rem 0.7rem; text-align: center; background: rgba(10, 8, 30, 0.9);
  border: 1px solid #4a3a6e; transition: transform 0.15s ease;
}
.trophy.lit {
  border-color: #ffd23f; box-shadow: 0 0 18px rgba(255, 210, 63, 0.5), inset 0 0 24px rgba(255, 210, 63, 0.08);
  animation: trophy-glow 2.6s ease-in-out infinite;
}
@keyframes trophy-glow {
  0%, 100% { box-shadow: 0 0 12px rgba(255, 210, 63, 0.4), inset 0 0 24px rgba(255, 210, 63, 0.06); }
  50% { box-shadow: 0 0 24px rgba(255, 210, 63, 0.75), inset 0 0 30px rgba(255, 210, 63, 0.14); }
}
.trophy.dim { opacity: 0.55; }
.trophy.dim .trophy-icon { filter: grayscale(1) brightness(0.6); }
.trophy-icon { font-size: 2.2rem; line-height: 1.2; }
.trophy-name { font-weight: 800; color: #fff; margin-top: 0.3rem; }
.trophy-tag { font-size: 0.72rem; color: var(--muted, #9aa4c7); margin-top: 0.25rem; min-height: 2.1em; }
.trophy-unlocked { margin-top: 0.4rem; font-size: 0.68rem; font-weight: 800; letter-spacing: 0.2em; color: #ffd23f; }
.trophy-progress { margin-top: 0.5rem; height: 8px; border-radius: 99px; background: #221a3e; overflow: hidden; }
.trophy-progress i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--neon-cyan, #22d3ee), var(--neon-pink, #ff2fb3)); box-shadow: 0 0 8px var(--neon-cyan, #22d3ee); }
.trophy-progress-label { font-size: 0.68rem; color: var(--muted, #9aa4c7); margin-top: 0.2rem; }

/* ---------- Machine record table ---------- */
.record-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.record-table th, .record-table td { padding: 0.55rem 0.6rem; text-align: left; border-bottom: 1px solid #2c2350; }
.record-table th { color: #ffd23f; letter-spacing: 0.08em; font-size: 0.72rem; }
.record-table td a { color: var(--neon-cyan, #22d3ee); }
.record-table tr:hover td { background: rgba(34, 211, 238, 0.06); }
.record-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- Player directory / global standings ---------- */
.directory-intro { max-width: 720px; }
.page-heading { color: #ffd23f; text-shadow: 0 0 14px rgba(255, 210, 63, 0.7); letter-spacing: 0.1em; margin: 0 0 0.5rem; }
.intro-copy { font-size: 0.9rem; line-height: 1.5; margin: 0; }
.intro-copy em { color: var(--gold); font-style: normal; }
.segment { background: rgba(10, 8, 30, 0.75); border: 1px solid var(--border); border-radius: 14px; padding: 0.9rem; }
.players-table td:first-child,
.players-table th:first-child { width: 2.4em; text-align: right; color: var(--muted); }
.players-table td:nth-child(3) { font-variant-numeric: tabular-nums; }

/* ---------- Scoreboard player links ---------- */
.score-list a { color: var(--neon-cyan, #22d3ee); text-decoration: none; }
.score-list a:hover { text-shadow: 0 0 8px var(--neon-cyan, #22d3ee); }
#score-msg a { color: #ffd23f; font-weight: 700; }

/* ---------- Unlock toast + confetti ---------- */
.unlock-toast {
  position: fixed; left: 50%; bottom: 1.2rem; transform: translate(-50%, 140%);
  z-index: 9999; max-width: min(92vw, 480px); background: #150b2e;
  border: 2px solid #ffd23f; border-radius: 14px; padding: 0.9rem 1.2rem;
  box-shadow: 0 0 30px rgba(255, 210, 63, 0.65); transition: transform 0.45s cubic-bezier(0.2, 1.4, 0.4, 1);
}
.unlock-toast.show { transform: translate(-50%, 0); }
.unlock-title { font-weight: 900; letter-spacing: 0.18em; color: #ffd23f; font-size: 0.8rem; margin-bottom: 0.4rem; }
.unlock-item { color: #fff; font-size: 0.85rem; margin-top: 0.25rem; }
.confetti-canvas { position: fixed; inset: 0; z-index: 9998; pointer-events: none; }

/* Code-kind games (pygame / desktop apps): screenshot + source + download. */
.code-game { display: flex; flex-direction: column; gap: 0.7rem; padding: 0.8rem; }
/* .screen zeroes line-height for pixel-perfect game frames — restore readable
   text rhythm inside the code-game branch or every line paints over the last. */
.screen .code-game { line-height: 1.45; }
.code-screenshot { width: 100%; border-radius: 8px; border: 2px solid #22d3ee; box-shadow: 0 0 18px rgba(34, 211, 238, 0.45); }
.code-run-hint { color: #ffd23f; font-size: 0.82rem; text-align: center; }
.code-view {
  max-width: 100%; max-height: 46dvh; overflow: auto; text-align: left;
  background: #070b16; color: #c9f6ff; font: 0.72rem/1.5 ui-monospace, Menlo, Consolas, monospace;
  border: 1px solid #22d3ee; border-radius: 8px; padding: 0.7rem; margin: 0; white-space: pre;
}
/* Flex items default to min-width:auto, which lets wide code lines force
   the whole page wider than a phone viewport. */
.under-screen[open] > * { min-width: 0; }
/* Live sandbox stream fills the hero like the screenshot it replaces.
The remote desktop is 4:3, so aspect-ratio sizes the frame exactly to the
video — no measuring JS, no black gap, no overflow cutoff. */
#live-frame { width: 100%; height: auto; aspect-ratio: 4 / 3; min-height: 0; border: 0; border-radius: 8px; }
/* Fullscreen play: the game owns the screen, keys pinned at the bottom.
.Bar lives inside .screen so it stays visible in native fullscreen. */
.fs-toggle { margin: 0.5rem auto 0; display: block; font-size: 0.85rem; }
#play-overlay-bar { display: none; }
.screen:fullscreen,
.screen:-webkit-full-screen {
  width: 100%; height: 100%; border-radius: 0; padding: 0;
  display: flex; flex-direction: column; background: #000;
}
.screen:fullscreen .code-game,
.screen:-webkit-full-screen .code-game,
.screen.fallback-full .code-game {
  /* The live iframe is nested in .code-game, so the WRAPPER is the flex
  filler; the iframe fills the wrapper. (Targeting the iframe alone left
  it at height 0.) */
  display: flex; flex-direction: column; flex: 1 1 0; min-height: 0;
}
.screen:fullscreen iframe#game-frame,
.screen:-webkit-full-screen iframe#game-frame,
.screen:fullscreen iframe#live-frame,
.screen:-webkit-full-screen iframe#live-frame {
  /* Fill exactly the leftover column space: flex-basis 0 + ratio off so a
  wide landscape viewport can never push the frame past the screen bottom
  (aspect-ratio sizing is inline-view only). noVNC letterboxes inside. */
  flex: 1 1 0; aspect-ratio: auto; width: 100%; height: auto; min-height: 0; border-radius: 0;
}
.screen:fullscreen .cabinet-marquee,
.screen:-webkit-full-screen .cabinet-marquee,
.screen:fullscreen #btn-fullscreen,
.screen:-webkit-full-screen #btn-fullscreen,
.screen:fullscreen #code-hero,
.screen:-webkit-full-screen #code-hero,
.screen:fullscreen #btn-play-live,
.screen:-webkit-full-screen #btn-play-live,
.screen:fullscreen #live-status,
.screen:-webkit-full-screen #live-status,
.screen:fullscreen .under-screen,
.screen:-webkit-full-screen .under-screen {
  display: none;
}
.screen:fullscreen #play-overlay-bar,
.screen:-webkit-full-screen #play-overlay-bar {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  /* In-flow at the column bottom: the frame above flex-fills, so the bar
  always sits exactly at the screen bottom with no overlap or cutoff. */
  flex: 0 0 auto;
  padding: 0.5rem 0.5rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
  background: rgba(10, 4, 28, 0.95);
  border-top: 1px solid #6d28d9;
}
/* No element Fullscreen API (iPhone Safari): .fallback-full pins the
cabinet to the viewport with the same layout as native fullscreen. */
.screen.fallback-full {
  position: fixed; inset: 0; z-index: 60;
  width: 100%; height: 100%; border-radius: 0; padding: 0;
  display: flex; flex-direction: column; background: #000;
}
.screen.fallback-full iframe#game-frame,
.screen.fallback-full iframe#live-frame {
  flex: 1 1 0; aspect-ratio: auto; width: 100%; height: auto; min-height: 0; border-radius: 0;
}
.screen.fallback-full .cabinet-marquee,
.screen.fallback-full #btn-fullscreen,
.screen.fallback-full #code-hero,
.screen.fallback-full #btn-play-live,
.screen.fallback-full #live-status,
.screen.fallback-full .under-screen,
.screen.fallback-full .cabinet-hint {
  display: none;
}
.screen.fallback-full #play-overlay-bar {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  /* Same in-flow bottom bar as native fullscreen (see above). */
  flex: 0 0 auto;
  padding: 0.5rem 0.5rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
  background: rgba(10, 4, 28, 0.95);
  border-top: 1px solid #6d28d9;
}
#play-keys {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  flex: 1 1 auto; max-width: 560px; margin: 0 auto; width: 100%;
}
/* Thumb D-pad (left): cross layout, big touch targets, press-and-hold. */
#play-keys .pad-cluster,
#play-keys .wasd-cluster {
  display: grid; grid-template-columns: repeat(3, 60px); grid-template-rows: repeat(2, 56px);
  gap: 4px; touch-action: none;
}
#play-keys .pad-up { grid-column: 2; grid-row: 1; }
#play-keys .pad-left { grid-column: 1; grid-row: 2; }
#play-keys .pad-right { grid-column: 3; grid-row: 2; }
#play-keys .pad-down { grid-column: 2; grid-row: 2; }
/* Action buttons (right): big fire button + start/select. */
#play-keys .action-cluster { display: flex; align-items: center; gap: 0.6rem; touch-action: none; }
#play-keys .action-fire { min-width: 72px; min-height: 72px; font-size: 1.6rem; border-radius: 50%; }
#play-keys button {
  min-width: 56px; min-height: 56px;
  /* none (not manipulation): holding an arrow must not scroll/zoom the page,
  and press-and-hold movement needs uninterrupted pointer capture. */
  touch-action: none; user-select: none; -webkit-user-select: none;
  font-size: 1.25rem; border-radius: 14px; cursor: pointer;
  background: #1a1033; color: #fff; border: 1px solid #6d28d9;
}
#btn-keyboard, #btn-exit-full {
  min-width: 52px; min-height: 52px; touch-action: manipulation; flex: 0 0 auto;
  font-size: 1.25rem; border-radius: 12px; cursor: pointer;
  background: #1a1033; color: #fff; border: 1px solid #6d28d9;
}
#play-keys button:active, #btn-keyboard:active { background: #6d28d9; transform: scale(0.94); }
#btn-exit-full { border-color: #f43f5e; }
#btn-keyboard.on { background: #6d28d9; border-color: #a855f7; }
/* Focus proxy for ⌨: a real input (opens the device keyboard) that stays
invisible — 16px font so iOS doesn't zoom, pointer-events off so only
programmatic focus lands here. */
#kbd-proxy {
  position: fixed; bottom: 2px; left: 50%; width: 8px; height: 8px;
  opacity: 0.01; border: 0; padding: 0; font-size: 16px;
  pointer-events: none; background: transparent; color: transparent;
}
/* Narrow portrait phones: the full-size bar (~500px) overflows a 390px
viewport and pushes the D-pad off-screen. Two rows — sticks on top,
⌨/exit centered below — with smaller touch targets. */
@media (max-width: 480px) {
  .screen:fullscreen #play-overlay-bar,
  .screen:-webkit-full-screen #play-overlay-bar,
  .screen.fallback-full #play-overlay-bar {
    flex-wrap: wrap; justify-content: center; row-gap: 6px;
  }
  #play-keys { flex: 1 1 100%; max-width: 430px; }
  #play-keys .pad-cluster,
  #play-keys .wasd-cluster {
    grid-template-columns: repeat(3, 48px); grid-template-rows: repeat(2, 48px);
  }
  #play-keys button { min-width: 48px; min-height: 48px; font-size: 1.1rem; }
  #play-keys .action-fire { min-width: 62px; min-height: 62px; }
  #btn-keyboard, #btn-exit-full { min-width: 48px; min-height: 48px; }
}
/* Short landscape screens: compact single-row bar so the game keeps its
height — full-size two-row bar would eat a third of a 390px viewport. */
@media (max-height: 500px) {
  .screen:fullscreen #play-overlay-bar,
  .screen:-webkit-full-screen #play-overlay-bar,
  .screen.fallback-full #play-overlay-bar {
    flex-wrap: nowrap; padding: 0.3rem;
  }
  #play-keys { flex: 1 1 auto; max-width: none; }
  #play-keys .pad-cluster,
  #play-keys .wasd-cluster {
    grid-template-columns: repeat(3, 40px); grid-template-rows: repeat(2, 40px); gap: 2px;
  }
  #play-keys button { min-width: 40px; min-height: 40px; font-size: 1rem; border-radius: 10px; }
  #play-keys .action-fire { min-width: 54px; min-height: 54px; }
  #btn-keyboard, #btn-exit-full { min-width: 42px; min-height: 42px; }
}
.code-game .arcade-btn { align-self: center; }
/* Minimized under-screen info: code, download, prompt, benchmark facts. */
.under-screen {
  border: 1px solid #b537f2; border-radius: 10px; padding: 0.6rem 0.8rem;
  background: rgba(181, 55, 242, 0.07);
}
/* NOTE: never display:flex/grid directly on <details> — in Chrome that
   breaks native open/close hiding and the content bleeds through closed. */
.under-screen:not([open]) > :not(summary) { display: none; }
.under-screen[open] { display: flex; flex-direction: column; gap: 0.6rem; }
.under-screen > summary {
  cursor: pointer; text-align: center; font-weight: 700; color: #ffd23f;
  padding: 0.45rem; border-radius: 8px; list-style: none;
}
.under-screen > summary:hover { background: rgba(255, 210, 63, 0.12); }
.under-screen .meta-list { text-align: left; }
.under-screen details summary { cursor: pointer; color: #22d3ee; font-size: 0.85rem; }

@media (max-width: 640px) {
  .player-wrap { padding: 0.9rem 0.75rem 2.2rem; }
  .stat-grid { grid-template-columns: minmax(0, 1fr); gap: 0.55rem; }
  .stat-card, .trophy { min-width: 0; overflow-wrap: anywhere; }
  .stat-num { font-size: 1.3rem; }
  .trophy-grid { grid-template-columns: minmax(0, 1fr); gap: 0.6rem; }
  .record-table { font-size: 0.76rem; min-width: 540px; }
  .record-table th, .record-table td { padding: 0.45rem 0.35rem; }
  #live-frame { height: auto; aspect-ratio: 4 / 3; min-height: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .trophy.lit { animation: none; }
  .unlock-toast { transition: none; }
}
