/* ═══════════════════════════════════════════════════════════════════════
   KRAY•SPACE — shared cosmic background ("space bg")
   Extracted from index.html's hero (.wp-cosmos: .wp-stars / .wp-glow /
   .wp-aurora / .wp-shooting + wpTwinkle/wpBreath/wpAurora/wpShoot).
   The home keeps its own hero-scoped copy (position:absolute inside the
   hero <section>); this version is VIEWPORT-FIXED so a single wrapper can
   sit behind any page. Layer styles, gradient stops, sizes, durations and
   delays are copied verbatim — only the containing element changed from
   `absolute` (within a `position:relative` hero) to `fixed` (viewport).
   Class/keyframe names are intentionally unprefixed (wp-*) to match the
   home 1:1; before reusing this on a new page, grep it for wp-stars /
   wp-glow / wp-aurora / wp-shooting / wpTwinkle / wpBreath / wpAurora /
   wpShoot and namespace here as ksb* if it already defines any of them.
   ═══════════════════════════════════════════════════════════════════════ */

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

/* Pages that use this file paint their own opaque `body` background (some
   with `!important`, e.g. ordinals.html / krayscan.html's "Dark Apple
   refresh" layer). `html {}` supplies the canvas paint underneath
   everything (no white flash), and `body {}` is forced transparent so the
   fixed, negative-z-index star field shows through: in normal stacking
   order, `body`'s own in-flow box background paints *after* (i.e. on top
   of) negative z-index descendants, so an opaque body would otherwise
   hide this layer completely. `html body` (rather than plain `body`) is
   used so this rule's specificity (0,0,0,2) beats a page's own
   `body { background: ... !important }` (0,0,0,1) even when that page's
   rule appears later in the document than this stylesheet's <link>. */
html { background: #000; }
html body { background: transparent !important; }

/* Star field: two depth layers of tiny dots, slow twinkle + drift */
.kray-space-bg .wp-stars {
    position: absolute; inset: -50px;
    background-image:
        radial-gradient(1.5px 1.5px at 12% 22%, rgba(255,255,255,.55) 50%, transparent 51%),
        radial-gradient(1px 1px at 28% 68%, rgba(255,255,255,.4) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 43% 12%, rgba(255,255,255,.5) 50%, transparent 51%),
        radial-gradient(1px 1px at 61% 41%, rgba(255,255,255,.35) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 74% 76%, rgba(255,255,255,.5) 50%, transparent 51%),
        radial-gradient(1px 1px at 88% 18%, rgba(255,255,255,.4) 50%, transparent 51%),
        radial-gradient(1px 1px at 52% 88%, rgba(255,255,255,.35) 50%, transparent 51%),
        radial-gradient(1.5px 1.5px at 94% 56%, rgba(255,255,255,.45) 50%, transparent 51%);
    background-size: 720px 720px;
    animation: wpTwinkle 7s ease-in-out infinite alternate;
}
.kray-space-bg .wp-stars--far {
    background-size: 420px 420px;
    opacity: .45;
    animation-duration: 11s;
    animation-delay: -4s;
}

/* Nebula glow, breathing */
.kray-space-bg .wp-glow {
    position: absolute;
    left: 72%; top: 52%;
    width: 900px; height: 640px;
    transform: translate(-50%, -50%);
    background: radial-gradient(ellipse at center,
        rgba(120,140,255,.10) 0%,
        rgba(255,255,255,.05) 32%,
        transparent 68%);
    animation: wpBreath 9s ease-in-out infinite;
    filter: blur(2px);
}

/* Aurora: huge blurred color fields drifting like a nebula */
.kray-space-bg .wp-aurora {
    position: absolute; inset: -20%;
    background:
        radial-gradient(42% 30% at 28% 32%, rgba(94,110,255,.10), transparent 70%),
        radial-gradient(38% 28% at 72% 60%, rgba(160,90,255,.08), transparent 70%),
        radial-gradient(30% 24% at 55% 20%, rgba(255,255,255,.05), transparent 70%);
    filter: blur(34px);
    animation: wpAurora 18s ease-in-out infinite alternate;
}

/* Shooting stars: invisible most of the cycle, then a fast streak */
.kray-space-bg .wp-shooting {
    position: absolute; top: 16%; left: -8%;
    width: 130px; height: 2px; border-radius: 2px;
    background: linear-gradient(90deg, rgba(255,255,255,.95), transparent);
    transform: rotate(12deg);
    opacity: 0;
    animation: wpShoot 9s linear infinite;
    animation-delay: 3s;
}
.kray-space-bg .wp-shooting--2 {
    top: 38%; left: -5%;
    width: 90px;
    transform: rotate(9deg);
    animation-duration: 13s;
    animation-delay: 8.5s;
}

@keyframes wpTwinkle {
    0% { opacity: .5; }
    100% { opacity: 1; }
}
@keyframes wpBreath {
    0%, 100% { opacity: .7; transform: translate(-50%, -50%) scale(1); }
    50% { opacity: 1; transform: translate(-50%, -50%) scale(1.07); }
}
@keyframes wpAurora {
    to { transform: translate3d(4%, 3%, 0) scale(1.08); }
}
@keyframes wpShoot {
    0%, 91% { opacity: 0; translate: 0 0; }
    93% { opacity: 1; }
    100% { opacity: 0; translate: 62vw 13vw; }
}

/* Performance guards ────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .kray-space-bg * { animation: none !important; }
    .kray-space-bg .wp-shooting { display: none; }
}

/* The blurred layers (glow, aurora) are the only GPU-costly ones — phones
   keep just the (cheap) star field. */
@media (max-width: 720px) {
    .kray-space-bg .wp-glow, .kray-space-bg .wp-aurora { display: none; }
}
