-
{header.title}
+
+ {header.title}
+
{header.subtitle && (
{header.subtitle}
)}
diff --git a/packages/client/workbench/src/surface/use-workbench-sessions.ts b/packages/client/workbench/src/surface/use-workbench-sessions.ts
index f14e6236..560a9f6d 100644
--- a/packages/client/workbench/src/surface/use-workbench-sessions.ts
+++ b/packages/client/workbench/src/surface/use-workbench-sessions.ts
@@ -17,6 +17,7 @@ import { useNavigationHistoryStore } from '../navigation/store';
import { useData, useMutation } from '../runtime/tayori';
import type { WorkbenchSessionDraft } from './selection-store';
import { useSessionSelectionStore } from './selection-store';
+import { applySessionSwitchTransition } from './session-switch-transition';
export interface WorkbenchSessions {
sessions: SessionInfo[];
@@ -142,7 +143,8 @@ export function useWorkbenchSessions(onError: (err: unknown) => void): Workbench
function select(id: SessionId): void {
recordNavigation(currentLocation, { surface: 'thread', sessionId: id });
- applySelection(id);
+ // Matched geometry: the clicked row's title travels to the conversation header.
+ applySessionSwitchTransition(id, () => applySelection(id));
}
function startDraft(workspaceId?: WorkspaceId): void {
diff --git a/packages/presentation/ui/src/shell/sidebar/thread-row.tsx b/packages/presentation/ui/src/shell/sidebar/thread-row.tsx
index 02735a25..7c73287d 100644
--- a/packages/presentation/ui/src/shell/sidebar/thread-row.tsx
+++ b/packages/presentation/ui/src/shell/sidebar/thread-row.tsx
@@ -94,7 +94,9 @@ export function ThreadRow({
)}
/>
-
{title}
+
+ {title}
+
diff --git a/packages/presentation/ui/src/styles.css b/packages/presentation/ui/src/styles.css
index 6eb1a7b7..16876e8f 100644
--- a/packages/presentation/ui/src/styles.css
+++ b/packages/presentation/ui/src/styles.css
@@ -144,6 +144,15 @@
}
}
+/* Matched-geometry session switch (thread row title → conversation header): pace the paired
+ element and the root crossfade on the motion scale. Reduce-motion never starts a transition
+ (gated where the switch is applied), so no override is needed here. */
+::view-transition-group(thread-title),
+::view-transition-old(root),
+::view-transition-new(root) {
+ animation-duration: var(--motion-normal);
+}
+
@layer components {
/* Read-only chat terminals mirror LiveTerminal's auto pair: GitHub Light Default / Dark+.
Scope the palette so ANSI class names from other libraries cannot inherit it accidentally. */