Found while verifying #583. Reproduces on every dashboard page, so it is not specific to that work.
Repro
Any /dashboard/* page at a viewport between 768px and ~890px wide. The whole page scrolls sideways; nothing on the right edge is reachable without horizontal panning.
Measured on /dashboard/student (identical on /dashboard/student/courses/:id/exercises and the exercise pages):
| viewport |
client width |
scroll width |
overflow |
main left / width |
| 700 |
685 |
685 |
0 |
0 / 685 |
| 768 |
753 |
878 |
125px |
256 / 622 |
| 800 |
785 |
878 |
93px |
256 / 622 |
| 850 |
835 |
878 |
43px |
256 / 622 |
| 900 |
885 |
885 |
0 |
256 / 629 |
| 1024 |
1009 |
1009 |
0 |
256 / 753 |
Cause
Two things collide at exactly md:
-
The sidebar appears at 768px. useIsMobile() is max-width: 767px, and Sidebar is md:block (Tailwind md = 768px), so at 768 the desktop sidebar renders and takes 256px (SIDEBAR_WIDTH = "16rem"), leaving 497px.
-
SidebarInset cannot shrink into what is left. components/ui/sidebar.tsx:310:
"relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 ..."
w-full inside a flex row that already contains the 256px sidebar, and no min-w-0, so the flex item will not shrink below its min-content width. Measured min-content is 622px against 497px available.
The min-content floor comes from the header's right-hand cluster (header .ml-auto, the LEVEL / DAY STREAK / COINS chips plus the locale, theme and avatar controls). It measures 545px at 768px and only 128px below 768, because it swaps to its compact form on the same md boundary that turns the sidebar on. So the sidebar appears and the header stops being compact at exactly the same width, and between them they need more room than the viewport has.
Suggested fix
- Add
min-w-0 to SidebarInset so the inset can actually shrink. That alone stops the page from scrolling sideways; anything genuinely too wide then has to clip or scroll inside its own container, which is the correct behaviour.
- Consider holding the compact header stats until
lg instead of md, or letting the chips wrap, so the header does not demand 545px in a 497px column.
Both are in shared shell components, so this wants its own change with its own check across dashboard pages rather than being folded into a feature PR.
Not in scope for #583/#584
Called out explicitly in #584 so it is not mistaken for a regression there: the branch reproduces it identically on pages it does not touch.
Found while verifying #583. Reproduces on every dashboard page, so it is not specific to that work.
Repro
Any
/dashboard/*page at a viewport between 768px and ~890px wide. The whole page scrolls sideways; nothing on the right edge is reachable without horizontal panning.Measured on
/dashboard/student(identical on/dashboard/student/courses/:id/exercisesand the exercise pages):mainleft / widthCause
Two things collide at exactly
md:The sidebar appears at 768px.
useIsMobile()ismax-width: 767px, andSidebarismd:block(Tailwindmd= 768px), so at 768 the desktop sidebar renders and takes 256px (SIDEBAR_WIDTH = "16rem"), leaving 497px.SidebarInsetcannot shrink into what is left.components/ui/sidebar.tsx:310:w-fullinside a flex row that already contains the 256px sidebar, and nomin-w-0, so the flex item will not shrink below its min-content width. Measured min-content is 622px against 497px available.The min-content floor comes from the header's right-hand cluster (
header .ml-auto, the LEVEL / DAY STREAK / COINS chips plus the locale, theme and avatar controls). It measures 545px at 768px and only 128px below 768, because it swaps to its compact form on the samemdboundary that turns the sidebar on. So the sidebar appears and the header stops being compact at exactly the same width, and between them they need more room than the viewport has.Suggested fix
min-w-0toSidebarInsetso the inset can actually shrink. That alone stops the page from scrolling sideways; anything genuinely too wide then has to clip or scroll inside its own container, which is the correct behaviour.lginstead ofmd, or letting the chips wrap, so the header does not demand 545px in a 497px column.Both are in shared shell components, so this wants its own change with its own check across dashboard pages rather than being folded into a feature PR.
Not in scope for #583/#584
Called out explicitly in #584 so it is not mistaken for a regression there: the branch reproduces it identically on pages it does not touch.