/* Text reveal in the hero: the text appears out of invisibility.
   Motion recipe from the 21st.dev text reveals: each letter or word comes out of transparency and blur
   with a small rise, staggered, on cubic-bezier(.23,1,.32,1). text-reveal.js splits the copy only while it
   plays and restores the original text nodes afterwards (the headline keeps its letters); without the
   script or under reduced motion nothing is hidden. */
:root.tr-on [data-tr="pending"] { opacity: 0; }
/* The hero headline keeps its letters after playing (see text-reveal.js): same boxes, no relayout. */
:is([data-tr="play"], [data-tr="kept"]) .tr-w, [data-tr="kept"] .tr-u { display: inline-block; }
:root.tr-on [data-tr="play"] .tr-u {
  display: inline-block;
  animation: tr-in var(--tr-dur, .62s) cubic-bezier(.23, 1, .32, 1) both;
  animation-delay: calc(var(--tr-t0, 0ms) + var(--i, 0) * var(--tr-step, 30ms));
}
:root.tr-on [data-tr="play"][data-tr-mode="block"] {
  animation: tr-in var(--tr-dur, .6s) cubic-bezier(.23, 1, .32, 1) both;
  animation-delay: var(--tr-t0, 0ms);
}
@keyframes tr-in {
  from { opacity: 0; filter: blur(var(--tr-blur, 8px)); translate: 0 var(--tr-rise, .3em); }
  to { opacity: 1; filter: blur(0); translate: 0 0; }
}
