ce1f5dd30d
Follow-up to the salvaged #88219 visibility/15fps work: - Dormancy: the rAF loop stops scheduling frames when no faces are mounted or none are visible, instead of running the 1Hz whole-document shadow-root scan forever. A mounting BotFace or a face scrolling into view wakes it. - Teardown: register() now hooks ctx.onDispose so disabling the Bots plugin (or a hot reload) cancels the animation frame, disconnects the IntersectionObserver, drops cached nodes, and clears window.__hbFaceClock. Previously the loop ran until app restart even with the plugin disabled. - Behavioral tests for park/wake/stop via a vm-extracted clock harness, verified to fail against the pre-fix source.