/* ===== Design tokens ===== */
:root {
  /* Primary theme: black + cyan. Gold survives only as the "win/jackpot"
     accent, kept deliberately rare so it still reads as a payoff color
     rather than competing with the cyan chrome everywhere else. */
  --cyan: #22e3ff;
  --cyan-bright: #7bf3ff;
  --cyan-deep: #0891a8;
  --cyan-glow: rgba(34, 227, 255, 0.35);
  --gold: #e6b325;
  --gold-bright: #ffd94d;
  --gold-deep: #8a5a12;
  --green: #17b34a;
  --green-dark: #0a7a2e;
  --red: #c0272d;
  --border-dim: #1c6470;
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --radius-xs: 6px;
  --radius-pill: 999px;
}

/* ---------- THEMES ----------
   Cyan-on-black chrome stays constant in spirit across dark/oled/midnight
   — what shifts is how black the backdrop and panels go. Light mode is
   the deliberate exception: it inverts to a light panel so the theme
   option is genuinely usable in bright environments, not just a dimmer
   version of dark mode. */
html[data-theme="dark"] {
  --control-top: #0e2b30;
  --control-mid: #0a1f23;
  --control-bottom: #061417;
  --panel-bg: #071316;
  --panel-bg-2: #0c1e22;
  --panel-text: #eafcff;
  --text-dim: #9fd6de;
}
html[data-theme="light"] {
  --control-top: #d6f4f8;
  --control-mid: #bdebf1;
  --control-bottom: #a3e0e8;
  --panel-bg: #f5fdfe;
  --panel-bg-2: #e3f6f9;
  --panel-text: #04262b;
  --text-dim: #2e5a61;
}
html[data-theme="oled"] {
  --control-top: #0b0b0b;
  --control-mid: #050505;
  --control-bottom: #000000;
  --panel-bg: #000000;
  --panel-bg-2: #0a0a0a;
  --panel-text: #eafcff;
  --text-dim: #7fb8c0;
}
html[data-theme="midnight"] {
  --control-top: #0d1a3a;
  --control-mid: #09142c;
  --control-bottom: #050a1c;
  --panel-bg: #050a1a;
  --panel-bg-2: #0a1230;
  --panel-text: #eafcff;
  --text-dim: #8fa3d6;
}

/* Reset + Base */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Orbitron', sans-serif;
  color: #fff;
  min-height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The scene lives on its own fixed .room element behind everything —
     see THE ROOM. body keeps a flat colour so the root canvas never
     paints whatever the browser feels like behind a transparent page. */
  background: var(--room-deep);
  transition: background 0.4s ease;
}

/* ---------- Top controls (mute + theme switcher) ---------- */
.top-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 1400px;
  margin: 0 auto 8px;
  padding: 4px 4px 0;
}

.home-link {
  font-family: 'Orbitron', sans-serif;
  font-size: 0.8rem;
  color: var(--cyan-bright);
  text-decoration: none;
  opacity: 0.85;
}
.home-link:hover { opacity: 1; text-decoration: underline; }

.top-controls-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mute-toggle {
  appearance: none;
  border: 1px solid var(--border-dim);
  background: rgba(0,0,0,0.35);
  color: var(--cyan-bright);
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.2s ease;
}
.mute-toggle svg { width: 15px; height: 15px; }
.mute-toggle:hover { transform: scale(1.08); }
.mute-toggle[aria-pressed="true"] { color: #ff8a8a; }

/* ---------- SOUND SIDEBAR ---------- */
.sound-panel {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: min(300px, 88vw);
  background: var(--panel-bg-2);
  border-left: 2px solid var(--cyan);
  box-shadow: -8px 0 30px rgba(0,0,0,0.5);
  z-index: 10050;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  transform: translateX(100%);
  transition: transform .35s ease;
  color: var(--panel-text);
  font-family: 'Orbitron', sans-serif;
}
.sound-panel.open { transform: translateX(0); }

.sound-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  letter-spacing: .16em;
  color: var(--text-dim);
}
.sound-panel-close {
  appearance: none;
  border: 1px solid var(--border-dim);
  background: rgba(0,0,0,0.3);
  color: var(--text-dim);
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.sound-panel-close:hover { color: var(--cyan-bright); border-color: var(--cyan); }

.sound-channel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px;
  background: rgba(0,0,0,0.25);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-md);
}
.sound-channel-label {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 700;
  color: var(--cyan-bright);
}
.sound-channel-label svg { width: 18px; height: 18px; }

.sound-channel-controls {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sound-mute-btn {
  appearance: none;
  border: 1px solid var(--border-dim);
  background: rgba(0,0,0,0.3);
  color: var(--text-dim);
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: color .2s ease, border-color .2s ease;
}
.sound-mute-btn svg { width: 16px; height: 16px; }
.sound-mute-btn:hover { border-color: var(--cyan); color: var(--cyan-bright); }
.sound-mute-btn[aria-pressed="true"] { color: #ff8a8a; border-color: #ff8a8a; }

.sound-slider {
  flex: 1;
  accent-color: var(--cyan);
  cursor: pointer;
  height: 6px;
}

@media (max-width: 420px) {
  .sound-panel { width: 100vw; }
}

.theme-switch {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: rgba(0,0,0,0.35);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-pill);
}
.theme-switch button {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-dim);
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.theme-switch button svg { width: 13px; height: 13px; }
.theme-switch button:hover { color: #fff; }
.theme-switch button[aria-pressed="true"] {
  background: var(--cyan);
  color: #002026;
}


/* Main wrapper */
.slot-machine {
  width: 100%;
  max-width: min(1900px, 98vw);
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0.75rem 1.25rem;
  box-sizing: border-box;
}


@keyframes flicker {
  0%, 19%, 21%, 23%, 25%, 54%, 56%, 100% { opacity: 1; }
  20%, 22%, 24%, 55% { opacity: 0.88; }
}


.machine-stage {
  display: flex;
  flex-grow: 1;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: 100%;
  min-height: 0;
}

.machine-frame {
  display: flex;
  flex-grow: 1;
  flex-shrink: 1;
  min-width: 0;
  justify-content: center;
  align-items: center;
  border: 10px solid var(--cyan);
  border-image: linear-gradient(180deg, var(--cyan-bright), var(--cyan) 45%, var(--cyan-deep)) 1;
  border-radius: var(--radius-lg);
  background: var(--panel-bg);
  overflow: hidden;
  position: relative;
  width: 100%;
  height: clamp(380px, 76vh, 1000px);
  max-width: min(1900px, 98vw);
  margin: 0 auto;
  box-shadow: inset 0 0 0 3px rgba(34, 227, 255, 0.5), 0 10px 30px rgba(0,0,0,0.45);
}

/* When a machine defines a background image, it's layered under the
   reels with a dark wash so symbols stay readable on top of it. */
.machine-frame.has-machine-bg {
  background-image:
    linear-gradient(rgba(0,0,0,0.55), rgba(0,0,0,0.65)),
    var(--machine-bg-image);
  background-size: cover;
  background-position: center;
}


.reels {
  display: flex;
  justify-content: center;
  align-items: stretch;
  gap: 10px;
  width: 100%;
  height: 100%;
  flex-grow: 1;
}

/* Each Reel Column */
.reel-col {
  flex: 1;
  height: 100%;
  background: var(--panel-bg);
  border-radius: var(--radius-xs);
  border: 2px solid var(--border-dim);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* Vertical symbol track inside each column */
.reel-track {
  transition: filter 150ms ease-out;
  backface-visibility: hidden;
  height: 100%;
}

/* Both of these used to sit on .reel-track unconditionally, which meant
   five permanently promoted layers each running a filter pass for a blur
   of ZERO — paid on every frame, at 120Hz on a modern phone, while the
   reels sat perfectly still. The same fix the curtains already got in
   mobile-bag-chest.css: hold the layer open only while it is moving.

   The zero-blur has to be present BEFORE .blurring lands or the
   transition has nothing to ease out of, which is why this is a separate
   spin-lifecycle class rather than simply deleting the filter. It is
   added when the reel starts and removed when the landing animation
   ends. Declared above .blurring: same specificity, so source order is
   what lets the real blur win. */
.reel-track.spin-active {
  will-change: transform;
  filter: blur(0px);
}

/* Applied while a reel is at full speed — eases in/out so the blur
   doesn't pop abruptly at the start/end of the fast phase. */
.reel-track.blurring {
  filter: blur(1.6px);
}

/* Landing bounce: overshoots past the resting position, rebounds
   slightly the other way, then settles exactly on target. The exact
   pixel values are supplied per-spin via custom properties since they
   depend on the measured symbol height. */
@keyframes reelSettle {
  0%   { transform: translateY(var(--approach-y, 0px)); }
  55%  { transform: translateY(var(--overshoot-y, 0px)); }
  78%  { transform: translateY(var(--settle-y, 0px)); }
  100% { transform: translateY(var(--rest-y, 0px)); }
}

.reel-track.landing {
  /* Scaled by the spin cue: a 1s spin cannot afford a 420ms bounce.
     JS sets --reel-settle per spin; 420ms stays the default. */
  animation: reelSettle var(--reel-settle, 420ms) cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

/* A quick compress-and-release "kick" on the column itself when a spin
   starts, and a heavier squash-bounce when it lands — layered on top of
   the track's own translateY motion for a more physical feel. */
@keyframes reelKickStart {
  0%   { transform: scaleY(1); }
  35%  { transform: scaleY(0.94); }
  100% { transform: scaleY(1); }
}

@keyframes reelKickLand {
  0%   { transform: scaleY(1); }
  35%  { transform: scaleY(1.06); }
  65%  { transform: scaleY(0.97); }
  100% { transform: scaleY(1); }
}

.reel-col.spin-kick {
  animation: reelKickStart 220ms ease-out;
}

.reel-col.spin-land {
  animation: reelKickLand 380ms ease-out;
}

/* Each Symbol — fixed thirds of the column, consistent at any zoom level */
.reel-track img {
  width: 100%;
  height: calc(100% / 3);
  object-fit: contain;
  background-color: var(--panel-bg);
  display: block;
  user-select: none;
  pointer-events: none;
}

/* The overlay the win bands and the WAYS badge are positioned into */
.win-lines {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 15;
}

/* Winning symbols glow and gently pulse in place */
.reel-track img.symbol-glow {
  animation: symbolGlow 1.1s ease-in-out infinite;
  position: relative;
  z-index: 5;
}
@keyframes symbolGlow {
  0%, 100% {
    filter: drop-shadow(0 0 4px rgba(255, 217, 77, 0.5)) brightness(1);
    transform: scale(1);
  }
  50% {
    filter: drop-shadow(0 0 22px rgba(255, 217, 77, 0.95)) drop-shadow(0 0 12px rgba(34, 227, 255, 0.7)) brightness(1.25);
    transform: scale(1.08);
  }
}

/* Control Panel */
.control-bar {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
  align-items: center;
  padding: 1rem;
  background: linear-gradient(180deg, var(--control-top), var(--control-mid) 60%, var(--control-bottom));
  border-top: 5px solid var(--cyan);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  width: 100%;
  gap: 1rem;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.08);
}

.control-bar select {
  font-size: 1.1rem;
  color: var(--cyan-bright);
  background: #001417;
  border: 2px solid var(--cyan);
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  outline: none;
  box-shadow: 0 0 8px rgba(34, 227, 255, 0.25);
  transition: box-shadow 0.25s ease, transform 0.25s ease, background-color 0.25s ease;
}

.control-bar select:hover,
.control-bar select:focus-visible {
  box-shadow: 0 0 12px var(--cyan), 0 0 20px var(--cyan);
  transform: scale(1.05);
}

.control-bar span {
  font-size: 1.1rem;
  color: var(--text-dim);
}


.balance {
  font-size: 1.3rem;
  color: var(--cyan-bright);
  font-weight: bold;
  border: 2px solid var(--cyan-deep);
  padding: 6px 16px;
  border-radius: var(--radius-pill);
  background: rgba(0, 10, 12, 0.75);
  text-shadow: 0 0 6px rgba(34, 227, 255, 0.5);
  box-shadow: 0 0 6px rgba(34, 227, 255, 0.25);
}

.balance-group {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.btn.reset {
  padding: 8px 14px;
  font-size: 0.85rem;
  background: linear-gradient(180deg, #4a6a72, #24393e 60%, #142226);
  border-color: rgba(255,255,255,0.35);
}

.btn.reset:disabled {
  background: linear-gradient(180deg, #24393e, #142226);
}

.reset-cooldown {
  font-size: 0.8rem;
  color: var(--text-dim);
  font-family: 'Orbitron', sans-serif;
  min-width: 3.5em;
}

.btn {
  padding: 12px 26px;
  border-radius: var(--radius-pill);
  font-weight: bold;
  font-family: 'Orbitron', sans-serif;
  color: #fff;
  border: 2px solid rgba(255,255,255,0.5);
  cursor: pointer;
  font-size: 1.1rem;
  transition: transform 0.2s ease, filter 0.2s ease, opacity 0.2s ease;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.4), inset 0 -3px 6px rgba(0,0,0,0.25), 0 3px 6px rgba(0,0,0,0.35);
}

.btn.spin {
  background: linear-gradient(180deg, #4be07a, var(--green) 50%, var(--green-dark));
  border-color: #a6f7bf;
}

.btn.auto {
  background: linear-gradient(180deg, #ef8a4d, var(--red) 60%, #8a1a1f);
  border-color: #ffcfa8;
}

.btn.auto.active {
  filter: brightness(1.25);
}

.btn.paytable {
  background: linear-gradient(180deg, var(--cyan-bright), var(--cyan) 55%, var(--cyan-deep));
  border-color: #bff8ff;
}

.btn:hover:not(:disabled) { transform: scale(1.05); }
.btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

@keyframes btnPress {
  0%   { transform: scale(1); filter: brightness(1); }
  30%  { transform: scale(0.92); filter: brightness(0.82); }
  100% { transform: scale(1); filter: brightness(1); }
}
.btn.btn-pressed {
  animation: btnPress 220ms ease-out;
}

/* ===== Paytable modal ===== */
/* Hidden by default. JS toggles the .open class — this must be the only
   thing controlling visibility (the old [hidden] attribute was being
   silently overridden by this rule's own display:flex, which is why the
   modal used to show on load and couldn't be closed). */
.paytable-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 11000;
  padding: 1.5rem;
}

.paytable-overlay.open {
  display: flex;
}

.paytable-modal {
  width: 100%;
  max-width: 560px;
  max-height: 80vh;
  overflow-y: auto;
  background: var(--panel-bg);
  border: 4px solid var(--cyan);
  border-radius: var(--radius-lg);
  box-shadow: 0 0 30px rgba(34, 227, 255, 0.4);
  padding: 1.25rem;
  color: var(--panel-text);
}

.paytable-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
  gap: 1rem;
}

.paytable-header h2 {
  font-size: 1.2rem;
  color: var(--cyan-deep);
}

.paytable-header h2 span {
  font-size: 0.8rem;
  color: var(--text-dim);
  font-weight: normal;
}

.paytable-close {
  background: transparent;
  border: 1px solid var(--border-dim);
  color: var(--panel-text);
  border-radius: var(--radius-xs);
  width: 32px;
  height: 32px;
  cursor: pointer;
  font-size: 1rem;
}
.paytable-close:hover { border-color: var(--cyan-deep); color: var(--cyan-deep); }

.paytable-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.75rem;
}

.paytable-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--panel-bg-2);
  border: 1px solid var(--border-dim);
  border-radius: var(--radius-sm);
  padding: 0.5rem;
}

.paytable-row img {
  width: 36px;
  height: 36px;
  object-fit: contain;
  flex-shrink: 0;
}

/* Payout amounts stay gold deliberately — one warm accent against the
   cyan chrome so "you won this much" still reads as a payoff color. */
.paytable-row .amount {
  color: var(--gold);
  font-weight: bold;
  font-size: 0.95rem;
}

/* Mobile */
@media (max-width: 768px) {
  body {
    overflow-y: auto;
    height: auto;
    padding-bottom: 80px;
  }

  .slot-machine {
    padding: 0.5rem 1rem;
    gap: 1rem;
  }

  .top-controls {
    padding: 0 0.25rem;
  }

  .machine-frame {
    height: clamp(280px, 58vh, 520px);
    flex-direction: column;
  }

  .reels {
    flex-direction: row;
    height: 100%;
    gap: 4px;
  }

  .reel-col {
    border: 1px solid var(--border-dim);
  }


  .control-bar {
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    align-items: stretch;
  }

  .control-bar span,
  .control-bar select {
    font-size: 1rem;
    width: 100%;
  }

  .control-bar select {
    padding: 12px 12px;
    min-height: 44px;
  }

  .btn {
    width: 100%;
    font-size: 1rem;
    margin: 6px 0;
    padding: 14px;
    min-height: 48px;
    box-shadow: 0 0 8px rgba(34, 227, 255, 0.25);
  }

  .balance {
    font-size: 1rem;
    padding: 6px 10px;
  }

  #winMessage {
    font-size: clamp(1.6rem, 8vw, 2.5rem);
    padding: 12px 20px;
  }

  #floatingWin {
    font-size: 1.5rem;
  }

}

@media screen and (max-width: 1099px) and (orientation: landscape) {
  .machine-frame { height: 55vh; }
  #winMessage { font-size: 2rem; padding: 10px 16px; }
}

/* Any device in a short landscape orientation (phones AND tablets held
   sideways) — governed by actual available height, not just width, so
   it catches cases the width-only queries above miss. */
@media screen and (max-height: 480px) {
  .machine-frame { height: 68vh; }
}

/* Tablets / small laptops — the mascot has room but shouldn't crowd
   the reels, so it scales down before disappearing entirely below the
   mobile breakpoint. */
@media screen and (min-width: 769px) and (max-width: 1099px) {
}

/* Large screens / TVs — scale the whole machine up rather than leaving
   it small in a sea of empty space, and keep it comfortably readable
   from a couch-viewing distance. */
@media screen and (min-width: 1600px) {
  .slot-machine { max-width: min(2200px, 98vw); }
  .machine-frame { max-width: min(2200px, 98vw); height: clamp(560px, 80vh, 1200px); }
  /* `.control-bar span { font-size: 1.35rem }` and `.btn { font-size: 1.3rem;
     padding: 16px 32px }` used to live here. They are the reason crossing
     1600px made the deck WORSE rather than better: the blanket span rule
     caught every sublabel, figure and readout in the deck, and the button
     padding pushed the row tall enough to take the space back off the
     reels. The deck is scaled deliberately in arcade.css instead, per
     element, where the selectors can carry the right specificity. */
  .control-bar select { font-size: 1.35rem; }
  .balance { font-size: 1.6rem; }
}

#copyright {
  position: fixed;
  bottom: 10px;
  right: 10px;
  font-family: 'Orbitron', sans-serif;
  font-size: 12px;
  color: #fff;
  z-index: 9999;
  opacity: 0.8;
}

.win-message-container {
  position: fixed;
  inset: 0;
  z-index: 10000;
  pointer-events: none;
  display: flex;
  justify-content: center;
  align-items: center;
}

#winMessage {
  display: none;
  font-size: 5rem;
  font-weight: 900;
  font-family: 'Orbitron', sans-serif;
  color: white;
  text-align: center;
  background: rgba(0, 0, 0, 0.75);
  padding: 20px 40px;
  border-radius: var(--radius-md);
  text-shadow: 0 0 10px #000, 0 0 20px #000;
  pointer-events: none;
  max-width: 90vw;
  word-break: break-word;
  text-wrap: balance;
}

#winMessage.show {
  display: block;
  animation: popFade 1.5s ease-in-out forwards;
}

@keyframes popFade {
  0% { opacity: 0; transform: scale(0.5); }
  30% { opacity: 1; transform: scale(1.2); }
  60% { transform: scale(0.95); }
  100% { opacity: 0; transform: scale(1); }
}

#floatingWin {
  position: absolute;
  top: 58%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2.5rem;
  font-weight: bold;
  color: gold;
  opacity: 0;
  pointer-events: none;
  z-index: 9999;
  text-shadow: 1px 1px 2px #000;
}

@keyframes floatWin {
  0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  50% { transform: translate(-50%, -70%) scale(1.2); opacity: 0.8; }
  100% { transform: translate(-50%, -90%) scale(1); opacity: 0; }
}

#winMessage.no-win {
  color: red;
  text-shadow: 2px 2px #900, 4px 4px #600;
}

#winMessage.big-win {
  color: gold;
  text-shadow: 2px 2px #f90, 4px 4px #cc0;
}

#winMessage.jackpot {
  color: cyan;
  text-shadow: 2px 2px #0ff, 4px 4px #09c;
}

.rainbow-text {
  background: linear-gradient(90deg, #ff4d4d, #ffd94d, #4be07a, #22e3ff, #b04dff, #ff4d4d);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: rainbowShift 1.2s linear infinite, popFade 2.5s ease-in-out forwards;
}
@keyframes rainbowShift {
  0% { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}

/* Big-win screen flash */
#winFlash {
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  background: radial-gradient(circle, rgba(255,255,255,0.5) 0%, rgba(34,227,255,0.25) 45%, transparent 75%);
  opacity: 0;
}
#winFlash.flash-active {
  animation: winFlashPulse 550ms ease-out;
}
@keyframes winFlashPulse {
  0% { opacity: 0; }
  15% { opacity: 1; }
  100% { opacity: 0; }
}

/* Mega/Jackpot machine shake */
@keyframes machineShake {
  0%, 100% { transform: translate(0, 0); }
  10% { transform: translate(-6px, 3px); }
  20% { transform: translate(6px, -3px); }
  30% { transform: translate(-5px, -2px); }
  40% { transform: translate(5px, 2px); }
  50% { transform: translate(-4px, 3px); }
  60% { transform: translate(4px, -3px); }
  70% { transform: translate(-3px, 0); }
  80% { transform: translate(3px, 0); }
  90% { transform: translate(-1px, 0); }
}
.machine-frame.shake-active {
  animation: machineShake 500ms ease-out;
}

#loader {
  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10000;
  transition: opacity 0.5s ease;
}

.loader-text {
  font-size: 2rem;
  color: gold;
  font-family: 'Orbitron', sans-serif;
  text-shadow: 0 0 10px #f90, 0 0 20px #ff0;
  animation: flicker 2s infinite alternate;
}

#loader.fade-out {
  opacity: 0;
  pointer-events: none;
}
@keyframes speechBubbleIn {
  0%   { opacity: 0; transform: translateY(6px) scale(0.92); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---------- MACHINE TRANSITION ---------- */
.machine-transition {
  position: fixed;
  inset: 0;
  z-index: 20500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0);
  opacity: 0;
  pointer-events: none;
  transition: background .3s ease, opacity .3s ease;
}
.machine-transition.active {
  opacity: 1;
  background: rgba(4, 0, 8, 0.95);
  pointer-events: all;
}
.machine-transition-label {
  font-family: 'Orbitron', sans-serif;
  font-weight: 900;
  font-size: clamp(1.4rem, 5vw, 2.4rem);
  color: #ff8a3d;
  text-shadow: 0 0 20px rgba(255, 138, 61, 0.9), 0 0 40px rgba(150, 30, 30, 0.7);
  text-align: center;
  padding: 0 24px;
  animation: transitionPulse 1.2s ease-in-out infinite;
}
@keyframes transitionPulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.06); opacity: 0.85; }
}

@media (max-width: 768px) {
}

