/*
 * web/css/bg.css
 *
 * Ambient background used on states where no peer video is shown
 * (lobby, alone, denied, error). Three layers, all pointer-events:none
 * and sitting behind every interactive surface:
 *
 *   z: -3   base mesh     — two radial pools of colour, centred, static
 *   z: -2   drifting orbs — four blurred blobs that float around the
 *                           centre with unrelated periods so the motion
 *                           never syncs up
 *   z: 9999 film grain    — inline SVG noise, 3.5% opacity, sits above
 *                           everything to kill the "CSS gradient" feel
 *
 * The blobs gravitate toward the centre of the viewport (each keyframe
 * stays within ~25vmax of origin placed near 50%/50%), so attention is
 * naturally drawn to whoever is in the middle of the screen.
 */

:root {
    /* Slightly cooler palette than Strix — more magenta and periwinkle
       than pure violet. Stored as RGB triplets so we can compose
       rgba() with arbitrary alpha everywhere. */
    --orb-1: 124, 77, 255;   /* #7C4DFF  deep violet  */
    --orb-2: 157, 78, 221;   /* #9D4EDD  magenta lean */
    --orb-3: 94, 114, 235;   /* #5E72EB  periwinkle  */
    --orb-4: 201, 124, 255;  /* #C97CFF  soft lilac  */

    --bg-deep:     #07070B;
    --bg-surface:  #0C0C14;
}

/* ─────────────────────────────────────────────────────────────────
   LAYER 1 — base mesh
   Two large soft radial pools both aimed at the centre plus a very
   subtle top-to-bottom lightness curve. Fixed, so it doesn't scroll.
   ───────────────────────────────────────────────────────────────── */
.ambient-bg {
    position: fixed;
    inset: 0;
    z-index: -3;
    pointer-events: none;
    background:
        radial-gradient(ellipse 1200px 900px at 50% 40%,
            rgba(var(--orb-1), 0.22),
            transparent 65%),
        radial-gradient(ellipse 1000px 800px at 50% 60%,
            rgba(var(--orb-2), 0.18),
            transparent 65%),
        linear-gradient(180deg,
            var(--bg-deep) 0%,
            var(--bg-surface) 50%,
            var(--bg-deep) 100%);
}

/* ─────────────────────────────────────────────────────────────────
   LAYER 2 — drifting orbs
   Four blurred circles orbiting the centre of the viewport. Each has
   its own keyframe cycle with a unique, prime-ish period so the four
   never drift in lockstep. mix-blend-mode: screen makes overlapping
   regions brighten into natural flares instead of muddy overlaps.
   ───────────────────────────────────────────────────────────────── */
.ambient-orbs {
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    overflow: hidden;
}

.ambient-orbs .orb {
    position: absolute;
    top: 50%;
    left: 50%;
    border-radius: 50%;
    filter: blur(140px);
    mix-blend-mode: screen;
    will-change: transform, opacity;
}

.ambient-orbs .orb-1 {
    width: 48vmax; height: 48vmax;
    margin: -24vmax 0 0 -24vmax;
    background: radial-gradient(circle,
        rgba(var(--orb-1), 1) 0%,
        transparent 70%);
    opacity: 0.55;
    animation: orb-drift-1 28s ease-in-out infinite;
}

.ambient-orbs .orb-2 {
    width: 52vmax; height: 52vmax;
    margin: -26vmax 0 0 -26vmax;
    background: radial-gradient(circle,
        rgba(var(--orb-2), 1) 0%,
        transparent 70%);
    opacity: 0.45;
    animation: orb-drift-2 37s ease-in-out infinite;
}

.ambient-orbs .orb-3 {
    width: 42vmax; height: 42vmax;
    margin: -21vmax 0 0 -21vmax;
    background: radial-gradient(circle,
        rgba(var(--orb-3), 1) 0%,
        transparent 70%);
    opacity: 0.4;
    animation: orb-drift-3 23s ease-in-out infinite;
}

.ambient-orbs .orb-4 {
    width: 38vmax; height: 38vmax;
    margin: -19vmax 0 0 -19vmax;
    background: radial-gradient(circle,
        rgba(var(--orb-4), 1) 0%,
        transparent 70%);
    opacity: 0.35;
    animation: orb-drift-4 41s ease-in-out infinite;
}

/* Each orbit stays inside ~22vmax of the centre so the mass of colour
   never drifts off-screen and the eye is always pulled to the middle. */
@keyframes orb-drift-1 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    25%      { transform: translate(12vmax, -8vmax) scale(1.08); }
    50%      { transform: translate(4vmax, 14vmax) scale(0.92); }
    75%      { transform: translate(-14vmax, 6vmax) scale(1.05); }
}

@keyframes orb-drift-2 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33%      { transform: translate(-16vmax, 10vmax) scale(0.9); }
    66%      { transform: translate(10vmax, -12vmax) scale(1.12); }
}

@keyframes orb-drift-3 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    20%      { transform: translate(6vmax, 12vmax) scale(1.15); }
    55%      { transform: translate(-12vmax, -4vmax) scale(0.88); }
    80%      { transform: translate(8vmax, -10vmax) scale(1.05); }
}

@keyframes orb-drift-4 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    40%      { transform: translate(-10vmax, -12vmax) scale(1.1); }
    70%      { transform: translate(14vmax, 4vmax) scale(0.95); }
}

/* ─────────────────────────────────────────────────────────────────
   LAYER 3 — film grain
   Inline SVG noise, no network request. Without this the page reads
   as "computer generated gradients"; with it, as "film".
   ───────────────────────────────────────────────────────────────── */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9999;
    opacity: 0.035;
    background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
    mix-blend-mode: overlay;
}

/* ─────────────────────────────────────────────────────────────────
   Hide the ambient layer when active peer video is on-screen. The
   body toggles data-bg="hidden" to fade the whole thing out smoothly.
   ───────────────────────────────────────────────────────────────── */
.ambient-bg,
.ambient-orbs {
    transition: opacity 600ms ease-out;
}

body[data-bg="hidden"] .ambient-bg,
body[data-bg="hidden"] .ambient-orbs {
    opacity: 0;
}

/* Mobile — fewer orbs and softer blur to hold 60fps on weaker GPUs. */
@media (max-width: 767px) {
    .ambient-orbs .orb-3,
    .ambient-orbs .orb-4 { display: none; }
    .ambient-orbs .orb { filter: blur(90px); }
}

/* Respect users who opted out of motion — orbs stop drifting. */
@media (prefers-reduced-motion: reduce) {
    .ambient-orbs .orb { animation: none; }
}

/* When the tab is hidden (visibilitychange -> body[data-visible="no"]),
   pause every orb animation to save battery on mobile. */
body[data-visible="no"] .ambient-orbs .orb { animation-play-state: paused; }
