Operator brief (#394): the header had thirteen distinct visual
elements in one flex row with three different border-radius
languages, four colour treatments, three label styles. Mara's
direction:
- agent icon bigger (full header height) as the identity anchor
- title glow stays
- nav links lose their default-anchor underline
- overflow `⋯` absorbs `↻ R3BU1LD` + `↻ new session` (rare,
destructive — both worth one extra click; rebuild is normally
done from the dashboard)
- accent stacking in the state strip stays — that's the vibe
## Layout shape
Three flex columns in `.agent-header`:
[icon · full height] [main column · 2 rows] [pills + ⋯]
The main column carries row 1 (`◆ AGENT ◆` title + meta-nav) on
top and row 2 (alive · state · model · ctx · cost · last-turn ·
cancel-turn) below.
## Changes
### `index.html`
- Wrap title + nav in `.agent-header-row .agent-header-title-row`;
wrap state-row siblings in `.agent-header-row .agent-state-row`;
both go inside a new `.agent-header-main` column.
- Right cluster `.agent-header-pills` contains the inbox + loose
pills + a new `<button id="overflow-btn">⋯</button>` trigger.
- Drop static `#new-session-btn` from `#state-row` — moved into the
overflow menu, populated dynamically.
- Add `<div id="overflow-menu" role="menu" hidden>` as a sibling
of `<header>` (lives outside the header so its `position: fixed`
popover isn't trapped by any header stacking context).
### `agent.css`
- `--agent-header-h: 4.6em → 6em` so the icon can be square + full
height without crowding the two-row main column. Terminal
padding-top + status overlay top + tail-pill all derive from
this variable, so they follow automatically.
- `.agent-header { align-items: stretch }` lets the icon stretch
to full height; `.agent-icon { height: 100%; aspect-ratio: 1 }`
sizes it as a square off the stretched height.
- `.agent-nav-link` rule added — `text-decoration: none`, cyan +
soft glow, hover lights brighter (mara's spec).
- `.overflow-btn` (round trigger) + `.overflow-menu` (frosted
popover, fixed-position) + `.overflow-item` (rows with an icon
column + label, hover ink matches per-action accent — cyan for
dashboard, amber for rebuild/new-session).
- Remove the old `#state-row` selector (layout now provided by
`.agent-state-row` + `.agent-header-row`).
### `app.js`
- `setHeader` no longer appends DASHB04RD / R3BU1LD chips into the
title — title is just the identity glyph now. Both actions get
rendered into the overflow menu by `populateOverflowMenu()`.
- `populateOverflowMenu(label, dashUrl)` builds three rows:
`↑ dashboard` (anchor), `↻ rebuild container` (button — same
POST-form action as before), `↻ new claude session` (button —
same `/api/new-session` call as the legacy header button).
- Overflow toggle / outside-click / Escape dismissal — same
pattern as the side-panel flyout (`Panel`).
- Drop the static `new-session-btn` IIFE binder; the dynamically-
rendered menu item owns its handler now.
- Drop the per-nav-link inline `marginLeft` (layout gap comes from
the new `.agent-nav { gap }` rule).
## Validation
- `npm run build` clean.
- Build deltas: agent.css 21.0kb → 23.6kb (overflow + nav rules
+ comments), app.js 117.4kb → 118.9kb (menu builder + toggle).
- Browser smoke test isn't possible from inside iris's container.
Worth eyeballing post-deploy:
- Icon fills the full header height as a square
- Title glow + uppercase styling preserved
- Nav links render without underline; hover lights brighter
- `⋯` opens a frosted popover with `↑ dashboard`, `↻ rebuild
container`, `↻ new claude session`
- Rebuild confirm + POST works the same as the legacy chip
- New-session confirm + POST works the same as the legacy button
- State strip still wraps when crowded (model/ctx/cost
multi-line on narrow viewports)
- Cancel-turn button still appears while thinking and clears
on turn end
- Terminal padding-top adjusts to the new 6em header height
(no row hidden under the chrome)