/* =========================================================
   preloader.css — full-screen load sequence
   Depends on studio.css tokens (:root). Link AFTER studio.css.
   Markup is injected by preloader.js (no per-page markup needed).
   ========================================================= */

/* Scroll-lock while the loader is up. preloader.js adds .is-loading to <html>
   as soon as it runs; hard-coding class="is-loading" on <html> kills any
   first-paint scroll before the script executes. */
html.is-loading, html.is-loading body { overflow: hidden; }

#preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  isolation: isolate;
  color: var(--color-text-primary);
  background:
    radial-gradient(ellipse 90% 70% at 50% 18%, rgba(40, 30, 80, 0.30) 0%, transparent 60%),
    radial-gradient(ellipse 80% 55% at 50% 100%, rgba(60, 45, 130, 0.20) 0%, transparent 65%),
    var(--color-bg-base);
}

/* Film grain — same noise field as .grain */
#preloader::after {
  content: "";
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  opacity: 0.05; mix-blend-mode: overlay;
  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.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* Corner registration ticks — same motif as .tick */
.pl-tick {
  position: absolute; width: 14px; height: 14px;
  border-color: rgba(255, 255, 255, 0.3);
  border-style: solid; z-index: 3;
}
.pl-tick.tl { top: 22px; left: 22px;  border-width: 1px 0 0 1px; }
.pl-tick.tr { top: 22px; right: 22px; border-width: 1px 1px 0 0; }
.pl-tick.bl { bottom: 22px; left: 22px;  border-width: 0 0 1px 1px; }
.pl-tick.br { bottom: 22px; right: 22px; border-width: 0 1px 1px 0; }

.pl-content {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center;
  gap: 22px;
  padding: 0 24px;
  width: min(640px, 90vw);
  text-align: center;
}

/* The latent point — the brand-mark diamond, the focal coordinate.
   preloader.js drives rotation via GSAP so the 45deg tilt survives scaling. */
.pl-point {
  width: 13px; height: 13px;
  transform: rotate(45deg);
  border: 1px solid var(--color-violet);
  box-shadow: 0 0 18px rgba(var(--violet-deep-rgb), 0.45);
  position: relative;
}
.pl-point::after {
  content: ""; position: absolute; inset: 3px;
  background: var(--color-violet);
}

/* Status eyebrow — telemetry readout */
.pl-status {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--color-violet-text);
  min-height: 1em;
}

/* Wordmark — display face (Geist), the resolving hero */
.pl-wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(38px, 8.5vw, 92px);
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  display: flex; flex-wrap: nowrap; justify-content: center;
  white-space: nowrap;
  margin: 2px 0 6px;
}
.pl-char {
  display: inline-block;
  min-width: 0.62em;          /* fixed cell stops the scramble from jittering layout */
  text-align: center;
  opacity: 0.28;
  color: var(--color-violet-text);
  filter: blur(6px);
  transform: translateY(0.08em);
  will-change: opacity, filter, transform;
  transition:
    opacity   0.5s var(--ease-spatial),
    filter    0.5s var(--ease-spatial),
    transform 0.5s var(--ease-spatial),
    color     0.6s var(--ease-spatial);
}
.pl-char.is-space { min-width: 0.34em; }
.pl-char.is-resolved {
  opacity: 1; color: var(--color-text-primary);
  filter: blur(0);
  transform: translateY(0);
}

/* Progress row — 1px track (echoes .page-progress) + percent */
.pl-progress {
  display: flex; align-items: center; gap: 16px;
  width: min(360px, 78vw);
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--color-text-tertiary);
}
.pl-track {
  flex: 1; height: 1px;
  background: var(--color-border);
  position: relative; overflow: hidden;
}
.pl-fill {
  position: absolute; inset: 0;
  background: var(--color-text-primary);
  box-shadow: 0 0 12px rgba(var(--violet-deep-rgb), 0.45);
  transform: scaleX(0);
  transform-origin: left center;
}
.pl-pct {
  color: rgba(255, 255, 255, 0.82);
  font-variant-numeric: tabular-nums;
}

/* Fixed brand caption — full studio name + descriptor */
.pl-caption {
  position: absolute; bottom: 26px; left: 0; right: 0; z-index: 1;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.pl-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Reduced motion: no scramble, no blur, no scale — resolved immediately.
   preloader.js also short-circuits its animation path under this preference. */
@media (prefers-reduced-motion: reduce) {
  .pl-char {
    opacity: 1; color: var(--color-text-primary);
    filter: none; transform: none;
    transition: none;
  }
}
