From 3b9bd2181da06862aea5875d901bba3dd68b16de Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 14 Aug 2026 11:23:11 -0400 Subject: [PATCH] =?UTF-8?q?=E2=99=BF=20fix:=20Honor=20reduced=20motion=20o?= =?UTF-8?q?n=20manual=20phase=20disclosure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The entrance already respected the preference, but manually opening or closing a phase did not: `useExpandCollapse` writes its transition as an inline style, which cannot carry a `prefers-reduced-motion` media query, and there is no global reduced-motion reset in the stylesheet. Before this PR the phase used `
`, which had no animation at all — so the swap to an animated disclosure handed reduced-motion readers a 300ms fold they did not have. Resolve the preference in the hook and drop the transition outright. Every expanding panel in the message content shares it, so tool calls, thinking blocks, attachments and web-search sources are covered by the same change. The chevron and the fold's own utility classes get `motion-reduce` overrides, which the inline styles cannot express. --- .../Messages/Content/ActivityPhaseGroup.tsx | 4 +- .../__tests__/useExpandCollapse.spec.tsx | 54 +++++++++++++++++++ .../src/hooks/Messages/useExpandCollapse.ts | 12 ++++- 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 client/src/hooks/Messages/__tests__/useExpandCollapse.spec.tsx diff --git a/client/src/components/Chat/Messages/Content/ActivityPhaseGroup.tsx b/client/src/components/Chat/Messages/Content/ActivityPhaseGroup.tsx index 0d786a21a5..431b285ce1 100644 --- a/client/src/components/Chat/Messages/Content/ActivityPhaseGroup.tsx +++ b/client/src/components/Chat/Messages/Content/ActivityPhaseGroup.tsx @@ -18,7 +18,7 @@ import { cn } from '~/utils'; /** Matches `EXPAND_TRANSITION` so the header, the panel, and the card chrome * all resolve on the same curve — three properties animating on two different * easings is what makes a fold read as two separate movements. */ -const FOLD_EASING = 'duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]'; +const FOLD_EASING = 'duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] motion-reduce:transition-none'; type ActivityPhasePart = Extract & { activity_label_type?: 'phase'; @@ -200,7 +200,7 @@ export default function ActivityPhaseGroup({