Agent chat: header tools float in a subtle glass capsule once text scrolls under them
Leo, 2026-11-03:
also, darn, i guess i realize why there was previously some sort of weird rectangle background behind buttons before. but surely we can do a nice and unobtrusive apple glass type thing that's super subtle until there's text or something beneath right ... if u just look at how chatgpt ios does things...
In a one-tab pane (#33142) the transcript runs up under the tab row, so text scrolled right under the header tools and collided with them. Now the tools sit in one glass capsule, as ChatGPT iOS floats its buttons:
- At rest (first message below the row): no capsule. The tools stay plain glyphs, so the "no fill at rest" rule (#32687, #28962) holds.
- Text underneath (the scroller's existing
data-fade-top): one rounded pill fades in behind the whole group in 160 ms. It uses the shared glass tint (--ds-glass-plain-tintof the theme surface),--ds-glass-popover-blur, the--glass-edgehairline and--elevation-1. Words under the tools go soft and dim, and the glyphs stay legible. - No hard rectangle. The old rectangle was the chat's page color painted behind the tools in the tab row. #32944 removed it, and the per-button resting plates went in #26499, #28962 and #32687. This change brings back neither: the capsule is clear at rest and is frosted glass over text, not a fill.
- No layout shift. The capsule is a
::beforebehind the group, and no box moves; the test checks this. It adds no JS and no scroll work: the selector reuses the transcript's existingdata-fade-topthrough:has(). No observer or timer. - Hover and pressed still light only their own button, drawn over the capsule.
- Reduce Transparency: the capsule is the opaque surface, with no blur. Reduce Motion: no fade.
- Two or more tabs keep the plain row, so nothing scrolls under it and there is no capsule.
Gallery agent-pane.header:
glass-pill-restandglass-pill-over-text: chosen.glass-none-over-text: before.glass-faint-restandglass-faint-over-text: always faint. Rejected: it puts a shape back behind the tools at rest.glass-circles-restandglass-circles-over-text: a disc per button. Rejected: four touching discs on a 26px pitch, the ā® becomes an oval, and it is busier than ChatGPT's one pill.
Design references: cmux/live/panels-subagent-glass-buttons-no-close, cmux/live/transcript-subagent-pill-no-close-button (the ChatGPT iOS reference), cmux/live/toolbar-session-info-button-background-2, cmux/live/toolbar-session-info-button-background (the plates Leo disliked).
Design spec: design/chat-header.md (leo-workspace).
Tests: webviews/test/chat-header-glass.test.ts (Chromium and WebKit) checks:
- no capsule at rest;
- the capsule is round and frosted over text, and lifts the pixels under the tools;
- no tool moves;
- two tabs never get it.
Captures: webviews/scripts/agent-pane/capture-header-glass.mjs.
Agent session: agent session
š¤ Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith Ā· Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Makes the agent chat header tools float in a single frosted-glass capsule when transcript text scrolls under them, so rows no longer collide with the buttons in a one-tab pane.
The capsule stays invisible at rest (tools remain plain glyphs), fades in via the motion scale's micro token once text passes beneath, and sits on a ::before behind the buttons so nothing moves. It's pure CSS built on the transcript's existing data-fade-top ā no JS or scroll work. Reduce Transparency turns the capsule opaque without blur; Reduce Motion skips the fade. Multi-tab panes keep the plain row. Gallery agent-pane.header covers the chosen pill over text plus always-faint and per-button circles alternatives; tests verify the capsule appears only over scrolled text and that the pill is a backing surface, not a control, on the no-capsules allowlist.