Skip to content

feat(ui): original AmbientGradient shader + act-2 sync cue (ADR 0013)#204

Open
kilbot wants to merge 4 commits into
mainfrom
scroll-story-shader-polish
Open

feat(ui): original AmbientGradient shader + act-2 sync cue (ADR 0013)#204
kilbot wants to merge 4 commits into
mainfrom
scroll-story-shader-polish

Conversation

@kilbot

@kilbot kilbot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

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.
    • rAF gated by IntersectionObserver + visibilitychange; reduced-motion renders one static frame; static CSS fallback on missing WebGL/context loss; DPR capped at 1.5; low-power context
    • Replaces the CSS blob ribbon (dead classes removed); reusable next on pricing/pro/downloads heroes
  • Act 2 sync cue — every device's Charge button breathes on the same document clock (SMIL, zero JS): "same store, same data" made visible
  • Act 4 — denser dot orbit (170)

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

    • Added a new ambient, WebGL-powered background effect for the homepage story sections, with a static fallback for reduced-motion and when WebGL isn’t available.
    • Increased the orbiting dot density for a richer look.
    • Added configurable “Charge” pulse behavior to phone/tablet/laptop visuals (suppressed when reduced motion is enabled).
  • Refactor

    • Replaced layered ribbon gradients with the new unified ambient background treatment.
  • Tests

    • Expanded coverage for reduced-motion behavior and the ambient gradient’s fallback/animation controls.

- 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

@greptile-apps greptile-apps 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.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: be710d54-31c2-4b19-8f1d-fdfa85536814

📥 Commits

Reviewing files that changed from the base of the PR and between f0466b5 and fa7f3a1.

📒 Files selected for processing (2)
  • docs/adr/0013-site-motion-language.md
  • src/components/ui/ambient-gradient.tsx
📝 Walkthrough

Walkthrough

Adds 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.

Changes

Ambient gradient and motion updates

Layer / File(s) Summary
AmbientGradient component implementation
src/components/ui/ambient-gradient.tsx, src/components/ui/ambient-gradient.test.tsx
New client-side WebGL component with shaders, fallback rendering, viewport/visibility gating, DPR-capped resizing, cleanup logic, and tests for fallback and offscreen behavior.
Scroll-story integration replacing ribbon gradient
src/components/home/scroll-story/scroll-story.tsx, src/components/home/scroll-story/story-static.tsx, src/components/home/scroll-story/story.module.css, src/components/home/scroll-story/scroll-story.test.tsx
Replaces the ribbon background with AmbientGradient, refactors reduced-motion branching, removes ribbon CSS, and adds reduced-motion coverage.
POS charge animation wiring
src/components/home/scroll-story/devices/laptop.tsx, src/components/home/scroll-story/devices/phone.tsx, src/components/home/scroll-story/devices/tablet.tsx, src/components/home/scroll-story/devices/pos-screen.tsx, src/components/home/scroll-story/acts/dot-orbit.tsx
Adds animateCharge prop plumbing through the device stack, conditionally renders SVG charge animations, increases dot count, and updates the red dot color.
Motion language ADR documentation
docs/adr/0013-site-motion-language.md
Adds ADR 0013 describing the motion rules, ambient gradient behavior, reduced-motion handling, and consequences.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately highlights the new AmbientGradient shader and the act-2 sync cue, which are the main changes in this PR.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch scroll-story-shader-polish

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

@coderabbitai coderabbitai 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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 975d67e and 2d4b96d.

📒 Files selected for processing (6)
  • docs/adr/0013-site-motion-language.md
  • src/components/home/scroll-story/acts/dot-orbit.tsx
  • src/components/home/scroll-story/devices/pos-screen.tsx
  • src/components/home/scroll-story/scroll-story.tsx
  • src/components/home/scroll-story/story.module.css
  • src/components/ui/ambient-gradient.tsx
💤 Files with no reviewable changes (1)
  • src/components/home/scroll-story/story.module.css

Comment thread src/components/home/scroll-story/devices/pos-screen.tsx
Comment thread src/components/ui/ambient-gradient.tsx Outdated
Comment thread src/components/ui/ambient-gradient.tsx Outdated
Comment thread src/components/ui/ambient-gradient.tsx
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

🚀 Preview: https://wcpos-f400d28n9-wcpos.vercel.app

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 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".

Comment thread src/components/home/scroll-story/devices/pos-screen.tsx Outdated
@wcpos-bot

wcpos-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Fix triage before changes:

# Source File Class Category Decision Outcome
1 CodeRabbit pos-screen.tsx:242 Logic Reduced-motion correctness Fix Omit the SVG Charge pulse animations when reduced motion is requested.
2 CodeRabbit ambient-gradient.tsx:210 Logic WebGL context-loss fallback Fix Register context-loss fallback before the reduced-motion return path.
3 CodeRabbit ambient-gradient.tsx:235 Logic Animation gating Fix Gate visibility resumes on both intersection state and document visibility.
4 CodeRabbit ambient-gradient.tsx:260 Mechanical Fallback sizing Fix Match fallback sizing to the canvas path with full-size classes.
5 Codex pos-screen.tsx:236 Logic Reduced-motion correctness Fix Same root cause as #1; resolve with the same reduced-motion Charge pulse guard.

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.

@greptile-apps greptile-apps 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.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

🚀 Preview: https://wcpos-gf4u3gs9g-wcpos.vercel.app

@greptile-apps greptile-apps 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.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@wcpos-bot

wcpos-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Post-fix triage:

Thread File Issue Decision Commit
CodeRabbit pos-screen.tsx Charge pulse SMIL animations remained active on the reduced-motion static path. Fixed f0466b5
CodeRabbit ambient-gradient.tsx webglcontextlost fallback was not registered before the reduced-motion return. Fixed f0466b5
CodeRabbit ambient-gradient.tsx visibilitychange could restart rAF while the canvas was offscreen. Fixed f0466b5
CodeRabbit ambient-gradient.tsx CSS fallback lacked the canvas path's full-size classes. Fixed f0466b5
Codex pos-screen.tsx Duplicate reduced-motion Charge pulse finding. Fixed f0466b5

Excluded threads:

Thread Reason for skipping
None Fresh post-resolution GraphQL inventory returned 0 unresolved threads.

Validation:

  • pnpm install --frozen-lockfile passed.
  • pnpm exec vitest run src/components/home/scroll-story/scroll-story.test.tsx src/components/ui/ambient-gradient.test.tsx passed.
  • pnpm lint passed with existing warnings in src/services/core/business/electron-service.ts.
  • pnpm exec tsc --noEmit passed.
  • pnpm test:unit passed: 137 files, 941 tests.
  • pnpm test:e2e --project=chromium could not complete in this container. First run was missing the Playwright Chromium binary; after pnpm exec playwright install chromium, Chromium failed to launch because libglib-2.0.so.0 is missing. pnpm exec playwright install --with-deps chromium failed with su: Authentication failure, so OS dependency installation is blocked here.

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).

@greptile-apps greptile-apps 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.

kilbot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
src/components/home/scroll-story/scroll-story.test.tsx (1)

156-161: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add 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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d4b96d and f0466b5.

📒 Files selected for processing (11)
  • docs/adr/0013-site-motion-language.md
  • src/components/home/scroll-story/acts/dot-orbit.tsx
  • src/components/home/scroll-story/devices/laptop.tsx
  • src/components/home/scroll-story/devices/phone.tsx
  • src/components/home/scroll-story/devices/pos-screen.tsx
  • src/components/home/scroll-story/devices/tablet.tsx
  • src/components/home/scroll-story/scroll-story.test.tsx
  • src/components/home/scroll-story/scroll-story.tsx
  • src/components/home/scroll-story/story-static.tsx
  • src/components/ui/ambient-gradient.test.tsx
  • src/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

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

🚀 Preview: https://wcpos-7m5p8y0qt-wcpos.vercel.app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant