Skip to content

feat(studio): make edit with framey stand out in the header - #5019

Merged
WaterrrForever merged 1 commit into
mainfrom
miao/framey-button-prominence
Oct 4, 2026
Merged

WaterrrForever merged 1 commit into
mainfrom
miao/framey-button-prominence

Conversation

@WaterrrForever

Copy link
Copy Markdown
Collaborator

What

"Edit with Framey" in the Studio header stands out instead of reading like the ghost controls beside it:

  • an accent tint and border, semibold label, and a larger Framey (20 → 24px);
  • a "New" badge that stays (hidden only while the button says "Opening in the app…");
  • a soft ring that pulses three times as Studio opens, then stops; none under prefers-reduced-motion.

Export stays the only filled button.

Why

Wenbo's feedback on #4951: the button was easy to miss next to Window and the theme toggle, and it is the way into editing by chat with Framey.

Related work

Refs #4951, #4999.

How

Classes on the existing Button plus one @keyframes in components.css next to Framey's wiggle and flight. The ring is a box-shadow, so it does not move the layout. No new state.

Before

Header before, light Header before, dark

After

Header after, light Header after, dark

Test plan

  • OpenInDesktopButton.dom.test.tsx (7) passes; lint, format, typecheck and fallow pass in pre-commit.
  • Manual, built CLI preview: light and dark; header does not overflow at 720px and 900px widths; badge still shows after a press and a reload; ring stops after three pulses.
  • Documentation updated (n/a)
  • Comments follow CONTRIBUTING.md "Comments"

Wenbo's feedback: the button read like the ghost controls beside it.
It now wears an accent tint and border, a larger Framey and a permanent
New badge, and pulses three times as Studio opens (none under reduced
motion).

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at da0567b. Two files, Studio only.

The pulse.

  • It's pure CSS: .hf-framey-trigger { animation: hf-framey-pulse 1.6s ease-out 3 }. A finite iteration count stops on its own, with no timer, listener or state to leak.
  • The ring is a box-shadow, so layout doesn't move. buttonBase's transition-[…] list leaves out box-shadow, so nothing fights the keyframes.
  • Reduced motion: .hf-framey-trigger is added to the existing @media (prefers-reduced-motion: reduce) block. The block comes after the base rule and has the same specificity, so animation: none wins. As a media query, it also takes effect immediately if the setting changes while Studio is open.
  • It plays once when the button mounts, which is after the route GET resolves. The button doesn't remount on press or while opening, so it doesn't replay.

No pulse on a dead button. The gating from #4999 on main is unchanged. useDesktopRoute returns null unless available is true and there's either a hand-off or a download URL.

  • Windows: handoff is false (not darwin) and there's no download URL, so the button doesn't render and nothing pulses.
  • Linux: the press opens the download card.
  • macOS: the press hands off, or falls back to the download card.

Contrast. I computed WCAG ratios from the theme.css oklch tokens:

  • Label text-0 on bg-surface plus the 10% accent tint: 15.1 light, 11.2 dark. On hover (20%): 13.2 light, 8.7 dark.
  • "New" badge (on-accent on accent): 4.85 light, 10.9 dark. That's the same pair as the filled Export button and passes AA for small text.
  • The 40% accent border is about 1.7 light and 2.7 dark. That's fine, since the tint and the label already mark the button.

cn puts the caller's classes after the ghost variant's, so bg-accent/10, enabled:hover:bg-accent/20, font-semibold and text-text-0 replace the ghost ones instead of stacking. Locally, the OpenInDesktopButton, StudioHeader and Button tests pass (28/28). CI was still running when I posted, with nothing failed.

Nits, none blocking:

  • The badge text is part of the button's accessible name, so screen readers now read "Edit with Framey New". If that's not what you want, add aria-hidden to the badge.
  • data-[preview-state=hover] (the gallery-only screenshot state) still uses the ghost's bg-hover, so a gallery shot of the hovered state won't match the real bg-accent/20 hover.

Keeping the "New" badge permanently is a product decision, not a defect.

— Rames

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Edit accuracy: accurate 1556 (base branch 1556), smooth 1283 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

@WaterrrForever
WaterrrForever added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit 2b82e39 Oct 4, 2026
76 checks passed
@WaterrrForever
WaterrrForever deleted the miao/framey-button-prominence branch October 4, 2026 16:06
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.

2 participants