/* ==========================================================================
   Animations — keyframes + scroll-reveal primitives
   Every reveal is opt-in via [data-reveal]; JS adds .is-in when in viewport.
   ========================================================================== */

/* ---------- Keyframes ---------- */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes spin-slow { to { transform: translateY(-50%) rotate(360deg); } }

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-11px); }
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 4px rgba(232, 128, 26, .2); }
  50%      { box-shadow: 0 0 0 9px rgba(232, 128, 26, 0); }
}

@keyframes ring {
  0%   { transform: scale(1); opacity: .8; }
  100% { transform: scale(1.7); opacity: 0; }
}

@keyframes ripple {
  to { transform: scale(3.2); opacity: 0; }
}

@keyframes scroll-dot {
  0%   { transform: translateY(-14px); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateY(42px); opacity: 0; }
}

@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* ---------- Scroll reveal ----------
   Every rule below is gated behind `.js` on <html>, which script.js sets at the
   top of <head>. Without JavaScript the content simply renders — it must never
   be left invisible because an observer failed to fire. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity .8s var(--ease-out),
    transform .8s var(--ease-out);
  transition-delay: var(--delay, 0ms);
  will-change: opacity, transform;
}
.js [data-reveal="left"]  { transform: translateX(-42px); }
.js [data-reveal="right"] { transform: translateX(42px); }
.js [data-reveal="zoom"]  { transform: scale(.9); }
.js [data-reveal="fade"]  { transform: none; }

.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Stagger children of a group */
.js [data-reveal-group] > * {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
}
.js [data-reveal-group].is-in > * { opacity: 1; transform: none; }
.js [data-reveal-group].is-in > *:nth-child(1) { transition-delay: .05s; }
.js [data-reveal-group].is-in > *:nth-child(2) { transition-delay: .14s; }
.js [data-reveal-group].is-in > *:nth-child(3) { transition-delay: .23s; }
.js [data-reveal-group].is-in > *:nth-child(4) { transition-delay: .32s; }
.js [data-reveal-group].is-in > *:nth-child(5) { transition-delay: .41s; }
.js [data-reveal-group].is-in > *:nth-child(6) { transition-delay: .5s; }
.js [data-reveal-group].is-in > *:nth-child(7) { transition-delay: .59s; }
.js [data-reveal-group].is-in > *:nth-child(8) { transition-delay: .68s; }

/* ---------- Hero entrance (runs once on load) ---------- */
.js .hero__badge,
.js .hero__title .line,
.js .hero__tagline,
.js .hero__text,
.js .hero__actions,
.js .hero__stats,
.js .hero__figure,
.js .hero__scroll {
  opacity: 0;
  animation: fade-up .95s var(--ease-out) forwards;
}
.hero__badge          { animation-delay: .15s; }
.hero__title .line:nth-child(1) { animation-delay: .28s; }
.hero__title .line:nth-child(2) { animation-delay: .4s; }
.hero__tagline        { animation-delay: .54s; }
.hero__text           { animation-delay: .66s; }
.hero__actions        { animation-delay: .78s; }
.hero__stats          { animation-delay: .9s; }
.hero__figure         { animation-delay: .4s; animation-duration: 1.3s; }
.hero__scroll         { animation-delay: 1.2s; }

/* Timeline items slide in from their side */
.js .tl__item { opacity: 0; transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); }
.js .tl__item:nth-child(odd)  { transform: translateX(-46px); }
.js .tl__item:nth-child(even) { transform: translateX(46px); }
.js .tl__item.is-in { opacity: 1; transform: none; }

/* Text reveal — masked line wipe for section headings */
.reveal-text { display: inline-block; overflow: hidden; }
.js .reveal-text > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform .9s var(--ease-out);
}
.js .reveal-text.is-in > span { transform: none; }

/* Shimmer placeholder while images decode */
.img-skeleton {
  background: linear-gradient(90deg, var(--beige) 25%, var(--gray-100) 37%, var(--beige) 63%);
  background-size: 200% 100%;
  animation: shimmer 1.5s linear infinite;
}

/* Page transition veil */
.veil {
  position: fixed;
  inset: 0;
  z-index: 1500;
  background: var(--ivory);
  opacity: 0;
  visibility: hidden;
  transition: opacity .38s var(--ease), visibility .38s;
}
.veil.is-on { opacity: 1; visibility: visible; }

/* Parallax layers get transform driven by JS */
[data-parallax] { will-change: transform; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal],
  [data-reveal-group] > *,
  .hero__badge, .hero__title .line, .hero__tagline, .hero__text,
  .hero__actions, .hero__stats, .hero__figure, .hero__scroll,
  .tl__item {
    opacity: 1 !important;
    transform: none !important;
  }
  .reveal-text > span { transform: none; }
}
