From 45d63060a975473367a0f0312572b349a5c448a4 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 10 Sep 2026 12:19:30 +0200 Subject: fix(hub): a pinned band's ring stops eating the form above it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tab bar paints an opaque ring of page colour around itself, `--band-margin` wide, so the gap it keeps in the flow is still there once it pins. A box-shadow spread goes out on all four sides, and above the tab bar there is only whatever the element before it happened to leave: the join-code form under a group's title leaves 12px, the ring is 16px, and the form came back with the bottom 4px of its field and its button painted over — page colour at z-index 30, against content that has none to answer with. Reported as "the form is slightly cut off", which is exactly what it looks like and says nothing about a stylesheet. The same 4px went off the bottom of the "could not reach this node" banner, the other thing that stands between a group's title and its tabs. The band reserves that room itself now. `* +`, so it is the gap between two elements rather than a margin the band always carries: `.search-bar` is a first child on the Search page, and a margin-top there would collapse through the page root and take the whole page down with it. Between siblings the two margins collapse to the larger of the pair, so everywhere that already leaves enough is untouched and only what was being painted over moves. Only the two bands that pin against the navigation bar, and that is the rule rather than an economy. Written for all six it fails 22 of the sticky-header cases: the gap *between* two bands is the upper one's `--band-margin` and nothing else — the number `--chrome-h` carries and the offset the lower band pins at — so a lower band's own margin-top wins the collapse wherever it is the bigger of the two and leaves the flow layout wider than the pinned one, at every phone width in every media view. A band under another band needs no room above it anyway: what is there is a band of higher z-index, which a ring cannot paint over. Measured against the shipped GroupPage in the state that was reported — a node answering `code_required` — in Chrome: 12px of clearance under a 16px ring before, 16 against 16 after. test_sticky_band_ring.py holds the two selector lists together out of the source rather than in a browser, because what a browser shows is the 4px at one width in one of the states that happen to put something above a band, while what has to hold is which bands are in which list. docs/apps.md sends the author of a new application to that section to make its toolbar pin; this is what says the toolbar they add does not get the gap, and why. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01BAJawZ25MZPBJ7TKgnVA1n --- .../meshbay-hub/src/meshbay_hub/static/style.css | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'packages/meshbay-hub/src/meshbay_hub/static/style.css') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/style.css b/packages/meshbay-hub/src/meshbay_hub/static/style.css index 774c9bc..d51e5b0 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/style.css +++ b/packages/meshbay-hub/src/meshbay_hub/static/style.css @@ -578,6 +578,38 @@ a:hover { text-decoration: underline; } box-shadow: 0 0 0 var(--band-margin) var(--bg-base); } +/* **And the same gap above the first one.** The ring is painted on all four + sides, which is what the corners need — so a band has to have + `--band-margin` of clearance above it too, or it paints page colour over + whatever is there. Every band but the first has that for free: what sits + above it is the band it pins under, at a higher z-index, and a ring cannot + paint over that. The first has the page's own content above it, and nothing + was making the two agree — the join-code form under a group's title leaves + 12px, the tab bar's ring is 16px, and the form was handed back with the + bottom 4px of its field and its button painted over. The same 4px went off + the bottom of the "could not reach this node" banner, which is the other + thing that stands between the title and the tabs. + + Only the first band, and that is the whole of the rule rather than an + economy: the gap *between* two bands is the upper one's `--band-margin` and + nothing else — it is the number `--chrome-h` carries and the offset the + lower one pins at. A margin-top on a lower band would collapse to the + larger of the pair and win wherever it was bigger, which is most widths, + leaving the flow a couple of pixels wider than the pinned layout. Measured, + in every media view at every phone width, the moment this rule was written + for all six. + + `* +`, so this is the gap between two elements and not a margin the band + always carries: as a first child — the Search page's field is one — a + margin-top would collapse through the page root and take the whole page + down with it. Between siblings the two margins collapse to the larger of + the pair, so every place that already leaves enough is untouched, and only + what was being painted over moves. */ +.sticky-chrome > * + .group-tabs, +.sticky-chrome > * + .search-bar { + margin-top: var(--band-margin); +} + /* ── Cards ────────────────────────────────────────────────────────────────── */ .card { -- cgit v1.2.3