If you run a masked window page transition, the incoming page is real DOM inserted by the router, not something your framework rendered. Every effect that waits for a component to mount never fires. Every scroll trigger measures a page that is not where it will be a moment later.
We hit this three times on this build, in three different disguises. The lesson each time was the same, and it was never about the animation.
Disguise one: the reveals that never played
Headings and images animate in on scroll, driven by an observer attached when the component mounts. Swap the page and nothing mounts, so nothing is observed, so every element sits at zero opacity forever. The fix is to re-attach the observers by hand once the new container is in the document, which means the transition layer has to know about the animation layer. That coupling feels wrong and is unavoidable.
Disguise two: the reveal that played too early
Headings split into masked lines and slide up. Correct, except they were sliding up while the mask still covered the page, so by the time the window opened the animation had finished and the headings just sat there. The reveal worked perfectly and nobody ever saw it.
Splitting one function into two fixed it: park the lines out of sight before the incoming page is visible, arm the triggers after the window opens. Prepare, then play. Same animation, two different moments.
Disguise three: the counter that arrived finished
Rolling numbers on a stats row, triggered on scroll. Navigate to the page and they were already on their final values. The trigger was being created before the scroll position had settled at the top, so it measured itself as already scrolled past, fired instantly, and completed before the reader ever saw the top of the page.
The fix was one reorder: refresh the scroll measurements first, then create the trigger. Not a single line of the animation changed.
The pattern
All three were the same bug wearing different clothes. When a page transition owns the moment the page becomes visible, every animation on that page has to be told about that moment. Ask two questions of anything that moves: when does it get set up, and when is it allowed to play. If those are the same moment, you have a bug you have not seen yet.
