/* Shared ambient "glass" aesthetic for the whole site (is-back/gameplay has its
   own canvas background and doesn't load this).

   Provides:
   - Two slowly drifting layers of soft colour behind the page (body::before/::after,
     z-index -1). For them to show, the page's opaque background must sit on the
     canvas — i.e. on html OR body, not both (a body background painted over an
     html background covers negative-z layers).
   - Frosted <rk-topbar> and <rk-footer>, with a faint light gliding along the
     top bar's bottom edge.
   - .fx-panel: frosted blur + an occasional soft diagonal shine (uses ::after,
     so don't put it on an element that already uses ::after). The panel's own
     background should be translucent (roughly 0.6–0.75 alpha) for the drifting
     colour to show through.
   - .fx-glow: slowly wandering teal/blue corner glows on top of a translucent
     base; set --fx-base to change the base colour.
   - .fx-ripple: .fx-glow + .fx-panel's shine for cards in a list. Driven by
     /components/fx-focus.js (rkFxRipple): each cycle a random on-screen card leads and
     the rest glow weaker and shine later with distance from it (--fx-dist /
     --fx-strength). Without the driver it just loops like .fx-panel. Uses ::after too.
   - .fx-sweep (set by fx-focus.js): one sweep of the shine, for driven cards/panels.
   All motion stops under prefers-reduced-motion. */

@property --fx-sheen { syntax: '<percentage>'; inherits: false; initial-value: -40%; }
@property --fx-gx    { syntax: '<percentage>'; inherits: false; initial-value: 85%; }
@property --fx-gy    { syntax: '<percentage>'; inherits: false; initial-value: -18%; }
/* Inherited so a card's ::after (its shine) follows the card's own value; registered so it
   can transition when the ripple's leader moves. */
@property --fx-strength { syntax: '<number>'; inherits: true; initial-value: 1; }

/* ── Background ─────────────────────────────────────────────────────────────── */
body::before,
body::after {
  content: '';
  position: fixed;
  inset: -25%;
  z-index: -1;
  pointer-events: none;
  will-change: transform;
}
body::before {
  background:
    radial-gradient(34% 28% at 26% 30%, rgba(56,139,253,0.13), transparent 70%),
    radial-gradient(30% 26% at 74% 24%, rgba(0,255,204,0.08), transparent 70%),
    radial-gradient(34% 30% at 58% 76%, rgba(130,90,240,0.08), transparent 70%);
  animation: fx-drift-a 70s ease-in-out infinite alternate;
}
body::after {
  background:
    radial-gradient(24% 20% at 20% 78%, rgba(255,0,102,0.045), transparent 70%),
    radial-gradient(28% 24% at 82% 62%, rgba(56,139,253,0.07), transparent 70%),
    radial-gradient(22% 18% at 50% 40%, rgba(0,255,204,0.04), transparent 70%);
  animation: fx-drift-b 95s ease-in-out infinite alternate;
}
@keyframes fx-drift-a {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
  50%  { transform: translate3d(4%, -3%, 0) rotate(7deg) scale(1.08); }
  100% { transform: translate3d(-3%, 4%, 0) rotate(-5deg) scale(1.03); }
}
@keyframes fx-drift-b {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg) scale(1.05); }
  50%  { transform: translate3d(-5%, 2%, 0) rotate(-8deg) scale(1); }
  100% { transform: translate3d(3%, -4%, 0) rotate(4deg) scale(1.1); }
}

/* ── Top bar & footer ───────────────────────────────────────────────────────── */
rk-topbar,
.rk-topbar {
  background: rgba(22,27,34,0.62);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom-color: rgba(255,255,255,0.07);
}
rk-topbar::after,
.rk-topbar::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 22%;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(to right, transparent, rgba(0,255,204,0.5), transparent);
  animation: fx-edge-x 18s ease-in-out infinite;
}
@keyframes fx-edge-x {
  0%        { transform: translateX(-100%); opacity: 0; }
  8%        { opacity: 1; }
  50%       { opacity: 1; }
  60%, 100% { transform: translateX(460%); opacity: 0; }
}

rk-footer,
.site-footer {
  background:
    radial-gradient(620px circle at 15% -18%, rgba(56,139,253,0.12), transparent 56%),
    radial-gradient(520px circle at 85% -12%, rgba(0,255,204,0.09), transparent 52%),
    linear-gradient(to bottom, rgba(17,17,17,0.6), rgba(12,12,12,0.7)),
    radial-gradient(rgba(125,140,158,0.2) 1px, transparent 1px);
  background-size: auto, auto, 100% 100%, 20px 20px;
  background-repeat: no-repeat, no-repeat, no-repeat, repeat;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* ── Panels ─────────────────────────────────────────────────────────────────── */
.fx-panel {
  position: relative;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.fx-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent calc(var(--fx-sheen) - 14%),
    rgba(255,255,255,0.035) var(--fx-sheen),
    transparent calc(var(--fx-sheen) + 14%));
  animation: fx-sheen 18s ease-in-out infinite;
}
/* Staggered so neighbouring panels don't shine in unison. */
.fx-panel:nth-of-type(3n+2)::after { animation-delay: -6s; }
.fx-panel:nth-of-type(3n+3)::after { animation-delay: -12s; }
@keyframes fx-sheen {
  0%        { --fx-sheen: -40%; }
  35%, 100% { --fx-sheen: 140%; }
}

.fx-glow {
  background:
    radial-gradient(620px circle at var(--fx-gx) var(--fx-gy), rgba(0,255,204,0.10), transparent 56%),
    radial-gradient(520px circle at calc(100% - var(--fx-gx)) calc(100% - var(--fx-gy)), rgba(56,139,253,0.10), transparent 52%),
    var(--fx-base, rgba(16,19,25,0.66));
  animation: fx-glow 38s ease-in-out infinite alternate;
}
@keyframes fx-glow {
  0%   { --fx-gx: 85%; --fx-gy: -18%; }
  50%  { --fx-gx: 62%; --fx-gy: -8%;  }
  100% { --fx-gx: 92%; --fx-gy: 6%;   }
}

.fx-ripple {
  position: relative;
  background:
    radial-gradient(420px circle at var(--fx-gx) var(--fx-gy), rgba(0,255,204,calc(0.10 * var(--fx-strength, 1))), transparent 60%),
    radial-gradient(360px circle at calc(100% - var(--fx-gx)) calc(100% - var(--fx-gy)), rgba(56,139,253,calc(0.10 * var(--fx-strength, 1))), transparent 58%),
    var(--fx-base, rgba(16,19,25,0.66));
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  animation: fx-glow 30s ease-in-out -8s infinite alternate;
  transition: --fx-strength 1.5s ease-in-out;
}
.fx-ripple::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent calc(var(--fx-sheen) - 14%),
    rgba(255,255,255,calc(0.04 * var(--fx-strength, 1))) var(--fx-sheen),
    transparent calc(var(--fx-sheen) + 14%));
  animation: fx-sheen 16s ease-in-out -3s infinite;
}
.fx-ripple-driven .fx-ripple::after { animation: none; }
.fx-ripple-driven .fx-ripple.fx-sweep::after { animation: fx-sweep 5.6s ease-in-out calc(var(--fx-dist, 0) * 0.2s) both; }
@keyframes fx-sweep {
  from { --fx-sheen: -40%; }
  to   { --fx-sheen: 140%; }
}

/* Set by /components/fx-pause.js while an element is off-screen: its glow/shine animations
   repaint every frame, so there's no point running them where nobody can see them. */
.fx-offscreen, .fx-offscreen::before, .fx-offscreen::after { animation-play-state: paused !important; }

/* Mobile GPUs pay per blurred pixel and per radius, and every blur is re-rendered each frame
   the drifting background moves under it — a smaller radius keeps the frosted look for less. */
@media (max-width: 767px) {
  rk-topbar, .rk-topbar, rk-footer, .site-footer, .fx-panel, .fx-ripple {
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  body::before, body::after,
  rk-topbar::after, .rk-topbar::after,
  .fx-panel::after, .fx-glow, .fx-ripple, .fx-ripple::after,
  .fx-ripple-driven .fx-ripple.fx-sweep::after {
    animation: none;
  }
}
