Found while reviewing #335 (which fixes this class of bug on five other screens but misses this one).
The bug
frontend/src/components/screens/Settings.tsx:232:
<divstyle={{display: "flex",height: "calc(100vh - 112px)"}}>112px is the TopBar height. Root total = 112 + (100vh - 112) = exactly 100vh — correct for the sidebar layout where <main> is 100vh.
But in the top-nav layout, ShellFrame stacks a 56px TopNav above <main>, so <main> is 100vh - 56px. The screen overflows by exactly 56px.
What the user sees
The inner pane at :233 already has overflowY: auto, so /settings shows two nested scrollbars, and the bottom 56px of the pane sits below the fold — including the account-deletion controls on the data tab.
Mobile always takes the top-nav path (useSidebar = pref === "sidebar" && !isMobile), so this is the mobile experience.
Fix
Use FullHeightScreen / height: 100% per #335's approach, or reference the exported TOP_NAV_HEIGHT (TopNav.tsx:75) which is already available and unused here.
Same class, lower severity — worth folding in
Tree.tsx:311 — height: calc(100vh - 240px); overflows top-nav <main> by ~29px, and the 3D graph canvas is sized off this box via ref/size.h so it renders oversized too.Gradebook/Landing.tsx:218 and Gradebook/Course.tsx:555 — minHeight: calc(100vh - var(--row-h)). --row-h is a density token (40/34/48px per globals.css:144,157,160), not a nav height — so the offset is semantically wrong and density-dependent (spurious scroll of 16/22/8px).
Root cause
Screens hand-roll viewport math instead of resolving against <main>. #335 collapses this onto ShellFrame's two 100vh declarations, which is the right shape — these are the stragglers.
Found while reviewing #335 (which fixes this class of bug on five other screens but misses this one).
The bug
frontend/src/components/screens/Settings.tsx:232:112pxis theTopBarheight. Root total =112 + (100vh - 112)= exactly100vh— correct for the sidebar layout where<main>is100vh.But in the top-nav layout,
ShellFramestacks a 56pxTopNavabove<main>, so<main>is100vh - 56px. The screen overflows by exactly 56px.What the user sees
The inner pane at
:233already hasoverflowY: auto, so/settingsshows two nested scrollbars, and the bottom 56px of the pane sits below the fold — including the account-deletion controls on thedatatab.Mobile always takes the top-nav path (
useSidebar = pref === "sidebar" && !isMobile), so this is the mobile experience.Fix
Use
FullHeightScreen/height: 100%per #335's approach, or reference the exportedTOP_NAV_HEIGHT(TopNav.tsx:75) which is already available and unused here.Same class, lower severity — worth folding in
Tree.tsx:311—height: calc(100vh - 240px); overflows top-nav<main>by ~29px, and the 3D graph canvas is sized off this box viaref/size.hso it renders oversized too.Gradebook/Landing.tsx:218andGradebook/Course.tsx:555—minHeight: calc(100vh - var(--row-h)).--row-his a density token (40/34/48px perglobals.css:144,157,160), not a nav height — so the offset is semantically wrong and density-dependent (spurious scroll of 16/22/8px).Root cause
Screens hand-roll viewport math instead of resolving against
<main>. #335 collapses this onto ShellFrame's two100vhdeclarations, which is the right shape — these are the stragglers.