feat(ui): original AmbientGradient shader + act-2 sync cue (ADR 0013)#204
feat(ui): original AmbientGradient shader + act-2 sync cue (ADR 0013)#204kilbot wants to merge 4 commits into
Conversation
- ui/ambient-gradient.tsx: clean-room WebGL fragment shader (domain-warped value noise, brand palette, diagonal band fading to warm white, slow upward drift) — Stripe-inspired in spirit, not in code. IO/visibility gated rAF, reduced-motion static frame, CSS fallback on no-WebGL/context loss, DPR cap 1.5. Replaces the CSS blob ribbon (classes removed). - act 2: every device's Charge button breathes on the same clock — a quiet 'same store, same data' cue (SMIL, zero JS) - act 4: denser dot orbit (170) - ADR 0013: site motion language + gradient provenance
There was a problem hiding this comment.
kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 26 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a WebGL-based ambient background, replaces the scroll-story ribbon gradient, threads charge-animation control through device components, updates dot-orbit styling, and records the motion language in a new ADR. ChangesAmbient gradient and motion updates
Estimated code review effort: 4 (Complex) | ~45 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@src/components/home/scroll-story/devices/pos-screen.tsx`:
- Around line 233-242: The Charge pulse SVG animations in PosScreen are still
active on the reduced-motion path because StoryStatic renders this component.
Add a prefers-reduced-motion check in PosScreen (including the animated rect
blocks around the Charge button) or switch those spots to a static fill when
reduced motion is enabled, so the StoryStatic render path does not include any
<animate> loops.
In `@src/components/ui/ambient-gradient.tsx`:
- Around line 203-210: The reduced-motion early return in the ambient gradient
setup prevents the webglcontextlost fallback from ever being registered, so
users can lose the canvas without switching to the CSS fallback. Update the
initialization flow in ambient-gradient.tsx so the webglcontextlost listener is
attached before any reduced-motion return, or otherwise ensure the listener is
always registered in the same setup path as drawFrame and resizeObserver. Keep
the reduced-motion drawFrame behavior, but do not exit before the fallback
wiring is in place.
- Around line 253-260: The fallback branch in the ambient gradient component
does not match the canvas sizing behavior, so it can collapse when callers rely
on the component defaults. Update the fallback element inside the
ambient-gradient component’s `fallback` return path to include the same
full-size sizing classes used by the canvas path, alongside the existing
`pointer-events-none` and `className` handling, so it fills its container
without requiring callers to pass `absolute inset-0`.
- Around line 229-235: The visibility resume logic in ambient-gradient.tsx
currently restarts animation on every tab focus even when the canvas is
offscreen. Update the IntersectionObserver/onVisibility flow in the
ambient-gradient component to remember the latest intersection state from the
observer callback and have onVisibility call start() only when the document is
visible and the canvas is currently intersecting; otherwise keep stop()
behavior. Use the existing start, stop, and IntersectionObserver setup to gate
resumption by both visibility and intersection state.
🪄 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: 715a46ac-7a97-45b1-b0fa-77d94d3e05c2
📒 Files selected for processing (6)
docs/adr/0013-site-motion-language.mdsrc/components/home/scroll-story/acts/dot-orbit.tsxsrc/components/home/scroll-story/devices/pos-screen.tsxsrc/components/home/scroll-story/scroll-story.tsxsrc/components/home/scroll-story/story.module.csssrc/components/ui/ambient-gradient.tsx
💤 Files with no reviewable changes (1)
- src/components/home/scroll-story/story.module.css
|
🚀 Preview: https://wcpos-f400d28n9-wcpos.vercel.app |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d4b96dcc3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Fix triage before changes:
Review body note: CodeRabbit review 4619057206 says "Actionable comments posted: 4" and lists the same four CodeRabbit inline findings above. No separate non-inline finding was present in the review body. |
Owner call: warm red/orange wash was unsettling. AmbientGradient defaults, fallback, base white and the act-4 orbit accent move to calm blues anchored to the POS UI blue (+ a whisper of Woo purple); brand red stays confined to small accents (CTAs, kicker). ADR 0013 updated.
There was a problem hiding this comment.
kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
🚀 Preview: https://wcpos-gf4u3gs9g-wcpos.vercel.app |
There was a problem hiding this comment.
kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Post-fix triage:
Excluded threads:
Validation:
|
Owner feedback round 2: brighter like the CSS pass, splash pink and yellow, less ethereal — so the field now renders terraced contour lines and a bright filament (holo/topo energy, not cloud). ADR 0013 records the palette and the interactive-kit library direction (motion + three/R3F).
There was a problem hiding this comment.
kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/components/home/scroll-story/scroll-story.test.tsx (1)
156-161: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd a positive-case test for Charge pulse animations.
This only verifies
<animate>elements are absent under reduced motion. Consider a companion test asserting they are present when motion is not reduced, to actually confirm the new SMIL charge-pulse feature renders correctly rather than just confirming it's suppressed.✅ Suggested companion test
+ it('renders Charge pulse animations when motion is not reduced', () => { + stubMatchMedia({ reducedMotion: false }) + render(<ScrollStory />) + + expect(document.querySelector('animate')).toBeInTheDocument() + })🤖 Prompt for 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. In `@src/components/home/scroll-story/scroll-story.test.tsx` around lines 156 - 161, Add a positive-case test for the Charge pulse SMIL animation in scroll-story.test.tsx alongside the existing reduced-motion check. Update the ScrollStory render test suite so the relevant case in ScrollStory (using stubMatchMedia and render) asserts that animate elements are present when prefers-reduced-motion is false, using the same query on document.querySelector('animate') to verify the Charge pulse feature actually renders.
🤖 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.
Nitpick comments:
In `@src/components/home/scroll-story/scroll-story.test.tsx`:
- Around line 156-161: Add a positive-case test for the Charge pulse SMIL
animation in scroll-story.test.tsx alongside the existing reduced-motion check.
Update the ScrollStory render test suite so the relevant case in ScrollStory
(using stubMatchMedia and render) asserts that animate elements are present when
prefers-reduced-motion is false, using the same query on
document.querySelector('animate') to verify the Charge pulse feature actually
renders.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1a0dda70-9c16-4090-b336-c10c036e989a
📒 Files selected for processing (11)
docs/adr/0013-site-motion-language.mdsrc/components/home/scroll-story/acts/dot-orbit.tsxsrc/components/home/scroll-story/devices/laptop.tsxsrc/components/home/scroll-story/devices/phone.tsxsrc/components/home/scroll-story/devices/pos-screen.tsxsrc/components/home/scroll-story/devices/tablet.tsxsrc/components/home/scroll-story/scroll-story.test.tsxsrc/components/home/scroll-story/scroll-story.tsxsrc/components/home/scroll-story/story-static.tsxsrc/components/ui/ambient-gradient.test.tsxsrc/components/ui/ambient-gradient.tsx
✅ Files skipped from review due to trivial changes (1)
- docs/adr/0013-site-motion-language.md
🚧 Files skipped from review as they are similar to previous changes (2)
- src/components/home/scroll-story/devices/pos-screen.tsx
- src/components/ui/ambient-gradient.tsx
|
🚀 Preview: https://wcpos-7m5p8y0qt-wcpos.vercel.app |
Polish pass on the merged light homepage (#201), per owner: "inspired by Stripe, not a rip-off".
What
ui/AmbientGradient— our own animated gradient, clean-room WebGL (~180 lines): domain-warped value noise through the brand palette (amber→coral→wcpos-red→Woo purple), inside a bottom-left→top-right diagonal band that fades to warm white where copy sits, drifting slowly upward (steam, not Stripe's sideways wave). Explicitly not minigl or any recreation of it — ADR 0013 records provenance and the site motion rules.Validation
vitest 937/937 · eslint clean · live probe in real Chromium confirms the shader compiles and renders (canvas path, not fallback) · act screenshots swept
Summary by CodeRabbit
New Features
Refactor
Tests