cmux NEXT webviews: every hover tooltip and hover card is the liquid glass
Leo-ask: ask-d547ac77f0
Leo: "WHERE IS THE GLASS EVERYWHERE, all these hover tooltips and hover previews." This makes every web tooltip and hover card use the liquid glass (.ui-glass, ui/glass/glass.css), the surface menus and session hover cards already use. Before this, tooltips had a dense popup-surface frost and link cards had the solid popup surface.
What changed, per surface
- Base UI tooltip (
ui/Tooltip.tsxTooltip) and the title tooltip on every first-party page (ui/titleTooltips.ts) now carryui-glass, with the glass rim as the only edge (the border is clear). The glass uses the tooltip frost: the host's--cmux-tooltip-tint, which is the lowest alpha that keeps the text at 4.5:1 over pure black and pure white (TooltipSurface.swift), plus--tooltip-blur. That is set on the tooltip itself, so it holds under plain, Lens and Spectrum glass. They keep the small elevation-1 tooltip shadow. Font, padding, radius, fade and rise are unchanged. - Toolbar hints (
ui/Toolbar.tsxvia AnchoredCard.ui-hint): glass, tooltip shadow. - Hover cards (
AnchoredCard: the markdown link bubble, link and PR cards, session hover cards): alwaysui-glass..ui-tooltip.ui-card.ui-glasskeeps elevation 2. A page class's solid fill (desktop.css.ui-card,.md-link-bubble) no longer wins over the glass. - Chief Usage chart tooltip (
.cu-tooltip):ui-glasswith the tooltip frost replaces--page-elevatedplus its border. - Reduce Transparency is unchanged: the opaque popup surface, no blur (
--glass-opaque: var(--surface-popup)).
Enforcement
webviews/scripts/check-glass-never-opaque.ts, which runs in test/glass-never-opaque.test.ts:
- A CSS rule whose selector names a tooltip or hover card (
tooltip,.ui-hint,.ui-card,hover-card,[role=tooltip]) now counts as glass even withbackdrop-filter: none, so an opaque fill on it fails. - New
findSolidTooltipMarkup: aui-tooltip/ui-title-tooltipclass list in the page code withoutui-glassfails. - Fixture tests show that both checks flag solid tooltips and pass glass ones.
Skipped because of overlap
webviews/src/pages/shared/desktop.css, ui/ui.css and ui/popupSurface.css are in #23066 (lucasr1b), so I did not edit them. desktop.css's solid .ui-card fill is overridden from glass.css instead and is listed in the checker's TOOLTIP_FILL_OVERRIDDEN with that reason. That entry can go once #23066 lands.
Verified (huge-blue)
bun test test/glass-never-opaque.test.ts test/glass-one-edge.test.ts src/ui/titleTooltips.test.ts test/chief-usage-page.test.tsx test/subtle-elevation.test.ts: pass.CMUX_BROWSER_TESTS=1 bun test test/tooltip-surface.test.ts test/popup-surface.test.ts: 6 + 26 pass (Chromium).tooltip-surfacechecks the host's tooltip tint and blur under plain, Lens and Spectrum glass, the clear border plus rim, and elevation 1. It also checks that the text keeps 4.5:1 over pure black and pure white, light and dark, on glass and under Reduce Transparency. Mutation check: if the tooltip's tint override is removed, both of those tests fail.bun x vp check: format, lint and types clean.test/tooltip-rules.test.tsfails the same way on base (6 title= sites in other files), so that failure is not from this PR.
Before / after
Headless Chromium with the real stylesheets (base vs head), tooltips and cards over a busy page. Left column: a tooltip with a shortcut and the title tooltip. Right column: a toolbar hint and a link hover card. Bottom: the Chief Usage chart tooltip. Headless Chromium does not render the backdrop blur in screenshots, so these show the tint and the edge only.
| dark | light | |
|---|---|---|
| before | ![]() | ![]() |
| after | ![]() | ![]() |
Native tooltip: #23970 (TooltipPanel to Glass.makeOverlayPanel).
Agent session: cosmic-gray
🤖 Generated with Claude Code



