/* ═══════════════════════════════════════════════════════════════════════
   SPACE BACKGROUND — the shared 2027 sky.
   Used by the marketing page (every section below the hero) and by the
   portal/lobby. Injected by space_bg.js, which builds the layers and the
   starfield; this file is only the styling.

   Rules: 2027_WEB_UX_Guidelines.html §2 (WEB27-BG-01..04).
   The plates are painted on PURE BLACK and composited with
   mix-blend-mode:screen, which is what makes the black disappear — they are
   not transparent PNGs. Each is pinned to its own edge and masked so its
   inner side fades rather than showing a straight cut.

   z-index:-1 puts the whole thing behind page content without the content
   needing a z-index of its own.

   TRAP: that only works while the page's BODY background is transparent.
   A body background normally propagates to the canvas and is painted below
   everything -- but the moment <html> has a background of its own, body's
   stops propagating and becomes an ordinary element background, which paints
   ON TOP of anything at z-index:-1 and hides the whole sky. portal.html did
   exactly this (`html, body { background: var(--bg) }`). Keep the fallback
   colour on <html> and set `body { background: transparent; }`.
   ═══════════════════════════════════════════════════════════════════════ */

.space-bg {
  position: fixed; inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

/* base sky — almost black, very slightly blue toward the bottom */
.space-bg .sky {
  position: absolute; inset: 0;
  background:
    radial-gradient(70% 50% at 82% 6%, rgba(40,60,160,0.20) 0%, transparent 70%),
    linear-gradient(178deg, #03040c 0%, #050716 40%, #06081c 72%, #08091f 100%);
}

/* the three painted nebula plates */
.space-bg .neb-img {
  position: absolute;
  background-repeat: no-repeat;
  mix-blend-mode: screen;
}
.space-bg .neb-left {
  left: 0; top: 0; bottom: 0; width: 48vw; opacity: .80;
  background-image: url('/static/bg/Nebula_left_Darker.png');
  background-position: left center;
  background-size: auto 100%;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 55%, transparent 100%);
          mask-image: linear-gradient(90deg, #000 0%, #000 55%, transparent 100%);
}
.space-bg .neb-tr {
  right: 0; top: 0; width: 66vw; height: 70vh; opacity: .78;
  background-image: url('/static/bg/Nebula_topright.png');
  background-position: right top;
  background-size: cover;
  -webkit-mask-image: linear-gradient(200deg, #000 0%, #000 45%, transparent 92%);
          mask-image: linear-gradient(200deg, #000 0%, #000 45%, transparent 92%);
}
.space-bg .neb-bot {
  left: 0; right: 0; bottom: 0; height: 46vh; opacity: .62;
  background-image: url('/static/bg/Nebula_botton.png');
  background-position: center bottom;
  background-size: 100% auto;
  /* the plate is cropped by the viewport, so fade the cut away */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 100%);
}

/* purple bloom along the very bottom edge */
.space-bg .horizon {
  position: absolute; left: -10%; right: -10%; bottom: -150px; height: 320px;
  opacity: .35;
  background: radial-gradient(60% 100% at 50% 100%,
    rgba(139,92,246,0.34) 0%, rgba(99,102,241,0.13) 45%, transparent 76%);
  filter: blur(28px);
}

.space-bg .vignette {
  position: absolute; inset: 0;
  background: radial-gradient(135% 105% at 50% 40%, transparent 62%, rgba(0,0,0,0.38) 100%);
}

/* ── starfield: five sizes, sparse, a few twinkling, one pulsar ──────── */
.space-bg .star { position: absolute; border-radius: 50%; background: #e8f0ff; }
.space-bg .star.s4 { box-shadow: 0 0 5px 1px rgba(191,219,254,0.45); }
.space-bg .star.s5 { box-shadow: 0 0 7px 1.5px rgba(191,219,254,0.60); }
.space-bg .star.tw {
  animation: spacebg-twinkle var(--dur, 5s) ease-in-out infinite;
  animation-delay: var(--dly, 0s);
}
@keyframes spacebg-twinkle {
  0%, 100% { opacity: var(--o, .5); transform: scale(1); }
  50%      { opacity: calc(var(--o, .5) * 0.25); transform: scale(.82); }
}

/* one slow pulsing star with diffraction spikes — the only motion besides
   the twinkle, and the entire motion budget for the background */
.space-bg .pulsar {
  position: absolute; width: 3px; height: 3px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 10px 3px rgba(199,210,254,.75);
  animation: spacebg-pulse 6.5s ease-in-out infinite;
}
.space-bg .pulsar::before,
.space-bg .pulsar::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
}
.space-bg .pulsar::before {
  width: 26px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(226,232,255,.65), transparent);
}
.space-bg .pulsar::after {
  width: 1px; height: 26px;
  background: linear-gradient(180deg, transparent, rgba(226,232,255,.65), transparent);
}
@keyframes spacebg-pulse {
  0%, 100% { opacity: .35; transform: scale(.85); }
  50%      { opacity: 1;   transform: scale(1.15); }
}

/* Respect the OS setting. The sky still renders; it just stops moving.
   Touch-first devices (iPad, phone) get the same still sky: the twinkle and
   pulsar keep re-compositing the screen-blended, masked nebula plates under
   the map every frame, which made globe rotation laggy on iPad. Keyed on the
   PRIMARY pointer, so a touchscreen laptop (primary pointer = mouse/trackpad)
   keeps the motion. Promoting the sky to its own layer lets the browser
   rasterise it once and reuse it while the map redraws above it. */
@media (prefers-reduced-motion: reduce), (hover: none) and (pointer: coarse) {
  .space-bg .star.tw,
  .space-bg .pulsar { animation: none; }
  .space-bg { transform: translateZ(0); }
}
