feat(layout): centre the header on each page's content width, centre the playlist table

Every page's floating header (search bar + sync chip) and the toolbar band now centre on the SAME
max-width the content column uses, instead of spanning the whole column while a max-w page centres
its grid. So the search bar lines up with the left edge of the cards/table on every page, and sits
centred with the content — not against the full page width.

- PageShell takes a `maxWidth`, published as --content-mw; the header adds max-w-[--content-mw] mx-auto
  inside its left-4 / right-(1rem+scrollbar) span, so it centres on that width (`none` = full width).
- moduleRegistry PAGE_CONTENT carries each page's content max width (plex 1600px, channels 96rem,
  playlists 64rem, downloads 56rem, notifications/users 48rem; feed stays full width) — one source.
- Playlists: its content (header, filter row, table) was left-aligned max-w-5xl → now mx-auto, so the
  table is centred and the header lines up with it.

Verified at 1920px: header left edge == content left edge — feed 340, channels 213, playlists 487.
This commit is contained in:
2026-08-21 21:38:49 +02:00
parent 011acd919e
commit 1801a58f6b
6 changed files with 37 additions and 12 deletions
+2 -1
View File
@@ -313,7 +313,7 @@ export default function App() {
const me = meQuery.data!;
const pageGate = moduleDef(page).gate;
const activePage: Page = !pageGate || pageGate(me) ? page : "feed";
const { Component: PageContent, fadeTop } = PAGE_CONTENT[activePage];
const { Component: PageContent, fadeTop, maxWidth } = PAGE_CONTENT[activePage];
const railDef = channelView ? undefined : PAGE_RAIL[activePage];
return (
@@ -379,6 +379,7 @@ export default function App() {
) : (
<PageShell
scrollKey={normalScrollKey}
maxWidth={maxWidth}
// Channels: the registry disables the top fade for its sticky-header table, but the card
// layout has no sticky header, so re-enable it there.
fadeTop={activePage === "channels" ? channelLayout === "cards" : (fadeTop ?? true)}