fix(ui): buttons no longer shift or resize on click (colour-only press)#103
Merged
Conversation
…ze on click Replace the three transform-based press treatments with the existing colour-only press language (OB-376): - Button: drop active:scale-[0.97] + disabled:active:scale-100, remove transform from the transition list (colour-mix press-darken stays). - IconButton: drop active:scale-[0.94] + disabled:active:scale-100; add a colour-only press (bg deepens to bg-hover-strong on :active) so it keeps visible feedback. - .obe-kit-action: delete the translateY(1px) press, swap transform out of the transition, add a --press-ink colour-mix darken to match Button. - SIDEBAR_PRESS: drop the now-redundant active:scale-100 override. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X78XTAemKrFw1uJpDpCEaG
Playwright e2e holds a real mousedown over a representative shared Button (sidebar Settings) and IconButton (page-actions copy-link) and asserts getBoundingClientRect is identical resting vs pressed, in light and dark. Waits for the :active transition to settle before measuring (background-color — and the removed transform — animate on the shared tempo) and asserts the background-color changes on press, proving the mousedown engaged :active so the geometry check is not vacuous. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X78XTAemKrFw1uJpDpCEaG
The base active:scale-[0.97] covered every variant; removing it left the transparent variants (ghost/outline) and link with hover but no press state, since the colour-mix press only exists on the opaque fills. Complete the two-rule model: transparent controls deepen to --hover-strong (the DS pressed/selected token) on :active, link darkens its text. - ghost: add active:bg-hover-strong active:text-accent-foreground - outline: add active:bg-hover-strong - link: add active:text-primary/70 (no bg press is conventional) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X78XTAemKrFw1uJpDpCEaG
- Add a plain ghost Button probe (sidebar Home launcher) asserting zero getBoundingClientRect delta on a held mousedown, so the base scale press can't silently regress for the transparent variants again. It is a geometry-only leg: HomeButton's SIDEBAR_HOVER dark override ties hover to active in dark, so the colour proof stays on targets with cleanly distinct hover/active in both themes. - Tighten the non-vacuity proof: compare hover-only bg vs pressed bg (both after the transition settles) so it proves :active specifically, not :hover. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X78XTAemKrFw1uJpDpCEaG
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jul 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Interactive controls physically shrank or nudged when pressed:
Buttonscaled to 0.97,IconButtonto 0.94, and the kit action button moved down 1px. This reads as jitter and is the press-instability the epic targets. Board: OB-376 (Epic OB-374 — colour & interaction consistency).Solution
Replace the three transform-based presses with a colour-only press, formalising a two-rule model already latent in the design system (imported in OB-271):
.obe-kit-action) darken their fill by mixing--press-ink(8%, the DS press standard).--hover-strong(the DS pressed/selected token, already used for selected tree rows).Key files:
button.tsx,icon-button.tsx,index.css(.obe-kit-action),sidebarStyles.ts(dropped the now-redundantactive:scale-100guard). New deps: none. Design review (Devon) caught that the first pass restored press feedback only for filled variants and dropped it for ghost/outline/link (~35 + ~28 call sites, incl. the profile-menu trigger); fixed here so every variant has a colour press.Before / After
scales to
0.97while held — visibly shrinks and springs back (131px pressed vs 135px resting)fill darkens via
--press-inkonly — 135px pressed = 135px resting, byte-identical edgesscale(0.97)only--hover-strong(link:text-primary/70); no geometry changescale(0.94)active:bg-hover-strong; no geometry change.obe-kit-actiontranslateY(1px)--press-ink; no geometry changeTest procedure
pnpm verify(repo root) — typecheck + lint (6 pkgs), unit (sdk 152 / ui 847 / server 586), server+mcp e2e. All green.packages/web/e2e/press-state.spec.ts— holds a realmousedownover a Button, an IconButton, and a plain ghost Button, assertinggetBoundingClientRectis identical resting-vs-pressed in light and dark, and that the background changed vs the hover-only state (proves:activeengaged → the geometry check is non-vacuous). Verified to fail if a scale is reintroduced.rm -rf packages/web/.next, then the web e2e harness (4 workers × own data server, port 4400+workerIndex).Operational notes
prefers-reduced-motion(no transform left to suppress). No migration, no env vars, nothing irreversible.chore/artifactsbranch (pr-assets/ob-376/), kept off this branch so no binaries merge tomain.Footer: verify green (typecheck 6 · lint 6 · unit 1585 · server e2e 251 · mcp 39 · press-state 1);
designgate cleared by Devon (CLEAR-WITH-NITS, all nits addressed in-PR, pre-endorsed → no re-review).🤖 Generated with Claude Code
https://claude.ai/code/session_01X78XTAemKrFw1uJpDpCEaG