/* ==========================================================================
   Scroll Reveal — subtle, premium scroll-based reveal system (site-wide).
   Vocabulary: fade-up, fade-up-sm, fade, scale, image, hero, parallax.

   Safety model:
   - Content is 100% visible by default (no JS / no-JS fallback / SEO safe).
   - Hidden/animated states ONLY apply when <html class="js-anim"> is present.
     That class is added by a tiny synchronous inline script in <head>
     (see main.blade.php) ONLY when IntersectionObserver is supported AND
     the user has not requested reduced motion. So reduced-motion / old
     browsers simply never see an opacity:0 state at all.
   - GPU-friendly only: opacity + transform. No width/height/top/left anim.
   ========================================================================== */

html.js-anim [data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .6s cubic-bezier(.22, .61, .36, 1),
              transform .6s cubic-bezier(.22, .61, .36, 1);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
html.js-anim [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Smaller-distance variant — headings (per spec: ~15px, slightly faster) */
html.js-anim [data-reveal="fade-up-sm"] { transform: translateY(14px); }
html.js-anim [data-reveal="fade-up-sm"].is-visible { transform: none; }

/* Pure fade, no movement — for elements where translateY would look odd */
html.js-anim [data-reveal="fade"] {
  transform: none;
  transition: opacity .5s ease-out;
  transition-delay: var(--reveal-delay, 0ms);
}
html.js-anim [data-reveal="fade"].is-visible { opacity: 1; }

/* Scale-in — very subtle, for card-like standalone blocks */
html.js-anim [data-reveal="scale"] { transform: scale(.98); }
html.js-anim [data-reveal="scale"].is-visible { transform: scale(1); }

/* Image reveal — container fades, image settles from a soft scale */
html.js-anim [data-reveal="image"] {
  opacity: 0;
  transform: scale(.98);
  transition: opacity .6s ease-out,
              transform .7s cubic-bezier(.22, .61, .36, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
html.js-anim [data-reveal="image"].is-visible { opacity: 1; transform: scale(1); }

/* ---- Hero reveal — runs immediately on load (above the fold), no
        IntersectionObserver needed. Short heading → subtitle → CTA beat. --- */
@keyframes haHeroReveal {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
html.js-anim .hhero-kicker,
html.js-anim .hhero-title,
html.js-anim .hhero-actions,
html.js-anim .hp-intro-eyebrow,
html.js-anim .hp-intro h1,
html.js-anim .hp-intro-tagline,
html.js-anim .hp-stats-row,
html.js-anim .blog_hero_eyebrow,
html.js-anim .blog_hero_title {
  opacity: 0;
  animation: haHeroReveal .7s cubic-bezier(.22, .61, .36, 1) both;
}
html.js-anim .hhero-kicker,
html.js-anim .hp-intro-eyebrow,
html.js-anim .blog_hero_eyebrow            { animation-delay: 60ms; }
html.js-anim .hhero-title,
html.js-anim .hp-intro h1,
html.js-anim .blog_hero_title              { animation-delay: 160ms; }
html.js-anim .hhero-actions,
html.js-anim .hp-intro-tagline             { animation-delay: 280ms; }
html.js-anim .hp-stats-row                 { animation-delay: 360ms; }

/* ---- Subtle parallax — opt-in only via [data-parallax], desktop only --- */
[data-parallax] { will-change: transform; }
@media (max-width: 767px) {
  [data-parallax] { transform: none !important; }
}

/* ---- Mobile: shorter distance + duration, keep it light --------------- */
@media (max-width: 767px) {
  html.js-anim [data-reveal] {
    transform: translateY(12px);
    transition-duration: .45s;
  }
  html.js-anim [data-reveal="scale"],
  html.js-anim [data-reveal="image"] { transform: scale(.99); }
  html.js-anim [data-reveal].is-visible,
  html.js-anim [data-reveal="scale"].is-visible,
  html.js-anim [data-reveal="image"].is-visible { transform: none; }
  html.js-anim [data-reveal="image"].is-visible { transform: scale(1); }
}

/* ---- Reduced motion: belt-and-suspenders. js-anim is normally never
        added at all when reduced motion is requested (see head script),
        but if it ever is, force full visibility with no movement. ------- */
@media (prefers-reduced-motion: reduce) {
  html.js-anim [data-reveal],
  html.js-anim .hhero-kicker,
  html.js-anim .hhero-title,
  html.js-anim .hhero-actions,
  html.js-anim .hp-intro-eyebrow,
  html.js-anim .hp-intro h1,
  html.js-anim .hp-intro-tagline,
  html.js-anim .hp-stats-row,
  html.js-anim .blog_hero_eyebrow,
  html.js-anim .blog_hero_title {
    animation: none !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    transform: none !important;
    opacity: 1 !important;
  }
  [data-parallax] { transform: none !important; }
}

/* ---- Optional: thin scroll progress bar (blog-detail long-form pages) - */
.ha-scroll-progress {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 3px;
  z-index: 9999;
  background: transparent;
  pointer-events: none;
}
.ha-scroll-progress-bar {
  height: 100%;
  width: 100%;
  background: #507C24;
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .ha-scroll-progress-bar { transition: none !important; }
}
