/* ==========================================================================
   ANIMATION SUPPORT STYLES
   Base states for elements GSAP animates + reduced-motion fallbacks.
   If JS never runs, everything here still renders fully visible.
   ========================================================================== */

[data-reveal] {
  opacity: 1;
  transform: none;
}

/* Only clip/hide once JS confirms it is ready to animate — prevents
   permanent-hidden-content bugs if a script fails to load. */
.js-ready [data-reveal="up"] { opacity: 0; transform: translateY(40px); }
.js-ready [data-reveal="fade"] { opacity: 0; }
.js-ready [data-reveal="scale"] { opacity: 0; transform: scale(.94); }
.js-ready [data-reveal="mask"] { clip-path: inset(0 0 100% 0); }

/* Hero title / shout lines: hidden state is applied by animations.js via
   gsap.set() instead of here. GSAP tracks yPercent as an axis separate
   from a CSS-parsed pixel transform, so setting translateY(110%) in CSS
   and then tweening yPercent in JS leaves a stray untweened pixel offset.
   Owning the whole lifecycle in JS also means the text stays visible by
   default if animations.js ever fails to load. */

.js-ready .studio-side { opacity: 0; }
.js-ready .studio-main { clip-path: inset(0 0 0 0); }

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

/* Service ticker marquee */
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.ticker-track {
  animation: marquee 32s linear infinite;
}
.ticker:hover .ticker-track { animation-play-state: paused; }

/* Depth-layer helper for cursor-responsive parallax */
[data-depth] { will-change: transform; }

/* Loading lock — only while preloader is actively running */
.preload-lock { overflow: hidden; height: 100vh; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .js-ready [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .js-ready .hero-title .line span,
  .js-ready .shout-text span b { transform: none !important; }
  .js-ready .studio-side { opacity: 1 !important; }
  .js-ready .story-panel,
  .js-ready .story-media { position: relative !important; opacity: 1 !important; transform: none !important; inset: auto !important; }
  .ticker-track { animation: none !important; }
  .cursor, .cursor-label { display: none !important; }
}
