/* ==========================================================================
   FINE ART PRODUCTION — Motion Layer
   Page loader, scroll reveals, split-text, parallax, magnetic cursor.
   Every effect degrades gracefully under prefers-reduced-motion.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PAGE LOADER / CURTAIN
   -------------------------------------------------------------------------- */
.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  background: var(--ink-900);
  color: var(--gold-300);
  transition: clip-path 1s var(--ease-in-out), visibility 1s;
  clip-path: inset(0 0 0 0);
}
.loader.is-done {
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  pointer-events: none;
}

.loader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4rem;
  transition: opacity 0.5s var(--ease-out), transform 0.6s var(--ease-out);
}
.loader.is-done .loader__inner { opacity: 0; transform: translateY(-14px); }

.loader__mark {
  width: 62px;
  height: 62px;
  object-fit: contain;
  border-radius: 50%;
  animation: loaderPulse 2s var(--ease-in-out) infinite;
}
@keyframes loaderPulse {
  0%, 100% { opacity: 0.55; transform: scale(0.94); }
  50% { opacity: 1; transform: scale(1); }
}

.loader__name {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  text-indent: 0.42em;
  color: var(--gold-200);
}

.loader__bar {
  width: 190px;
  height: 1px;
  background: rgba(217, 189, 133, 0.22);
  overflow: hidden;
}
.loader__bar::after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  background: var(--gold-300);
  transform: scaleX(var(--load, 0));
  transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}

/* --------------------------------------------------------------------------
   2. SCROLL REVEALS
   Elements start hidden only once JS confirms it is running (html.js),
   so no-JS visitors still see everything.
   -------------------------------------------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out), transform 1s var(--ease-out), clip-path 1.1s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

/* Default: rise */
.js [data-reveal] { transform: translateY(34px); }

/* Variants */
.js [data-reveal="fade"] { transform: none; }
.js [data-reveal="left"] { transform: translateX(-46px); }
.js [data-reveal="right"] { transform: translateX(46px); }
.js [data-reveal="zoom"] { transform: scale(0.94); }
.js [data-reveal="blur"] { transform: translateY(20px); filter: blur(9px); }

/* Wipe variants clip their CHILD, never themselves.
   Clipping the observed element to zero height makes its intersection area
   zero, so IntersectionObserver never reports it as visible and it stays
   hidden forever. Keeping the element's own box intact avoids that deadlock. */
.js [data-reveal="wipe"],
.js [data-reveal="wipe-x"] {
  opacity: 1;
  transform: none;
  clip-path: none;
}
.js [data-reveal="wipe"] > *,
.js [data-reveal="wipe-x"] > * {
  transition: clip-path 1.1s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal="wipe"] > * { clip-path: inset(0 0 100% 0); }
.js [data-reveal="wipe-x"] > * { clip-path: inset(0 100% 0 0); }
.js [data-reveal="wipe"].is-in > *,
.js [data-reveal="wipe-x"].is-in > * { clip-path: inset(0 0 0 0); }

/* Revealed state */
.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Staggered children */
.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.8s var(--ease-out), transform 0.9s var(--ease-out);
}
.js [data-stagger].is-in > * { opacity: 1; transform: none; }
.js [data-stagger].is-in > *:nth-child(1) { transition-delay: 0ms; }
.js [data-stagger].is-in > *:nth-child(2) { transition-delay: 90ms; }
.js [data-stagger].is-in > *:nth-child(3) { transition-delay: 180ms; }
.js [data-stagger].is-in > *:nth-child(4) { transition-delay: 270ms; }
.js [data-stagger].is-in > *:nth-child(5) { transition-delay: 360ms; }
.js [data-stagger].is-in > *:nth-child(6) { transition-delay: 450ms; }
.js [data-stagger].is-in > *:nth-child(7) { transition-delay: 540ms; }
.js [data-stagger].is-in > *:nth-child(8) { transition-delay: 630ms; }
.js [data-stagger].is-in > *:nth-child(n + 9) { transition-delay: 700ms; }

/* --------------------------------------------------------------------------
   3. SPLIT TEXT (word-by-word headline reveal)
   -------------------------------------------------------------------------- */
.split-line { display: block; overflow: hidden; }

.split-word {
  display: inline-block;
  transform: translateY(105%) rotate(3deg);
  opacity: 0;
  transition: transform 1.05s var(--ease-out), opacity 0.8s var(--ease-out);
  transition-delay: calc(var(--w, 0) * 55ms);
  will-change: transform;
}
.is-in .split-word,
.split-ready .split-word { transform: none; opacity: 1; }

/* The wrapper keeps a literal space between words, so no extra margin here —
   adding one would double the gap. */

/* --------------------------------------------------------------------------
   4. PARALLAX & SCROLL-LINKED
   -------------------------------------------------------------------------- */
[data-parallax] {
  will-change: transform;
  transition: transform 0.15s linear;
}

.hero__media img,
.hero__media video {
  transform: scale(1.12);
  animation: kenBurns 26s var(--ease-in-out) infinite alternate;
}
@keyframes kenBurns {
  from { transform: scale(1.1) translate3d(0, 0, 0); }
  to { transform: scale(1.2) translate3d(-1.5%, -1.5%, 0); }
}
.hero__media video { animation: none; transform: scale(1.02); }

/* Image mask reveal for editorial media */
.js .media[data-reveal="wipe"] img { transform: scale(1.14); transition: transform 1.4s var(--ease-out); }
.js .media[data-reveal="wipe"].is-in img { transform: scale(1); }

/* --------------------------------------------------------------------------
   5. MAGNETIC CURSOR (desktop, fine pointer only)
   -------------------------------------------------------------------------- */
.cursor,
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  transition: opacity 0.3s var(--ease-out), width 0.35s var(--ease-out), height 0.35s var(--ease-out),
    background-color 0.35s var(--ease-out), border-color 0.35s var(--ease-out);
  mix-blend-mode: difference;
}

.cursor {
  width: 34px;
  height: 34px;
  border: 1px solid rgba(255, 255, 255, 0.8);
  transform: translate3d(-50%, -50%, 0);
}
.cursor-dot {
  width: 5px;
  height: 5px;
  background: #fff;
  transform: translate3d(-50%, -50%, 0);
}

body.cursor-ready .cursor,
body.cursor-ready .cursor-dot { opacity: 1; }

body.cursor-hover .cursor {
  width: 66px;
  height: 66px;
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.95);
}
body.cursor-hover .cursor-dot { opacity: 0; }

body.cursor-zoom .cursor {
  width: 82px;
  height: 82px;
  background: rgba(255, 255, 255, 0.14);
  border-color: transparent;
}
body.cursor-zoom .cursor::after {
  content: "VIEW";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-sans);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  color: #fff;
}

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-dot { display: none; }
}

/* Magnetic pull target */
[data-magnetic] {
  transition: transform 0.35s var(--ease-out);
  will-change: transform;
}

/* --------------------------------------------------------------------------
   6. THEME SWITCH TRANSITION
   -------------------------------------------------------------------------- */
.theme-ripple {
  position: fixed;
  z-index: 8500;
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0);
  animation: themeRipple 0.75s var(--ease-in-out) forwards;
}
@keyframes themeRipple {
  to { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

/* --------------------------------------------------------------------------
   7. MICRO-ANIMATIONS
   -------------------------------------------------------------------------- */
@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-12px); }
}
.float { animation: floatY 6s var(--ease-in-out) infinite; }

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.shimmer-text {
  background: linear-gradient(90deg, var(--text) 25%, var(--accent) 50%, var(--text) 75%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shimmer 5s linear infinite;
}

@keyframes spinSlow { to { transform: rotate(360deg); } }
.spin-badge {
  animation: spinSlow 22s linear infinite;
  transform-origin: center;
}

/* Counter roll-in */
.counter { display: inline-block; font-variant-numeric: tabular-nums; }

/* Lazy image fade */
img[loading="lazy"] { background: var(--bg-alt); }
.img-fade { opacity: 0; transition: opacity 0.7s var(--ease-out); }
.img-fade.is-loaded { opacity: 1; }

/* Hover lift utility */
.lift { transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out); }
.lift:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

/* Underline sweep for inline links inside prose */
.prose-link {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size 0.45s var(--ease-out);
  color: var(--accent);
}
.prose-link:hover { background-size: 100% 1px; }

/* --------------------------------------------------------------------------
   8. REDUCED MOTION — flatten everything
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal],
  .js [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
  }

  .js [data-reveal="wipe"] > *,
  .js [data-reveal="wipe-x"] > * { clip-path: none !important; }

  .split-word { opacity: 1 !important; transform: none !important; }
  .hero__media img, .hero__media video { animation: none; transform: none; }
  .cursor, .cursor-dot { display: none; }
  .marquee__track { animation: none; }
  .grain { display: none; }
}
