/* =========================================================
   KUDZINA logo loader and page transition — layout + static styles
   Shared by the public site and the admin "Preview animation" box.

   All motion lives in public/js/kudzina-anim.js (GSAP): the style
   timelines, the page transitions and the progress tween. This file
   only positions the overlay and defines the static logo, so the mark
   is visible before GSAP boot, and stays visible (un-animated) when
   GSAP is blocked or fails to load.

   Every value comes from Admin → Animation through CSS variables:
     --loader-speed        loop period (slow 3.6s / normal 2.4s / fast 1.6s)
     --loader-bg           overlay background (falls back to --dark)
     --loader-fg           logo colour (falls back to the official #e3d5c2)
     --loader-glow         halo colour
     --loader-accent       glow, orbit dot, vinyl arc and spotlight tint
     --loader-accent-soft  the same accent colour with alpha
     --loader-transition   page transition length
     --loader-origin-x/y   circle reveal origin, set by main.js on click
     --loader-scale        logo size, from data-logo-size below
   ========================================================= */

.logo-loader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8vh 6vw;
  overflow: hidden;
  background: var(--loader-bg, var(--dark, #101110));
  color: var(--loader-fg, #e3d5c2);
  opacity: 1;
  visibility: visible;
  pointer-events: none;
  will-change: opacity;
}

.logo-loader.is-hidden {
  opacity: 0;
  visibility: hidden;
}

.logo-loader-inner {
  position: relative;
  z-index: 3;
  width: calc(min(76vw, 340px) * var(--loader-scale, 1));
  max-width: 100%;
  transform-origin: 50% 50%;
}

.logo-loader[data-logo-size='small'] {
  --loader-scale: 0.72;
}

.logo-loader[data-logo-size='large'] {
  --loader-scale: 1.3;
}

/* Soft stage light, used by the spotlight sweep and the heartbeat glow.
   It sits above the mark so the light travels across it. */
.logo-loader-light {
  position: absolute;
  inset: -20% -55%;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    ellipse 34% 52% at 50% 50%,
    var(--loader-accent-soft, rgba(185, 164, 134, 0.4)) 0%,
    transparent 70%
  );
  mix-blend-mode: screen;
  will-change: transform, opacity;
}

/* Cover / reveal panels, created and animated by kudzina-anim.js.
   They sit under the logo (z-index 1) and above the page. */
.logo-panels {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  overflow: hidden;
  pointer-events: none;
}

.logo-loader.has-panels .logo-panels {
  display: block;
}

.logo-panel {
  position: absolute;
  display: block;
  background-color: var(--loader-bg, var(--dark, #101110));
  transform-origin: 50% 50%;
  will-change: transform;
}

/* ---------------------------------------------------------
   The static mark — the official KUDZINA logo
   (public/uploads/artboard-1-mw6h0uml-3f354baa.png, redrawn on a
   400 x 400 viewBox with the geometry written into the SVG). This
   block only sets the colour and the thin wordmark font; sizes,
   positions and the textLength live in views/partials/logo-loader.ejs
   so the artwork is never re-shaped by CSS.
   --------------------------------------------------------- */

.logo-mark {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: 50% 50%;
}

.logo-line,
.logo-key,
.logo-word {
  fill: var(--loader-fg, #e3d5c2);
}

.logo-line {
  fill: none;
  stroke: var(--loader-fg, #e3d5c2);
  stroke-width: 3;
  stroke-linecap: butt;
}

.logo-key {
  transform-origin: 50% 50%;
}

/* Thin light sans, cap height ~37 on the 400 unit artwork: y 360 -> 397,
   spanning x 2 -> 394 through textLength="392" lengthAdjust="spacing". */
.logo-word {
  font-family: var(--font, 'Inter', 'DejaVu Sans', Helvetica, Arial, sans-serif);
  font-size: 51px;
  font-weight: 300;
  letter-spacing: 0;
}

.logo-loader.no-wordmark .logo-word {
  display: none;
}

/* Decorative layers (record grooves and the orbiting dot) stay hidden
   until the vinyl / orbit style asks for them; the GSAP timeline shows
   them with an inline display. */
.logo-vinyl,
.logo-orbit {
  display: none;
}

.logo-vinyl-ring {
  fill: none;
  stroke: var(--loader-fg, #e3d5c2);
  stroke-width: 0.7;
  opacity: 0.14;
}

.logo-vinyl-ring-outer {
  stroke-width: 1.1;
  opacity: 0.24;
}

.logo-vinyl-arc {
  fill: none;
  stroke: var(--loader-accent, var(--gold, #b9a486));
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 24 100;
  opacity: 0.75;
}

.logo-vinyl-arc-thin {
  stroke-width: 1;
  stroke-dasharray: 46 100;
  opacity: 0.35;
}

.logo-orbit-trail {
  fill: none;
  stroke: var(--loader-accent, var(--gold, #b9a486));
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 22 100;
  stroke-dashoffset: 22;
  opacity: 0.18;
}

.logo-orbit-trail-2 {
  stroke-width: 1.9;
  stroke-dasharray: 14 100;
  stroke-dashoffset: 14;
  opacity: 0.32;
}

.logo-orbit-trail-3 {
  stroke-width: 1.3;
  stroke-dasharray: 7 100;
  stroke-dashoffset: 7;
  opacity: 0.48;
}

.logo-orbit-dot {
  fill: var(--loader-accent, var(--gold, #b9a486));
}

/* ---------------------------------------------------------
   Uploaded image / video as the loader media
   (Admin → Animation → Media type). The picture replaces the SVG
   mark; GSAP only changes its light (opacity), scales it uniformly as
   one unit, or animates the decorative layers below — so an uploaded
   image or video is never distorted.
   --loader-media-size comes from animation.mediaSize (60–600px).
   --------------------------------------------------------- */

.logo-media {
  position: relative;
  display: block;
  width: var(--loader-media-size, 220px);
  max-width: 100%;
  margin: 0 auto;
  transform-origin: 50% 50%;
}

.logo-media-el {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  object-fit: contain;
  transform-origin: 50% 50%;
}

/* The built-in mark and the uploaded media never show at the same time. */
.logo-loader:not([data-media-type='image']):not([data-media-type='video']) .logo-media {
  display: none;
}

.logo-loader[data-media-type='image'] .logo-mark,
.logo-loader[data-media-type='video'] .logo-mark {
  display: none;
}

/* Media is sized by mediaSize, not by the logo size presets. */
.logo-loader[data-media-type='image'] .logo-loader-inner,
.logo-loader[data-media-type='video'] .logo-loader-inner {
  width: auto;
  max-width: 92vw;
}

/* Decorative layers for the vinyl / orbit media styles. They sit outside
   the picture and are only shown by the matching GSAP timeline. */
.logo-media-vinyl,
.logo-media-orbit {
  position: absolute;
  inset: -12%;
  display: none;
  pointer-events: none;
}

.logo-media-vinyl {
  border-radius: 50%;
  border: 1px solid rgba(241, 237, 229, 0.22);
  background-image: repeating-radial-gradient(
    circle at 50% 50%,
    transparent 0 7px,
    rgba(241, 237, 229, 0.09) 7px 8px
  );
}

.logo-media-vinyl::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--loader-accent, var(--gold, #b9a486));
  opacity: 0.7;
}

.logo-media-orbit::after {
  content: '';
  position: absolute;
  top: -4px;
  left: 50%;
  width: 8px;
  height: 8px;
  margin-left: -4px;
  border-radius: 50%;
  background: var(--loader-accent, var(--gold, #b9a486));
  box-shadow: 0 0 12px var(--loader-accent-soft, rgba(185, 164, 134, 0.4));
}

/* Placeholder used by the admin preview when no file is picked yet. */
.logo-media[data-empty='1'] {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(var(--loader-media-size, 220px) * 0.66);
  border: 1px dashed rgba(241, 237, 229, 0.28);
  color: var(--loader-fg, #e3d5c2);
  font-family: var(--font, 'Inter', 'DejaVu Sans', Helvetica, Arial, sans-serif);
  font-size: 10px;
  letter-spacing: 0.2em;
  line-height: 1.7;
  text-align: center;
  text-transform: uppercase;
  opacity: 0.7;
}

.logo-media[data-empty='1']::before {
  content: 'Choose an image or video';
}

/* Soft halo around the mark (Admin → Animation → Glow) */

.logo-loader.has-glow .logo-mark {
  filter: drop-shadow(0 0 18px var(--loader-glow, rgba(227, 213, 194, 0.28)));
}

.logo-loader.has-glow .logo-media-el {
  filter: drop-shadow(0 0 18px var(--loader-glow, rgba(227, 213, 194, 0.28)));
}

/* ---------------------------------------------------------
   Caption and progress bar
   --------------------------------------------------------- */

.logo-caption {
  margin: 1.1rem 0 0;
  color: var(--loader-fg, #e3d5c2);
  font-family: var(--font, 'Inter', 'DejaVu Sans', Helvetica, Arial, sans-serif);
  font-size: 10px;
  letter-spacing: 0.42em;
  line-height: 1.6;
  text-align: center;
  text-transform: uppercase;
  opacity: 0.72;
  will-change: opacity;
}

.logo-caption[hidden] {
  display: none;
}

.logo-caption-dots,
.logo-caption[data-caption-style='percent'] .logo-caption-dots,
.logo-caption[data-caption-style='none'] .logo-caption-dots {
  display: none;
}

.logo-caption[data-caption-style='loading-dots'] .logo-caption-dots {
  display: inline;
}

.logo-caption-dots span {
  opacity: 0.25;
}

.logo-caption-value {
  display: none;
  margin-left: 0.5em;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2em;
}

.logo-caption[data-caption-style='percent'] .logo-caption-value {
  display: inline;
}

.logo-progress {
  position: relative;
  width: 100%;
  height: 1px;
  margin-top: 1.1rem;
  background: rgba(241, 237, 229, 0.18);
  overflow: hidden;
}

.logo-progress[hidden] {
  display: none;
}

/* The width is tweened by KudzinaAnim.progress() — no CSS transition,
   so the bar never fights the GSAP proxy tween. */
.logo-progress-fill {
  display: block;
  width: 0%;
  height: 100%;
  background: var(--loader-accent, var(--gold, #b9a486));
  will-change: width;
}

/* ---------------------------------------------------------
   prefers-reduced-motion — GSAP already falls back to a static
   mark and a plain fade (gsap.matchMedia), these rules keep the
   mark readable even before the module boots.
   --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .logo-loader,
  .logo-panel {
    transition: none !important;
  }

  .logo-loader .logo-key,
  .logo-loader .logo-word,
  .logo-loader .logo-letter {
    opacity: 1 !important;
  }

  .logo-loader .logo-mark {
    opacity: 1;
    filter: none !important;
    clip-path: none !important;
    transform: none !important;
  }

  .logo-loader .logo-media-el {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }

  .logo-loader .logo-media-vinyl,
  .logo-loader .logo-media-orbit {
    display: none !important;
  }

  .logo-loader .logo-line {
    stroke-dashoffset: 0 !important;
  }

  .logo-loader .logo-loader-light {
    display: none;
  }
}

/* ---------------------------------------------------------
   No GSAP — the vendor script was blocked or failed to load.
   main.js flags <html class="no-gsap">, this keeps the static
   logo on screen and lets the hard 4s timeout fade it out.
   --------------------------------------------------------- */

html.no-gsap .logo-loader {
  transition: opacity 240ms ease, visibility 0s linear 0s;
}

html.no-gsap .logo-loader.is-hidden {
  transition: opacity 240ms ease, visibility 0s linear 240ms;
}

html.no-gsap .logo-loader-light,
html.no-gsap .logo-panels {
  display: none !important;
}
