fix(admin): suppress painted scrollbar on mobile section strip

Production probe at /admin/api-tokens on a Pixel-5 viewport pinned the
scrollbar that kept showing up after two earlier fixes: it lives in
the AdminShell mobile section strip (13 entries, scrollWidth ~1700 vs
clientWidth ~360), not in the api-tokens table. The strip sits right
above the api-tokens card, which is why every previous attempt
targeted the table while the bar stayed put.

Adds a `no-scrollbar` utility in globals.css (scrollbar-width: none +
::-webkit-scrollbar { display: none }) and applies it to the strip in
both AdminShell and SettingsShell. Swipe and keyboard-arrow scrolling
keep working; the painted bar simply doesn't draw.

New AdminShell unit suite locks in the class so a future refactor
can't silently regress it; settings-shell test gets the matching
assertion. The api-tokens e2e spec gains a regression check that the
strip declares `no-scrollbar` and overflow-x-auto together.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-10 10:16:56 +02:00
1 parent 15c852f48e
commit 3e1607471b
6 files changed
+197 -4

No files matched your search

+8 -2
View File
@@ -148,10 +148,16 @@ export function AdminShell({ active, children }: AdminShellProps) {
return (
<div className="mx-auto w-full max-w-screen-xl px-4 py-6 md:px-6 md:py-8">
{/* Mobile section strip — horizontal scroll, hidden on md+. */}
{/* Mobile section strip — horizontal scroll, hidden on md+.
`no-scrollbar` (defined in `globals.css`) suppresses the
painted scrollbar at the top of every admin page; the
horizontal swipe + keyboard arrow scrolling still work, the
bar just doesn't draw. Without this the 13-section strip
would render an always-on scrollbar that Marc kept
mis-attributing to the api-tokens table below it. */}
<nav
aria-label={t("admin.shell.sectionsNav")}
className="-mx-4 mb-4 overflow-x-auto px-4 md:hidden"
className="no-scrollbar -mx-4 mb-4 overflow-x-auto px-4 md:hidden"
>
<ul className="flex min-w-max gap-2">
{ADMIN_SECTIONS.map((section) => {