agent: badges join the pills cluster, not the other way around

mara, live, correcting the prior round: 'oh i meant move badges to
where the dropdowns are not the other way around. this way the height
does not change even on widescreen.'

Prior commit nested pills INTO a new row inside .agent-header-main
(badges + pills sharing a row under the title). Backwards from what
she wanted: badges now join .agent-header-pills instead — the same
header-level column pills already lived in, which already handles a
variable child count via flex-wrap + justify-content: flex-end.
.agent-header-main goes back to just the title + hive-label rows,
which don't wrap in practice, so its height stays stable regardless of
how many badges/pills are showing.

The ResizeObserver dynamic-height fix from the prior commit is
untouched and still does the real work of keeping .agent-status-
overlay's offset correct if anything does wrap — this is a pure
layout-preference change on top of that, not a new bugfix.

Verified at 500/1024/1400px — badges+pills form one right-aligned
cluster next to the title, no overlap, no ResizeObserver console
error. tsc --noEmit clean, build clean, both pre-push lints clean.
This commit is contained in:
iris 2026-08-28 22:47:49 +02:00
commit d7e70fd195
2 changed files with 35 additions and 40 deletions

View file

@ -128,24 +128,18 @@ body.agent-shell {
margin: 0;
gap: 0.5em;
}
/* New Preact page only: `Header.tsx` nests `.agent-header-pills`
INSIDE `.agent-state-row` (badges + pills sharing one row mara,
live: "can we put the badges on the same row as the links button
etc? then the header would be more compact"), unlike the old
app.js markup where `.agent-header-pills` is a separate header-
level column (index.html line ~54). Scoped as a descendant
selector so it only fires for that nesting app.js's own
still-live 3-column layout below is untouched. Pushes the pills
cluster to the row's right edge; badges (`children`, rendered
first) fill the space to its left. */
.agent-state-row .agent-header-pills {
margin-left: auto;
}
/* Right cluster flyout pills stacked / inline with the overflow
trigger. Vertically centred against the full-height icon, no
wrap; pills can drop to a row of their own under crowding via
the flex-wrap of `.agent-header-pills` itself. */
the flex-wrap of `.agent-header-pills` itself. New Preact page also
puts the status badges (`StatusChips`) in here now, alongside the
flyout pills mara, live: "move badges to where the dropdowns
are" this same rule already handles a variable child count
gracefully (flex-wrap + flex-end), no changes needed to absorb
them; `.agent-header-main` (agent.css, `.agent-header-title-row`/
`.agent-hive-row`) only ever holds the title + hive-label rows now,
which don't wrap in practice, so it stays a stable height. */
.agent-header-pills {
display: flex;
align-items: center;

View file

@ -1,12 +1,12 @@
// <Header> — the agent page's identity strip: icon, glyphic title, the
// "swarm / hive" label row, and a slot for the status row
// (`<StatusChips>` — ../status-chips/, kept separate so this component
// has no opinion on what badges exist). Two columns (icon · main),
// NOT the old `#agent-header` markup's three (icon · main · pills) —
// see the `pills` prop doc below for why. Reuses `agent.css`'s
// existing `.agent-header*`/`.agent-icon` rules (loaded globally by
// index.html) rather than a component-scoped stylesheet — no new
// visual language needed for the chrome itself.
// has no opinion on what badges exist). Same three-column shape as the
// old `#agent-header` markup (icon · main · pills) — see the `pills`
// prop doc below for what moved into that third column and why.
// Reuses `agent.css`'s existing `.agent-header*`/`.agent-icon` rules
// (loaded globally by index.html) rather than a component-scoped
// stylesheet — no new visual language needed for the chrome itself.
// Measures its own rendered height via ResizeObserver, writes it to
// `--agent-header-real-h` (agent.css's downstream consumers —
@ -41,25 +41,24 @@ function handleIconError(e: Event) {
export interface HeaderProps {
label: string;
hiveLabel?: string | null;
/** The status/badge row (`<StatusChips>`) shares its row with
* `pills` now (see below), not stacked in a row of its own. */
/** The status/badge row (`<StatusChips>`) lives in the
* `.agent-header-pills` cluster now, alongside `pills` (see below),
* not stacked as its own row under the title. */
children?: ComponentChildren;
/** Flyout triggers (inbox/todos/links pills, the overflow menu
* button). Old markup's `.agent-header-pills` was its own header-
* level column, self-centered against the full header height the
* new page instead nests it inside the same row as `children`
* (`.agent-state-row`), pushed to the row's right edge via
* `margin-left: auto` (scoped to that nesting in agent.css so
* app.js's still-live separate-column usage is untouched). mara,
* live: "can we put the badges on the same row as the links button
* etc? then the header would be more compact" one shared row
* instead of two disconnected clusters reads as one unit, and (as a
* side effect) is one less row that could ever grow the header past
* the fixed `--agent-header-h` the rest of the page is offset
* against (see the overlap-bug history on this same PR). Meta-nav
* (`<MetaNav>`) lives in here too, as a fixed-size trigger NOT in
* the title row the old markup put it in (`<nav id="meta-links">`,
* docs/web-ui/agent.md) same overlap-bug reasoning. */
* button) and, since this round, `children` (the status badges)
* too, both in `.agent-header-pills`, the SAME header-level column
* the old markup used for pills alone. First pass of this ask
* nested pills into a row inside `.agent-header-main` instead
* backwards, mara corrected live: "i meant move badges to where the
* dropdowns are, not the other way around. this way the height does
* not change even on widescreen" `.agent-header-main` now only
* ever holds the title + hive-label rows, which don't wrap in
* practice, so it stays a stable height; only this pills-cluster
* column (already used to absorbing a variable pill count) grows to
* fit badges+pills together. Meta-nav (`<MetaNav>`) lives in here
* too, as a fixed-size trigger not the old markup's inline list in
* the title row (`<nav id="meta-links">`, docs/web-ui/agent.md). */
pills?: ComponentChildren;
}
@ -88,11 +87,13 @@ export function Header({ label, hiveLabel, children, pills }: HeaderProps) {
<h2 class="agent-header-title"> {label} </h2>
</div>
{hiveLabel ? <div class="agent-header-row agent-hive-row">{hiveLabel}</div> : null}
<div class="agent-header-row agent-state-row">
{children}
{pills ? <div class="agent-header-pills">{pills}</div> : null}
</div>
</div>
{children || pills ? (
<div class="agent-header-pills">
{children}
{pills}
</div>
) : null}
</header>
);
}