Agent pane: a line joining the running tray enters like a transcript row
Leo, on the running tray above the composer:
"When I said to animate this stuff in line with everything else, like when you open, when you close, this too, something running, whatever, this more slightly more dynamic. I don't even know. Like why is this not animating and, like, following along with the exact same things as everything else? This section right here, it just doesn't conform to the animating sort of train." (2026-10-26)
"plus the bottom running situation still not animating correctly" (2026-10-27)
"there's the animations, right? Of the whole, like, um, you know I mentioned the background section area. I don't know if we made a term for that, but it's, like, how it animates differently from everything else." (2026-10-28)
What was still different
#25719 put the tray card on a live transcript row's entrance: cv-enter, a fade and a 4px rise on --agent-motion-in and --agent-ease-out. #27355 eased its exit out. A line that joins the open list (a second or third subagent or command starting) still rose on the popup's ui-enter, through its data-enter="bottom" (ui/popupSurface.css). That is a different motion: 8px of travel, 1.25x the duration (150ms instead of 120ms) and its own curve, cubic-bezier(0.2, 0, 0, 1). So in one tray the card arrived one way and its lines another. Design foundations §6 lists this as an open violation, "Running tray matches the rest".
What changed
subagents/subagents.css: a line arriving in the list now runs the card's own entrance, through a new--acpmux-tray-line-entertoken:cv-enteron--agent-motion-inand--agent-ease-out. Under Reduce Motion it usescv-enter-fade, as a transcript row does. Thedata-enterattribute stays, becauseSubagentTray.tsxlistens for the line'sanimationendthrough it and the leaving copy intrayMotion.tsxholds it where it is drawn.gallery/fixtures/trayMotionArms.css: the gallery's other two arms (tight fade, slight spring) now give the line the same entrance as their card. All three arms stay comparable in Compare arms. The shipped arm is stillmessage, the transcript's own.SubagentTrayMotion.gallery.tsx: a newline-joinsvariant. Two subagents run with the list open, a third starts, and its line rises in. That makes four variants:enter-exit,start-empty,line-joinsandtwo-running.test/subagent-tray-line-motion.test.ts(browser lane, Chromium, real stylesheets) checks three things:- a live transcript row, the tray card and an arriving tray line compute the same
animation-name, duration and timing function; - in each gallery arm the line runs the card's keyframe, never
ui-enter; - under Reduce Motion the line gets the row's
cv-enter-fade.
- a live transcript row, the tray card and an arriving tray line compute the same
Not changed, deliberately: the tray's running lines keep the shared running wave on their icon, and a live command keeps the spinner. On 2026-10-28 Leo said of this tray: "I NEVER SAID TO PUT THE SPINNER HERE". The agent working-state rule covers the sidebar, tab and status mark only, and nobody named the wave. #27672's flush card, the tray layout PRs (#28133, #28533, #28587) and the fold default (#27930) are not touched.
Spec: leo-workspace design/foundations.md §1 (OPEN motion) and §6 ("Running tray matches the rest") get updated in their own leo-workspace PR, linked below.
Evidence
cmux-ci(Linux, Blacksmith 32 vCPU):bun test test/subagent-tray-line-motion.test.ts test/subagent-tray-motion.test.tsx test/calm-motion.test.ts test/subagent-tray.test.tsxgave 54 pass, 0 fail, including the 3 new tests (run).tsc --noEmitreports onlytest/latency/probe.ts(115,60) interactionId. That file isn't touched here, and the error is on base too.
Review
Independent review (Codex gpt-6-astra, high, through router-review): SHIP at b1f9249549fae3fb09552741daf7395220d9cbba, no follow-ups.
Risk
Low. This is a CSS-only motion change to one element: an arriving tray line. Its timing goes from 150ms to 120ms and its travel from 8px to 4px. No new timer, observer or animation loop. Arrivals are still marked only when motion is allowed (SubagentTray.tsx), and the leaving copy still stops every animation inside it.
Before / after
Gallery agent-pane.subagent-tray-motion/two-running: press Start subagent, then freeze the third line ("Review the diff") 40ms into its entrance. Rendered in Linux Chromium with synthetic data; the CSS is base's for before and this head's for after.
Before (base 0acabeca) | After (this head) | |
|---|---|---|
| Dark | ![]() | ![]() |
| Light | ![]() | ![]() |
What the arriving line computes, read live in that gallery:
| animation | duration | curve | at 40ms: opacity, rise left | |
|---|---|---|---|---|
| Before | ui-enter | 150ms | cubic-bezier(0.2, 0, 0, 1) | 0.64, 2.9px of 8px |
| After | cv-enter (a transcript row's) | 120ms | cubic-bezier(0, 0, 0.58, 1) | 0.49, 2.0px of 4px |
Settled, the tray looks the same as before: this changes how a line arrives, not where anything sits. I viewed the after images (dark and light). The line is still mid-entrance at 40ms, the spinner and wave are as before, and the rows, columns, chevrons and header are unchanged.
Gallery: agent-pane.subagent-tray-motion/line-joins, agent-pane.subagent-tray-motion/two-running, agent-pane.subagent-tray-motion/enter-exit
Agent session: agent session



