From eea1ed6bcb85439172d426547565ffd7ed0d923b Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Thu, 21 May 2026 16:22:46 -0400 Subject: [PATCH] shell.css: codify body + .wd-shell + .wd-main as a primitive (fix dead-space layout bug) --- services/web-ui/src/css/components/shell.css | 61 ++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 services/web-ui/src/css/components/shell.css diff --git a/services/web-ui/src/css/components/shell.css b/services/web-ui/src/css/components/shell.css new file mode 100644 index 0000000..ee9a85b --- /dev/null +++ b/services/web-ui/src/css/components/shell.css @@ -0,0 +1,61 @@ +/* shell.css ─ root document + app shell primitives. + * + * Defines the html/body baseline AND the .wd-shell horizontal layout + * (sidebar + main pane). Every authenticated app page mounts inside + * .wd-shell; this is the only correct way to lay out the app. + * + * History: pre-shell.css, each page rolled its own + * body { margin: 0; } .wd-shell { display: flex; min-height: 100vh; } + * inline. Pages that forgot rendered with the sidebar stacking on top + * of the content (8px default body margin + display:block .wd-shell), + * which read as "dead space at top, left-shifted content at bottom". + * Codifying it here prevents that footgun. + */ + +html, body { + height: 100%; +} + +body { + margin: 0; + background: var(--bg-base); + color: var(--text-primary); + font-family: var(--font); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* App shell: sidebar (fixed width) + main pane (flex-fills viewport). + * 100dvh handles mobile chrome resize; 100vh as fallback. */ +.wd-shell { + display: flex; + min-height: 100vh; + min-height: 100dvh; + width: 100%; +} + +/* Default main-pane container. Pages may override background/scroll, + * but the sizing contract is fixed: fill remaining horizontal space, + * scroll vertically, never escape viewport horizontally. */ +.wd-main { + flex: 1; + min-width: 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow-x: hidden; + overflow-y: auto; + background: var(--bg-base); +} + +/* Content wrapper inside .wd-main. Caps width for readability on + * ultrawide displays; --full opts out for dense data pages. */ +.wd-content { + flex: 1; + width: 100%; + max-width: 1440px; + margin: 0 auto; + padding: 24px 32px; +} +.wd-content--full { max-width: none; padding: 0; } +.wd-content--narrow { max-width: 780px; }