Skip to content

feat(ui): motion primitives — keyframes, hover overlays, reduced-motion (slice 03, issue #440)#450

Merged
Astro-Han merged 3 commits into
devfrom
claude/i440-slice-03
May 5, 2026
Merged

feat(ui): motion primitives — keyframes, hover overlays, reduced-motion (slice 03, issue #440)#450
Astro-Han merged 3 commits into
devfrom
claude/i440-slice-03

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 5, 2026

Copy link
Copy Markdown
Owner

Summary

Slice 03 of eleven in issue #440 (PawWork UI carve-out). Scope: motion layer primitives only — no component changes, no token renames, no layout impact.

  • packages/ui/src/styles/animations.css: adds three PawWork keyframe definitions (pw-spin, pw-rail, pw-shimmer) plus matching --animate-pw-* shorthand variables in :root.
  • packages/ui/src/styles/theme.css: adds --hover-overlay (rgba 4%) and --hover-overlay-warm (rgba 6%) as regulated tokens under the Motion section, and appends a global @media (prefers-reduced-motion: reduce) kill-switch (animations → 0.001ms, transitions → 0.001ms, scroll-behavior → auto).

Why

Provides the motion vocabulary that slices 04–11 consume. Without these keyframe primitives, component slices would embed literal animation values inline and drift from each other. The hover overlay tokens canonicalise the 0.04 / 0.06 pair so sidebar/cream-surface hover in slice 08 reads var(--hover-overlay-warm) rather than a raw rgba literal. The reduced-motion rule is a one-time global gate required by STANDARDS L22; individual component @media overrides added in slices 04–11 will coexist correctly since the kill-switch uses !important.

Related Issue

Refs #440 (umbrella). This PR is slice 03 of eleven.

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.

Review Focus

  • pw-spin: rotation 0→360, 700ms linear infinite. Must only be applied to circular geometry (spinner, thinking ring) per the keyframe comment. No call sites yet — future slices wire it in.
  • pw-rail: translateX −100% → +500%. Highlight sweeps across the rail container in ~1400ms. The 500% endpoint ensures clean off-screen exit for elements up to container width.
  • pw-shimmer: background-position 200% → −200%, intended for background-clip: text gradient sweeps on tool-name text. Consumer sets the gradient on the element; this keyframe animates the position.
  • --hover-overlay / --hover-overlay-warm: purely additive, no existing callers. Not included in pawwork.json (not opencode loader tokens; hover prefix is outside REGULATED_PREFIXES).
  • Reduced-motion rule: !important is load-bearing here. Without it, component transition-duration declarations win the cascade and the kill-switch does nothing.

Risk Notes

  • No component CSS or TSX files touched. No existing call sites for the new keyframes or hover tokens in this slice.
  • The !important on the reduced-motion rule is intentional and documented in the Review Focus above.
  • --hover-overlay / --hover-overlay-warm are light-only tokens. Dark mode hover on warm surfaces (sidebar) has a different effective surface color; dark-mode callers will inline the appropriate alpha or use a dark-specific override. No dark-override is needed in this slice because there are no call sites yet.

Changed-file boundary check

Only two files changed, both inside packages/ui/src/styles/:

  • animations.css — in scope (motion primitives)
  • theme.css — in scope (token layer)

No files in packages/app/, packages/opencode/, packages/desktop-electron/, or packages/ui/src/components/ are touched.

How To Verify

parity test:
  bun --cwd packages/ui test test/theme-parity.test.ts
  131 pass, 0 fail (unchanged — new tokens not in pawwork.json scope)

colors consistency test:
  bun --cwd packages/ui test test/colors-generation.test.ts
  4 pass, 0 fail

undefined-token scan:
  bun --cwd packages/ui test test/undefined-tokens.test.ts
  2 pass, 0 fail

git diff --stat HEAD~1:
  packages/ui/src/styles/animations.css | 25 +++++++++++++++++++++++++
  packages/ui/src/styles/theme.css      | 20 ++++++++++++++++++++
  2 files changed, 45 insertions(+)

Screenshots or Recordings

No visible changes in this slice. Keyframes are defined but have no call sites yet; hover overlay tokens and reduced-motion rule have no runtime effect until component slices consume them.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • Style
    • Added new animation effects for spin, rail, and shimmer interactions with customizable motion properties.
    • Introduced hover overlay design tokens for standardized surface styling and visual consistency.
    • Enhanced accessibility support with respect for reduced-motion preferences, automatically adjusting animation and transition durations.

…on (slice #3, issue #440)

Add three PawWork keyframes (pw-spin / pw-rail / pw-shimmer) with matching
--animate-pw-* shorthand variables, two hover-overlay tokens that canonicalise
the 0.04 / 0.06 overlay values from STANDARDS L22, and a global
prefers-reduced-motion kill-switch that floors animations to 0.001ms and caps
transitions at 80ms.

All 137 existing parity + colors + undefined-token tests pass unchanged.
@Astro-Han Astro-Han added P3 Low priority ui Design system and user interface labels May 5, 2026
@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces motion design tokens and keyframes for PawWork animations (spin, rail, shimmer) in the animation system, and adds hover overlay color tokens plus a global reduced-motion media query to the theme for accessibility support.

Changes

Animation System Enhancements

Layer / File(s) Summary
Animation Properties
packages/ui/src/styles/animations.css
Added PawWork custom properties --animate-pw-spin, --animate-pw-rail, and --animate-pw-shimmer to :root.
Keyframes Implementation
packages/ui/src/styles/animations.css
Defined @keyframes pw-spin (360° rotation), pw-rail (horizontal translate), and pw-shimmer (background-position sweep).

Theme & Accessibility Updates

Layer / File(s) Summary
Hover Overlay Tokens
packages/ui/src/styles/theme.css
Added --hover-overlay (4% black) and --hover-overlay-warm (6% black) color tokens to :root.
Reduced Motion Support
packages/ui/src/styles/theme.css
Introduced @media (prefers-reduced-motion: reduce) block that disables animations and transitions with near-instant durations and forces scroll-behavior: auto.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Spin and shimmer, rail and sway,
Overlay tokens light the way,
For those who motion wish to rest,
We pause the dance—accessibility's best!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding motion primitives (keyframes and hover overlays) plus reduced-motion support to the UI styles, with clear reference to issue #440 and slice 03.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description comprehensively covers all required template sections with detailed explanations, verification evidence, risk analysis, and a completed checklist.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/i440-slice-03

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new motion primitives and hover overlay tokens to the UI package, along with a global reduced-motion media query. Feedback suggests adjusting the pw-rail animation to ensure a complete exit from the container, providing dark mode overrides for the new hover tokens to maintain visibility, and refining the reduced-motion transition duration to prevent perceived lag and improve override flexibility.

Comment thread packages/ui/src/styles/animations.css
Comment thread packages/ui/src/styles/theme.css
Comment thread packages/ui/src/styles/theme.css
…il exit point

- Change transition-duration in the prefers-reduced-motion kill-switch from
  80ms to 0.001ms. Four existing components (animated-number, tool-count-label,
  tool-status-title, text-shimmer) explicitly set transition-duration:0ms inside
  their own reduced-motion blocks; the prior 80ms !important would have overridden
  those to a visible 80ms transition for users with the system preference enabled.
  Using 0.001ms is consistent with animation-duration and functionally instant.

- Fix pw-rail keyframe endpoint: translateX(400%) leaves a highlight element
  touching the container right edge rather than exiting it. 500% ensures clean
  off-screen exit for highlight elements up to the container's full width.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui/src/styles/theme.css`:
- Around line 529-537: The reduced-motion media query block for the global
selectors (*, ::before, ::after) currently resets animation-duration and
transition-duration but not delays; update the `@media` (prefers-reduced-motion:
reduce) rule (the block targeting *, ::before, ::after) to also set
animation-delay: 0s !important and transition-delay: 0s !important so any
staggered animations or transitions are effectively disabled when users request
reduced motion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2d1a337b-5a57-4708-b4ba-d3cf8704f7ce

📥 Commits

Reviewing files that changed from the base of the PR and between bfa9e7d and 477d684.

📒 Files selected for processing (2)
  • packages/ui/src/styles/animations.css
  • packages/ui/src/styles/theme.css

Comment thread packages/ui/src/styles/theme.css
… block

Staggered animations (fade-up-text up to 3s, text-shimmer calc delay) keep
elements at their start state while waiting for the delay even though
animation-duration is already 0.001ms. Adding delay resets ensures no element
is left stuck in its initial opacity/transform state under reduced-motion.
@Astro-Han Astro-Han merged commit c6f1bcf into dev May 5, 2026
22 checks passed
@Astro-Han Astro-Han deleted the claude/i440-slice-03 branch May 5, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant