Copy-paste motion for real apps — page fades, scroll reveals, list springs,
and modal physics. Two files, zero dependencies, CSP-safe. Every recipe respects
prefers-reduced-motion.
This page just did it. Put .tx-page on your top wrapper —
the whole view fades and rises in on load. On supporting browsers it also opts into the
native cross-document View Transitions API.
<!-- one class, that's the whole recipe -->
<body class="tx-page"> … </body>
Scroll the cards into view — each fades up a beat after the last.
Wrap them in data-tx-stagger, tag each with tx-reveal.
transitions.js numbers them and reveals via IntersectionObserver. No JS to write.
--tx-i × 60ms.tx-scale to grow from 94%.tx-left or tx-right.<div data-tx-stagger>
<div class="tx-reveal">…</div>
<div class="tx-reveal tx-scale">…</div>
</div>
/* or drive it yourself: */
Transitions.reveal(".tx-reveal", { stagger: 60 });
Same stagger, springier curve. tx-spring pops each row in
with a touch of overshoot — good for freshly loaded lists and search results.
<ul data-tx-stagger> <li class="tx-spring">…</li> </ul>
Backdrop fades, panel springs up and scales in. Open with a
data-tx-open button; close on the ✕, the scrim, or Esc.
Focus moves in and returns on close. All wiring is in transitions.js — the markup is declarative.
<button data-tx-open="demo-modal">Open</button>
<div id="demo-modal" class="tx-modal" aria-hidden="true">
<div class="tx-modal__scrim"></div>
<div class="tx-modal__panel">
… your content …
<button data-tx-close>Close</button>
</div>
</div>