/* =====================================================================
   THE ROOM — a royal scene, in CSS
   ---------------------------------------------------------------------
   Replaces assets/ui/bg.gif: 4.9 MB decoded and composited behind every
   frame of the game, almost none of which was ever visible behind an
   already-busy foreground.

   Built as ONE fixed element that is the first child of <body> at
   z-index -1. That clears every existing layer without touching
   main.slot-machine's stacking — appending it after <main> at z-index 0
   is exactly the trap `body.in-castle main.slot-machine { z-index: 1 }`
   exists to work around.

   Every colour comes from a token with a :root default, so a missing
   data-theme attribute cannot drop the whole declaration.
   ===================================================================== */

:root {
  --room-deep: #0a0510;
  --room-mid:  #2a0d24;
  --room-gilt: rgba(255, 200, 90, 0.16);
  --room-veil: rgba(0, 0, 0, 0.55);
  --room-tint: rgba(120, 20, 60, 0.30);
}

html[data-theme="dark"] {
  --room-deep: #07040c;
  --room-mid:  #22091d;
  --room-gilt: rgba(255, 200, 90, 0.14);
  --room-veil: rgba(0, 0, 0, 0.6);
}

html[data-theme="oled"] {
  --room-deep: #000000;
  --room-mid:  #16060f;
  --room-gilt: rgba(255, 200, 90, 0.12);
  --room-veil: rgba(0, 0, 0, 0.72);
}

html[data-theme="midnight"] {
  --room-deep: #04060f;
  --room-mid:  #0d1230;
  --room-gilt: rgba(150, 190, 255, 0.14);
  --room-veil: rgba(0, 0, 0, 0.58);
  --room-tint: rgba(40, 60, 150, 0.32);
}

/* Light is the one theme where a deep royal room would fight the UI, so
   it keeps the shape and inverts the value. */
html[data-theme="light"] {
  --room-deep: #e9e4f2;
  --room-mid:  #f6eef2;
  --room-gilt: rgba(190, 140, 40, 0.16);
  --room-veil: rgba(255, 255, 255, 0.35);
  --room-tint: rgba(190, 150, 170, 0.25);
}

.room {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    /* the pool of light the machine stands in */
    radial-gradient(ellipse 70% 55% at 50% 38%, var(--room-tint), transparent 72%),
    /* the room itself */
    radial-gradient(ellipse 120% 90% at 50% 42%, var(--room-mid), var(--room-deep) 78%);
}

/* Damask. Layered radial gradients on a repeating tile — the texture
   that stops the room reading as a plain gradient. Deliberately at the
   edge of visible: it should be felt, not looked at. */
.room::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image:
    radial-gradient(circle at 50% 20%, var(--room-gilt) 0 6px, transparent 7px),
    radial-gradient(circle at 0% 70%, var(--room-gilt) 0 5px, transparent 6px),
    radial-gradient(circle at 100% 70%, var(--room-gilt) 0 5px, transparent 6px),
    radial-gradient(circle at 50% 92%, var(--room-gilt) 0 3px, transparent 4px);
  background-size: 132px 132px;
}

/* Gold rays from above the machine, and the vignette that keeps the eye
   on it. One element, two jobs, so the scene stays at three nodes. */
.room::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 45% at 50% 42%, transparent 40%, var(--room-veil) 100%),
    conic-gradient(from var(--room-ray-angle, 0deg) at 50% -12%,
      transparent 0deg 8deg,
      var(--room-gilt) 8deg 10deg,
      transparent 10deg 22deg);
  animation: roomRays 140s linear infinite;
}

@property --room-ray-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@keyframes roomRays { to { --room-ray-angle: 360deg; } }

/* Motes. Two sizes, long staggered drifts, transform-only so they never
   cost layout or paint. */
.room-mote {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 224, 150, 0.85), transparent 70%);
  animation: roomDrift var(--mote-dur, 26s) linear infinite;
  animation-delay: var(--mote-delay, 0s);
  will-change: transform;
}

@keyframes roomDrift {
  0%   { transform: translate3d(0, 0, 0) scale(0.7); opacity: 0; }
  12%  { opacity: 0.7; }
  85%  { opacity: 0.55; }
  100% { transform: translate3d(var(--mote-x, 40px), -110vh, 0) scale(1.1); opacity: 0; }
}

/* The Castle keeps its own room — a colder, redder one — rather than
   having the royal scene erased out from under it. Tinting the shared
   tokens means every layer above still works. */
body.in-castle {
  --room-tint: rgba(120, 12, 22, 0.42);
  --room-mid:  #1a0206;
  --room-deep: #05020a;
  --room-gilt: rgba(200, 60, 60, 0.12);
}

body.jk1x-active {
  --room-tint: rgba(255, 184, 0, 0.28);
  --room-gilt: rgba(255, 217, 77, 0.2);
}

@media (max-width: 720px) {
  /* The rays repaint a conic gradient across the whole viewport; the
     damask is a full-screen tiled paint. Both go on a phone. */
  .room::after { animation: none; }
  .room::before { display: none; }
  .room-mote { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .room::after { animation: none; }
  .room-mote { display: none; }
  .wheel-claim-rays, .wheel-claim-art img { animation: none; }
  .wheel-claim, .wheel-claim-inner { animation: none; }
}

/* =====================================================================
   MACHINE BACKDROPS — the royal treatment, one per machine
   ---------------------------------------------------------------------
   What sits BEHIND the reels. The frame's conic border is handled
   further up (--frame-paint) and is deliberately untouched here.

   Three things this section fixes as well as dresses:

   1. `generic` and `aliceWonderland` had no rule at all, so both fell
      through to `.machine-frame`'s flat `var(--panel-bg)` — a plain
      black box. They were the two most-played machines in the game.

   2. The Castle's fog used `.machine-frame[data-machine=...]::after`,
      but `.cabinet .machine-frame::after` paints the frame border and
      is both later and equal-specificity, so it won every shared
      property. The fog never drew; all that survived was its
      `height: 45%`, which shrank the frame border's own mask box on
      that machine only. The fog now lives on `.terror-backdrop`, a
      Castle-only element with both pseudos free.

   3. These rules use background LONGHANDS. The `background` shorthand
      resets `background-image`, which is what `.has-machine-bg` sets
      for a machine that ships a real picture — a shorthand here would
      silently discard it. `.has-machine-bg` is also restated at the
      end of this section so it outranks everything above it.

   Every layer is a gradient. Nothing here waits on a download, which
   matters because the Castle is entered abruptly.
   ===================================================================== */

/* Shared: a gilt vignette and a floor pool under every machine, so the
   reels always sit in a lit space rather than on a flat field. */
.machine-frame {
  background-color: #05060b;
  background-image:
    radial-gradient(ellipse 120% 60% at 50% 118%, rgba(255, 214, 138, 0.10), transparent 70%),
    radial-gradient(ellipse 90% 70% at 50% -18%, rgba(255, 232, 190, 0.07), transparent 70%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.55), transparent 30%, transparent 70%, rgba(0, 0, 0, 0.6));
}

/* ---- Generic: a cyan state room. Midnight velvet, a shaft of cold
   light from the ceiling, crimson banked in the corners, gilt at the
   floor — the border's cyan > red > black, read as a room. ---- */
.machine-frame[data-machine="generic"] {
  background-color: #03060d;
  background-image:
    radial-gradient(ellipse 55% 78% at 50% -12%, rgba(34, 227, 255, 0.20), transparent 66%),
    radial-gradient(ellipse 42% 55% at 2% 96%, rgba(200, 27, 40, 0.22), transparent 70%),
    radial-gradient(ellipse 42% 55% at 98% 96%, rgba(200, 27, 40, 0.18), transparent 70%),
    radial-gradient(ellipse 90% 30% at 50% 104%, rgba(255, 206, 120, 0.16), transparent 72%),
    repeating-linear-gradient(58deg, rgba(120, 220, 255, 0.030) 0 2px, transparent 2px 15px),
    repeating-linear-gradient(-58deg, rgba(255, 120, 140, 0.022) 0 2px, transparent 2px 15px),
    linear-gradient(180deg, #071021 0%, #050a16 46%, #01030a 100%);
}
.machine-frame[data-machine="generic"]::before {
  opacity: 1;
  background-image:
    radial-gradient(1.6px 1.6px at 16% 26%, rgba(190, 245, 255, 0.55), transparent),
    radial-gradient(2px 2px at 71% 16%, rgba(255, 190, 200, 0.42), transparent),
    radial-gradient(1.4px 1.4px at 41% 71%, rgba(255, 226, 170, 0.45), transparent),
    radial-gradient(2.2px 2.2px at 86% 61%, rgba(150, 235, 255, 0.40), transparent),
    radial-gradient(1.4px 1.4px at 28% 88%, rgba(255, 210, 150, 0.35), transparent);
  animation: royalDust 13s ease-in-out infinite alternate;
}

/* ---- Wonderland: dusk over the tea party. Violet and teal, a pastel
   bloom overhead, and a chequered floor falling away into the dark. ---- */
.machine-frame[data-machine="aliceWonderland"] {
  background-color: #0a0616;
  background-image:
    radial-gradient(ellipse 60% 70% at 50% -14%, rgba(142, 202, 230, 0.22), transparent 68%),
    radial-gradient(ellipse 46% 46% at 12% 20%, rgba(255, 179, 198, 0.18), transparent 70%),
    radial-gradient(ellipse 46% 46% at 88% 26%, rgba(214, 40, 40, 0.14), transparent 70%),
    radial-gradient(ellipse 88% 30% at 50% 104%, rgba(247, 225, 160, 0.16), transparent 74%),
    repeating-conic-gradient(from 0deg at 50% 100%, rgba(255, 255, 255, 0.030) 0deg 6deg, transparent 6deg 12deg),
    linear-gradient(180deg, #150a2b 0%, #0d0720 48%, #05030d 100%);
}
.machine-frame[data-machine="aliceWonderland"]::before {
  opacity: 1;
  background-image:
    radial-gradient(2px 2px at 20% 30%, rgba(255, 205, 225, 0.55), transparent),
    radial-gradient(1.6px 1.6px at 64% 20%, rgba(180, 230, 255, 0.50), transparent),
    radial-gradient(2.4px 2.4px at 44% 74%, rgba(247, 225, 160, 0.45), transparent),
    radial-gradient(1.6px 1.6px at 82% 58%, rgba(214, 140, 200, 0.42), transparent),
    radial-gradient(2px 2px at 32% 52%, rgba(255, 255, 255, 0.30), transparent);
  animation: wonderBloom 9s ease-in-out infinite alternate;
}

/* ---- Castle of Terror: blood overhead, poison at the floor, and
   almost no light in between. Longhands so the frame border is left
   alone; the fog is on .terror-backdrop below. ---- */
.machine-frame[data-machine="terrorCastle"] {
  background-color: #030104;
  background-image:
    radial-gradient(ellipse 66% 52% at 50% -6%, rgba(140, 14, 26, 0.46), transparent 64%),
    radial-gradient(ellipse 50% 44% at 16% 104%, rgba(24, 78, 40, 0.36), transparent 62%),
    radial-gradient(ellipse 50% 44% at 86% 104%, rgba(58, 16, 82, 0.34), transparent 62%),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.30) 0 3px, transparent 3px 26px),
    linear-gradient(180deg, #16060b 0%, #080206 62%, #000 100%);
}

/* ---- Opal Fruits: tropical light, and the rainbow the border wears
   banked along the floor. ---- */
.machine-frame[data-machine="fruits"] {
  background-color: #0a0402;
  background-image:
    radial-gradient(ellipse 62% 60% at 50% -10%, rgba(255, 196, 90, 0.30), transparent 64%),
    radial-gradient(ellipse 40% 40% at 84% 100%, rgba(255, 90, 140, 0.24), transparent 60%),
    radial-gradient(ellipse 40% 40% at 14% 100%, rgba(52, 199, 89, 0.20), transparent 60%),
    linear-gradient(100deg, rgba(255, 45, 85, 0.10), rgba(255, 149, 0, 0.10) 20%,
      rgba(255, 214, 10, 0.10) 38%, rgba(52, 199, 89, 0.09) 56%,
      rgba(34, 227, 255, 0.09) 74%, rgba(191, 90, 242, 0.10) 100%),
    linear-gradient(180deg, #33170a 0%, #1b0d05 58%, #0a0402 100%);
}

/* Fog, re-homed. .terror-backdrop is fixed, Castle-only and has both
   pseudo-elements free, so nothing here can collide with the frame. */
.terror-backdrop::after {
  content: '';
  position: absolute;
  left: -30%;
  right: -30%;
  bottom: 0;
  height: 42%;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(ellipse at 50% 100%, rgba(150, 220, 180, 0.20), transparent 70%);
  animation: terrorFogDrift 17s ease-in-out infinite alternate;
}

@keyframes royalDust {
  from { opacity: 0.55; transform: translateY(0) scale(1); }
  to   { opacity: 1;    transform: translateY(-16px) scale(1.04); }
}
@keyframes wonderBloom {
  from { opacity: 0.5; transform: translateY(0) scale(1); }
  to   { opacity: 1;   transform: translateY(-12px) scale(1.05); }
}

/* Restated last, and only for the machine that actually ships a
   picture: every rule above sets background-image, and at equal
   specificity the later one wins. Without this the image would be
   painted over by its own machine's gradients. */
.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;
}

/* The new ambient layers join the existing ones in both kill lists. */
@media (prefers-reduced-motion: reduce) {
  .machine-frame[data-machine="generic"]::before,
  .machine-frame[data-machine="aliceWonderland"]::before,
  .terror-backdrop::after { animation: none; }
}

@media (max-width: 720px) {
  /* Speckle layers are a full-frame paint every frame for decoration
     that is nearly invisible at this size. The gradients underneath
     are static and stay — they are what makes the machine look built
     rather than blank, and they cost one paint, not one per frame. */
  .machine-frame[data-machine="generic"]::before,
  .machine-frame[data-machine="aliceWonderland"]::before,
  .machine-frame[data-machine="fruits"]::before,
  .machine-frame[data-machine="terrorCastle"]::before { animation: none; }
  .terror-backdrop::after { animation: none; }
}


/* =====================================================================
   BACKDROPS FOR THE NEW MACHINES
   ---------------------------------------------------------------------
   .room-photo is opacity 0 by default and only lifted for machines named
   in the list in arcade.css — a machine missing from it has no backdrop
   at all, permanently, which is exactly what happened to Wonderland once
   before (arcade.css records it). Halloween was in that state too, having
   been retired.

   Gradients rather than photographs: there is no carnival, bar, emoji or
   christmas art in assets/ui, and inventing one by reusing an unrelated
   photo would look worse than a colour that belongs to the machine. Each
   is keyed off its own reels — the carnival's warm bulbs, the bar's green
   felt, the emoji's yellow, Christmas's spruce and red. Halloween gets
   terror.jpg, which is already a night scene and already in the repo.

   This sheet loads AFTER arcade.css (see the link order in index.html),
   so these win without touching the original block.
   ===================================================================== */
body[data-machine="carnival"] .room-photo,
body[data-machine="bar"] .room-photo,
body[data-machine="emoji"] .room-photo,
body[data-machine="christmas"] .room-photo,
body[data-machine="halloween"] .room-photo {
  opacity: 1;
}

body[data-machine="carnival"] .room-photo {
  background:
    radial-gradient(ellipse at 50% 12%, rgba(255, 176, 64, 0.30), transparent 62%),
    linear-gradient(180deg, #3b0f2e 0%, #2a0a24 42%, #14061a 100%);
}
body[data-machine="bar"] .room-photo {
  background:
    radial-gradient(ellipse at 50% 14%, rgba(255, 214, 120, 0.22), transparent 60%),
    linear-gradient(180deg, #0d2a1c 0%, #0a1f16 46%, #06110d 100%);
}
body[data-machine="emoji"] .room-photo {
  background:
    radial-gradient(ellipse at 50% 12%, rgba(255, 226, 92, 0.26), transparent 60%),
    linear-gradient(180deg, #2a1a52 0%, #1d1140 44%, #0d0722 100%);
}
body[data-machine="christmas"] .room-photo {
  background:
    radial-gradient(ellipse at 50% 10%, rgba(255, 240, 200, 0.22), transparent 58%),
    linear-gradient(180deg, #0b2f22 0%, #121a2e 48%, #070c16 100%);
}
body[data-machine="halloween"] .room-photo {
  background:
    linear-gradient(180deg, rgba(8, 3, 14, 0.58) 0%, rgba(8, 3, 14, 0.34) 40%,
                    rgba(8, 3, 14, 0.62) 100%),
    url('/assets/ui/jk1x/terror.jpg') center / cover no-repeat;
}

/* --- HALLOWEEN AND CHRISTMAS GET A SCENE, NOT A WASH -----------------
   Both had a single flat gradient, which is the right answer for a
   machine with no art but the wrong one for the two the whole month is
   built around. Layered instead: a horizon, a light source, and a
   repeating figure — a moon low and orange behind bare colour for
   Halloween, falling snow over a cold spruce night for Christmas.

   Still pure CSS, because there is no photograph for either and a
   borrowed one would belong to a different game. The repeating layers
   are cheap gradients rather than images, so this costs nothing to load
   and is disabled under .lean-fx with everything else ambient.
   ===================================================================== */
body[data-machine="halloween"] .room-photo {
  background:
    /* the moon */
    radial-gradient(circle 190px at 78% 18%, rgba(255, 176, 64, 0.55), rgba(255, 140, 30, 0.16) 55%, transparent 72%),
    /* mist off the ground */
    linear-gradient(0deg, rgba(150, 60, 200, 0.20) 0%, transparent 34%),
    /* the night */
    linear-gradient(180deg, rgba(10, 3, 18, 0.55) 0%, rgba(10, 3, 18, 0.30) 42%, rgba(6, 2, 12, 0.72) 100%),
    url('/assets/ui/jk1x/terror.jpg') center / cover no-repeat;
}

body[data-machine="christmas"] .room-photo {
  background:
    /* snow, three sizes on three offsets so it does not read as a grid */
    radial-gradient(circle 2px at 12% 18%, rgba(255,255,255,0.75), transparent 100%),
    radial-gradient(circle 2px at 68% 42%, rgba(255,255,255,0.65), transparent 100%),
    radial-gradient(circle 3px at 34% 76%, rgba(255,255,255,0.55), transparent 100%),
    radial-gradient(circle 2px at 88% 66%, rgba(255,255,255,0.6),  transparent 100%),
    /* the warm window at the bottom of the scene */
    radial-gradient(ellipse 60% 30% at 50% 104%, rgba(255, 196, 120, 0.28), transparent 70%),
    /* a cold star overhead */
    radial-gradient(circle 150px at 50% 6%, rgba(210, 245, 255, 0.30), transparent 70%),
    /* the spruce night */
    linear-gradient(180deg, #06283b 0%, #072a24 46%, #04121c 100%);
  background-size: 260px 260px, 340px 340px, 420px 420px, 300px 300px, auto, auto, auto;
  background-repeat: repeat, repeat, repeat, repeat, no-repeat, no-repeat, no-repeat;
  animation: xmasSnow 34s linear infinite;
}
@keyframes xmasSnow {
  from { background-position: 0 0, 0 0, 0 0, 0 0, 50% 104%, 50% 6%, 0 0; }
  to   { background-position: 0 260px, 0 340px, 0 420px, 0 300px, 50% 104%, 50% 6%, 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  body[data-machine="christmas"] .room-photo { animation: none; }
}
.lean-fx body[data-machine="christmas"] .room-photo { animation: none; }
