/* ==========================================================================
   Entrance animations — fade in up
   Elements fade and rise into place as they scroll into view.

   Pairs with js/entrance-animations.js. >>> THE SELECTOR LIST BELOW IS
   DUPLICATED THERE <<< It has to be: the hidden state must apply from the first
   paint or the page flashes its content and then hides it, and CSS cannot read
   a list out of the JS. Change one, change the other.

   This file is enqueued after main.css, so anything it declares wins on a tie.
   Keep the entrance styling here and nowhere else — a second copy in main.css
   is what left the CTA banner stuck at opacity 0, because the two lists had
   drifted apart.

   Heroes and page heads are deliberately absent: .hero-stack, .campaign-hero,
   .page-head, .page-hero, .archive-hero, .article-hero and .banner-small all
   sit above the fold, where an entrance animation delays the first thing a
   visitor came to read. .text-scroll is out too — a transform on an ancestor of
   its position:sticky column breaks the sticky. .tab-block-inner is out because
   its panels are display:none until active.
   ========================================================================== */

:root {
  --fade-duration: 0.45s;
  --fade-distance: 16px;
  /* Decelerating ease — quick off the mark, settles softly. */
  --fade-easing: cubic-bezier(0.22, 1, 0.36, 1);
}

/*
 * Hidden, pre-reveal. Scoped to .has-anim, which is set on <html> by a
 * one-liner in header.php before <body> is parsed — so with JavaScript off the
 * class never lands, nothing is hidden, and the page reads normally.
 *
 * Note these are the INNER wrappers and grid children, never the section
 * itself. Hiding a whole section (the old list did exactly that with
 * .cta-banner) means one missed reveal takes the entire block down with it.
 */
.has-anim :is(
  .benefits-inner > *,
  .benefits-grid > *,
  .library-inner > *,
  .library-grid > *,
  .archive-inner > *,
  .archive-grid > *,
  .ebook-grid > *,
  .text-block-inner > *,
  .cta-banner-inner > *,
  .title-text-panels-inner > *,
  .panels > *,
  .reviews-inner > *,
  .reviews-grid > *,
  .related-inner > *,
  .related-grid > *,
  .faq-block-inner > *,
  .demo-faq-inner > *,
  .fa-item,
  .text-full-inner > *,
  .text-section-inner > *,
  .section-heading-inner > *,
  .accreditations-inner > *,
  .integrations-inner > *,
  .book-demo-inner > *,
  .page-form-inner > *,
  .feature-accordion-inner > *,
  .stat-band-grid > *,
  .image-text-panel > *,
  .team-inner > *,
  .team-grid > *,
  .gallery-inner > *,
  .gallery-grid > *,
  .webinar-gate-inner > *
) {
  opacity: 0;
  transform: translateY(var(--fade-distance));
}

/*
 * Revealed. The transition and its delay are applied inline by the JS, for the
 * duration of the reveal only, then stripped — so an element with a transition
 * of its own (the FAQ accordion's grid-template-rows, a card's hover lift) gets
 * it straight back. All this rule states is the finished position.
 *
 * Doubled class so it always outranks the hidden rule above, rather than
 * depending on which of the two happens to come later.
 */
.has-anim .is-visible.is-visible {
  opacity: 1;
  transform: none;
}

/* Anyone who has asked for less motion gets none of it. The script checks the
   same query and reveals everything immediately, so this is belt and braces. */
@media (prefers-reduced-motion: reduce) {
  .has-anim :is(
    .benefits-inner > *,
    .benefits-grid > *,
    .library-inner > *,
    .library-grid > *,
    .archive-inner > *,
    .archive-grid > *,
    .ebook-grid > *,
    .text-block-inner > *,
    .cta-banner-inner > *,
    .title-text-panels-inner > *,
    .panels > *,
    .reviews-inner > *,
    .reviews-grid > *,
    .related-inner > *,
    .related-grid > *,
    .faq-block-inner > *,
    .demo-faq-inner > *,
    .fa-item,
    .text-full-inner > *,
    .text-section-inner > *,
    .section-heading-inner > *,
    .accreditations-inner > *,
    .integrations-inner > *,
    .book-demo-inner > *,
    .page-form-inner > *,
    .feature-accordion-inner > *,
    .stat-band-grid > *,
    .image-text-panel > *,
    .team-inner > *,
    .team-grid > *,
    .gallery-inner > *,
    .gallery-grid > *,
    .webinar-gate-inner > *
  ) {
    opacity: 1;
    transform: none;
    transition: none !important;
  }
}
