/* ============================================================
   Animations — initial states set by JS-enhancement class,
   reduced-motion fallbacks, non-GSAP CSS transitions
   ============================================================ */

/* Elements marked [data-animate] start hidden ONLY when JS is present.
   Fallback: without JS, everything is visible immediately. */
.js [data-animate] {
  opacity: 0;
  transform: translateY(20px);
  will-change: opacity, transform;
}

/* Hero elements are staged for the GSAP hero timeline. Hiding them via CSS
   prevents a flash while the GSAP module downloads. Restored by the timeline
   itself (.from() animates from opacity 0 back to 1) — or by the safety
   fallback that adds .hero-ready after 400ms. */
.js [data-hero-eyebrow],
.js [data-hero-title],
.js [data-hero-description],
.js [data-hero-actions],
.js [data-hero-media] {
  opacity: 0;
  transition: opacity 400ms var(--ease-standard);
}

.js .hero-ready [data-hero-eyebrow],
.js .hero-ready [data-hero-title],
.js .hero-ready [data-hero-description],
.js .hero-ready [data-hero-actions],
.js .hero-ready [data-hero-media] {
  opacity: 1;
}

.js [data-animate='fade'] {
  transform: none;
}

.js [data-animate='rise-lg'] {
  transform: translateY(40px);
}

.js [data-animate='rise-line'] {
  transform: translateY(110%);
}

/* When an animation container is marked "in" (added by IntersectionObserver
   fallback if GSAP is unavailable) reveal children cleanly */
.js [data-animate].is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--duration-slow) var(--ease-standard),
    transform var(--duration-slow) var(--ease-standard);
}

/* Reduced motion — collapse all animation into an immediate show */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-animate],
  .js [data-hero-eyebrow],
  .js [data-hero-title],
  .js [data-hero-description],
  .js [data-hero-actions],
  .js [data-hero-media] {
    opacity: 1;
    transform: none;
    will-change: auto;
  }
}

/* Nav mobile-menu smoothing */
.header__mobile {
  transition: max-height var(--duration-medium) var(--ease-standard);
}

/* Focus-visible ring smoothing */
:focus-visible {
  transition:
    outline-offset var(--duration-fast) var(--ease-standard),
    outline-color var(--duration-fast) var(--ease-standard);
}

/* View Transition API — branded ember-tinted page shift */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-timing-function: cubic-bezier(0.16, 0.9, 0.3, 1);
}

::view-transition-old(root) {
  animation-name: viewfade-out;
  animation-duration: 240ms;
}

::view-transition-new(root) {
  animation-name: viewfade-in;
  animation-duration: 400ms;
}

@keyframes viewfade-out {
  from { opacity: 1; transform: translateY(0) scale(1); filter: brightness(1); }
  to   { opacity: 0; transform: translateY(-24px) scale(0.98); filter: brightness(0.85); }
}

@keyframes viewfade-in {
  from { opacity: 0; transform: translateY(24px) scale(1.02); filter: brightness(1.1) sepia(0.12) saturate(1.05); }
  to   { opacity: 1; transform: translateY(0) scale(1); filter: brightness(1) sepia(0) saturate(1); }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 1ms;
  }
}

/* ============================================================
   MICRO-INTERACTIONS — added by micro.js
   ============================================================ */

/* ── Scroll progress bar ─────────────────────────────────── */
[data-scroll-progress] {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2.5px;
  background: var(--grad-ember);
  transform-origin: left center;
  transform: scaleX(0);
  z-index: calc(var(--z-nav) + 5);
  pointer-events: none;
  will-change: transform;
}

/* ── Button ripple ───────────────────────────────────────── */
/* .btn already has position:relative in components.css; add overflow:hidden */
.btn {
  overflow: hidden;
}

.btn-ripple {
  position: absolute;
  border-radius: 50%;
  background: oklch(1 0 0 / 0.22);
  width: 6px;
  height: 6px;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0);
  animation: btn-ripple 0.65s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}

@keyframes btn-ripple {
  to {
    transform: translate(-50%, -50%) scale(65);
    opacity: 0;
  }
}

/* ── Play-button pulse rings ─────────────────────────────── */
.play-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid oklch(1 0 0 / 0.55);
  pointer-events: none;
}

/* ── Urgency chip — spots left ───────────────────────────── */
@keyframes ember-pulse {
  0%, 100% { box-shadow: 0 0 0 0 oklch(0.67 0.15 47 / 0.5); }
  55%       { box-shadow: 0 0 0 7px oklch(0.67 0.15 47 / 0); }
}

.chip--ember-sm {
  animation: ember-pulse 2.4s ease-in-out infinite;
}

/* ── Performance note ──────────────────────────────────────
   Scroll/pointer-heavy effects (3-D tilt, hover pan, scroll parallax,
   custom cursor) have been removed to keep scrolling native. The earlier
   `will-change: transform` blanket rule that promoted every card/tile to
   its own compositor layer is therefore gone as well. */

/* ── Eyebrow dot — pulse on load ─────────────────────────── */
@keyframes dot-pop {
  0%   { transform: scale(0) rotate(-45deg); opacity: 0; }
  65%  { transform: scale(1.35) rotate(0deg); opacity: 1; }
  100% { transform: scale(1); }
}

.eyebrow span {
  display: inline-block;
  animation: dot-pop 0.55s var(--ease-emphasized) both;
  animation-delay: 0.6s;
}

/* Counter numbers — tabular figures for stable width during count-up */
[data-count] {
  font-variant-numeric: tabular-nums;
}

