/* ==========================================================================
   ANIMATIONS.CSS — motion primitives, reveal states, reduced-motion
   Motion is progressive enhancement: all content is visible by default
   unless JS adds the .js class and elements opt into .reveal.
   ========================================================================== */

/* JS-only reveal: hidden until observed (never blocks content if JS fails) */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.6s var(--ease),
    transform 0.6s var(--ease);
  will-change: opacity, transform;
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}
.js .reveal[data-delay="1"] { transition-delay: 0.08s; }
.js .reveal[data-delay="2"] { transition-delay: 0.16s; }
.js .reveal[data-delay="3"] { transition-delay: 0.24s; }

/* Hero entrance */
.js .hero-anim { opacity: 0; transform: translateY(30px); }

/* Modal transitions (transform-based, no layout shift) */
.modal-overlay .modal {
  transform: translateY(24px) scale(0.98);
  opacity: 0;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.modal-overlay.is-open .modal {
  transform: none;
  opacity: 1;
}

/* Loader fallback (used when GSAP is unavailable) */
@keyframes tyre-roll {
  from { transform: translateX(0) rotate(0deg); }
  to   { transform: translateX(calc(min(78vw, 460px) + 140px)) rotate(720deg); }
}
@keyframes tyre-spin {
  to { transform: rotate(360deg); }
}
@keyframes streak-fly {
  0%   { transform: translateX(120px); opacity: 0; }
  25%  { opacity: 0.9; }
  100% { transform: translateX(-260px); opacity: 0; }
}
@keyframes wordmark-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.loader-fallback .loader-wordmark { animation: wordmark-in 0.5s var(--ease) both; }
.loader-fallback #loaderTyre { animation: tyre-roll 1.6s var(--ease) both; }
.loader-fallback .loader-streak:nth-of-type(1) { animation: streak-fly 0.9s 0.35s var(--ease) both; }
.loader-fallback .loader-streak:nth-of-type(2) { animation: streak-fly 0.9s 0.55s var(--ease) both; }
.loader-fallback .loader-streak:nth-of-type(3) { animation: streak-fly 0.9s 0.7s var(--ease) both; }

/* Subtle CTA shimmer on primary buttons */
@keyframes btn-sheen {
  from { transform: translateX(-120%) skewX(-20deg); }
  to   { transform: translateX(240%) skewX(-20deg); }
}
.btn--primary::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: translateX(-120%) skewX(-20deg);
  pointer-events: none;
}
.btn--primary:hover::after { animation: btn-sheen 0.75s var(--ease); }

/* Gallery item reveal stagger (JS sets is-visible) */
.js .gallery-item { transition: opacity 0.45s var(--ease), transform 0.45s var(--ease); }
.js .gallery-item.is-filtering { opacity: 0; transform: scale(0.97); }

/* Accordion panel animation is handled via display toggle + opacity */
.faq-a { opacity: 1; }
.js .faq-a.is-open { animation: faq-open 0.3s var(--ease) both; }
@keyframes faq-open {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------
   Reduced motion: honor prefers-reduced-motion everywhere.
   Essential state changes remain instant; no large movement.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .js .reveal,
  .js .hero-anim {
    opacity: 1 !important;
    transform: none !important;
  }

  .btn:hover, .service-card:hover, .tint-card:hover,
  .related-card:hover { transform: none !important; }

  .service-card:hover .service-card-media img,
  .gallery-item:hover img { transform: none !important; }

  .btn--primary:hover::after { animation: none !important; }

  .loader-fallback #loaderTyre,
  .loader-fallback .loader-streak,
  .loader-fallback .loader-wordmark { animation: none !important; }
}
