/* =========================================================
   PARALLAX — atmosphere stylesheet
   Palette: void #040404 / deep violet / faint blue / white
   ========================================================= */

:root {
  --void: #040404;
  --violet: 168, 120, 255;
  --violet-deep: 78, 44, 150;
  --blue: 96, 140, 220;
  --white: 255, 255, 255;

  --ease-soft: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  overflow: hidden; /* no scrolling, ever */
  background: var(--void);
}

body {
  font-family: "Jost", "Helvetica Neue", sans-serif;
  color: rgb(var(--white));
  cursor: none; /* the cursor becomes the light */
  -webkit-font-smoothing: antialiased;
  user-select: none;
}

/* ---------------------------------------------------------
   WORLD — the moving camera
   --------------------------------------------------------- */
#world {
  position: fixed;
  inset: -8vmax;
  perspective: 1200px;
  transform-style: preserve-3d;
  will-change: transform;
}

/* ---------------------------------------------------------
   FOG — thin atmospheric depth layers, never clouds
   --------------------------------------------------------- */
.fog-layer {
  position: absolute;
  inset: -20%;
  will-change: transform, opacity;
  pointer-events: none;
  opacity: 0;
  animation: fogReveal 9s var(--ease-soft) forwards;
  background:
    radial-gradient(
      55% 34% at 22% 62%,
      rgba(var(--violet-deep), 0.1) 0%,
      rgba(var(--violet-deep), 0) 70%
    ),
    radial-gradient(48% 26% at 74% 38%, rgba(var(--blue), 0.08) 0%, rgba(var(--blue), 0) 72%);
  filter: blur(60px);
  animation:
    fogReveal 9s var(--ease-soft) forwards,
    fogDrift 170s ease-in-out infinite alternate;
}

.fog-layer--b {
  animation-delay: 1.4s, 0s;
  animation-duration: 13s, 226s;
  background:
    radial-gradient(60% 30% at 68% 74%, rgba(var(--violet), 0.08) 0%, rgba(var(--violet), 0) 72%),
    radial-gradient(40% 22% at 34% 26%, rgba(var(--white), 0.045) 0%, rgba(var(--white), 0) 74%);
  filter: blur(90px);
}

.fog-layer--c {
  animation-delay: 2.6s, 0s;
  animation-duration: 16s, 288s;
  background: radial-gradient(
    70% 40% at 50% 108%,
    rgba(var(--violet-deep), 0.13) 0%,
    rgba(var(--violet-deep), 0) 76%
  );
  filter: blur(120px);
}

/* --d: the far haze that sits behind everything */
.fog-layer--d {
  animation-delay: 3.6s, 0s;
  animation-duration: 18s, 340s;
  background:
    radial-gradient(80% 46% at 30% 22%, rgba(var(--blue), 0.05) 0%, rgba(var(--blue), 0) 74%),
    radial-gradient(64% 38% at 84% 68%, rgba(var(--violet-deep), 0.08) 0%, rgba(var(--violet-deep), 0) 76%);
  filter: blur(150px);
}

/* --e / --f: thin near banks that the creatures can pass behind */
.fog-layer--e {
  animation-delay: 4.8s, 0s;
  animation-duration: 20s, 212s;
  background:
    linear-gradient(
      104deg,
      rgba(var(--white), 0) 26%,
      rgba(var(--violet), 0.05) 46%,
      rgba(var(--white), 0.022) 56%,
      rgba(var(--white), 0) 74%
    );
  filter: blur(46px);
  mix-blend-mode: screen;
}

.fog-layer--f {
  animation-delay: 6.2s, 0s;
  animation-duration: 22s, 258s;
  background: linear-gradient(
    78deg,
    rgba(var(--white), 0) 34%,
    rgba(var(--blue), 0.045) 52%,
    rgba(var(--white), 0) 70%
  );
  filter: blur(64px);
  mix-blend-mode: screen;
}

@keyframes fogReveal {
  to {
    opacity: 1;
  }
}

@keyframes fogDrift {
  0% {
    transform: translate3d(-4%, 1.5%, 0) scale(1.06);
  }
  33% {
    transform: translate3d(1%, -1%, 0) scale(1.12);
  }
  66% {
    transform: translate3d(3%, -2.4%, 0) scale(1.16);
  }
  100% {
    transform: translate3d(-2%, 2.5%, 0) scale(1.09);
  }
}

/* ---------------------------------------------------------
   VOLUMETRIC RAYS — faint shafts leaning out of the center.
   Long, blurred, blended, never quite readable as shapes.
   --------------------------------------------------------- */
#rays {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
  opacity: 0;
  animation: fogReveal 18s var(--ease-soft) 4s forwards;
}

#rays span {
  position: absolute;
  left: 0;
  bottom: 0;
  width: var(--w);
  height: 132vmax;
  transform-origin: 50% 100%;
  transform: translateX(-50%) rotate(var(--r));
  background: linear-gradient(
    to top,
    rgba(var(--violet), 0.05) 0%,
    rgba(var(--violet), 0.02) 34%,
    rgba(var(--white), 0.012) 62%,
    rgba(var(--white), 0) 100%
  );
  filter: blur(26px);
  mix-blend-mode: screen;
  animation: raySway 118s ease-in-out infinite alternate;
  animation-delay: var(--d);
}

#rays span:nth-child(even) {
  animation-duration: 154s;
  background: linear-gradient(
    to top,
    rgba(var(--blue), 0.035) 0%,
    rgba(var(--blue), 0.02) 40%,
    rgba(var(--white), 0) 100%
  );
}

@keyframes raySway {
  0% {
    opacity: 0.4;
    transform: translateX(-50%) rotate(calc(var(--r) - 2.5deg)) scaleX(0.9);
  }
  50% {
    opacity: 0.9;
    transform: translateX(-50%) rotate(var(--r)) scaleX(1.15);
  }
  100% {
    opacity: 0.55;
    transform: translateX(-50%) rotate(calc(var(--r) + 2.5deg)) scaleX(0.95);
  }
}

/* ---------------------------------------------------------
   AMBIENT LIGHTING — soft bloom pools
   --------------------------------------------------------- */
.ambient {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  filter: blur(130px);
  opacity: 0;
  animation:
    ambientReveal 14s var(--ease-soft) forwards,
    ambientBreathe 44s ease-in-out infinite;
}

.ambient--violet {
  width: 78vmin;
  height: 78vmin;
  left: 50%;
  top: 50%;
  margin: -39vmin 0 0 -39vmin;
  background: radial-gradient(circle, rgba(var(--violet), 0.12) 0%, rgba(var(--violet), 0) 70%);
}

.ambient--blue {
  width: 120vmin;
  height: 120vmin;
  left: 50%;
  top: 46%;
  margin: -60vmin 0 0 -60vmin;
  animation-duration: 22s, 64s;
  background: radial-gradient(circle, rgba(var(--blue), 0.06) 0%, rgba(var(--blue), 0) 68%);
}

@keyframes ambientReveal {
  to {
    opacity: 1;
  }
}

@keyframes ambientBreathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.12);
  }
}

/* ---------------------------------------------------------
   PARTICLES
   --------------------------------------------------------- */
#particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  animation: fogReveal 12s var(--ease-soft) 1s forwards;
}

/* ---------------------------------------------------------
   THE CENTER — sacred
   --------------------------------------------------------- */
#center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
}

#core {
  position: relative;
  width: 1px;
  height: 1px;
  --pulse: 0; /* raised by script.js when the creatures meet */
}

#core span {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.core__dot {
  width: 4px;
  height: 4px;
  background: rgb(var(--white));
  box-shadow: 0 0 calc(10px + var(--pulse) * 22px) rgba(var(--white), 0.9);
  opacity: 0;
  animation:
    coreReveal 8s var(--ease-soft) 0.8s forwards,
    coreFlicker 19s ease-in-out 8s infinite;
}

.core__halo {
  width: calc(30px + var(--pulse) * 26px);
  height: calc(30px + var(--pulse) * 26px);
  background: radial-gradient(circle, rgba(var(--white), 0.3) 0%, rgba(var(--white), 0) 70%);
  filter: blur(6px);
  opacity: 0;
  animation:
    coreReveal 12s var(--ease-soft) 1.4s forwards,
    corePulse 21s ease-in-out 12s infinite;
}

.core__bloom {
  width: calc(240px + var(--pulse) * 190px);
  height: calc(240px + var(--pulse) * 190px);
  background: radial-gradient(
    circle,
    rgba(var(--violet), calc(0.13 + var(--pulse) * 0.16)) 0%,
    rgba(var(--violet-deep), 0.05) 42%,
    rgba(var(--violet), 0) 72%
  );
  filter: blur(28px);
  opacity: 0;
  animation:
    coreReveal 16s var(--ease-soft) 2s forwards,
    corePulse 47s ease-in-out 16s infinite;
}

@keyframes coreReveal {
  to {
    opacity: 1;
  }
}

/* almost imperceptible — a breath, not a pulse */
@keyframes corePulse {
  0%,
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.9;
  }
  50% {
    transform: translate(-50%, -50%) scale(1.055);
    opacity: 1;
  }
}

@keyframes coreFlicker {
  0%,
  100% {
    opacity: 1;
  }
  46% {
    opacity: 0.88;
  }
  54% {
    opacity: 0.97;
  }
}

#legend {
  margin-top: clamp(72px, 12vh, 130px);
  font-weight: 100;
  font-size: clamp(0.6rem, 1.05vw, 0.82rem);
  letter-spacing: 1.15em;
  text-indent: 1.15em;
  text-transform: uppercase;
  color: rgba(var(--white), 0.8);
  opacity: 0;
  animation:
    legendReveal 11s var(--ease-soft) 3.4s forwards,
    legendBreathe 26s ease-in-out 16s infinite;
}

@keyframes legendReveal {
  from {
    opacity: 0;
    filter: blur(7px);
    letter-spacing: 1.5em;
  }
  to {
    opacity: 1;
    filter: blur(0);
    letter-spacing: 1.15em;
  }
}

@keyframes legendBreathe {
  0%,
  100% {
    opacity: 0.78;
  }
  50% {
    opacity: 0.52;
  }
}

/* ---------------------------------------------------------
   CREATURES
   --------------------------------------------------------- */
.creature {
  position: absolute;
  left: 0;
  top: 0;
  will-change: transform, opacity;
  pointer-events: none;
  opacity: 0;
}

.creature__wing {
  will-change: transform;
  transform-style: preserve-3d;
}

.creature img {
  display: block;
  width: 100%;
  height: auto;
}

#moth {
  width: 16vmin;
  filter: brightness(0.4) contrast(1.12) saturate(0.42) blur(var(--haze, 0.5px))
    drop-shadow(0 0 16px rgba(var(--violet-deep), 0.4));
}

#butterfly {
  width: 11vmin;
  filter: brightness(1.3) saturate(0.32) blur(var(--haze, 0.35px))
    drop-shadow(0 0 22px rgba(var(--violet), 0.42));
}

/* ---------------------------------------------------------
   GRAIN + VIGNETTE
   --------------------------------------------------------- */
#grain {
  position: fixed;
  inset: -50%;
  pointer-events: none;
  opacity: 0.038;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='4'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  animation: grainShift 9s steps(8) infinite;
  filter: blur(0.2px) contrast(1.1);
}

@keyframes grainShift {
  0% {
    transform: translate3d(0, 0, 0);
  }
  20% {
    transform: translate3d(-3%, 2%, 0);
  }
  40% {
    transform: translate3d(2%, -3%, 0);
  }
  60% {
    transform: translate3d(-2%, -2%, 0);
  }
  80% {
    transform: translate3d(3%, 1%, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

#vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(108% 82% at 50% 50%, rgba(4, 4, 4, 0) 22%, rgba(4, 4, 4, 0.6) 62%, rgba(4, 4, 4, 0.97) 100%),
    linear-gradient(rgba(4, 4, 4, 0.28), rgba(4, 4, 4, 0) 22%, rgba(4, 4, 4, 0) 78%, rgba(4, 4, 4, 0.4));
}

/* First-load fade from pure black */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--void);
  pointer-events: none;
  animation: openFromBlack 5s var(--ease-soft) forwards;
}

@keyframes openFromBlack {
  to {
    opacity: 0;
  }
}

/* Reserved stage for future chapters — inert for now */
#layer-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
  }
}
