diff --git a/apps/web/src/layouts/AppLayout.scss b/apps/web/src/layouts/AppLayout.scss index a58c09b..3615e4f 100644 --- a/apps/web/src/layouts/AppLayout.scss +++ b/apps/web/src/layouts/AppLayout.scss @@ -7,8 +7,14 @@ // No `@use` of the theme partial needed here — see HomePage.scss's identical // note: every token below is a CSS custom property, available at runtime. +// `height` (not `min-height`): the layout must stay pinned to exactly the +// viewport, never grow taller than it — otherwise a tall page scrolls the +// whole document, dragging the sidebar out of view with it. `overflow: +// hidden` backs that up so nothing can force the document itself to grow; +// `.app-content` below is the one place that actually scrolls. .app-layout { - min-height: 100vh; + height: 100vh; + overflow: hidden; display: flex; background: var(--color-background); } @@ -27,6 +33,10 @@ background: var(--color-surface); border-right: 1px solid var(--color-border); transition: width 0.15s ease; + // Own scroll, independent of `.app-content` — only matters on a very + // short viewport with a long nav, but keeps the rail from ever forcing + // `.app-layout` past 100vh. + overflow-y: auto; &__top { display: flex; @@ -315,6 +325,11 @@ // Content can scroll independently of the sidebar (e.g. a long planning // table) without the fixed-width rail ever needing to shrink. min-width: 0; + // The actual scroll container: `.app-layout` is pinned to `height: 100vh` + // above, so a page taller than the viewport scrolls in here instead of + // scrolling the document (which would drag the sidebar along with it). + min-height: 0; + overflow-y: auto; padding: var(--space-xl); } diff --git a/apps/web/src/pages/ComingSoonPage.scss b/apps/web/src/pages/ComingSoonPage.scss index 122f5dc..1121fff 100644 --- a/apps/web/src/pages/ComingSoonPage.scss +++ b/apps/web/src/pages/ComingSoonPage.scss @@ -2,8 +2,13 @@ // Styles for ComingSoonPage — shared by every stub section page. // ============================================================================= +// Centered, not pinned to `.app-content`'s left edge — same reasoning as +// `.settings-page` (settings-pages.scss): on a wide desktop viewport a +// left-aligned `max-width` here just left a lopsided gap down the right +// side instead of framing the placeholder copy. .coming-soon-page { max-width: 40rem; + margin: 0 auto; p { color: var(--color-text-muted);