From d2be72d57a686317b3182742e7ca4666e1d52eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 19 Jun 2026 21:18:05 +0200 Subject: [PATCH] feat(mobile): add scroll-touch momentum utility for horizontal strips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a `.scroll-touch` utility that restores iOS WebKit momentum scrolling (`-webkit-overflow-scrolling: touch`) and contains the overscroll chain so a flick at the end of a horizontal row does not rubber-band the whole page. Apply it to the insights tab strip and the cycle tab list — the two in-app horizontal scrollers that lost inertial flick under the default `overflow-x-auto`. --- src/app/globals.css | 15 +++++++++++++++ src/components/cycle/cycle-view.tsx | 2 +- src/components/insights/insights-tab-strip.tsx | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 4696df20e..20db09ff5 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -448,6 +448,21 @@ display: none; } +/* + * `.scroll-touch` — momentum scrolling for horizontal scrollers on iOS + * WebKit. `-webkit-overflow-scrolling: touch` restores the inertial + * flick the default `overflow-x-auto` row loses on touch; `overscroll- + * behavior: contain` keeps a flick that reaches the end of the row from + * chaining into the document scroll (the "rubber-band drags the whole + * page" paper-cut). Applied to the in-app horizontal pill / tab strips + * (insights tab strip, cycle tab list) so the gesture matches the + * native feel the bottom-sheet scrollers already get for free. + */ +.scroll-touch { + -webkit-overflow-scrolling: touch; + overscroll-behavior: contain; +} + /* ── Insight card animations ─────────────────────── */ @keyframes insight-fade-in { from { diff --git a/src/components/cycle/cycle-view.tsx b/src/components/cycle/cycle-view.tsx index 74e6b9bea..37562ae52 100644 --- a/src/components/cycle/cycle-view.tsx +++ b/src/components/cycle/cycle-view.tsx @@ -255,7 +255,7 @@ export function CycleView() { triggers size to their content (`text-xs`, no `flex-1`) and the strip scrolls cleanly if needed; from `sm` up they reclaim the equal-width `flex-1` layout. */} - + {tabs.map((tab) => { if (tab.kind === "link") {