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
+10 -6
View File
@@ -75,21 +75,25 @@ export type PageDef = {
// Channels + Audit render a table with a sticky header at the scroller top; the shell's top fade
// would sit on it and flip on with the first scroll, so they turn it off. Defaults to on.
fadeTop?: boolean;
// The content column's max width. The header + toolbar centre on this same width (via --content-mw)
// so the floating chrome lines up with the centred content instead of spanning the whole column.
// MUST match the max-w the page's own content wrapper uses. Omit for a full-width page (feed).
maxWidth?: string;
};
// page id → the component App renders in the content column (+ its shell chrome config).
export const PAGE_CONTENT: Record<Page, PageDef> = {
feed: { Component: FeedPage },
channels: { Component: Channels, fadeTop: false },
playlists: { Component: Playlists },
plex: { Component: PlexBrowse },
notifications: { Component: NotificationsPanel },
channels: { Component: Channels, fadeTop: false, maxWidth: "96rem" },
playlists: { Component: Playlists, maxWidth: "64rem" },
plex: { Component: PlexBrowse, maxWidth: "1600px" },
notifications: { Component: NotificationsPanel, maxWidth: "48rem" },
messages: { Component: MessagesPage },
downloads: { Component: DownloadCenter },
downloads: { Component: DownloadCenter, maxWidth: "56rem" },
stats: { Component: Stats },
scheduler: { Component: Scheduler },
config: { Component: ConfigPanel },
users: { Component: AdminUsers },
users: { Component: AdminUsers, maxWidth: "48rem" },
audit: { Component: AuditLog, fadeTop: false },
settings: { Component: SettingsPanel },
};