Skip to content

Fix ECG SVG repaint on Mobile WebKit (remove paint containment; add regression test) - #1974

Merged
BigSimmo merged 4 commits into
mainfrom
codex/fix-ecg-animation-on-mobile-devices
Aug 15, 2026
Merged

Fix ECG SVG repaint on Mobile WebKit (remove paint containment; add regression test)#1974
BigSimmo merged 4 commits into
mainfrom
codex/fix-ecg-animation-on-mobile-devices

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Motivation

  • The ECG progress trace could appear frozen on iOS Safari / installed PWAs because the wrapper used contain: paint, which can prevent WebKit from repainting animated SVG stroke properties (stroke-dashoffset) on phone devices. The change restores reliable repainting on mobile WebKit.

Description

  • Remove contain: paint from .answer-activity-trace in src/app/globals.css so the animated SVG can repaint every frame on WebKit-based browsers.
  • Add a regression Vitest that asserts globals.css does not reintroduce contain: paint for .answer-activity-trace in tests/answer-activity-trace-css.test.ts while keeping the WebKit-safe positive dash-offset keyframes intact.
  • Files changed: src/app/globals.css, tests/answer-activity-trace-css.test.ts.

Testing

  • Ran the focused CSS unit: npx vitest run tests/answer-activity-trace-css.test.ts — passed (2 tests).
  • Ran the relevant E2E subset via the repository Playwright wrapper: npm run test:e2e -- tests/answer-progress-ui-smoke.spec.ts --project=chromium --grep "answer progress keeps focus|follow-up answer generation" — the targeted mobile ECG journeys passed (2 tests).
  • Ran formatting (npm run format) and local checks; formatting completed and no style errors remained.
  • Ran the full test suite (npm test): 6,510 tests passed, 1 skipped; 5 unrelated timeout failures occurred in repository hook-related tests (these are unrelated to the ECG change).
  • Verification shows the ECG animation CSS and compact/expanded sweep remain functional and are now guarded by the new regression test.

Codex Task

@supabase

supabaseBot commented Aug 14, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitaiBot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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:56 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

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

Run ID: fe50978f-dfa1-43a5-8aef-4e6f8a02569d

📥 Commits

Reviewing files that changed from the base of the PR and between 37bbce8 and 3223a65.

📒 Files selected for processing (3)
  • docs/branch-review-records/3dc49fdd6e24d09e3e6830eb12934c340fc3a9008650b6c058d34bd4d87a2afe.record.md
  • src/app/globals.css
  • tests/answer-activity-trace-css.test.ts

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

@BigSimmo
BigSimmo enabled auto-merge (squash) August 14, 2026 18:09
@BigSimmo
BigSimmo merged commit e60b49a into mainAug 15, 2026
26 checks passed
@BigSimmo
BigSimmo deleted the codex/fix-ecg-animation-on-mobile-devices branch August 15, 2026 06:26
BigSimmo added a commit that referenced this pull request Aug 17, 2026
…ress (#2046)
* fix(a11y): stop OS Reduce Motion from freezing and hiding answer progress
The answer-loading panel was reported dead on a physical iPhone in both
Safari and the installed PWA. Three prior PRs (#1974, #1989, #1995)
diagnosed it as a Mobile WebKit repaint bug and all three failed on the
device. The cause was this app's own reduced-motion CSS: with iOS Reduce
Motion on, the universal suppression rule froze every animation on the
page (including the step spinner) and the ECG trace was additionally set
to `opacity: 0`, so the only progress indicator disappeared entirely.
Every gate stayed green because playwright.config.ts applies
`reducedMotion: "reduce"` suite-wide while the one spec asserting the
animation opts out to "no-preference" first, so the default user
configuration was never exercised. The only WebKit project is Desktop
Safari; there was no mobile-WebKit coverage at all.
Three changes:
1. Suppressing motion no longer deletes the indicator. The reduced-motion
rules stop the animation but leave a legible static trace instead of
`opacity: 0`.
2. New tri-state Motion preference (System / Reduced / Full). "Full" is an
explicit opt-in that overrides an OS Reduce Motion request, because iOS
Reduce Motion is commonly enabled for app-launch zoom rather than
vestibular sensitivity and there was no in-app way to get the feedback
back. Default stays "system", so nobody silently gains motion. The
`motion-reduce`/`motion-safe` Tailwind variants are redefined via
@custom-variant so the override reaches all 164 call sites.
3. The pulse becomes a travelling sweep. The previous whole-line opacity
fade (0.2 -> 1.0 over 1.8s) technically ran but was too subtle on a
phone hairline to read as motion. It is now a continuously scrolling
ECG strip driven only by `transform: translateX`, reusing the
compositor recipe `.animate-skeleton-shimmer::after` already relies on.
Adds tests/ui-phone-motion.spec.ts covering the exact reported
configuration (phone + OS Reduce Motion), which nothing covered before.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYndHWrYJzirxbBvt68Tmx
* docs(ledger): record phone/PWA animation defect review
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYndHWrYJzirxbBvt68Tmx
* docs(issues): capture phone motion verification follow-ups
Four inbox requests from the PR #2046 investigation. They travel with
their owning product PR rather than a dedicated ledger-only branch, per
the AGENTS.md PR-bundling rule.
- P2 issue: playwright.config.ts applies reducedMotion:"reduce" suite-wide,
so no gate reflects the default user configuration. That inversion is why
three PRs shipped green against a broken phone.
- P2 task: no mobile-WebKit or display-mode:standalone Playwright project;
phone coverage is a narrow viewport on desktop engines, while the only
phone-AND-standalone CSS in the repo goes untested.
- P3 task: physical iPhone acceptance still owed for this fix, in Safari
and the installed PWA with Motion set to Full.
- P3 rec: three dead spring easing tokens in globals.css.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYndHWrYJzirxbBvt68Tmx
---------
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@BigSimmo