viewportStateChanged

Reports the full viewport snapshot, including pixel scroll range.

Implementations that only need the historical row-based contract can keep overriding viewportChanged.