diff --git a/frontend/src/components/PageShell.tsx b/frontend/src/components/PageShell.tsx index 61236b79..f21f9dea 100644 --- a/frontend/src/components/PageShell.tsx +++ b/frontend/src/components/PageShell.tsx @@ -67,12 +67,30 @@ export default function PageShell({ }) { const [toolbarSlot, setToolbarSlot] = useState(null); // Publish this page's content max-width so the floating header (and toolbar band) can centre on the - // same width the content column uses. Global (one page shell renders at a time). + // same width the content column uses. Global (one page shell renders at a time). Also decide whether + // a PINNED filter rail should stay OVERLAY (keep the toolbar's fixed leading gutter, don't push the + // centred content) or go in-flow: overlay only when the centred content leaves a wide-enough left + // margin for the rail to sit in — else pinning would overlap the content, so it pushes (in-flow). useLayoutEffect(() => { const root = document.documentElement; root.style.setProperty("--content-mw", maxWidth ?? "none"); + // Room the pinned rail needs: its own width (~16rem) on each side of the centred content, plus the + // nav rail (~4rem). Below that, or on a full-width page (no maxWidth), pin in-flow (w-67). + const apply = () => { + const mwPx = maxWidth + ? maxWidth.endsWith("rem") + ? parseFloat(maxWidth) * 16 + : parseFloat(maxWidth) + : null; + const roomy = mwPx != null && window.innerWidth >= mwPx + 576; + root.style.setProperty("--rail-pinned-w", roomy ? "2.25rem" : "16.75rem"); + }; + apply(); + window.addEventListener("resize", apply); return () => { + window.removeEventListener("resize", apply); root.style.removeProperty("--content-mw"); + root.style.removeProperty("--rail-pinned-w"); }; }, [maxWidth]); // The floating header pads the content below it by `--hdr-h`. That must equal the header's REAL diff --git a/frontend/src/components/SidePanel.tsx b/frontend/src/components/SidePanel.tsx index f338aa49..897ab19f 100644 --- a/frontend/src/components/SidePanel.tsx +++ b/frontend/src/components/SidePanel.tsx @@ -44,14 +44,16 @@ export default function SidePanel({ return ( // Layout slot: reserves only the tab's gutter when unpinned, so the expanded card overlays - // content instead of pushing it. Pinned reserves the full width (in-flow), as before. + // content instead of pushing it. Pinned reserves --rail-pinned-w: 16.75rem (in-flow, pushes) on a + // full-width page or a narrow window, but 2.25rem (overlay, doesn't push) when the centred content + // leaves room for the rail to sit in its left margin — see PageShell. Default 16.75rem = old w-67.
{/* The tab: a small handle flush against the nav rail, flat on the docked edge. It stays mounted while the card is open — swapping it out from under the pointer would drop the very