In-call avatar decoration (animated APNG) ignores prefers-reduced-motion, unlike the host renderer #19
Closed
opened 2026-09-12 02:13:07 -04:00 by jared
·
0 comments
No Branch/Tag Specified
lotus
chore/dev-tool-security
feat/expected-devices
lotus-upstream-v0.28.0
feat/call-summary-details
feat/soundboard-mic-mix
feat/mobile-self-tile
feat/screenshare-audio-state
feat/decorations-origin
docs/lotus-call-error
lotus-stall-retry
docs/lotus-protocol
lotus-soundboard-not-permitted
lotus-mic-sampler-churn
lotus-call-error
fix/audio-output-list
lotus-notify-none
lotus-screenshare-prompt
lotus-call-origin
v0.28.0-lotus.4
v0.28.0-lotus.3
v0.28.0-lotus.2
v0.28.0-lotus.1
v0.25.0-lotus.29
v0.25.0-lotus.28
v0.25.0-lotus.27
v0.25.0-lotus.26
v0.25.0-lotus.25
v0.25.0-lotus.24
v0.25.0-lotus.23
v0.25.0-lotus.22
v0.25.0-lotus.21
v0.25.0-lotus.20
v0.25.0-lotus.19
v0.25.0-lotus.18
v0.25.0-lotus.17
v0.25.0-lotus.16
v0.25.0-lotus.15
v0.25.0-lotus.14
v0.25.0-lotus.13
v0.25.0-lotus.12
v0.25.0-lotus.11
v0.25.0-lotus.10
v0.25.0-lotus.9
v0.25.0-lotus.8
v0.25.0-lotus.7
v0.25.0-lotus.6
v0.25.0-lotus.5
v0.25.0-lotus.4
v0.25.0-lotus.3
v0.25.0-lotus.2
v0.25.0-lotus.1
v0.20.1
Labels
Clear labels
a11y
area: audio-pipeline
area: build-publish
area: deafen
area: decorations
area: denoise
area: livekit
area: mobile-ui
area: soundboard-inject
area: upstream-sync
area: widget-actions
bug
dependencies
docs
enhancement
performance
priority: critical
priority: high
priority: low
priority: medium
research
security
tech-debt
ux
Accessibility
Fork area: audio-pipeline
Fork area: build-publish
Fork area: deafen
Fork area: decorations
Fork area: denoise
Fork area: livekit
Fork area: mobile-ui
Fork area: soundboard-inject
Fork area: upstream-sync
Fork area: widget-actions
Something is not working
Package versions and advisories
Docs wrong or missing
New feature
Audio pipeline cost, re-render storms, leaks
Data loss, security hole, or crash on a main path
Broken feature or serious usability problem
Minor issue or polish
Wrong behaviour in an edge case or notable degradation
Origin checks, capability leaks, media/key handling
Code health, fragile patterns
Usability or visual inconsistency
Milestone
No items
No Milestone
EC fork audit 2026-09 · Medium & Low
Projects
Clear projects
No projects
Notifications
Due Date
Dependencies
No dependencies set.
Reference: LotusGuild/element-call#19
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: medium · Type: a11y · Confidence: high
Location:
src/tile/MediaView.tsx:142-152,src/tile/MediaView.module.css:64-79src/tile/MediaView.tsx:95,142-152,src/lotus/lotusDecorations.ts(no motion check anywhere in the module)Problem
decorations are animated APNGs. cinny's own
AvatarDecorationcomponent explicitly suppresses them underprefers-reduced-motion(/root/code/cinny/src/app/components/avatar-decoration/AvatarDecoration.tsx:23-28, shipped as LOTUS_TODO item P2), but the fork's in-call renderer has no such guard, and neither the CSS nor the host push filters by the preference. A user with reduced motion enabled therefore gets animated overlays on every camera-off tile — the densest possible concentration of them — which is exactly the case the cinny fix was written for.Related finding: Lotus decorations are animated APNGs (per cinny's own comment: "Decorations are animated APNGs with no static asset to freeze to"). The host-side
AvatarDecoration.tsxexplicitly checksuseReducedMotion()and renders onlychildren(no<img>) when the user has that preference — LOTUS_TODO.md even lists this as a shipped, deliberate a11y fix ("Avatar-decorationprefers-reduced-motion— DONE"). The EC in-callMediaView.tsxrenders<img src={decoration} …>unconditionally wheneveruseLotusDecoration(userId)returns a URL and the avatar (not video) is showing, with nomatchMedia('(prefers-reduced-motion: reduce)')guard and no such rule inMediaView.module.css. A user who opted out of motion on the host still gets animated decorations inside every video call tile.How to trigger
enable "reduce motion" in the OS, join a call where several participants have decorations and cameras off.
Also: Set OS/browser
prefers-reduced-motion: reduce, join a call where any participant has a decoration and their camera is off (or hasn't started).Suggested fix
wrap the
<img>in aprefers-reduced-motioncheck (media query hiding.lotusDecoration, matching cinny's behaviour of rendering just the avatar).Also: Mirror the host's guard — read
matchMedia('(prefers-reduced-motion: reduce)')(or a small shared hook) inMediaView.tsx/useLotusDecorationand skip rendering.lotusDecorationwhen it matches, matching the rest of the Lotus theming stack's documented policy.Filed from the September 2026 audit (branch
lotus).