/* Motion layer: cross-document view transitions and the scroll-reveal
   primitive (issue #34). Loaded last (see css/README.md) so it can name and
   animate elements that header.css, sections.css and interior.css already
   define, without editing those files -- this lane owns only base.css,
   this file, head.html and baseof.html.

   Two rules hold everywhere below:
   - Progressive enhancement: an unsupported browser must render every
     animated element exactly as a plain one. `@view-transition` and
     `view-transition-name` are inert without support (unknown at-rules and
     unrecognised property values are simply ignored), so they need no
     guard. `animation-timeline: view()` is different -- it can hide content
     that never becomes visible again without it -- so `.wr-reveal` only
     applies opacity/transform inside an `@supports` test.
   - prefers-reduced-motion disables rather than shortens. The actual
     disabling rules live in base.css's existing reduced-motion block, not
     here: they use !important specifically so they keep winning even
     though this file loads after base.css in the cascade. */

/* ---------- Cross-document view transitions ---------- */

@view-transition {
  navigation: auto;
}

/* The header and the brand persist across a navigation instead of
   cross-fading with the rest of the page, so the chrome reads as one
   continuous surface and only the content beneath it changes. Named here
   rather than in header.html (a different lane's file) -- view-transition-
   name is a plain CSS property, so styling the classes header.html already
   emits is enough; no markup change needed. */
.wr-header {
  view-transition-name: wr-vt-header;
}

.wr-header__brand {
  view-transition-name: wr-vt-brand;
}

/* Everything else -- the page content, carrying no name of its own -- falls
   into the default ::view-transition-old(root)/::view-transition-new(root)
   pair, whose default is a flat cross-fade. A considered enter reads as the
   new page settling into place rather than two states dissolving into each
   other: the incoming page rises slightly as it fades in, the outgoing one
   only fades. calc() against --motion-base rather than a new duration token
   in tokens.css -- this lane does not own that file, and the existing scale
   composes fine for a page-level transition. */
::view-transition-old(root) {
  animation: wr-vt-leave calc(var(--motion-base) * 1.5) var(--ease) both;
}

::view-transition-new(root) {
  animation: wr-vt-enter calc(var(--motion-base) * 1.5) var(--ease) both;
}

@keyframes wr-vt-leave {
  to {
    opacity: 0;
  }
}

@keyframes wr-vt-enter {
  /* No "to" block: the implicit end state is the pseudo-element's own
     resolved style, i.e. fully visible in place. Only the entry point needs
     stating. */
  from {
    opacity: 0;
    transform: translateY(var(--space-3));
  }
}

/* ---------- Scroll reveal ----------
   One utility, for the two or three moments per page that earn it -- not a
   fade-and-slide-up on every section, which is the generic default this
   issue exists to avoid (see css/README.md for the usage rule). It carries
   no base opacity/transform outside the @supports test below: a browser
   without animation-timeline support must render a .wr-reveal element
   exactly like any other, not hidden and waiting for an animation that will
   never run. */

@supports (animation-timeline: view()) {
  .wr-reveal {
    animation: wr-reveal-in linear both;
    animation-timeline: view();
    /* The full "entry" phase: animation progress tracks the element moving
       from just-below-the-viewport to fully on screen, so the motion
       finishes by the time a reader would actually look at it rather than
       continuing to animate under their attention. */
    animation-range: entry;
  }
}

@keyframes wr-reveal-in {
  from {
    opacity: 0;
    transform: translateY(1.25rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* The one placement this lane wires directly: the footer, in baseof.html,
   the sole template file here that reaches real page markup. It is the one
   moment every template shares regardless of which page-content section
   built it, so it is a legitimate single use of the primitive rather than a
   dead class -- see the README for where the remaining moments belong once
   the page-build issues can reach their own templates. */
