Bottom-zone threshold now scales with the scroll container's clientHeight
rather than window.innerHeight. The threshold is meant to mirror the empty
spacer at the end of the chat, but what users perceive as "the empty tail"
is relative to the visible chat area, not the whole viewport — on desktop
the chat is shorter than the window because of the input row below it.
This keeps the scroll-to-bottom button hidden until the user has actually
scrolled past the spacer they see, regardless of viewport size.
Wheel and touch release detection no longer treats every nested
[data-scrollable] as a blocker. The old check returned true for any
nested scrollable ancestor, so wheel-up over a code block already at its
own scrollTop=0 produced no effect — the inner element could not consume
the gesture and the outer chat refused to release auto-follow. The new
check returns true only when the nested element can actually scroll up
(scrollTop > 0); otherwise the gesture bubbles to the chat and releases
auto-follow as expected.