Files
ThothII/docs/plans/2026-07-21-button-press-feedback.md
T

2.7 KiB

Button Press Feedback Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Give every enabled button immediate, consistent click acknowledgment while preserving a non-kinetic reduced-motion alternative.

Architecture: Define the interaction once in the global Tailwind base layer so both Base UI and native buttons inherit it. Remove the shared button's older translation-only active state to avoid compounded transforms. Verify the CSS contract first, then exercise the real interaction in Playwright.

Tech Stack: React 18, Tailwind CSS 3, Vitest, Playwright CLI.


Task 1: Specify the global press contract

Files:

  • Create: frontend/src/button-press-feedback.test.ts
  • Test: frontend/src/button-press-feedback.test.ts

Step 1: Write the failing test

Read src/index.css and assert the enabled-button active selector, scale(0.97), 140 ms duration, ease-out-quint curve, disabled exclusion, and reduced-motion transform override. Assert that components/ui/button.tsx no longer contains the legacy translation active class.

Step 2: Run test to verify it fails

Run: npx vitest run src/button-press-feedback.test.ts

Expected: FAIL because the global press rules do not exist and the shared button still uses translation.

Task 2: Implement the press feedback

Files:

  • Modify: frontend/src/index.css
  • Modify: frontend/src/components/ui/button.tsx
  • Test: frontend/src/button-press-feedback.test.ts

Step 1: Add the minimal CSS

Add a global enabled-button transition and active state using only transform, filter, and shadow. Add a prefers-reduced-motion override that removes scale while preserving non-kinetic contrast feedback.

Step 2: Remove the legacy shared-button translation

Delete active:not-aria-[haspopup]:translate-y-px from the shared variant base string.

Step 3: Run the focused test

Run: npx vitest run src/button-press-feedback.test.ts

Expected: PASS.

Task 3: Verify regressions and real-browser behavior

Files:

  • Verify: frontend/src/index.css
  • Verify: frontend/src/components/ui/button.tsx

Step 1: Run frontend verification

Run: npx vitest run

Run: npx tsc -b

Expected: all tests pass and typecheck exits 0.

Step 2: Verify in Playwright

Open http://localhost:5173, hold pointer-down on an enabled button, and inspect its computed transform and filter before release. Repeat with reduced motion emulation and confirm transform remains none while contrast feedback remains.

Step 3: Review the final diff

Run: git diff --check and inspect git diff --stat.

Expected: no whitespace errors and only the intended product/design, CSS, component, and test files changed.