From a9c3d3396afacacf68b0f5a9082eed56cdb17be6 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Sun, 23 Aug 2026 14:13:15 +0800 Subject: [PATCH] fix(settings): scrollable panel without clipping overflow + close on Escape/backdrop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The config panel content could overflow the window with no way to scroll (#settings-view had no overflow set). A bare overflow-y:auto is not enough by itself though: the panel centers its card with justify-content:center, and centering a flex container whose content overflows leaves the start of the overflow unreachable by scroll (scrollTop can't go negative). Switch to justify-content:flex-start + margin:auto on the card — same centered look when it fits, but auto margins clamp to 0 instead of going negative, so an oversized card scrolls from the top instead of losing its start. Also closes the settings modal on Escape and on a backdrop click (outside the card), matching standard modal UX — neither existed before. Co-Authored-By: Claude Sonnet 5 --- sidepanel.css | 8 +++++++- sidepanel.js | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sidepanel.css b/sidepanel.css index 1069126..0d46307 100644 --- a/sidepanel.css +++ b/sidepanel.css @@ -686,7 +686,11 @@ body { background: rgba(10, 15, 26, 0.85); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); - justify-content: center; + /* flex-start + margin:auto on the card (not justify-content:center) so overflow + scrolls correctly — centering via justify-content clips the overflowed start + of the content out of scroll reach when it doesn't fit. */ + justify-content: flex-start; + overflow-y: auto; padding: 24px; } @@ -699,6 +703,8 @@ body { display: flex; flex-direction: column; gap: 20px; + margin: auto 0; + flex-shrink: 0; } .settings-card h2 { diff --git a/sidepanel.js b/sidepanel.js index 052042d..3545619 100644 --- a/sidepanel.js +++ b/sidepanel.js @@ -860,6 +860,14 @@ settingsBtn.addEventListener("click", () => { cancelSettingsBtn.addEventListener("click", () => switchView("chat")); +// Close on Escape or a click on the backdrop itself (not the card) — standard modal UX. +document.addEventListener("keydown", (e) => { + if (e.key === "Escape" && settingsView.classList.contains("active")) switchView("chat"); +}); +settingsView.addEventListener("click", (e) => { + if (e.target === settingsView) switchView("chat"); +}); + // Clear the on-screen scrollback + this window's persisted mirror (storage.session). The agents' // resumable ACP sessions are deliberately KEPT — this wipes the local transcript without making the // agents forget, so `session/resume` still restores their side of the conversation on reconnect,