/* ============================================================
   Hubb Homepage Hero - Entrance Animations
   Version: v1.1.0   (style + script ship as a matched pair)

   Scope: every selector is rooted at `section.ActualHero` so this
   can never reach the ASP.NET <form> page wrapper, other modules,
   or the MobileHero block.

   Progressive enhancement: the running animation hides nothing until
   the JS adds `.hero-anim-ready`. A separate first-paint guard (the
   `html.hero-js` rules below) prevents the heading/image from flashing
   in before the JS wires up - see the head-snippet note in that block.
   If JS is disabled, the guard class is never set, so the hero renders
   fully and statically - no blank states for no-JS users.
   ============================================================ */

/* --- First-paint FOUC guard ---------------------------------------- */
/* PROBLEM: the animated wrappers (.hero-line1, the typed span,
   .hero-img-anim) are built by the JS at DOM-ready, so they don't exist
   in the first paint. What paints first is the raw <h1> and <img>, at
   full opacity - causing the flash, plus the yellow highlight box at full
   width. CSS alone can't pre-hide elements that don't exist yet.

   FIX: a one-line inline script in Hubb -> Head Contents sets `hero-js`
   on <html> *before* the body paints, and these rules hide the real
   heading + hero image while that flag is present. The JS removes the
   flag the instant it has applied its own hide state (`.hero-anim-ready`),
   so there is no flash and no specificity fight. A 2.5s self-removing
   timeout in the snippet is the safety net if the main script never runs.

   Paste this into Head Contents:
   <script>(function(d){d.classList.add('hero-js');setTimeout(function(){d.classList.remove('hero-js');},2500);})(document.documentElement);</script>

   NOTE: `h1.ShrinkIfNeeded` is the static marker for the desktop hero
   heading (the MobileHero h1 has no class, so it is left untouched). On a
   church site whose hero heading uses a different class, this selector is
   the single thing to adjust. */
html.hero-js section.ActualHero h1.ShrinkIfNeeded,
html.hero-js section.ActualHero h1.ShrinkIfNeeded ~ img {
  opacity: 0; /* instant, no transition - this is a hide, not an animation */
}
/* Motion-sensitive users must never wait on JS to see content. */
@media (prefers-reduced-motion: reduce) {
  html.hero-js section.ActualHero h1.ShrinkIfNeeded,
  html.hero-js section.ActualHero h1.ShrinkIfNeeded ~ img {
    opacity: 1;
  }
}

section.ActualHero {
  /* Timing/easing tokens - one place to retune the whole sequence.
     A per-church override block can change the feel without touching rules. */
  --hero-fade-duration: 0.7s;
  --hero-img-duration: 0.9s;
  --hero-ease: cubic-bezier(0.22, 1, 0.36, 1); /* soft ease-out: settles rather than snaps */
  --hero-img-rise: 24px;                        /* how far images travel up while fading in */
  --hero-caret-width: 0.06em;
}

/* --- Line 1: "Introducing Messaging &" - easy fade ------------------ */
section.ActualHero.hero-anim-ready .hero-line1 {
  opacity: 0;
  transition: opacity var(--hero-fade-duration) var(--hero-ease);
}
section.ActualHero.hero-anim-ready .hero-line1.is-in {
  opacity: 1;
}

/* --- Line 2: "Safer Messaging" - typewriter ------------------------- */
/* The host stays invisible until typing actually starts, so the empty
   highlighted span never shows a stray yellow nub during the lead-in pause. */
section.ActualHero.hero-anim-ready .hero-tw {
  opacity: 0;
}
section.ActualHero.hero-anim-ready .hero-tw.is-typing {
  opacity: 1;
  transition: opacity 0.2s ease;
}
/* Blinking caret while typing; fades out once the word is complete. */
section.ActualHero .hero-caret {
  display: inline-block;
  border-right: var(--hero-caret-width) solid currentColor;
  margin-left: 0.04em;
  animation: hero-caret-blink 0.9s step-end infinite;
}
section.ActualHero .hero-caret.is-done {
  animation: none;
  opacity: 0;
  transition: opacity 0.45s ease;
}
@keyframes hero-caret-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}
/* Full phrase kept for assistive tech - the typed text is aria-hidden,
   so screen readers always announce the real heading, never a fragment. */
section.ActualHero .hero-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- Hero images: classy fade + slight rise, one after another ------ */
section.ActualHero.hero-anim-ready .hero-img-anim {
  opacity: 0;
  transform: translateY(var(--hero-img-rise));
  transition: opacity var(--hero-img-duration) var(--hero-ease),
              transform var(--hero-img-duration) var(--hero-ease);
  will-change: opacity, transform;
}
section.ActualHero.hero-anim-ready .hero-img-anim.is-in {
  opacity: 1;
  transform: translateY(0);
}

/* --- Accessibility: honour reduced-motion --------------------------- */
/* Belt-and-braces. The JS already bails out entirely under reduced motion
   (leaving the DOM untouched and visible); this guards the case where the
   animation state is somehow applied anyway. */
@media (prefers-reduced-motion: reduce) {
  section.ActualHero.hero-anim-ready .hero-line1,
  section.ActualHero.hero-anim-ready .hero-tw,
  section.ActualHero.hero-anim-ready .hero-img-anim {
    opacity: 1 !important;     /* override the hide state for motion-sensitive users */
    transform: none !important;
    transition: none !important;
  }
  section.ActualHero .hero-caret { display: none !important; }
}

/* --- Mobile Responsiveness ----------------------------------------- */
/* These animations target the desktop hero heading (the h1 carrying the
   highlighted span) and the large image(s) beside it. At <=720px the same
   fade/typewriter still reads well; we just shorten the image rise so it
   doesn't feel sluggish on a small viewport. If the MobileHero block
   replaces this content at some breakpoint, the JS simply finds nothing to
   animate and stays inert. */
@media (max-width: 720px) {
  section.ActualHero {
    --hero-img-rise: 14px;
    --hero-img-duration: 0.7s;
  }
}
