Repository navigation
Composer: a subtler, glassy focus ring - #22114
Conversation
…e glass rim (failing) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… glass rim The focused composer's rim steps 22% toward the text instead of 30% (Leo 2026-10-19: subtler). Over art the focused glass card's top-lit rim brightens instead of the ring growing heavier. No new tokens; Reduce Transparency draws no rim layer, so it keeps the plain step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Unclear: CI failed on
Not re-run automatically: Written by red: web / Web status; do not merge until green; see lane-rules
Agents: |
|
Bead |
|
Visual preview of 3b420ff: in the maintainers' private review feed. |
|
Found 1 test failure on Blacksmith runners: Failure
|
[Low impact] The PR appears safe to merge, with the previous non-blocking border-setting issue still open. Findings
SummaryMakes the composer's focus ring subtler and brightens its glass edge over art.
Reviews (2) · Last reviewed commit: "chore(next): PR autofix at 6312d76b8f6e" · Reviewed by Greptile |
| :root[data-cmux-see-through] | ||
| :is( | ||
| .acpmux-composer-box:has(:focus-visible), | ||
| .acpmux-composer:has(> .acpmux-composer-strip :focus-visible) > .acpmux-composer-box | ||
| ) { | ||
| --acpmux-composer-rim: inset 0 1px 0 light-dark( |
There was a problem hiding this comment.
With data-cmux-see-through and data-borders="none", keyboard focus still brightens the composer's top edge. The border setting clears --acpmux-card-ring and --acpmux-composer-edge-focus, but this new rule changes a separate shadow layer. Exclude data-borders="none" from this rule so focusing the card respects the user's border setting.
There was a problem hiding this comment.
Leaving this as is on purpose. borders none doesn't clear the glass card's top-lit rim at rest either; it's the glass highlight, not a border. With borders none the focus ring is already transparent, so over art this brightening is the only visible keyboard focus cue. Dropping it would leave a focused composer identical to an idle one.
There was a problem hiding this comment.
That context makes sense. Since --acpmux-composer-rim is the glass highlight and remains present at rest, data-borders="none" clearing only --acpmux-card-ring and the focus tone is intentional. Removing this override would make keyboard focus indistinguishable from idle over art, so the brightened top rim is a valid remaining focus cue rather than a border violation. I’m withdrawing this finding.
- vp fmt webviews/test/composer-rim-hairline.test.ts Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39315390260
|
Base reds, not from this PR, which only touches |
…ws only with the focused ring The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every bar-scoped rule skipped it: the plain footer look (data-footer-look, the default), #22107's hover, press and keyboard-focus pills and outline, and #22114's glass focus rim. The row now takes the chat's footer look and the same state rules. The caret and the focused ring now follow one state: pageKey.ts marks the root data-page-inactive while the page is not the key one (window blur, hidden, document without focus), and then a focused field hides its caret and every composer draws its resting ring. A key or press on the page, or the window's focus, brings both back. Gallery: composer-rest/hover/open/focus/keyboard/background variants for the chat composer and the New Tab page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Shipped in:
|
…ows only with the focused ring (#22216) * test(composer): one caret, focus and chip behavior in the chat and New Tab composers (failing) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): New Tab gets the chat's chip states, and the caret shows only with the focused ring The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every bar-scoped rule skipped it: the plain footer look (data-footer-look, the default), #22107's hover, press and keyboard-focus pills and outline, and #22114's glass focus rim. The row now takes the chat's footer look and the same state rules. The caret and the focused ring now follow one state: pageKey.ts marks the root data-page-inactive while the page is not the key one (window blur, hidden, document without focus), and then a focused field hides its caret and every composer draws its resting ring. A key or press on the page, or the window's focus, brings both back. Gallery: composer-rest/hover/open/focus/keyboard/background variants for the chat composer and the New Tab page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): read the glass rim in WebKit's shadow order too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(composer): vp fmt the caret and focus test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): a chip a click focused does not lift the New Tab glass rim; test a key marks the page key From review: the chat card lifts only for its prompt or keyboard focus, so the New Tab card does the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): the glass rim check runs where the engine draws the rim Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…election, compact disc (#22229) * cmux NEXT Home list: one-row header at every width, theme selection tint, compact disc The conversation list's header drew a lone compose button on its own row above a system-blue-ringed search field and a dropdown filter, and below 180 pt the search and filter vanished. Now search, an Unread toggle and compose share one row in a 52 pt band (the transcript header's height) at every width: only the field's width changes, it becomes a search icon that opens over the row when the field no longer fits, and the buttons shrink rather than wrap at the narrowest list. The buttons are quiet icon buttons (no pill at rest, the theme's hover pill, pressed fill and a 0.94 shrink). The field has no AppKit bezel or focus ring: a capsule with the composer's quiet fill and hairline rim, stepped 22% toward the text while focused (#22114), a secondary placeholder and the theme accent caret. The filter dropdown with two choices is now a one-click toggle. The selected row is the theme's translucent selection tint, not the opaque unemphasized grey, and in the compact list the selected row or tile is a disc behind the avatar instead of a slab. MessagesLabSidebar patches: headerLayout (the host lays out the header), neutralFill and the compact disc, CmuxSidebarSearchField (reports focus). Patches/ regenerated against the pin; README patch table updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux-next media: a Home list tour at 320, 260, 180, 140 and 76 pt, dark and light Tour steps can send one app control-socket request (`rpc`) for DEBUG fixtures with no CLI verb. The home tour seeds fixture rows and sets the list's width, selection, search focus and Unread toggle through debug.home.sidebar_fixture, and path_map routes the Home list's sources to it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Home list header review: buttons never grow below the full row, an emptied field closes a collapsed search, the capsule rim focuses the field, debug hooks DEBUG only Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at a08ba74 - schemas/defaults/cmux-next.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39351916892 * Home list header: debug look in CmuxNextHome (CmuxNextApp size cap), nonisolated test widths (fast tier) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at 94f77db - schemas/defaults/cmux-next.json Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39357465558 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
…othing (#22353) * test(composer): focus draws no ring or glass rim, and a press changes nothing (failing) Leo 2026-10-19: the glass focus ring flashes on the composer, and he does not want the mousedown/mouseup click feedback. The tests now assert that a focused chat or New Tab composer draws its resting rim (over art too, and on the strip and queue edges), that the caret alone shows focus, and that a press on a composer chip changes neither its transform nor its opacity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): no focus ring or glass rim, and no press shrink or dip Leo 2026-10-19: "the fucking stupid glass focus ring keeps flashing it's bad on the composer i dont like and i dont like the click feedback mousedown mouseup situation let's not do the thing for now". Focus: the focused edge token is now the resting edge, so a focused chat or New Tab composer, its strip and its queue draw the resting rim. The glass focus rim from #22114 (extended to New Tab in #22216), the shell mode's brighter focused ring and New Tab's own focus-within step are gone. The caret still hides while the page is not key. Increase Contrast keeps its shared focus ring. Press: the 0.975 shrink and 4% dip from #22107 and their spring-back transitions are gone. #22107's hover pill and keyboard-focus pill stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…box; mode, model, effort and context ring in a quiet row under it) (#22285) * test(composer): one caret, focus and chip behavior in the chat and New Tab composers (failing) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): New Tab gets the chat's chip states, and the caret shows only with the focused ring The New Tab button row is .nt-pickers, not .acpmux-composer-bar, so every bar-scoped rule skipped it: the plain footer look (data-footer-look, the default), #22107's hover, press and keyboard-focus pills and outline, and #22114's glass focus rim. The row now takes the chat's footer look and the same state rules. The caret and the focused ring now follow one state: pageKey.ts marks the root data-page-inactive while the page is not the key one (window blur, hidden, document without focus), and then a focused field hides its caret and every composer draws its resting ring. A key or press on the page, or the window's focus, brings both back. Gallery: composer-rest/hover/open/focus/keyboard/background variants for the chat composer and the New Tab page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): read the glass rim in WebKit's shadow order too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(composer): vp fmt the caret and focus test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): a chip a click focused does not lift the New Tab glass rim; test a key marks the page key From review: the chat card lifts only for its prompt or keyboard focus, so the New Tab card does the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): the glass rim check runs where the engine draws the rim Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * cmux NEXT composer: Claude Code's split, mode/model/effort in a quiet row under the box Leo 2026-10-19: follow Claude Code. Under the plain footer look (the default) the box keeps +, the prompt, the mic and Send or Stop; the permission mode (left) and the model and effort (right) sit in a quiet row under it (ComposerFoot.tsx), in the chat composer and on the New Tab page alike. The mic never leaves a row. + names itself Add in the shared tooltip. The mode menu's check sits at the trailing edge in its number's place. Send is the theme's ink, no iMessage blue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the mic stays at every width; row steps measure both composer rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * composer: the quiet row ends on the context ring; New Tab mic gallery states Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * composer: the quiet row keeps the model and effort right without a mode; split test measures chips Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: row rhythm and plain footer measure the split rows; the plain look is the default Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * composer: the context ring holds its place before usage, so the quiet row never shifts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the location strip's control check reads both composer rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * style: oxfmt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: rhythm per composer row; Tab reaches the model from the quiet row; gallery covers ComposerFoot Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * composer: the row fit follows the footer look toggled live; an inert ring draws no hover pill; the quiet row widens with a narrow box Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at 15a8255 - webviews/test/composer-row-rhythm.test.ts Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39357323337 * test: Tab from the prompt reaches the model chip in the quiet row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(next): PR autofix at cfb38b8 - webviews/test/composer-footer-plain.test.ts Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39358917109 * chore(next): PR autofix at 36bb517 - webviews/src/agent-session/acpmux/newtab/NewTabScreen.tsx Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39365778871 * test(new tab): on Cards the suggestions leave the quiet row's chips reachable The menu-over-suggestions harness takes ?template=cards, the app's default page, which draws Claude Code's split: the mode, model and effort sit in the quiet row under the box. Each menu test runs there too, and a new test asks that the suggestions open under the quiet row with every chip still taking its own press (greptile on #22285, NewTabScreen.tsx:894). Red until the suggestions anchor under the whole composer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(new tab): the suggestions hang under the quiet row, not over it With the split, the mode, model and effort sit under .nt-box, and the suggestions opened 6 px under the box, over them: a click on a chip picked a suggestion. The popover (both the Popover anchor and useEscapingPopup) now anchors on the whole .nt-composer when the split draws, and a press in the quiet row keeps the suggestions as one in the box does. Cards' pill keeps the box anchor: its toolbar steps aside while Search suggests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): Full access in the quiet row draws in the model chip's color The quiet row tinted Full access's shield with --acpmux-warning, which undoes Leo's quiet permission chip (2026-10-18, #21744): the chip draws in the model chip's color, its shield's "!" names the risk, and the menu keeps the warning color where the mode is chosen. quiet-access-chip asserts that and was red on Chromium and WebKit. The shield still shows for Full access. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): the fast bolt sits in the quiet row with the split With Claude Code's split (the plain footer, on by default) the bolt leaves the box with the chips: it follows the model and effort in the quiet row and comes before the context ring, while the box keeps the mic and Send. The old test looked for it in the box's trailing cluster. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(composer): before any use the quiet row's context ring is off, not absent Claude Code's split keeps the context ring's place in the quiet row from the first frame, so the first usage report moves nothing (hq#1957). Leo's "no context ring before any use" (2026-10-13) now reads as no reading: the ring is disabled and draws only its track. The old test counted no ring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the New Tab split checks read the Default template now that Cards is the default Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(new tab): Cards with the agent's chips draws the split, and the mic stays in Search Cards, the first dot, draws Claude Code's split when the agent's chips are there: the project strip heads the card, the box holds the prompt, the mic and Send, and the mode, model and effort sit in the quiet row under it. No pill toolbar draws, so Search, which hides that toolbar, never hides the mic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the split's quiet row in the scroll, ring and Cards menu checks - new-tab-scroll: All chats is the only scroller at 400 px; at 360 the quiet row's 32 px puts the list at its two-row floor, where the page scrolls by design. - composer-footer-essentials: before use the ring draws only its track (the fixture reports zero use, so the ring is not disabled). - new-tab-menu-over-suggestions: on Cards only the model menu reaches over the suggestions; the effort and access menus open clear of them (CI on dbc55ac measured no overlap and no misses). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(new tab): stub the observers the split's quiet row fits with Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(new tab): Cards with the split draws no create row The app always passes the chips and the plain footer is on by default, so Cards draws the split, and NewTabScreen gated the create row on !pill: the row came back on the default page. Red until the gate names Cards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(new tab): Cards draws no create row with the split either The create row was gated on !pill, and pill is now Cards with the split off. In the app the chips are always there and the plain footer is on, so the default page showed New Terminal, New Browser Tab and New Chat again. The gate names the template. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: the split's rows in turn-cycle, footer-essentials and narrow panes - composer-turn-cycle: calm() reads both rows. The box's row has no chips now, so the lock and status-chip checks read the quiet row as well, which may hold its one context ring. The ring is also measured across the cycle. - composer-footer-essentials: the ring check needs at least one ring. - narrow-layouts: New Tab's Default template (chips beside the mic, wide type) and the chat composer with the plain footer off keep the single-row case measured at every width. - Gallery notes for template-cards and template-cards-search describe the split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(narrow panes): the single-row stage keeps the plain footer off Turning the setting back on after the play redrew the composer while the stage's own hover checks measured it (layout shift 0.013). Each variant loads its own page, so the setting can stay off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): a short pane's dock spills upward, so Stop keeps Send's place With the split, the composer is 32 px taller (the quiet row under the box). In a 300 px pane with a queued prompt, the float dock's content outgrew its max-height and ran past the pane's bottom, so Stop drew 13 px below where Send sat (composer-row-layout). The dock now packs its content at the bottom, so what doesn't fit spills over the transcript instead. narrow-layouts' single-row stage also lets the footer swap settle before its measured hover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): the composer form, not the dock, packs at the bottom The dock holds one form, which shrinks to the dock's max-height, so the overflow was inside the form. A probe on Blacksmith Linux (run 39390110264) showed it: queued, the box sat 13 px lower (174-265 against 161-252), with the queue at its 34 px floor. The form now packs its queue, box and quiet row at the bottom, so what doesn't fit spills upward. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(composer): put the dock back; row-layout measures a pane the split fits Packing the form at the bottom made a short pane's queue spill over the pull request dock above it, which agent-pane-bottom-stack forbids. The stack's base rules come back unchanged. composer-row-layout measures Send and Stop in a 340 px pane: at 300 px, with a queued prompt, the dock is at its floor and the split's 32 px quiet row doesn't fit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: cmux-autofix[bot] <cmux-autofix[bot]@users.noreply.github.com>
A focused composer now steps its one-device-pixel rim 22% toward the text instead of 30%, so focus reads quieter. That's still well above the 8% step the 10-14 focus audit found invisible. Over art (
data-cmux-see-through), focus also brightens the glass card's top-lit rim from #21786, so it looks like light catching a raised pane of glass. The ring itself stays a hairline and never gets heavier.It uses only existing tokens (
--acpmux-composer-edge-focus,--acpmux-composer-rim,--cmux-tone-light) and has no motion. Reduce Transparency draws no rim layer, so it keeps the plain step. Increase Contrast keeps the shared focus ring, andappearance.bordersnone still clears the rim. The ring stays on the owning card through:has(:focus-visible), never on the field. The New Tab box reads the same--acpmux-composer-edge-focustoken, so its focus step gets subtler too. Its glass rim is unchanged.Testing
composer-rim-hairline.test.tsis real Chromium computing the card'sbox-shadow. It now expects the 22% step, and it has a new test: over art, keyboard focus brightens the top-lit rim while keeping one quiet ring.Run on huge-blue with
CMUX_BROWSER_TESTS=1 bun test <file>fromwebviews/:02213772: the three scale tests fail on the focus alpha (expected 0.3604, received 0.426).-t brightensfails with "focus brightens the top-lit rim".6312d76b:composer-rim-hairline.test.ts7/7,newtab-quiet-focus.test.tsall pass,focus-visuals.test.tsall pass.Observed / Not run
Changelog
Changed: The composer's focus ring is subtler, and over art focus brightens the glass edge instead.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Makes the composer's focus ring subtler: the one-pixel rim steps 22% toward the text instead of 30%. Over art, keyboard focus now brightens the glass card's top-lit rim instead of making the ring heavier.
Testing
composer-rim-hairline.test.tsto expect the 22% step and adds a Chromium test for the glass-rim brightening over art.Written for commit 3b420ff. Summary will update on new commits.