The curve for cycle 32 came out above the threshold.
Message Scroller
Conversation transcript that behaves like a chat: it follows new messages only if you are at the bottom, shows "Jump to latest" (with how many arrived) when you have scrolled up, and keeps your position when older messages are added at the top. It does not care how messages arrive: it watches its own content. Uses role=log with aria-live=polite.
New via HTMX, older at the top, and streaming
Scroll up and ask for new messages: your position stays put, and the button counts what arrived. "Load earlier" adds to the top without pushing what you are reading.
@components.MessageScroller(components.MessageScrollerProps{ID: "chat", Label: "Conversation"}) {
for _, m := range messages { @components.Message(...) { { m.Text } } }
}
// new ones: hx-get="/messages" hx-target="#chat-content" hx-swap="beforeend"