From d42b00939f5c240ca5c6469d3df3e73b39880ea4 Mon Sep 17 00:00:00 2001 From: scotttong Date: Thu, 17 Sep 2026 23:48:33 -0700 Subject: [PATCH] fix(ui): keep bottom-left overlays clear of the sidebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The announcement well is `fixed left-3 bottom-3` and 22rem wide. On desktop that is not the corner of the page — it is the sidebar's footer, where the account menu and the Share feedback button live. A 352px card at left:12px covers the whole width of a 240px sidebar, so an announcement lands on top of those controls, and the feedback button's tooltip (z-50, opening upward) lands back on top of the announcement. The toast viewport has the same anchor and the same collision. The two never appear together — the well hides itself while a toast is up — so they have to move together or they disagree with each other. Rather than bump a z-index, which would only decide who wins a fight neither should be in, the overlays now clear the sidebar: - `SidebarShell` publishes its reserved width on the root. It is a sibling of these overlays, not an ancestor, so a custom property is the shared channel. Reserved width, not panel width: a peeking panel overlays content on purpose and is transient, so the overlays must not slide as the pointer crosses it. - `--overlay-gutter-left` and `--overlay-available-width` derive from it. With no sidebar they are exactly the values these overlays already used, so the mobile drawer and any host outside the app shell are unchanged. - Both overlays take the offset at `md:` and up only. Co-Authored-By: Claude Opus 5 (1M context) --- ui/src/components/AnnouncementWell.tsx | 5 +- ui/src/components/SidebarShell.production.tsx | 13 ++++ ui/src/components/SidebarShell.test.tsx | 67 +++++++++++++++++++ ui/src/components/SidebarShell.tsx | 13 ++++ ui/src/components/ToastViewport.tsx | 4 +- ui/src/index.css | 22 +++++- 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/ui/src/components/AnnouncementWell.tsx b/ui/src/components/AnnouncementWell.tsx index b71ce16f095..48612619d8f 100644 --- a/ui/src/components/AnnouncementWell.tsx +++ b/ui/src/components/AnnouncementWell.tsx @@ -41,7 +41,10 @@ export function AnnouncementWell({ health }: { health?: HealthStatus }) { const modalOpen = useModalOpen(Boolean(announcement)); if (!announcement || modalOpen || (toasts?.length ?? 0) > 0) return null; return ( -