Follow-up to 534b2ff. Dropping the strip to its own bar was now measured,
but two things still produced a wrapped bar on the XIAO example at 1440
with the chat docked:
- The first collapse tier (Serial / Camera / Mic / Scope / Add / Libraries
labels -> icons) was still a fixed 1010px container query, so on the
1060px own-bar the labels stayed and the bar wrapped in two. That tier is
now the unified-toolbar--compact class, set by the same measurement:
labels on the brand row if they fit, icons on the brand row if those fit,
else the own bar — labelled if the full bar holds it, icons otherwise.
The finer tiers (board pill 905, count/zoom 835, view toggle 760/1140)
stay as container queries.
- Each candidate layout is measured IN that layout: the zones carry their
own container queries (the view-mode toggle hides on a narrow row and
reappears on the wide bar), so a width read on the brand row said the
bar would fit when it would not.
With the AI chat docked at 1440px, a board with many canvas controls (XIAO:
display + camera + mic + scope) wrapped the strip INSIDE the header — the
canvas controls orphaned on a second line next to a black hole — because
the drop-to-own-bar fallback fired on media-query thresholds (1040 / 1060 /
1400px by chat state) that were only right for one board's strip width.
AppHeader now measures: natural single-row width of the strip (each zone at
its content width) against the room left next to the brand + menus, and
sets app-header--strip-below when it does not fit. Always measured in the
inline layout (class removed, measured, restored before paint) so the
below-state's margins and uncollapsed labels never bias the decision, and
there is nothing to oscillate. Re-measured via ResizeObserver on the strip
host, the brand block and the zones (plus a MutationObserver for the
portaled canvas controls), deferred a frame so a toggle never re-enters
delivery. The three media-query blocks collapse into one class rule; a
1000px window without the chat now keeps one row when the collapsed strip
fits, instead of being forced to two.