Scrolled()MessagePosted whenever the chat's vertical scroll offset changes.
Transcript hydration keys off the actual scroll offset instead of the
scrollbar ScrollUp/ScrollDown messages, because those never reach
the app for the common scroll paths: wheel/trackpad scrolling arrives as
MouseScroll* events, keyboard scrolling runs through key-binding scroll
actions, and both move scroll_y directly without posting a scrollbar
message. Scrollbar-track clicks do post ScrollUp/ScrollDown, but this
container's own _on_scroll_up/_on_scroll_down handlers consume them
via event.stop() before they can bubble to the app. Watching scroll_y
covers every input device uniformly. Validated against Textual 8.2.7.