/* ============================================================================
   Playit — the ARCADE KIT: the design system's foundation, and the ONE file both
   halves of the product share.

   Everything in here is used in TWO places that are different documents:
     • every site page — base.html links it before global.css, and
     • every played GAME — the play frame is a sandboxed, opaque-origin iframe with
       its own document, so it can never inherit the site's CSS. The BFF injects
       this file into each served game page (routes/ide/routes.py), which is what
       lets a game's start screen and its score board use the very same fonts,
       colours and buttons as the rest of the app instead of look-alikes.

   So this file holds only what BOTH need: the self-hosted pixel fonts, the colour
   tokens, and the .btn system. Page scaffold, header, background sprites and the
   rest stay in global.css. If you add a token or a button variant, it goes HERE.
   ============================================================================ */

/* ---- Self-hosted fonts (no external calls; keeps the strict CSP clean) ---- */
@font-face {
  font-family: 'Press Start 2P';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/vendors/fonts/press-start-2p-400.woff2') format('woff2');
}
@font-face {
  font-family: 'VT323';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/vendors/fonts/vt323-400.woff2') format('woff2');
}

/* ---- Design tokens: the single source of truth for the theme ---- */
:root {
  /* surfaces (dark, from back to front) */
  --color-ink: #0b0a24;
  --color-bg-top: #241a52;
  --color-panel: #100e2c;
  --color-panel-2: #161636;
  --color-panel-raised: #12102f;
  --color-well: #0a0920;        /* inset wells, darker than any panel */
  --color-line: #34316e;
  --color-line-2: #4a468f;
  --color-disabled-bg: #20204a;

  /* text (bright to faint) */
  --color-text: #f3f1ff;
  --color-text-dim: #cfc9ff;
  --color-muted: #9b95d8;
  --color-muted-2: #7d78b8;
  --color-faint: #6f6ab0;

  /* accents — each has a matching darker "shadow" for the chunky 3D edge */
  --color-pink: #ff3d9a;
  --color-pink-light: #ff8ac0;
  --color-pink-shadow: #b81e63;
  --color-green: #3ef08b;
  --color-green-shadow: #1a9c56;
  --color-cyan: #24e5ff;
  --color-cyan-shadow: #0f9bb3;
  --color-gold: #ffd23f;
  --color-gold-shadow: #b8860b;
  --color-title-yellow: #ffe35a;
  /* the podium: 2nd and 3rd place beside --color-gold (the gallery's ranks and Hall of Fame) */
  --color-silver: #dfe3ff;
  --color-bronze: #ff9d5c;
  --color-deep-pink: #c01f6d;
  --color-shadow-ink: #7a1145;
  /* white social button (e.g. LOGIN WITH GMAIL) + its grey ledge */
  --color-white: #ffffff;
  --color-white-shadow: #b9b9c4;

  /* translucent helpers (glows, grid, glass header) */
  --glow-pink: rgba(255, 61, 154, .22);
  --glow-cyan: rgba(36, 229, 255, .18);
  --grid-line: rgba(94, 84, 196, .10);
  --header-glass: rgba(15, 14, 44, .72);
  --drop-soft: rgba(0, 0, 0, .4);

  /* fonts */
  --font-display: 'Press Start 2P', monospace;
  --font-body: 'VT323', monospace;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--color-ink);
  background: var(--color-panel-raised);
  border: 3px solid var(--color-ink);
  --btn-shadow-color: var(--drop-soft);
  box-shadow: 0 4px 0 var(--btn-shadow-color);
  padding: 9px 12px;
  white-space: nowrap;
  transition: transform .1s, box-shadow .1s;
}
.btn:hover  { transform: translateY(-2px); box-shadow: 0 8px 0 var(--btn-shadow-color); }
.btn:active { transform: translateY(2px);  box-shadow: 0 2px 0 var(--btn-shadow-color); }

/* Colour variants: bright fill + the matching darker ledge colour. */
.btn-cyan  { background: var(--color-cyan);  --btn-shadow-color: var(--color-cyan-shadow); }
.btn-green { background: var(--color-green); --btn-shadow-color: var(--color-green-shadow); }
.btn-pink  { background: var(--color-pink);  --btn-shadow-color: var(--color-pink-shadow); }
.btn-gold  { background: var(--color-gold);  --btn-shadow-color: var(--color-gold-shadow); }

/* White variant — a light social-auth button (e.g. LOGIN WITH GMAIL). Keeps the
   ink text + border from the base and the shared lift; only the fill + ledge
   colour change, so it lifts on hover like every other button. */
.btn-white { background: var(--color-white); --btn-shadow-color: var(--color-white-shadow); }

/* Ghost / outline variant (transparent, light text) — e.g. REGISTER. Uses the
   default soft ledge colour, so it lifts on hover just like the rest. */
.btn-ghost {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-line-2);
}
.btn-ghost:hover { border-color: var(--color-muted); }

/* Small variant — a compact call to action (e.g. wizard Back / NEXT, SEND). */
.btn-sm { font-size: 13px; padding: 14px 22px; box-shadow: 0 6px 0 var(--btn-shadow-color); }
.btn-sm:hover  { transform: translateY(-2px); box-shadow: 0 10px 0 var(--btn-shadow-color); }
.btn-sm:active { transform: translateY(4px);  box-shadow: 0 2px 0 var(--btn-shadow-color); }

/* Medium variant — a mid-sized call to action (e.g. GENERATE MY GAME). Bigger
   than the base, smaller than the hero; same lift animation via the variable. */
.btn-md { font-size: 15px; padding: 18px 26px; box-shadow: 0 7px 0 var(--btn-shadow-color); }
.btn-md:hover  { transform: translateY(-2px); box-shadow: 0 11px 0 var(--btn-shadow-color); }
.btn-md:active { transform: translateY(6px);  box-shadow: 0 2px 0 var(--btn-shadow-color); }

/* Large variant — a hero-sized call to action (e.g. CREATE YOUR GAME). Same lift
   animation, just a bigger ledge to match its size. */
.btn-lg { font-size: 18px; padding: 20px 40px; box-shadow: 0 6px 0 var(--btn-shadow-color); }
.btn-lg:hover  { transform: translateY(-2px); box-shadow: 0 10px 0 var(--btn-shadow-color); }
.btn-lg:active { transform: translateY(6px);  box-shadow: 0 2px 0 var(--btn-shadow-color); }

/* Width modifier — stretch a button to fill its row (e.g. GENERATE MY GAME). */
.btn-full { width: 100%; }

/* Disabled state — a flat, muted, un-clickable button (e.g. GENERATE before the
   user has typed an idea). It never lifts or sinks. */
.btn:disabled {
  cursor: not-allowed;
  color: var(--color-faint);
  background: var(--color-disabled-bg);
  border-color: var(--color-line);
  box-shadow: none;
  opacity: .6;
}
.btn:disabled:hover,
.btn:disabled:active {
  transform: none;
  box-shadow: none;
}

/* Arcade "ready!" bounce (an opt-in modifier, in the same .btn-<name> family as
   the colour variants). A primary button hops in place to invite the tap the
   moment it becomes actionable — CREATE YOUR GAME on the landing (always), and
   GENERATE / NEXT once the user has done the thing that unlocks them. Add
   `.btn-animate` to switch it on. The hop stops the instant the user hovers or
   presses (so the normal lift/sink takes over) and never runs on a disabled
   button. Like the colour variants, this modifier adds ONE thing: the animation. */
.btn-animate { animation: btn-bounce 1.4s ease-in-out infinite; }
.btn-animate:hover,
.btn-animate:active,
.btn-animate:disabled { animation: none; }
/* The hop: a quick double bounce, then a rest before it repeats — the classic
   "press me" attract loop, not a constant jiggle. The ledge (box-shadow) rides
   along with it, so the whole chunky button appears to hop. */
@keyframes btn-bounce {
  0%, 55%, 100% { transform: translateY(0); }
  15% { transform: translateY(-9px); }
  30% { transform: translateY(0); }
  42% { transform: translateY(-4px); }
}

/* ---- The arcade loader: four app-colour boxes pulsing in a staggered arcade wave — what a busy
   button shows (the busy state below puts it there), and the site's "working" mark elsewhere (the
   review step's cover boot, a building game's rail tile). The ink border makes every box read —
   even the pink one on a pink button. ---- */
.btn-loader { display: inline-flex; align-items: center; gap: 6px; }
.btn-loader i {
  width: 12px;
  height: 12px;
  display: block;
  border: 2px solid var(--color-ink);
  animation: btn-box-pulse .9s ease-in-out infinite;
}
.btn-loader i:nth-child(1) { background: var(--color-pink);  animation-delay: 0s; }
.btn-loader i:nth-child(2) { background: var(--color-green); animation-delay: .12s; }
.btn-loader i:nth-child(3) { background: var(--color-cyan);  animation-delay: .24s; }
.btn-loader i:nth-child(4) { background: var(--color-gold);  animation-delay: .36s; }
/* Each box shrinks + dims, then pops to full size + brightness — the arcade "loading" flicker. */
@keyframes btn-box-pulse {
  0%, 100% { transform: scale(.5); opacity: .4; }
  50%      { transform: scale(1);  opacity: 1; }
}
/* Motion-sensitive users: hold the four boxes lit, no pulse. */
@media (prefers-reduced-motion: reduce) {
  .btn-loader i { animation: none; opacity: 1; transform: none; }
}

/* ---- BUSY state — any button waiting on the server (busy_button.js setBusy): switched off (the
   pointer here; keys and submits by busy_button.js's guard), its label hidden at the same size so
   nothing moves, and the four-box loader centred over it, in the button's own colours — it is
   working, not unavailable. Works on every button (the kit's .btn, icon chips, card buttons) and
   on link buttons. ---- */
.btn-busy {
  cursor: progress;
  pointer-events: none;
  color: transparent !important;
}
.btn-busy > :not(.btn-busy-layer) { visibility: hidden; }
.btn-busy:hover,
.btn-busy:active { transform: none; }
/* the anchor for the loader, only on a button that isn't positioned already */
.btn-busy-anchor { position: relative; }
.btn-busy-layer {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* the compact loader for a small button (under 96px wide): 22px across, so it fits inside the
   smallest ones (the asset cards' 30px icon buttons) */
.btn-busy-small .btn-loader { gap: 2px; }
.btn-busy-small .btn-loader i { width: 4px; height: 4px; border-width: 1px; }

/* Keyboard focus — a bright ring on the one component every screen is built from.
   Lives with the buttons so it can never be forgotten when a variant is added.
   :focus-visible (not :focus) so a mouse press doesn't leave a ring behind. */
.btn:focus-visible {
  outline: 3px solid var(--color-cyan);
  outline-offset: 3px;
}

/* Motion-sensitive users: buttons keep their look and their ledge, they just stop
   moving. The hover/press feedback is still there in the shadow, so nothing
   becomes unclear — it only stops animating. */
@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:hover, .btn:active { transform: none; }
  .btn-animate { animation: none; }
}

/* Phone: the hero button steps down so CREATE YOUR GAME never wraps or crowds its row.
   Lives with the buttons (it moved here with them from global.css). */
@media (max-width: 560px) {
  .btn-lg { font-size: 15px; padding: 16px 26px; }
}
