/* ==========================================================================
   Dynamic Restoration - shared hero headline motion (r2)

   ONE definition for all seven pages (index + the six service pages). Loaded
   page-relative as <link rel="stylesheet" href="hero-anim.css"> from each
   page's <head>, paired with hero-anim.js. Do not copy these rules back into
   a page's inline <style> block - the point of this file is that the spec
   lives in exactly one place.

   Two effects:
     1. WORD-RISE  - the top line of the hero h1 (the text before the
                     highlighted word) fades up word by word on load.
     2. U-SHEEN    - a slow highlight sweep across the highlighted word.
                     Keyframe lifted verbatim from the home hero so home and
                     the service pages run the same animation.

   Both respect prefers-reduced-motion: reduce.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. WORD-RISE

   hero-anim.js splits the leading text of a .hero-rise headline into
   .hero-rise-word spans and stamps each with --i (0-based word index).
   Delay is calc(var(--i) * .11s), so the effect is word-count agnostic - it
   works the same on a 3-word line as on an 8-word one.

   NO LAYOUT SHIFT: the headline is held at visibility:hidden (not display or
   height) until the split lands, so its line box occupies full height from
   first paint. After that only opacity and transform animate, neither of
   which is a layout property. Nothing in this file can move the page.

   The html.hero-anim guard is set by hero-anim.js before <body> parses. If the
   script never runs (blocked, errored, no JS), the class is absent, nothing
   is hidden, no splitting happens, and the headline renders as plain static
   text. hero-anim.js adds .hero-rise-split in a finally block, so a headline
   cannot get stuck invisible even if the split itself throws.
   -------------------------------------------------------------------------- */

html.hero-anim .hero-rise            { visibility: hidden; }
html.hero-anim .hero-rise-split      { visibility: visible; }

.hero-rise-word {
  /* inline-block so transform applies; whitespace between words is preserved
     as normal text nodes, so wrapping behaves exactly as it did before. */
  display: inline-block;
}

html.hero-anim .hero-rise .hero-rise-word {
  animation: hero-word-rise .68s cubic-bezier(.2, .75, .2, 1) both;
  animation-delay: calc(var(--i) * .11s);
}

@keyframes hero-word-rise {
  from { opacity: 0; transform: translateY(.55em); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  html.hero-anim .hero-rise .hero-rise-word {
    animation: none;
    opacity: 1;
    transform: none;
  }
}


/* --------------------------------------------------------------------------
   2. U-SHEEN (highlighted hero word)

   The keyframe and the 100deg / 250% gradient geometry are the home hero's
   original .heroG h1 .u treatment, moved here unchanged so every page shares
   one definition. Only the three gradient stops are parameterised, because
   the home hero sits on a light cream field and the service heroes sit on
   deep navy - the same literal colors would be invisible on one or the other.

   Defaults below are home's exact original stops (green-deep -> green ->
   gold-soft, which in the DR palette is the light green #8fd24f, not gold).
   .subhero overrides them to the light-on-dark analog of that same ramp.

   SPECIFICITY / ORDER: each page's inline <style> already sets a solid color
   on the highlighted word (`.heroG h1 .u` on home, `.subhero h1 em` on the
   service pages). The sweep needs `color: transparent` to win over those, so
   this file is linked AFTER the inline <style> in every page's <head>, and
   the sweep rule is written at matching specificity.
   -------------------------------------------------------------------------- */

.u-sheen {
  --sheen-base: var(--green-deep);
  --sheen-mid:  var(--green);
  --sheen-hi:   var(--gold-soft);
}

/* Service-page heroes are navy; start from the em's existing #a6e07a and
   sweep lighter, mirroring home's dark-to-light ramp. */
.subhero h1 .u-sheen {
  --sheen-base: #a6e07a;
  --sheen-mid:  #c6ee9f;
  --sheen-hi:   #ecffd6;
}

@media (prefers-reduced-motion: no-preference) {
  .heroG h1 .u-sheen,
  .subhero h1 .u-sheen {
    background: linear-gradient(100deg,
      var(--sheen-base) 0%,
      var(--sheen-mid) 35%,
      var(--sheen-hi) 50%,
      var(--sheen-mid) 65%,
      var(--sheen-base) 100%);
    background-size: 250% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: u-sheen 5.5s ease-in-out infinite;
  }
}

@keyframes u-sheen {
  0%   { background-position: 125% 0; }
  100% { background-position: -25% 0; }
}

/* Under reduced motion the .u-sheen block above never applies, so the word
   keeps whatever solid color its page already gives it (--green-deep on home,
   #a6e07a on the service pages). Nothing further needed. */
