Composer: the location strip stands a few px apart from the card

Closed
TE
22d ago
+68-92

The location strip on top of the chat composer (folder · computer · branch, the "top bump") merged into the composer card. It shared the card's fill and edge, sat flush on the card's top edge, and the card's rim was masked out under it, so the tab and the card read as one blob. Leo asked for a bit of separation, not a heavy border.

Now the strip stands 4px above the card inside its own closed hairline rim, and the card keeps its whole rim. The queued-prompts tray still sits flush on the strip, so the queue and the strip read as one tab over the card. The same change applies to the New Tab composer, which uses the same strip.

What changed

  • composerLocation.css: the strip gets a bottom margin (--acpmux-strip-gap, 4px), one inset hairline ring on all four sides in --acpmux-composer-edge (the existing hairline token, --cmux-hairline wide, clear under appearance.borders = none), and small bottom corners (5px). Under a queue, its top corners stay square and its top edge gives way to the queue as before, but it keeps its bottom hairline and corners.
  • The seam mask is removed: the card no longer draws its rim on a ::before layer with a cutout under the strip. It draws its normal --acpmux-card-ring, including focus and shell-mode states.
  • Fill, inset, height, type, and the strip's controls are unchanged. The bottom footer row is untouched.
  • Comments in composerStates.css and newtab/screen.css updated to match.

Stills (before → after)

Catppuccin Latte / Mocha, chat composer with a project:

BeforeAfter
light 760 px
light 400 px
light 300 px
dark 760 px
dark 400 px
dark 300 px

With queued prompts (the queue and strip are one tab, now separated from the card):

BeforeAfter
light 760 px
light 400 px
light 300 px
dark 760 px
dark 400 px
dark 300 px

Apple System Colors light / dark (after):

760 px300 px
apple-light
apple-light, queued
apple-dark
apple-dark, queued

Borrowed from AI Elements

From the shadcn AI Elements study (cmux-cgc-notes/ai-elements.md):

  • Spacing: the gap is 4px, on their 4px grid. It is the smallest step that reads as a separate surface without pushing the strip away from the card it belongs to.
  • Restraint: their composer group is one 1px border-input rim with no shadows layered on top. Here the strip uses one hairline ring in the existing composer edge token. There is no heavier border, no new color, and no fill step, so the strip and the card are still the same material.
  • Nesting: AI Elements shows hierarchy with a single rule and spacing, not boxes inside boxes. The strip sits next to the card as a sibling tab instead of being folded into the card's outline.
  • Type weights: unchanged. The strip's labels stay normal weight and muted, which matches their rule that only buttons and titles get font-medium.

Verification

  • test/composer-location-strip.test.ts: the strip now sits 2–6px above the card (chat, new chat, New Tab at 420/720px). The old "no hairline across the seam" pixel probe is replaced with a check that the strip draws one whole inset hairline ring and the card draws its own unmasked rim.
  • test/agent-pane-bottom-stack.test.ts: new boundary test at 760 and 480px pane heights. With the queue and the strip both shown, the queue sits flush on the strip and the tab stands 2–6px above the card.
  • These tests fail against the old CSS (10 failures) and pass with the change. I ran the focused browser suites locally with CMUX_BROWSER_TESTS=1 (composer-location-strip, agent-pane-bottom-stack, composer-edges, composer-rim-hairline, new-tab-composer-layout): 26 pass.
  • bun run check passes (layers, type-scale, status-glyphs, system-blue, text-focus, fmt, lint, typecheck).
  • No localization impact: no user-facing strings changed.

🤖 Generated with Claude Code