/* Cosmetic background scene (Store → Worlds). Keyframes live here rather than
   in <style> tags inside JSX — game.jsx used to re-insert a stylesheet on every
   mount of the scene. */

.bg-scene { position: absolute; inset: 0; overflow: hidden; }
.bg-scene [data-bg-layer] { position: absolute; pointer-events: none; }

/* Layer 1 — sky. Fills the frame; everything above the horizon shows it. */
.bg-sky { inset: 0; }

/* Layer 2 — back plane. Starts at or below the horizon, never above it —
   that is the whole fix, expressed as geometry. */
.bg-back { left: 0; right: 0; bottom: 0; }
.bg-back-window { overflow: hidden; }

/* Layer 3 — key light, anchored on the horizon line. */
.bg-key { left: 0; right: 0; }

/* Layer 4 — floor plane. */
.bg-floor { left: 0; right: 0; bottom: 0; }

/* Layer 5 — foreground silhouette, bottom corners only. */
.bg-fg { left: 0; right: 0; bottom: 0; overflow: hidden; }

/* Layer 6 — frame + vignette. */
.bg-frame { inset: 8px; border-radius: 22px; }
.bg-vignette { inset: 0; }

/* Motion bands. These clip their slot: art inside them physically cannot
   reach the middle of the screen, where items fall and get tapped. */
.bg-band-top    { top: 0;    left: 0; right: 0; height: 22%; overflow: hidden; }
.bg-band-floor  { bottom: 0; left: 0; right: 0; height: 22%; overflow: hidden; }
/* One screen-height of travel per cycle. Generous rather than exact — the
   container clips, so overshooting costs nothing and undershooting would park
   particles mid-screen. */
.bg-air         { inset: 0; overflow: hidden; --travel: 900px; }

/* ── Motion slots ──────────────────────────────────────────────
   Every animation below moves transform or opacity and nothing else, so it
   runs on the compositor and never triggers layout or paint. */

/* --travel is an absolute distance, NOT a percentage. A percentage translate
   resolves against the ELEMENT's own box, and these particles are 2-4px wide,
   so `translateY(-110%)` moved them three pixels per cycle and the whole air
   slot sat there looking static. */
@keyframes bgDrift   { 0%   { transform: translate3d(0,0,0); opacity: 0; }
                       10%  { opacity: 1; }
                       90%  { opacity: 1; }
                       100% { transform: translate3d(14px, calc(var(--travel) * -1), 0); opacity: 0; } }
@keyframes bgFall    { 0%   { transform: translate3d(0,0,0) rotate(0deg); opacity: 0; }
                       10%  { opacity: 1; }
                       90%  { opacity: 1; }
                       100% { transform: translate3d(-30px, var(--travel), 0) rotate(300deg); opacity: 0; } }
@keyframes bgSway    { 0%,100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
@keyframes bgPulse   { 0%,100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes bgFlicker { 0%,100% { opacity: 1; } 42% { opacity: .72; } 47% { opacity: .95; } 78% { opacity: .66; } }
@keyframes bgRipple  { 0%,100% { transform: translate3d(-3%,0,0) scaleY(1); }
                       50%     { transform: translate3d(3%,0,0) scaleY(1.06); } }
@keyframes bgShimmer { 0%,100% { opacity: .35; transform: translate3d(0,0,0); }
                       50%     { opacity: .6;  transform: translate3d(2%,0,0); } }

/* Slot A — top band */
.bg-m-shaft-shimmer  { animation: bgShimmer var(--dur) ease-in-out infinite; }
.bg-m-sign-flicker   { animation: bgFlicker var(--dur) steps(1, end) infinite; }
.bg-m-steam-rise     { animation: bgDrift   var(--dur) linear infinite; }
.bg-m-candle-flicker { animation: bgFlicker var(--dur) steps(1, end) infinite; }
.bg-m-leaf-sway      { animation: bgSway    var(--dur) ease-in-out infinite; transform-origin: 50% 0; }
.bg-m-star-twinkle   { animation: bgPulse   var(--dur) ease-in-out infinite; }
.bg-m-ribbon-drift   { animation: bgRipple  var(--dur) ease-in-out infinite; }
.bg-m-lantern-sway   { animation: bgSway    var(--dur) ease-in-out infinite; transform-origin: 50% 0; }
.bg-m-fire-flicker   { animation: bgFlicker var(--dur) steps(1, end) infinite; }
.bg-m-spark-fizz     { animation: bgPulse   var(--dur) steps(1, end) infinite; }

/* Slot B — floor band */
.bg-m-pool-drift     { animation: bgShimmer var(--dur) ease-in-out infinite; }
.bg-m-reflect-ripple { animation: bgRipple  var(--dur) ease-in-out infinite; }
.bg-m-grass-sway     { animation: bgSway    var(--dur) ease-in-out infinite; transform-origin: 50% 100%; }
.bg-m-snow-settle    { animation: bgShimmer var(--dur) ease-in-out infinite; }
.bg-m-petal-settle   { animation: bgShimmer var(--dur) ease-in-out infinite; }
.bg-m-ember-pulse    { animation: bgPulse   var(--dur) ease-in-out infinite; }

/* Slot C — air. The only motion that crosses the play area.
   Heat does NOT touch this. It used to: `calc(var(--dur) * var(--heat-speed))`
   sped the particles up at high combo, but changing animation-duration on a
   running animation recomputes its position for the elapsed time, and the
   harness measured the particles teleporting 16% of the screen height at each
   milestone. Heat drives the key light only; that difference is visible enough
   on its own and costs nothing. */
.bg-air-p {
  position: absolute; border-radius: 50%;
  animation-duration: var(--dur);
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  will-change: transform, opacity;
}
.bg-air-rise .bg-air-p { animation-name: bgDrift; }
.bg-air-fall .bg-air-p { animation-name: bgFall; }
