/* ==========================================================================
   Animations

   Two things: the page fades in once, and each section's contents rise into
   place as it is scrolled to. animations.js does the watching; everything
   drawn lives here.

   Loaded by index.html on its own rather than through main.css, so it stays a
   per-page opt-in while it is only on the homepage.

   Smooth scrolling is not here. base.css already sets it on html, with the
   reduced-motion counterpart, and a second copy would only be one more place
   to keep in step.
   ========================================================================== */

:root {
  --reveal-duration: 0.6s;
  --reveal-stagger: 0.1s;   /* read by animations.js, applied per child below */
  --page-fade-duration: 0.3s;
}


/* -- Page fade ------------------------------------------------------------- */

/* Opacity only. A transform or a filter here would make body a containing
   block for everything fixed inside it, which is what the header becomes the
   moment it pins. */
body {
  animation: page-fade var(--page-fade-duration) var(--ease-out) backwards;
}

@keyframes page-fade {
  from { opacity: 0; }
}


/* -- Section reveal -------------------------------------------------------- */

/* The hidden state applies only where scripting is on, because only the script
   can undo it. Without the query a reader with JavaScript off would be left
   with a page of empty sections.

   The hero is left out. It is on screen before any scrolling happens, so the
   page fade above already covers its arrival, and it is the element the header
   is inserted into: a transform on it, even for the length of one reveal,
   would make it the containing block for the pinned header and break it. */
@media (scripting: enabled) {
  section:not(.hero) > * {
    opacity: 0;
    transform: translateY(30px);
    transition:
      opacity var(--reveal-duration) var(--ease-out) var(--reveal-delay, 0s),
      transform var(--reveal-duration) var(--ease-out) var(--reveal-delay, 0s);
  }

  /* none rather than translateY(0). An identity transform is still a transform
     and still creates a containing block, so the elements have to come out of
     the reveal with no transform at all. */
  section:not(.hero).is-revealed > * {
    opacity: 1;
    transform: none;
  }
}

/* The section is what is watched, and its children are what move, one after
   another. Moving the section itself as well would double both the fade and
   the 30px, since the two would compound. */


/* -- Reduced motion -------------------------------------------------------- */

/* Written out rather than left to the duration tokens: the values above are
   this file's own, so the tokens' own reduced-motion rule does not reach them. */
@media (prefers-reduced-motion: reduce) {
  body {
    animation: none;
  }

  section:not(.hero) > *,
  section:not(.hero).is-revealed > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
