Agent chat: your prompt bubble stays glass, even when the minimap lands on it

Merged
TE
14d ago
+188-11

Leo-ask: ask-627d348be0

What changed

The prompt bubble (your own message in the agent pane) is already liquid glass on feat-cmux-next: #23477 replaced the opaque composer-colored fill (color-mix(... var(--agent-text) 13%, var(--acpmux-base)), from #22754) with .ui-glass and a 12% text tint over transparent, no blue, no accent. Two things could still make it opaque:

  • Landing highlight (fixed here). Jumping to a prompt from the thread minimap flashed its bubble in color-mix(in srgb, var(--agent-text) 22%, var(--acpmux-base, ...)): the opaque base, so the glass bubble went solid for the flash. It now mixes over transparent: the bubble's own tint a step brighter. threadMinimap.css.
  • No guard (added here). glass-never-opaque sees a surface as glass only by a CSS blur or a class named glass. The bubble is glass through .ui-glass on its element, so an opaque rule on .cv-user__bubble passed it; that's how the opaque fill went unnoticed. New webviews/test/user-bubble-glass.test.ts:
    • every element drawn as cv-user__bubble (UserBubble, ChiefPromptBubble, PastChat, gallery) carries ui-glass;
    • every fill a .cv-user__bubble rule paints outside Reduce Transparency (background, --glass-tint, --acpmux-landing-highlight) is provably translucent; --glass-opaque (the Reduce Transparency fill) is the only solid one, as the rule allows.
    • check-glass-never-opaque.ts now exports its rule loader and classifier (glassContextRules, fillKind) for this; findOpaqueGlass behaves as before.
  • Reduce Transparency keeps the flash opaque (review fix, ee7c5d032ce). The flash is a Web Animation on background-color, so glass.css's !important hold on --glass-tint doesn't reach it. Under either Reduce Transparency source (prefers-reduced-transparency, data-reduce-transparency) the highlight is the same step brighter over --glass-surface, so every frame is opaque there, as the bubble is.
  • Gallery: agent-pane.thread-minimap gets a landing state: click row 8, wait until that prompt lands 35 px below the top, stop its flash and paint its first color (a still can't catch the flash in flight).

Legibility from #22754 / #23477 is unchanged: the 12% tint and the composer hairline rim stay; Reduce Transparency still draws the same grey opaque.

The garish blue in the same ask is a menu's selected-row highlight, a different surface (menus and popovers); not touched here.

Verification

bun test test/user-bubble-glass.test.ts on huge-blue, measured before the rebase (d3b0c62e57b and 52331da43a, rebased as the SHAs below):

  • at 78c82c8241b (test only, before the fix): 1 fail, naming threadMinimap.css:250 .acpmux-row .cv-user__bubble { --acpmux-landing-highlight: color-mix(in srgb, var(--agent-text) 22%, var(--acpmux-base, var(--agent-page-bg))) }
  • at 865cdd1822 (fix): user-bubble-glass 3 pass, glass-never-opaque 2 pass.

At head 170f6ee19d0 (rebased on feat-cmux-next 67f7791933): bun run check in webviews passes; user-bubble-glass 3 pass, glass-never-opaque 4 pass.

Gallery before/after (landing state, compact minimap arm, 1040 px, Linux Chromium on huge-blue; before = base CSS at 5641122fed2, after = this branch). The landed bubble's computed background at the flash's start:

beforeafter
darkcolor(srgb 0.31 0.31 0.31), opaquecolor(srgb 1 1 1 / 0.22)
lightcolor(srgb 0.78 0.78 0.78), opaquecolor(srgb 0 0 0 / 0.22)

At head ee7c5d032ce (after the Codex review), on huge-blue: bun run check passes; CMUX_BROWSER_TESTS=1 bun test test/thread-minimap-motion.test.ts 5 pass, including two new tests that read the landing animation's keyframes: every frame translucent normally, every frame opaque under data-reduce-transparency. That second test fails before the Reduce Transparency rule (Expected: 1, Received: 0.22). The motion harness now loads ui/glass/glass.css, as acpmux/dev.tsx and the bundle do. The rebuilt gallery's landing state lands on prompt 8 ("Summarize what is ready to land") with the same / 0.22 backgrounds.

On the gallery's flat backdrop the two look alike. The difference shows over a wallpaper, which now shows through the bubble during the flash.

No capture: webview-only change (the landing-highlight CSS custom property, a gallery state and tests); no native UI changes. The gallery state and the computed colors above are the evidence.

Observed / Not run

  • Observed: the red/green, the check and the computed colors above, all on huge-blue.
  • Not run: a real-app capture over a wallpaper (this is a webview-only change). scripts/gallery-compare.sh was started, but its host can't be reached from huge-blue, so I measured the stills directly instead.

Changelog

Fixed: Jumping to a prompt from the thread minimap no longer flashes its bubble opaque.

Agent session: cosmic-gray

🤖 Generated with Claude Code