style(layout): tighten the oversized vertical gaps around the page toolbars

The floating-header → toolbar → filter-chips → content stack carried ~2× the whitespace it
needed. Halve it, app-wide where the chrome is shared:
- PageShell: the --hdr-h gap below the floating header 8px → 4px (every page's header).
- Feed: toolbar wrapper pt-4 → pt-2, the toolbar's own pb-3 → pb-1.5, and the grid's top pt-2
  → pt-1. Measured on the feed: header→toolbar 24→12px, toolbar→chips 12→6px, chips→cards 12→8px.
- Plex / Playlists / ChannelDiscovery / DownloadCenter / Notifications / AdminUsers: toolbar
  wrapper pt-3 → pt-2, so every page's top band matches the tighter feed.

PageShell.dom.test updated for the 4px gap.
This commit is contained in:
2026-08-21 19:13:38 +02:00
parent 1be1dc9d06
commit ec3bbc78dc
9 changed files with 17 additions and 17 deletions
@@ -43,7 +43,7 @@ describe("PageShell --hdr-h (E5 S7)", () => {
Object.defineProperty(hdr, "offsetTop", { value: 12, configurable: true });
Object.defineProperty(hdr, "offsetHeight", { value: 96, configurable: true });
roCb?.();
expect(content.style.getPropertyValue("--hdr-h")).toBe("116px"); // 12 + 96 + 8
expect(content.style.getPropertyValue("--hdr-h")).toBe("112px"); // 12 + 96 + 4
});
it("adds no `--hdr-h` pad when there is no header", () => {
@@ -55,7 +55,7 @@ describe("PageShell --hdr-h (E5 S7)", () => {
// PageShell is REUSED across feed↔channel navigation (same component position in App.tsx) — it
// never remounts, so the header DOM node is swapped under a stable PageShell. The measurement
// must re-run on that swap; a one-shot effect kept observing the FIRST node and, when it detached,
// rewrote --hdr-h to a stale 8px that stuck on Back. Regression for the channel-Back header overlap.
// rewrote --hdr-h to a stale 4px that stuck on Back. Regression for the channel-Back header overlap.
const hdr = () => <div data-testid="hdr">H</div>;
const { container, rerender } = render(<PageShell header={hdr()}>content</PageShell>);
const measure = (top: number, h: number) => {
@@ -66,11 +66,11 @@ describe("PageShell --hdr-h (E5 S7)", () => {
};
measure(12, 52);
const content = () => container.querySelector('[class*="pt-(--hdr-h)"]') as HTMLElement;
expect(content().style.getPropertyValue("--hdr-h")).toBe("72px"); // 12 + 52 + 8
expect(content().style.getPropertyValue("--hdr-h")).toBe("68px"); // 12 + 52 + 4
rerender(<PageShell>content</PageShell>); // → channel page: header gone
rerender(<PageShell header={hdr()}>content</PageShell>); // → Back: header returns as a NEW node
measure(12, 52); // fires the NEW header's observer
expect(content().style.getPropertyValue("--hdr-h")).toBe("72px"); // re-measured, not the stale 8px
expect(content().style.getPropertyValue("--hdr-h")).toBe("68px"); // re-measured, not the stale 4px
});
});