/* buildcontrol — scroll motion vocabulary.
 *
 * Reference: the craft of aardvarkbookclub.com, without its playfulness — no
 * rotation, no bounce, no colour shifts, brand palette untouched.
 *
 * Built on native scroll-driven animations (`animation-timeline: view()`) rather
 * than a scroll library, so the whole file costs nothing at runtime and simply
 * does not apply in browsers that lack support. Everything is inside a
 * prefers-reduced-motion guard.
 *
 * Only `.mo-split` needs JavaScript (assets/js/motion.js) to wrap each word.
 */

@media (prefers-reduced-motion: no-preference) {

  /* ---------- headings rise word by word ---------- */
  /* motion.js rewrites the heading as <span class="mo-w"><i>word</i></span>.
     The outer span is a mask; the inner element is what travels. The padding /
     negative-margin pair stops descenders (g, y, p) being clipped by it. */
  .mo-split .mo-w {
    display: inline-block;
    overflow: hidden;
    vertical-align: bottom;
    padding-bottom: .14em;
    margin-bottom: -.14em;
  }
  .mo-split .mo-w > i {
    display: inline-block;
    font-style: inherit;
    transform: translateY(110%);
    transition: transform .62s cubic-bezier(.2, .7, .3, 1);
    transition-delay: calc(var(--mo-i, 0) * 55ms);
  }
  .mo-split.mo-in .mo-w > i { transform: none; }

  /* ---------- content blocks rise once ---------- */
  /* Driven by `animation` with `backwards` fill, not `transition`, for the same
     reason as reveal.css: many of these elements carry their own `transition`
     shorthand for hover, which would replace the entrance and leave opacity
     snapping. `backwards` also stops applying once played, so hover transforms
     still work afterwards. */
  .mo-rise { opacity: 0; }
  .mo-rise.mo-in {
    opacity: 1;
    animation: mo-rise-in .6s cubic-bezier(.2, .7, .3, 1) backwards;
    animation-delay: calc(var(--mo-i, 0) * 90ms);
  }

  /* ---------- card grids stagger their children ---------- */
  .mo-stag > * { opacity: 0; }
  .mo-stag.mo-in > * {
    opacity: 1;
    animation: mo-rise-in .55s cubic-bezier(.2, .7, .3, 1) backwards;
    animation-delay: calc(var(--mo-i, 0) * 70ms);
  }

  @keyframes mo-rise-in {
    from { opacity: 0; transform: translateY(22px); }
  }

  @supports (animation-timeline: view()) {

    /* ---------- dark bands unfurl to full bleed ---------- */
    /* At rest this is inset(0 round 0), which clips nothing, so the resting
       design is unchanged. Both sections already carry overflow:hidden. */
    .band {
      animation: mo-unfurl linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
    @keyframes mo-unfurl {
      from { clip-path: inset(0 3% round 2.75em); }
      to   { clip-path: inset(0 round 0); }
    }

    /* ---------- hero artwork drifts against the scroll ---------- */
    /* Driven by the page scroller, not view(): the hero sits inside
       header.hhero, whose overflow:hidden makes it a scroll container that never
       scrolls, which would freeze a view() timeline at a fixed progress.
       Uses `translate` rather than `transform` so it cannot collide with the
       transform-based animations on this element's children. Starting at 0 keeps
       the top of the page pixel-identical to the current design. */
    .hshot {
      animation: mo-hero-drift linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 780px;
    }
    @keyframes mo-hero-drift {
      from { translate: 0 0; }
      to   { translate: 0 44px; }
    }
  }
}

/* ---------- cross-page fade ---------- */
/* @view-transition cannot live inside @media, so reduced motion is handled by
   switching the generated animation off below. */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: .3s; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
