The idleSpriteWrapperStyle was using `keyframes.toString()` inside a JS
template literal, so Emotion's serializer hit the string-handling branch
and never injected the @keyframes block — the animation silently did
nothing. Switch to direct Keyframes-object interpolation inside css\`...\`
so Emotion registers the rule and returns the animation name.
Also add 'wheel' to ACTIVITY_EVENTS so desktop mouse-wheel scrolling on
the inner scrollable content area resets the idle timer (the existing
'scroll' listener on window only catches mobile/touch scroll).
Update the source plan doc to reflect the corrected idiom so future
implementers don't repeat the bug.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After 30s without user input on Elements tab, producer sprites cycle a
subtle yawn (translateY + scale) every 8s. Resets immediately on any
pointer/touch/key/scroll event. Implemented via wrapper div so
CharacterSprite internals are untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>