- Reveal timing is now word-proportional per page: when a block's reveal only
covers part of the block (the continuation spread is not paginated at reveal
time), the page reveals only its share of the TTS, offset by the words before
it. The right page no longer absorbs the whole TTS before flipping; it flips at
normal pace and the continuation resumes on the next spread while TTS plays. No
effect when the regions already cover the whole block (unified plan / one page).
- Page flip start now shows the target spread's same-side page beneath the lifting
page (revealed as it turns away) instead of a blank that pops in after the flip.
Deferred (pending-reveal) sides stay blank so the masked reveal still lands via
activate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Establish book-playback-timeline as the sole playback owner driving the
scene through formal webgl-book:* events (not the BookLabDebug surface),
with a single reveal clock in the scene render loop and webgl-page-cache as
the only texture cache. Remove the legacy dual playback path and the
ownsPageFlipCommit gating.
Fixes:
- Flip page detached/folded at the spine: restore the raw page-cap line for
flip geometry (matches the prototype/pre-regression), removing
normalizeFlipLineToVisiblePage which moved the pivot off the spine arc.
- Flip textures: distance-based UVs (no horizontal compression),
direction-aware face material (source on the camera-facing side), source
meta derived from the visible spread (manual flips), prewarm shape fix.
- Reveal: flash removed on the static page and the flip back surface;
spanning blocks rebuild the reveal plan at activate and continue the
reveal on the next spread after the fill flip.
- Cache staleness is contentVersion-primary; nav clamps to spreadCount.
Docs updated to describe the intended single-owner architecture. Regression
checks updated to match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>