/* ==========================================================================
   Shamaz — design tokens
   Re-skinned to match the surya.place desktop theme: same pastel
   sky-gradient backdrop, window chrome (light panels, #8f8f9a borders,
   drop shadows), Tahoma/Segoe UI type, and the site's blue-for-interaction
   / peach-for-brand accent split. Vinyl/K-pop motif kept only where it's
   game-functional (seek bar, play button, confetti) — everything else now
   reads as one more window on the desktop.
   ========================================================================== */

:root {
  color-scheme: light;

  --bg: #eef1f6;
  --bg-elevated: #f4f2f0;
  --bg-inset: #eceaf2;
  --border: #8f8f9a;
  --border-soft: #c7c5d0;

  /* Warm "brand" accent — the site's titlebar-peach / folder-peach family. */
  --gold: #e5934a;
  --gold-dim: #d9903c;
  --gold-soft: rgba(229, 147, 74, 0.16);

  /* Cool "interactive" accent — the site's hover/selection/focus blue. */
  --accent-blue: #6f9ce8;
  --accent-blue-dim: #4a78d6;
  --accent-blue-soft: rgba(111, 156, 232, 0.22);

  --ink: #3a3a4a;
  --ink-muted: #83839a;

  --good: #4caf7d;
  --good-soft: rgba(76, 175, 125, 0.14);
  --bad: #e2636f;
  --bad-soft: rgba(226, 99, 111, 0.14);

  --ring-track: #e4e2e0;

  /* Surfaces that were hardcoded to white/grey — themed so dark mode can
     re-key them alongside everything else. */
  --input-bg: #fff;
  --btn-ghost-start: #ffffff;
  --btn-ghost-end: #dfe3ec;
  --btn-ghost-border: #9aa0b0;
  --btn-ghost-hover-end: #ffd3e6;
  --btn-ghost-hover-border: #e284ac;

  --bg-gradient: linear-gradient(135deg, #a9c9ec 0%, #f5c6d8 40%, #f7cf9e 100%);

  --font-display: 'Tahoma', 'Segoe UI', Verdana, sans-serif;
  --font-body: 'Tahoma', 'Segoe UI', Verdana, sans-serif;
  --font-mono: 'Courier New', monospace;

  --radius-lg: 6px;
  --radius-md: 4px;
  --radius-pill: 999px;

  --shadow-window: 4px 6px 18px rgba(0, 0, 0, 0.25);
  --shadow-window-soft: 2px 3px 10px rgba(0, 0, 0, 0.18);
}

/* ---- Dark mode ------------------------------------------------------------
   Same token set, re-keyed for a dark desktop. Applies when the toggle sets
   data-theme explicitly, or — with no explicit choice — when the OS is set
   to dark (":not([data-theme=\"light\"])" keeps an explicit "light" choice
   from being overridden by the system preference). The two blocks below
   intentionally duplicate the same values rather than nesting the media
   query, to keep the CSS parseable without relying on native nesting. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg: #1c1d26;
    --bg-elevated: #262732;
    --bg-inset: #20212c;
    --border: #4a4b5c;
    --border-soft: #383a4a;

    --gold: #e5934a;
    --gold-dim: #f0a868;
    --gold-soft: rgba(229, 147, 74, 0.22);

    --accent-blue: #7fa8f0;
    --accent-blue-dim: #a8c4f5;
    --accent-blue-soft: rgba(127, 168, 240, 0.24);

    --ink: #e6e6ee;
    --ink-muted: #9797ad;

    --good: #6fd0a0;
    --good-soft: rgba(111, 208, 160, 0.18);
    --bad: #f0838d;
    --bad-soft: rgba(240, 131, 141, 0.18);

    --ring-track: #333442;

    --input-bg: #2b2c38;
    --btn-ghost-start: #3a3b48;
    --btn-ghost-end: #2a2b36;
    --btn-ghost-border: #52546a;
    --btn-ghost-hover-end: #4a2e3c;
    --btn-ghost-hover-border: #e284ac;

    --bg-gradient: linear-gradient(135deg, #1c2436 0%, #2c1f2e 40%, #2e2418 100%);

    --shadow-window: 4px 6px 18px rgba(0, 0, 0, 0.55);
    --shadow-window-soft: 2px 3px 10px rgba(0, 0, 0, 0.4);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #1c1d26;
  --bg-elevated: #262732;
  --bg-inset: #20212c;
  --border: #4a4b5c;
  --border-soft: #383a4a;

  --gold: #e5934a;
  --gold-dim: #f0a868;
  --gold-soft: rgba(229, 147, 74, 0.22);

  --accent-blue: #7fa8f0;
  --accent-blue-dim: #a8c4f5;
  --accent-blue-soft: rgba(127, 168, 240, 0.24);

  --ink: #e6e6ee;
  --ink-muted: #9797ad;

  --good: #6fd0a0;
  --good-soft: rgba(111, 208, 160, 0.18);
  --bad: #f0838d;
  --bad-soft: rgba(240, 131, 141, 0.18);

  --ring-track: #333442;

  --input-bg: #2b2c38;
  --btn-ghost-start: #3a3b48;
  --btn-ghost-end: #2a2b36;
  --btn-ghost-border: #52546a;
  --btn-ghost-hover-end: #4a2e3c;
  --btn-ghost-hover-border: #e284ac;

  --bg-gradient: linear-gradient(135deg, #1c2436 0%, #2c1f2e 40%, #2e2418 100%);

  --shadow-window: 4px 6px 18px rgba(0, 0, 0, 0.55);
  --shadow-window-soft: 2px 3px 10px rgba(0, 0, 0, 0.4);
}

.user-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  object-fit: cover;
  vertical-align: middle;
  display: inline-block;
  margin-right: 6px;
  background-color: var(--bg-inset);
  border: 1px solid var(--border);
}
.user-avatar-fallback {
  display: inline-block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 6px;
  background-color: var(--bg-inset);
  border: 1px solid var(--border);
}

* {
  box-sizing: border-box;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

html, body {
  margin: 0;
  padding: 0;
}

/* Same diagonal pastel sky + drift animation as the desktop's root
   stylesheet (assets/css/style.css), so a Shamaz tab feels like part of
   the same desktop rather than a separate site. */
body {
  background: var(--bg-gradient);
  background-size: 200% 200%;
  animation: driftBg 22s ease-in-out infinite;
  color: var(--ink);
  font-family: var(--font-body);
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  padding: 2rem 1rem 16rem;
  -webkit-font-smoothing: antialiased;
}

/* The `hidden` attribute is how JS toggles elements off (e.g. the locked-out
   daily view hiding the song chip / points indicator / seek bar). Several
   components below (`.topbar-chip`, `.points-indicator`, `.seek-bar`) set an
   explicit `display` unconditionally, which — same specificity, later origin
   — wins over the UA's `[hidden] { display: none }` default and leaves the
   element visible. Force it back so `el.hidden = true` always actually hides. */
[hidden] {
  display: none !important;
}

/* Hide scrollbar but keep functionality */
html, body {
  -ms-overflow-style: none;  /* IE and Edge */
  scrollbar-width: none;  /* Firefox */
}
html::-webkit-scrollbar, body::-webkit-scrollbar {
  display: none;
}

@keyframes driftBg {
  0%, 100% { background-position: 0% 0%; }
  50% { background-position: 100% 60%; }
}

.page {
  width: 100%;
  max-width: 440px;
}

/* ---- Top bar: home + volume ------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.25rem;
  font-size: 0.9rem;
}

.topbar a {
  color: var(--ink-muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: color 0.15s ease;
}

.topbar a:hover,
.topbar a:focus-visible {
  color: var(--accent-blue-dim);
}

/* ---- Card shell (styled like a desktop window) -------------------------- */

.card {
  position: relative;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.5rem 2rem;
  box-shadow: var(--shadow-window);
}

/* A thin "titlebar" strip standing in for real window chrome, using the
   same three-hue gradient as the desktop background. */
.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: linear-gradient(90deg, #6f9ce8, #ee9fc0 50%, #f3b871);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-dim);
  margin: 0 0 0.4rem;
}

h1 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  font-size: clamp(1.9rem, 6vw, 2.4rem);
  line-height: 1;
  margin: 0 0 0.5rem;
  color: var(--ink);
}

.subtitle {
  color: var(--ink-muted);
  font-size: 0.95rem;
  margin: 0 0 1.5rem;
}

/* ---- Seek-bar stage indicator -------------------------------------------
   Each stage is a segment sized proportionally to that stage's actual
   snippet duration (a 16s stage is visually ~16x wider than a 1s stage), so
   the bar reads as a real timeline of cumulative snippet length. The active
   stage's fill sweeps left-to-right over its real playback duration, like a
   video seek bar's progress indicator; passed stages sit fully filled. */

.stage-bar,
.seek-bar {
  display: flex;
  gap: 6px;
  margin: 0 0 1.5rem;
}

.seek-segment {
  height: 10px;
  min-width: 6px;
  border-radius: var(--radius-pill);
  background: var(--ring-track);
  overflow: hidden;
  transition: box-shadow 0.25s ease, background 0.25s ease;
}

/* The stage you're currently positioned on (fresh load, or just after
   Skip) — a visibly different shade from both "already passed" (full
   gold fill) and "not reached yet" (plain dark track), so Skip has an
   obvious, immediate effect. */
.seek-segment.is-current {
  background: var(--gold-soft);
  box-shadow: 0 0 0 1px var(--gold-dim) inset;
}

.seek-fill {
  height: 100%;
  width: 0%;
  background: var(--gold);
  box-shadow: 0 0 12px rgba(229, 147, 74, 0.55);
  border-radius: var(--radius-pill);
}

/* ---- Points-available indicator -----------------------------------------
   Mirrors Scoring::STAGE_POINTS client-side: a number plus a shrinking bar
   that ticks down every time the player advances to the next clue, so the
   cost of "one more clue" is visible before they ask for it. */

.points-indicator {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: -0.75rem 0 1.25rem;
}

.points-indicator-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
}

.points-indicator-track {
  flex: 1;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--ring-track);
  overflow: hidden;
}

.points-indicator-fill {
  height: 100%;
  width: 100%;
  background: var(--indicator-color, var(--gold));
  border-radius: var(--radius-pill);
  /* The width change itself is the "shrinking bar" — animate it so a stage
     advance visibly sweeps down instead of jump-cutting. */
  transition: width 0.5s ease, background-color 0.5s ease;
}

.points-indicator-value {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--indicator-color, var(--gold));
  min-width: 3ch;
  text-align: right;
  transition: color 0.5s ease;
}

/* Toggled briefly on every update() call so even a same-value refresh
   (e.g. re-rendering the current stage) still reads as a change. */
.points-indicator.did-update .points-indicator-value {
  animation: points-value-pulse 0.45s ease;
}

@keyframes points-value-pulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.25); color: var(--ink); }
  100% { transform: scale(1); }
}

/* ---- The record: signature play button ---------------------------------
   A circular button sits like a record label. While idle it holds a slow
   ambient glow pulse; while a snippet is actually playing (.is-playing)
   a dashed ring spins around it like a turntable in motion. */

.player-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  margin: 0.5rem 0 1.75rem;
}

.play-btn {
  position: relative;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  border: 2px solid var(--gold-dim);
  background: radial-gradient(circle at 35% 30%, #ffd9ad, var(--gold) 60%);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 0 0 0 rgba(229, 147, 74, 0.5);
  animation: pulse-glow 2.6s ease-in-out infinite;
}

/* An inline SVG triangle rather than the ▶ glyph it replaces — glyph
   vertical metrics vary across fonts/platforms and made the icon look
   vertically squashed or off-center on some displays. Fixed pixel sizing
   here renders identically everywhere. The 3px left margin re-centers the
   triangle's visual weight (a right-pointing shape sits left-heavy in a
   perfectly centered box). */
.play-btn svg {
  display: block;
  width: 30px;
  height: 30px;
  margin-left: 3px;
}

/* The host's vinyl-note glyph (multiplayer-host.html) isn't an SVG icon
   like the play button — keep it centered on its own font metrics. */
#host-vinyl.play-btn {
  font-size: 1.6rem;
}

.play-btn::before {
  content: '';
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  border: 2px dashed var(--accent-blue-dim);
  opacity: 0;
  animation: none;
}

.play-btn.is-playing::before {
  opacity: 0.7;
  animation: spin 3s linear infinite;
}

.play-btn:active {
  transform: scale(0.96);
}

@keyframes pulse-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229, 147, 74, 0.35); }
  50% { box-shadow: 0 0 0 14px rgba(229, 147, 74, 0); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.topbar-chip {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink);
  letter-spacing: 0.04em;
  background: var(--bg-inset);
  border: 1px solid var(--border-soft);
  padding: 0.3rem 0.9rem;
  border-radius: var(--radius-pill);
  transition: transform 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}

/* Toggled briefly whenever the chip's text actually changes, so a change
   that reads identically to the previous state (e.g. streak going 0 -> 0)
   doesn't look frozen. */
.topbar-chip.did-update {
  animation: chip-pulse 0.45s ease;
}

@keyframes chip-pulse {
  0% { transform: scale(1); background: var(--bg-inset); border-color: var(--border-soft); }
  40% { transform: scale(1.14); background: var(--gold-soft); border-color: var(--gold-dim); }
  100% { transform: scale(1); background: var(--bg-inset); border-color: var(--border-soft); }
}

/* ---- Volume ------------------------------------------------------------ */

.volume-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink-muted);
  font-size: 0.8rem;
  margin: 0 0 1.25rem;
}

.volume-row input[type="range"] {
  flex: 1;
  accent-color: var(--accent-blue);
}

/* ---- Inputs & buttons ---------------------------------------------------- */

input[type="text"] {
  width: 100%;
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-soft);
  background: var(--input-bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  margin-bottom: 0.75rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input[type="text"]:focus-visible {
  outline: none;
  border-color: var(--accent-blue);
  box-shadow: 0 0 0 2px var(--accent-blue-soft);
}

input[type="text"]::placeholder {
  color: var(--ink-muted);
}

/* ---- Autocomplete -------------------------------------------------------- */

.autocomplete-wrap {
  position: relative;
}

.autocomplete-wrap input[type="text"] {
  padding-right: 8rem;
}

.input-actions {
  position: absolute;
  top: 0;
  right: 0.5rem;
  height: calc(100% - 0.75rem);
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.guess-btn-inline {
  padding: 0.55rem 1rem;
}

.clear-btn-inline {
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-muted);
  border: none;
  font-size: 1.2rem;
  line-height: 1;
}

.clear-btn-inline:hover:not(:disabled) {
  color: var(--ink);
  background: var(--bg-inset);
}

.autocomplete-dropdown {
  position: absolute;
  top: calc(100% - 0.75rem + 2px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-window);
  max-height: 260px;
  overflow-y: auto;
}

.autocomplete-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
  font-size: 0.92rem;
}

.autocomplete-item:hover,
.autocomplete-item.is-active {
  background: var(--accent-blue-soft);
}

.autocomplete-thumb {
  width: 36px;
  height: 36px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-inset);
}

.autocomplete-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.autocomplete-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.autocomplete-item .autocomplete-artist {
  color: var(--ink-muted);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Reveal card (correct guess / failed reveal) ------------------------ */

.reveal-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.25rem;
  padding: 0.85rem;
  background: var(--bg-inset);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
}

/* A stack of reveal-cards (e.g. Daily Challenge's history of past songs),
   as opposed to a single-slot reveal-card. */
.reveal-history {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1.25rem;
}

.reveal-history .reveal-card {
  margin-top: 0;
}

.reveal-card.is-correct {
  border-color: rgba(76, 175, 125, 0.4);
}

.reveal-card.is-wrong {
  border-color: rgba(226, 99, 111, 0.4);
}

.reveal-cover {
  width: 64px;
  height: 64px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--bg-elevated);
}

.reveal-info {
  min-width: 0;
}

.reveal-status {
  margin: 0 0 0.15rem;
  font-size: 0.78rem;
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.reveal-card.is-correct .reveal-status {
  color: var(--good);
}

.reveal-card.is-wrong .reveal-status {
  color: var(--bad);
}

.reveal-title {
  margin: 0;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reveal-artist {
  margin: 0.1rem 0 0;
  color: var(--ink-muted);
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reveal-links {
  margin: 0.4rem 0 0;
  display: flex;
  gap: 0.6rem;
}

.reveal-link {
  display: inline-flex;
  color: var(--ink-muted);
  transition: color 0.15s ease;
}

.reveal-link svg {
  width: 20px;
  height: 20px;
}

.reveal-link:hover {
  color: var(--accent-blue-dim);
}

/* ---- Game-over summary (end of a Daily/Endless run) --------------------- */
/* Rendered inline in .card in place of the gameplay controls — the run is
   over, so the seek bar, player, guess box, and action buttons are hidden
   in favor of the summary + leaderboard below. */

.card.game-over-active #guest-note,
.card.game-over-active #stage-bar,
.card.game-over-active #points-indicator,
.card.game-over-active .player-wrap,
.card.game-over-active .volume-row,
.card.game-over-active .autocomplete-wrap,
.card.game-over-active > .button-row,
.card.game-over-active #result {
  display: none;
}

.game-over-card {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-soft);
}

.game-over-summary {
  margin: 0 0 1rem;
  font-size: 1.1rem;
  font-weight: 700;
}

.game-over-actions {
  margin-top: 1.25rem;
}

.game-over-menu-btn,
.game-over-play-again-btn {
  display: inline-block;
  text-decoration: none;
  text-align: center;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.95rem;
  border: none;
  border-radius: var(--radius-pill);
  padding: 0.8rem 1.4rem;
  cursor: pointer;
}

/* ---- Give up (distinct from Skip: reveals the answer and moves on) ----- */

.btn-danger {
  background: transparent;
  color: var(--bad);
  border: 1px solid rgba(226, 99, 111, 0.4);
}

.btn-danger:hover:not(:disabled) {
  background: var(--bad-soft);
  border-color: var(--bad);
}

/* ---- Confetti burst (correct-guess celebration) ------------------------- */

.confetti-piece {
  position: fixed;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  pointer-events: none;
  z-index: 999;
  top: 0;
  left: 0;
  animation: confetti-burst 0.9s ease-out forwards;
}

@keyframes confetti-burst {
  0% { transform: translate(-50%, -50%) rotate(0deg); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)); opacity: 0; }
}

.button-row {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.button-grid {
  display: flex !important;
  background: var(--bg-inset) !important;
  border: 1px solid var(--border-soft) !important;
  border-radius: var(--radius-lg) !important;
  padding: 0.35rem !important;
  gap: 0 !important;
  overflow-x: auto !important;
  scrollbar-width: none !important;
  flex-wrap: nowrap !important;
}

.button-grid::-webkit-scrollbar {
  display: none !important;
}

.button-grid button {
  flex: 1 !important;
  min-width: max-content !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  color: var(--ink-muted) !important;
  border-radius: var(--radius-md) !important;
  padding: 0.6rem 0.55rem !important;
  font-size: 0.78rem !important;
  white-space: nowrap !important;
  transition: all 0.2s ease !important;
  margin: 0 !important;
}

.button-grid button.btn-ghost {
  background: transparent !important;
  border: none !important;
  color: var(--ink-muted) !important;
}

.button-grid button.btn-primary {
  background: var(--bg-elevated) !important;
  color: var(--ink) !important;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1) !important;
  border: none !important;
}

.button-grid button:not(.btn-primary):hover {
  color: var(--ink) !important;
  background: rgba(0,0,0,0.03) !important;
}

button {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.95rem;
  border: none;
  border-radius: var(--radius-pill);
  padding: 0.8rem 1.4rem;
  cursor: pointer;
  transition: transform 0.1s ease, filter 0.15s ease, background 0.15s ease;
}

button:active {
  transform: scale(0.97);
}

button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Primary CTA styled like the desktop's peach titlebar (titlebar-peach /
   folder-peach gradient stops), white text for contrast. */
.btn-primary {
  background: linear-gradient(180deg, #f3b871, #e5934a);
  border: 1px solid #d9903c;
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  filter: brightness(1.06);
}

/* Secondary action styled like the desktop's neutral window-control
   buttons (white-to-grey gradient, pink hover), so it reads as "chrome"
   rather than a competing brand color. */
.btn-ghost {
  background: linear-gradient(180deg, var(--btn-ghost-start), var(--btn-ghost-end));
  color: var(--ink);
  border: 1px solid var(--btn-ghost-border);
}

.btn-ghost:hover:not(:disabled) {
  color: var(--ink);
  background: linear-gradient(180deg, var(--btn-ghost-start), var(--btn-ghost-hover-end));
  border-color: var(--btn-ghost-hover-border);
}

/* Fallback for any bare <button> not yet given a variant class. */
button:not(.btn-primary):not(.btn-ghost):not(.btn-danger):not(.tier-btn) {
  background: linear-gradient(180deg, #f3b871, #e5934a);
  border: 1px solid #d9903c;
  color: #fff;
}

/* ---- Feedback / result banners ------------------------------------------ */

.result-banner {
  margin-top: 1.25rem;
  padding: 0.75rem 0.9rem;
  background: var(--bg-inset);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  font-size: 0.95rem;
  color: var(--ink-muted);
}

.result-banner.is-correct {
  color: var(--good);
  border-color: rgba(76, 175, 125, 0.4);
}

.result-banner.is-wrong {
  color: var(--bad);
  border-color: rgba(226, 99, 111, 0.4);
}

/* ---- Home page: mode picker -------------------------------------------- */

.mode-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1.5rem;
}

.mode-card {
  display: block;
  padding: 1rem 1.2rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-soft);
  background: var(--bg-inset);
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}

.mode-card:hover,
.mode-card:focus-visible {
  border-color: var(--accent-blue);
  background: var(--accent-blue-soft);
  transform: translateY(-1px);
}

.mode-card .mode-desc {
  display: block;
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--ink-muted);
  margin-top: 0.2rem;
}

/* ---- Multiplayer specifics ---------------------------------------------- */

.room-code {
  font-family: var(--font-mono);
  font-size: 2rem;
  letter-spacing: 0.14em;
  color: var(--gold-dim);
  text-align: center;
  margin: 0.5rem 0 1.25rem;
}

.player-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.player-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-md);
  background: var(--bg-inset);
  border: 1px solid var(--border-soft);
  font-size: 0.9rem;
}

.player-row .score {
  font-family: var(--font-mono);
  color: var(--gold-dim);
  font-weight: 600;
}

.player-row .lock-status {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.tier-btn {
  padding: 0.5rem 1rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-soft);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.tier-btn.is-selected {
  background: var(--accent-blue-soft);
  border-color: var(--accent-blue);
  color: var(--accent-blue-dim);
}

.stage-toggle-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1rem 0;
}

.stage-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-soft);
  background: transparent;
  font-size: 0.9rem;
  font-family: var(--font-mono);
  color: var(--ink-muted);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.stage-toggle:has(input:checked) {
  background: var(--accent-blue-soft);
  border-color: var(--accent-blue);
  color: var(--accent-blue-dim);
}

.stage-toggle input[type="checkbox"] {
  width: 15px;
  height: 15px;
  accent-color: var(--accent-blue);
  cursor: pointer;
}

.lock-tag {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-soft);
  color: var(--ink-muted);
}

.lock-tag.is-correct {
  color: var(--good);
  border-color: rgba(76, 175, 125, 0.4);
  background: var(--good-soft);
}

.lock-tag.is-gave-up {
  color: var(--bad);
  border-color: rgba(226, 99, 111, 0.4);
  background: var(--bad-soft);
}

.lock-tag.is-deciding {
  animation: pulse-text 1.6s ease-in-out infinite;
}

@keyframes pulse-text {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

.status-line {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-muted);
  margin-bottom: 1rem;
}

.status-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1rem;
  margin-bottom: 1rem;
}

.status-row .status-line {
  margin-bottom: 0;
}

.live-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--good);
  background: var(--good-soft);
  border: 1px solid rgba(76, 175, 125, 0.4);
  border-radius: var(--radius-pill);
  padding: 0.35rem 0.7rem 0.35rem 0.6rem;
}

.live-badge::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--good);
  animation: pulse-glow 1.4s ease-in-out infinite;
}

/* ---- Confirm modal (in-theme replacement for window.confirm) ----------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(40, 38, 54, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 1rem;
  animation: modal-fade-in 0.15s ease;
}

.modal-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  max-width: 360px;
  width: 100%;
  box-shadow: var(--shadow-window);
  animation: modal-pop-in 0.18s ease;
}

.modal-message {
  margin: 0 0 1.25rem;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.4;
}

@keyframes modal-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modal-pop-in {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: scale(1); }
}

/* ---- Toast notifications ------------------------------------------------ */

.toast-container {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 320px;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius-md);
  padding: 0.7rem 0.75rem;
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.7);
  pointer-events: auto;
  animation: toast-in 0.2s ease;
}

.toast-error {
  border-left-color: var(--bad);
}

.toast-info {
  border-left-color: var(--gold);
}

.toast-message {
  flex: 1;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.85rem;
  line-height: 1.35;
}

.toast-close {
  background: none;
  border: none;
  color: var(--ink-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.15rem;
}

.toast-close:hover {
  color: var(--ink);
}

.toast-leaving {
  animation: toast-out 0.18s ease forwards;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes toast-out {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-8px); }
}
