Instead of listening to scroll directly, IntersectionObserver watches only for the moment an element starts appearing. The callback just adds a class; a CSS transition does the rest.
It's common to observer.unobserve() an element once it's shown — re-triggering on every scroll pass is distracting, not delightful. A threshold (say 0.5) controls how much of the element must be visible before it fires.
Since a card preview can't be scrolled, this demo auto-scrolls a mock container upward and reveals each row as it crosses into view.
When to use
Use it to add delight to content that's already there, not to hide information — it gets in the way for slow scrollers and screen readers.