/* Site loader: covers the whole page until the desk and the city are ready (js/main.js).
   A vague street flickers in the haze; it pulls closer once the desk is in (.is-near) and fades as
   the room and the city come into focus (.is-done).
   Everything that moves is opacity or transform, which the browser animates off the main thread,
   so the loader stays alive while the 3D scenes are being built. */

.site-loader {
  --zoom: 1.8s;
  position: fixed;
  inset: 0;
  z-index: 1500; /* over the HUD and menus; under the noscript note */
  overflow: hidden;
  cursor: progress;
  background: linear-gradient(#05030f 0%, #0d0726 30%, #2a0f47 42%, #12081f 60%, #070514 100%);
  transition: opacity 1.1s var(--ease-out);
}

/* neon haze over the street, flickering on its own beat */
.site-loader::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 45% 22% at 50% 42%, rgba(179, 107, 255, .45), transparent 70%),
    radial-gradient(ellipse 30% 40% at 22% 60%, rgba(255, 60, 200, .16), transparent 70%),
    radial-gradient(ellipse 30% 40% at 78% 58%, rgba(63, 243, 255, .13), transparent 70%);
  animation: loader-flicker 2.4s steps(1, end) infinite;
}

.site-loader__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform-origin: 50% 42%; /* the street's vanishing point, as in the real city */
  transition: transform var(--zoom) cubic-bezier(.55, 0, .25, 1);
  will-change: transform, opacity;
}
.site-loader__far {
  fill: #160b2c;
  filter: blur(4px);
  animation: loader-flicker 3.1s steps(1, end) infinite;
}
.site-loader__near {
  fill: #08050f;
  filter: blur(3px);
  animation: loader-flicker 1.9s steps(1, end) infinite reverse;
}
.site-loader__lit { fill: rgba(255, 196, 140, .22); }

.site-loader.is-near .site-loader__far { transform: scale(1.35); }
.site-loader.is-near .site-loader__near { transform: scale(2.3); }

/* ---------- caption: status line and a sweeping neon bar ---------- */

.site-loader__caption {
  position: absolute;
  left: 50%;
  bottom: max(12vh, 64px);
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: min(320px, calc(100vw - 32px));
  text-align: center;
  transition: opacity .5s, transform .8s var(--ease-out);
}

/* small, quiet nametag at the top */
.site-loader__name {
  position: absolute;
  top: max(4vh, 20px);
  left: 50%;
  translate: -50% 0;
  font-family: var(--font-neon);
  font-size: 15px;
  line-height: 1;
  letter-spacing: .3em;
  text-transform: uppercase;
  white-space: nowrap;
  color: color-mix(in srgb, var(--neon-magenta) 25%, #fff);
  text-shadow: 0 0 6px color-mix(in srgb, var(--neon-magenta) 70%, transparent);
  opacity: .55;
  transition: opacity .5s;
}

.site-loader__status {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--holo);
  text-shadow: 0 0 6px rgba(63, 243, 255, .7);
}

.site-loader__bar {
  position: relative;
  width: 100%;
  height: 2px;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(110, 243, 255, .14);
}
.site-loader__bar::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, var(--holo), transparent);
  box-shadow: 0 0 8px var(--holo);
  animation: loader-sweep 1.6s cubic-bezier(.45, 0, .55, 1) infinite;
}

/* ---------- done: fade out (the city's own blur-to-focus runs underneath, css/city.css) ---------- */

.site-loader.is-done { opacity: 0; pointer-events: none; }
.site-loader.is-done .site-loader__caption { opacity: 0; transform: translateY(12px); }
.site-loader.is-done .site-loader__name { opacity: 0; }
.site-loader.is-done::before,
.site-loader.is-done .site-loader__layer { animation-duration: .35s; }

/* Irregular on/off beats, like a neon tube that hasn't caught yet. */
@keyframes loader-flicker {
  0%, 7%, 12%, 40%, 44%, 71% { opacity: 1; }
  5%, 10%, 38%, 42%, 69%, 74% { opacity: .35; }
  76%, 100% { opacity: .9; }
}

@keyframes loader-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(250%); }
}

@media (prefers-reduced-motion: reduce) {
  .site-loader { --zoom: 0s; transition-duration: .3s; }
  .site-loader::before,
  .site-loader__layer { animation: none; }
  .site-loader__bar::after { animation: none; transform: translateX(75%); } /* parked in the middle */
}
