ef728331cf
Implements Story 74: agent lozenges now animate as fixed-position overlays that fly from the roster badge in AgentPanel to the story slot in StagePanel (and back when the agent is removed), satisfying all acceptance criteria. Key changes: - LozengeFlyContext.tsx (new): coordinates FLIP animations via React context. LozengeFlyProvider tracks pipeline changes, hides slot lozenges during fly-in (useLayoutEffect before paint), then creates a portal-rendered fixed-position clone that transitions from roster → slot (or reverse). z-index 9999 ensures the clone travels above all other UI elements. - AgentPanel.tsx: RosterBadge registers its DOM element with the context so fly animations know the correct start/end coordinates. - StagePanel.tsx: AgentLozenge registers its DOMRect on every render via useLayoutEffect (for fly-out) and reads pendingFlyIns to stay hidden while a fly-in clone is in flight. Added align-self: flex-start so the lozenge maintains its intrinsic width and never stretches in the panel. - Chat.tsx: right-column panels wrapped in LozengeFlyProvider. - LozengeFlyContext.test.tsx (new): 10 tests covering fixed width, fly-in/fly-out clone creation, portal placement, opacity lifecycle, and idle vs active visual distinction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>