fix(coach): give the chat page more width and fix the rail scrollbar

The Coach page read as cut off against other pages and the left
conversation scrollbar looked broken.

Width: the page sat inside the shared max-w-screen-xl content frame with
a tall pb-20 FAB gutter that does nothing on /coach (the FAB hides
there). Break out of the frame so the chat claims the full content width
and viewport height, edge-to-edge on small screens and a contained card
from sm up, and centre the thread on a comfortable reading measure.

Scrollbar: the page-surface history rail was wrapped in an overflow-auto
container while the rail itself is a flex column with its own
overflow-auto list — two nested scroll regions. The inner list's height
never resolved, so its scrollbar rendered against an indeterminate track
and the search field scrolled away. Drop the outer scroll: the rail
keeps a fixed search header and one internal list-scroll.
This commit is contained in:
Marc-André Bombeck committed 2026-06-18 21:19:36 +02:00
1 parent 3a3f88a80c
commit 96c5641787
3 files changed
+49 -10

No files matched your search

+30 -9
View File
@@ -63,15 +63,35 @@ export default function CoachPage() {
<div
data-slot="coach-page"
data-tour-id="coach-hero"
// v1.18.1 (W-COACH-UI C1/C3) — the card was capped at
// `100dvh-13rem`, leaving a band of wasted space below it on a
// standalone route that no longer carries the Insights tab strip.
// Claim the page height down to a comfortable bottom gutter so the
// thread + rail fill the viewport, and lift the card with a soft
// shadow so it reads as one contained surface rather than a thin
// outline.
className="bg-card flex h-[calc(100dvh-8rem)] min-h-[32rem] flex-col overflow-hidden rounded-2xl border shadow-sm"
// v1.18.6 (CCH-01) — Marc: the Coach read "cut off" vs other pages
// and wanted more width / a focused Claude-like surface. The page
// sits inside `<AuthShell>`'s shared `mx-auto max-w-screen-xl px-4
// pt-6 pb-20 md:px-6` content frame, which boxed the chat into the
// same narrow column every dashboard card uses and left a tall dead
// band below the card (the `pb-20` FAB gutter, pointless here since
// the FAB hides on `/coach`). Break out of that frame: negative
// margins cancel the container's horizontal + top/bottom padding so
// the chat claims the full content width and the viewport height,
// then a light inner padding keeps it off the window edge. The card
// itself drops its rounded border on small screens (edge-to-edge,
// app-like) and keeps the contained card look from `sm+`.
//
// v1.18.1 (W-COACH-UI C1/C3) — the card formerly capped at
// `100dvh-13rem`, leaving wasted space below it; we now fill the
// reclaimed height.
className={
// Cancel the AuthShell container's padding (`-mt-6` top,
// `-mb-20` bottom, `-mx-4 md:-mx-6` sides) so the surface is
// full-bleed, then re-pad lightly. The height is the full
// viewport minus the top bar (`4rem`) and the small gutters.
"-mx-4 -mt-6 -mb-20 flex h-[calc(100dvh-4rem)] min-h-[32rem] flex-col md:-mx-6 " +
"px-2 pt-2 pb-3 sm:px-4 sm:pt-4 sm:pb-4"
}
>
<div
data-slot="coach-page-card"
className="bg-card flex min-h-0 flex-1 flex-col overflow-hidden rounded-none border-y shadow-sm sm:rounded-2xl sm:border"
>
<CoachConversation
surface="page"
autoFocusComposer
@@ -95,7 +115,8 @@ export default function CoachPage() {
</Button>
</>
}
/>
/>
</div>
</div>
);
}
@@ -78,7 +78,18 @@ export function CoachDrawerBody({
<h2 className="border-border/70 text-muted-foreground flex h-14 shrink-0 items-center border-b px-4 text-xs font-medium tracking-wide uppercase">
{t("insights.coach.historyTitle")}
</h2>
<div className="min-h-0 flex-1 overflow-y-auto">{historyRail}</div>
{/* v1.18.6 (CCH-01) — the wrapping `overflow-y-auto` div here
was the broken left scrollbar: `<HistoryRail>` is itself a
`flex h-full flex-col` with its OWN `overflow-y-auto` list,
so this nested it inside a second scroll container. The
outer container scrolled the whole rail (search field
included) against an `h-full` child whose height resolved to
its content, leaving the inner list's `flex-1 min-h-0`
without a bounded track — the scrollbar rendered against an
indeterminate height and read as half-broken. Drop the outer
scroll: the rail keeps a fixed search header and its single
internal list-scroll is the only scroll region. */}
<div className="flex min-h-0 flex-1 flex-col">{historyRail}</div>
</aside>
)}
@@ -363,6 +363,13 @@ export function MessageThread({
data-slot="coach-message-thread"
className={cn(
"flex h-full flex-col gap-4 overflow-y-auto px-4 py-4 sm:px-6",
// v1.18.6 (CCH-01) — on the now full-width page surface a thread
// stretched edge-to-edge sprawled the prose to an unreadable
// measure. Centre the content on a comfortable max width (Claude-
// like) via an `mx-auto` inner gutter; the scrollbar still rides
// the surface edge. The drawer surface is already narrow, so the
// cap only bites on the wide page surface.
"[&>*]:mx-auto [&>*]:w-full [&>*]:max-w-3xl",
"scroll-smooth",
)}
>