The scroll-to-bottom disc (ConversationScrollButton) was the scroller's
last child — DOM order painted it ABOVE the dock overlay, so it floated
at the scroller's bottom edge, partly covering the composer (owner
refinement round 3, 2026-09-24: it must ALWAYS sit above the composer,
never over any element, and stay positioned with respect to the
composer — which grows a lot taller when a question owns the band).
The fix is a DOM move, not a coordinate: the button now renders INSIDE
the DockOverlay, as a sibling of the DOCK container within the dock
block — `absolute bottom-full mb-2`, anchored to the BLOCK's top edge.
Because the anchor is the block itself (not the scroller's bottom):
- it sits above the composer shell AND the stats row, in the
gradient's transparent band;
- it rides every height change LIVE: typing growth, a pending
question expanding the band (verified: the disc moves with the
393px question form, 9px clear), the 180ms fold morph to the slim
bar (8px clear of the folded bar — no overlap mid-morph either,
height animations reflow per frame);
- pointer-events-auto (the overlay is none by default); the
isAtBottom/scrollToBottom context still reaches it — DockOverlay
is a Conversation child.
The use-stick-to-bottom pattern comment updated; the shared
ConversationScrollButton component itself is untouched (positioning
arrives via className, twMerge swaps bottom-4 → bottom-full).
Live-verified on :3001 with a tall transcript, all three states:
chat mode (15px clear of the composer textarea), expanded question
(9px clear of the form top), folded slim bar (8px clear). 902/902.