Skip to content

Commit 5916265

Browse files
DylanMerigaudclaude
andcommitted
Make the page exactly viewport-height — kill the competing page scroll
The dashboard's fixed lg:h-[min(620px,100vh-220px)] under-counted the chrome (header + footer + padding ≈ 250px, not 220), so on shorter laptops the page overflowed by ~20px → a window scrollbar on TOP of the panel scroll (the double-scroll in the screenshot). To the "overflow on main/body?" question: no — overflow + fixed height clips at the padding edge, which is the bug. Instead the page is now a viewport-tall flex column (lg:h-screen) with the dashboard filling the flex-1 slot, so there is ONE scroll context — inside the queue/trace panels — and no page scroll. Footer/socials stay visible. Verified across 1280×800 / 1440×900 / 1536×864: pageScrolls=false, footerVisible=true, queue scrolls internally (pill now reads "1 more"). typecheck · knip · 82 tests · build · e2e 3/3 all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f21904a commit 5916265

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

app/page.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,20 @@ export default async function Page() {
2929
}
3030

3131
return (
32-
<main className="mx-auto max-w-[1200px] px-4 py-6 sm:px-6 sm:py-8">
32+
// On desktop the page is exactly viewport-tall (flex column) so there is ONE
33+
// scroll context — inside the queue/trace panels — not a competing page
34+
// scroll. On mobile it falls back to natural height + normal page scroll.
35+
<main className="mx-auto flex max-w-[1200px] flex-col px-4 py-6 sm:px-6 sm:py-8 lg:h-screen">
3336
<Header />
34-
{dbError ? (
35-
<SetupNotice detail={dbError} />
36-
) : queue.length === 0 ? (
37-
<SetupNotice detail="The database is reachable but empty — run `pnpm db:seed` to load the demo invoices." />
38-
) : (
39-
<Dashboard queue={queue} />
40-
)}
37+
<div className="min-h-0 flex-1">
38+
{dbError ? (
39+
<SetupNotice detail={dbError} />
40+
) : queue.length === 0 ? (
41+
<SetupNotice detail="The database is reachable but empty — run `pnpm db:seed` to load the demo invoices." />
42+
) : (
43+
<Dashboard queue={queue} />
44+
)}
45+
</div>
4146
<Footer />
4247
</main>
4348
);

components/dashboard.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ export function Dashboard({ queue }: { queue: QueueItem[] }) {
6161
}
6262

6363
return (
64-
// A fixed, sensible viewport-relative height (not full-bleed stretch) so the
65-
// two panes sit side by side, each scrolling internally, and the page footer
66-
// stays reachable. On mobile they stack at natural height.
67-
<div className="grid grid-cols-1 gap-4 lg:h-[min(620px,calc(100vh-220px))] lg:grid-cols-[minmax(300px,380px)_1fr]">
64+
// Desktop: fill the parent's flex-1 slot (the page is viewport-tall), so the
65+
// two panes sit side by side and scroll INTERNALLY — no competing page
66+
// scroll. Mobile: stack at natural height.
67+
<div className="grid grid-cols-1 gap-4 lg:h-full lg:grid-cols-[minmax(300px,380px)_1fr]">
6868
{/* LEFT — queue */}
6969
<Card className="flex max-h-[70vh] flex-col overflow-hidden lg:max-h-none">
7070
<CardHeader className="flex items-center justify-between">

0 commit comments

Comments
 (0)