chat: stick-to-bottom auto-scroll with jump-to-latest button
Nightly Build / build (push) Successful in 6m51s

Auto-scroll now yields when the reader scrolls away from the bottom, so a
fast-streaming reply no longer fights someone reading the start. Stickiness is
a flag driven by a passive scroll listener (not a per-flush distance check,
which breaks when one flush adds more than the threshold of content); scrolling
back within the band re-arms it.

Centralised in chat-session.js (_scrollToBottom(force) + _forceScrollToBottom
+ _messagesContainer hook), removing the duplicated overrides in copilot.js /
chat-page.js. Force-scroll is used where the latest must be shown: history
load, chat reopen, approval/clarification prompts, and message send.

A sticky 'jump to latest' affordance appears only while scrolled up.
This commit is contained in:
2026-07-24 21:06:04 +01:00
parent d1d0a2af26
commit db6e395c11
7 changed files with 140 additions and 19 deletions
+33
View File
@@ -9,6 +9,39 @@
gap: 0.7rem;
}
/* ── "Jump to latest" floating affordance ──────────────────────────────────── */
/* Shown only while the reader is scrolled away from the bottom (auto-scroll has
yielded). Sticky to the scrollport bottom so it stays in view as they read;
removed from the DOM entirely while stuck to the bottom. */
.copilot-jump-btn {
position: sticky;
bottom: 0.6rem;
align-self: flex-end;
width: 38px;
height: 38px;
display: grid;
place-items: center;
padding: 0;
border: 1px solid var(--card-border);
border-radius: 50%;
background: rgba(var(--accent-rgb), 0.92);
color: #fff;
box-shadow: var(--card-shadow);
cursor: pointer;
z-index: 5;
font-size: 1.1rem;
line-height: 1;
transition: transform 0.12s ease, background-color 0.12s ease;
}
.copilot-jump-btn:hover { background: var(--accent); transform: translateY(-1px); }
.copilot-jump-btn:active { transform: translateY(0); }
.copilot-jump-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
.copilot-jump-btn { transition: none; }
.copilot-jump-btn:hover { transform: none; }
}
/* ── Message bubbles ───────────────────────────────────────────────────────── */
.copilot-msg {