From 551dde10786e996ab99a1c5d6f18b3821b1cf7b1 Mon Sep 17 00:00:00 2001 From: bndct-devops Date: Sat, 18 Jul 2026 21:46:47 +0200 Subject: [PATCH] =?UTF-8?q?fix(mobile):=20clamp=20main=20scrollers=20to=20?= =?UTF-8?q?viewport=20width=20=E2=80=94=20WebKit=20pans=20pre-transform=20?= =?UTF-8?q?overflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user's screen recording showed the real failure: on iOS the content area itself pans sideways and rubber-bands back. WebKit counts the focus rotary's pre-transform 540px stage as scrollable overflow (Chromium uses the post-transform size, which is why emulation missed it), giving the main scroller ~150px of horizontal scroll on a phone. overflow-x-hidden on the app's main scrollers makes sideways panning impossible app-wide. Verified on Playwright WebKit (iPhone 13 viewport): scrollLeft is pinned to 0. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 15 +++++++++------ frontend/src/components/AppShell.tsx | 4 +++- frontend/src/pages/DashboardPage.tsx | 5 ++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f2425..3051529 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,15 @@ All notable changes to Tome are documented here. Format loosely follows ### Fixed - **The mobile app no longer feels like a draggable website.** On phones the - whole viewport could be rubber-banded past its edges, double-tap zoomed, and - a long press selected interface text — classic browser-tab behavior. The app - now suppresses edge bounce and scroll chaining, removes double-tap zoom (taps - fire immediately), disables text selection on interface chrome for touch - devices (text fields and the reader keep it), and sizes the shell to the - real visible viewport instead of overhanging behind mobile browser toolbars. + page content could be dragged sideways and rubber-banded (on iOS the Focus + view's scaled cover fan still counted its full unscaled width as scrollable + overflow), the viewport bounced past its edges, double-tap zoomed, and a + long press selected interface text — classic browser-tab behavior. The app + now clamps content to the viewport width, suppresses edge bounce and scroll + chaining, removes double-tap zoom (taps fire immediately), disables text + selection on interface chrome for touch devices (text fields and the reader + keep it), and sizes the shell to the real visible viewport instead of + overhanging behind mobile browser toolbars. - **The notifications panel no longer renders behind sticky page content.** The top bar sat at the same layer as page-level sticky toolbars (and below the new timeline axis), so the open notification dropdown was cut by the Stats diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx index 4f2d546..2434f5b 100644 --- a/frontend/src/components/AppShell.tsx +++ b/frontend/src/components/AppShell.tsx @@ -104,7 +104,9 @@ export function AppShell({ mobileOpen={mobileSidebarOpen} onMobileClose={() => setMobileSidebarOpen(false)} /> -
{children}
+ {/* overflow-x-hidden: see DashboardPage's main — WebKit pans pre-transform + layout overflow sideways; keep the app clamped to the viewport. */} +
{children}
) diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index 3ef39eb..210fb5c 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -1077,7 +1077,10 @@ export function DashboardPage() { onMobileClose={() => setMobileSidebarOpen(false)} /> -
+ {/* overflow-x-hidden: WebKit counts pre-transform layout boxes (e.g. the + focus rotary's scaled 540px stage) as scrollable overflow, letting the + content pan sideways on phones; Chromium doesn't, so test on Safari. */} +
{/* Section heading */} {activeLibraryName && (

{activeLibraryName}