fix(frontend): stack the warning banner + tab bar in one sticky wrapper (#1587)

Per mara's review: instead of measuring the banner height in JS and
offsetting the chrome's sticky top, put the warning banner and the page
chrome in the same sticky div so they stack naturally.

common.js builds the wrapper: ensureStickyTop() wraps the page's chrome
(.dashboard-chrome / .page-header) in a single .sticky-top container and
injects the warning banner as its first child. The banner and the chrome
are no longer individually sticky — .sticky-top owns the stickiness, so
they pin together in one context instead of two top:0 stickies colliding
(the banner used to overlay the tab bar). Pages without a chrome (the
H0M3 hub) get a banner-only sticky region. No per-page markup needed; no
JS height measurement. Build green.
This commit is contained in:
iris 2026-06-10 01:05:55 +02:00
commit d7bba48176
4 changed files with 46 additions and 19 deletions

View file

@ -501,22 +501,27 @@ body.side-panel-resizing * { cursor: ew-resize !important; }
ST4TS / S3TT1NGS are full-bleed with their own `.<page>-main` padding. */
.page-content { padding: 0 1.5em; }
/* server warnings banner
Generic top-of-page strip, injected at the top of <body> by
common.js (renderServerWarnings) on every page. One row per warning;
colour comes from the per-warning `level` (warn = amber, crit = red).
`position: sticky; top: 0` keeps it pinned above the page chrome so an
operator sees it on any page no matter how far they've scrolled. */
.server-warnings {
/* sticky top region
One sticky container per page holding the warning banner above the
page chrome (tab bar / page header). common.js (ensureStickyTop)
wraps the page's chrome in this on first render and injects the banner
as its first child, so the banner + chrome stack in a single sticky
context pinned together instead of two separate `top:0` stickies
colliding (the banner used to overlay the tab bar). */
.sticky-top {
position: sticky;
top: 0;
z-index: 50;
}
/* The bar is prepended as a direct child of <body> and spans the full
width edge-to-edge. The dashboard + H0M3 are full-bleed at the body
level their 1.5em horizontal gutter lives on an inner `.page-content`
wrapper (see below), so the banner is full-width for free with no
breakout. FL0W + L0GS are full-bleed too. */
/* server warnings banner
Generic top-of-page strip, injected as the first child of `.sticky-top`
by common.js (renderServerWarnings) on every page. One row per warning;
colour comes from the per-warning `level` (warn = amber, crit = red).
Stickiness lives on the `.sticky-top` wrapper, not here. The bar spans
the full width edge-to-edge; the dashboard + H0M3 are full-bleed at the
body level (their 1.5em gutter lives on an inner `.page-content`
wrapper), so the banner is full-width for free. */
.server-warnings[hidden] { display: none; }
.server-warn {
text-align: center;