From 48a55324df974ea617ba46442e2589cf00c22077 Mon Sep 17 00:00:00 2001 From: RealZST Date: Fri, 28 Aug 2026 21:27:54 +0800 Subject: [PATCH] fix(a11y): stop claude's mascot bouncing under reduced motion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reduced-motion block exempted `.mascot-claude.is-animated *`, but claude-jump is on the wrapper itself, not a descendant — and `*` only matches descendants. Users with "reduce motion" on saw the arms, legs and eyes freeze while the whole figure kept bouncing, which reads as a stuck animation rather than a calm one. Name the wrapper explicitly, as omp, dsh and grok already do for their own wrapper-level loops. claude-jump's 0%/100% is the identity transform and the wrapper carries no base transform, so stopping the animation lands exactly on the resting pose — no shift. The other twelve mascots are unaffected: an audit of every `.mascot-*.is-animated/.is-clicked` rule that sets `animation` finds six wrapper-level ones (claude x2, dsh x2, grok, omp) and this was the only one missing from the exemption list. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015weU8hXkgz73A96UcHL7oS --- src/components/shared/agent-mascot/mascot.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/shared/agent-mascot/mascot.css b/src/components/shared/agent-mascot/mascot.css index 7b42ec7..382dd6f 100644 --- a/src/components/shared/agent-mascot/mascot.css +++ b/src/components/shared/agent-mascot/mascot.css @@ -1930,6 +1930,11 @@ /* === Reduced Motion === */ @media (prefers-reduced-motion: reduce) { + /* The bare `.is-animated` selectors below are not redundant with the `*` + ones: `*` only matches descendants, so a mascot that animates its own + wrapper needs to name itself. claude-jump, omp-float and dsh-breach are + the three hover loops that live on the wrapper. */ + .mascot-claude.is-animated, .mascot-claude.is-animated *, .mascot-cursor.is-animated *, .mascot-codex.is-animated *,