Aurora AppKit / Supernova Handover / ButtonGlass

Component handover · For all platforms

ButtonGlass

A pill-shaped frosted-glass button with a label and a trailing crown icon. Its depth comes from a layered treatment — gradient fill, gradient edge ring, a neutral-grey inner-shadow rim, and a very subtle drop shadow.

Open in Figma
Version
v1.0
Released
30 Jun 2026
Scope
All platforms
Breakpoints
None
Implementation
iOS · Android · macOS · Windows · Web
Accessibility
Blocked (see Accessibility)
ℹ️ This release (v1.0). Initial release. Added a subtle inner shadow (neutral-600 rim) for better light-mode visibility — this is the glass rim / top highlight and is structural.

Summary

ButtonGlass is a pill-shaped frosted-glass button with a leading-optional / trailing-default icon (the “Upgrade” crown). Its frosted look comes from a layered treatment — a linear-gradient fill, a linear-gradient edge ring, a neutral-grey inner shadow (the glass rim/top highlight), and a very subtle drop shadow. It ships with two states (default / active) that share identical geometry; only the gradient treatment changes, and state is driven by application logic, not CSS :hover.

Anatomy

  • 1
    ButtonGlass — pill container. Border weight 1, radius 9999, drop shadow 0/2/8 #000000 @4%.
  • 2
    iconStart — leading icon slot (size S). Off by default.
  • 3
    text — label. Colour text-primary #2A2A2D, centred, style body-xs-bold.
  • 4
    iconEnd — trailing icon (the Upgrade crown, size S). On by default.
📐Layout order: [iconStart] · text · [iconEnd], horizontal, centred. Padding 10 (top/bottom) × 16 (left/right), 4px gap.

Properties / API

PropertyType / valuesDefaultDescription
statedefault · activedefaultInteractive state, driven by app logic. Both states share identical geometry; only the gradient treatment differs.
iconEndbooleantrueToggles the trailing icon (the Upgrade crown).
iconStartbooleanfalseToggles the leading icon slot.
texttext / swap“Upgrade”Label text; recolourable, defaults to text-primary.

Variants

  • state = default — glass fill bg-glass (#F7F7F8 @70%) → bg-gradient-primary-end (transparent). Edge ring white @0.48.
  • state = active — fill switches to bg-gradient-secondary-start (#FFFFFF) → …-end (#FFFFFF @0%). Edge ring white @0.65.

Size is identical for both: ~103 × 38–40px.

States

Two states exposed as variants: default and active. On web the interaction model maps :hover → active look and :active (pressed) → default look.

Gap: focus, hover, pressed and disabled are not real variants today — only default/active exist. This is the main accessibility blocker (see the Accessibility section).

Sizes

Single size. Pill width hugs content (≈103px at “Upgrade”), height 40 (artwork 38). Icons 16×16 (size S). No size scale.

Effects / shadow stack

Four layered effects build the frosted look. Get these right or the glass reads as a flat button.

#EffectLightDark
1Glass fill (linear gradient, ≈234°)bg-glass #F7F7F8 @70% → transparent #F7F7F800#141415 @70% → transparent
2Edge ring (1px gradient stroke, 25°, 3 stops)white 0.48 @0/100%, rgba(105,106,109,.04) @62%(same structure)
3Inner shadow (glass rim — structural)colour neutral-600 #696A6D, offset (0, 0.5), blur 1, spread 0same neutral-600 → grey rim
4Drop shadow (shadow-bevel, subtle)offset 0/2, blur 8, spread 0, #0000000A (black @4%)transparent drop + white-16% inset
⚠️Gotchas. Keep the transparent fill stop’s RGB equal to the glass colour (e.g. #00141415, not #00000000) to avoid a dark fringe · the 25° edge ring must use real-pixel geometry, not a unit/corner gradient · don’t use 50% radius — use 9999 · don’t remove the inner shadow or amplify the drop shadow.

Breakpoints

Not applicable — ButtonGlass has no breakpoint axis (only state). The md = 1 token in the defs is the 1px border-weight, not a breakpoint.

Design tokens

TokenValue
text-primary#2A2A2D
body-xs-boldInter Semi Bold, 12/18, weight 600
bg-glass#F7F7F8 @70% (light) / #141415 @70% (dark)
bg-gradient-primary-end#F7F7F800 (transparent)
bg-gradient-secondary-start (active)#FFFFFF
bg-gradient-secondary-end (active)#FFFFFF00
neutral-600#696A6D (inner-shadow rim)
shadow-beveldrop #0000000A (black @4%) 0/2/8
radius border-radius-full · border-width 19999 · 1
spacinggap 4 · v-pad 10 · h-pad 16
📝Per-platform notes. WPF fakes the inner shadow with a blurred 1px ring + CornerRadius=20 · SwiftUI radius ≈ Figma blur ÷ 2 · Android must use a glass inner-shadow modifier, not an inset draw-shadow.

Accessibility

On-page verdict: NOT READY FOR DEV. The Accessibility Review records unresolved critical issues across all platforms; deployment is blocked until resolved. Audit scope: WCAG 2.2 AA across Web, Desktop, Mobile.

Critical (blockers)

  • No focus state (WCAG 2.4.7 / 2.4.11) — add state=focus with a visible ring ≥3:1; desktop also needs state=hover.
  • Glass contrast not verifiable (WCAG 1.4.3) — verify label ≥4.5:1 against worst-case content behind the blur; add a reduce-transparency solid fallback (desktop), check bright photo backgrounds (mobile).

Serious

  • Missing real hover / pressed / disabled variants (4.1.2) — distinct without relying on colour alone.
  • Touch target 38px below platform minimums — expand tappable area to ≥44×44pt (iOS) / 48×48dp (Android) via padding.
  • No handoff a11y annotations — accessible name “Upgrade”, role button, decorative trailing icon, state→variant mapping.

Moderate

  • 12px text — confirm Dynamic Type / sp scaling and reflow at 200% zoom.
  • Trailing crown icon must be decorative (aria-hidden / accessibilityHidden / importantForAccessibility=no).
  • No access key / mnemonic for Windows/GTK (e.g. Alt+U).
  • Result announcements via a polite live region; honour prefers-reduced-motion.

Usage

✓ Do

  • Use radius token border-radius-full / 9999 for the pill.
  • Keep both fill and stroke as linear gradients.
  • Keep the inner shadow — it renders the glass rim and is structural.

✕ Don't

  • Don’t use 50% radius (ovals on non-square bounds).
  • Don’t replace the gradient with a solid background.
  • Don’t remove the inner shadow or amplify the drop shadow.

Implementation status

Implemented across platforms (parity with v1.0 + the a11y fixes to be verified):

Android ✓ iOS ✓ macOS ✓ Windows ✓ Web reference ✓

Changelog

  • v1.030.6.2026
    • Added a subtle inner shadow for better light-mode visibility.
    • Initial release.
  • v0.918.6.2026
    • Initial draft.
📝On-page text reads “lightMode visbility” (typos in source). Captured here as intended.

Ticket scaffold

Title: ButtonGlass v1.0 — frosted glass button + a11y states [PLATFORM]

Acceptance criteria

  • Pill (radius 9999), label + trailing crown icon; iconStart/iconEnd/text props.
  • Four-layer effect stack reproduced (gradient fill, 25° gradient edge ring, neutral-600 inner-shadow rim, subtle drop shadow), light + dark.
  • state=default / active use the correct fill tokens.
  • Add focus + hover + pressed + disabled states (a11y blocker) distinct without colour alone.
  • Tap target ≥44×44pt / 48×48dp via padding; label contrast ≥4.5:1 with a reduce-transparency fallback.
  • Trailing icon decorative; accessible name “Upgrade”; honour reduced-motion.

Jira ticket template

Jira wiki-markup. Copy into a new issue, replace every [PLACEHOLDER], and duplicate one per platform.

Jira · duplicate per platform
h2. [PLATFORM] · ButtonGlass v1.0 — frosted glass pill + accessibility states

*Project / Epic*  : [EPIC-KEY]  Aurora AppKit · Supernova
*Issue type*      : Story
*Components*      : ButtonGlass · [PLATFORM]
*Labels*          : aurora-appkit, supernova, design-system, button-glass, accessibility
*Priority*        : [High]
*Story points*    : [estimate]
*Fix version*     : ButtonGlass v1.0
*Sprint*          : [sprint]
*Assignee*        : [assignee]

h3. Background
A glass-morphism pill button (label + trailing "Upgrade" crown). Depth comes from a four-layer treatment. NOTE: the design Accessibility Review is currently "NOT READY FOR DEV" — this ticket must also deliver the missing interaction/focus states.

h3. Objective
Implement ButtonGlass v1.0 on [PLATFORM]: the frosted pill with its effect stack AND real focus / hover / pressed / disabled states.

h3. Design source
* Figma — "Aurora AppKit · Components" -> ButtonGlass page (Specification, Developer Handover, Accessibility Review, Changelog frames)
* Handover spec — supernova-handover/buttonglass.html
* [paste the platform-specific Figma frame link]

h3. Spec (platform-agnostic — map to [PLATFORM] idioms)
* Properties : {{state}} (default | active) · {{iconStart}} (default false) · {{iconEnd}} (default true, the crown) · {{text}} (default "Upgrade")
* Single size : pill, content-hug width, ~40 tall, icons 16x16, radius {{border-radius-full}} 9999 (never 50%)
* Effect stack (all four required) :
*# Glass fill — linear gradient {{bg-glass}} (#F7F7F8 at 70%) -> transparent {{bg-gradient-primary-end}} (keep the transparent stop the SAME rgb as the glass colour to avoid a dark fringe)
*# Edge ring — 1px linear-gradient stroke, ~25deg, white 0.48 (default) / 0.65 (active) at the ends, neutral-600 at 4% mid
*# Inner shadow — {{neutral-600}} #696A6D, offset 0/0.5, blur 1 (the glass rim; structural — do not remove)
*# Drop shadow — {{shadow-bevel}} 0/2/8 black at 4% (subtle; do not amplify)
* active swaps fill to {{bg-gradient-secondary-start}} (#FFFFFF) -> {{bg-gradient-secondary-end}}
* Typography {{body-xs-bold}} · padding 10 (v) x 16 (h) · gap 4

h3. Scope
In scope : pill + four-layer effect stack + {{state}}/{{icon*}}/{{text}} + the new focus/hover/pressed/disabled states on [PLATFORM].
Out of scope : other platforms.

h3. Dependencies / blockers
* BLOCKER: design must confirm the focus-ring colour token + hover/pressed/disabled treatments (Accessibility Review open). Build to the agreed spec.

h3. Acceptance criteria
# Renders the four-layer effect stack so it reads as glass in light and dark (no dark fringe on the transparent stop).
# {{state}} default/active use the correct fill + edge-ring tokens.
# Adds visible focus (ring contrast at least 3:1), hover, pressed and disabled — distinct without relying on colour alone.
# Touch target at least 44x44 pt (iOS) / 48x48 dp (Android) via padding; visual height may stay ~40.
# Label contrast at least 4.5:1 against worst-case content behind the blur; provide a reduce-transparency solid fallback.
# Trailing crown is decorative (hidden from assistive tech); accessible name is the label ("Upgrade"); honour reduced-motion.

h3. Definition of Done
* Matches Figma (visual diff) in light and dark; effect values per spec
* All four interaction states implemented and verified with keyboard + screen reader
* Tokens only (no hard-coded colours); radius full (not 50%)
* Tests updated; reviewed and merged; version v1.0; changelog updated

h3. QA / test notes
* Keyboard focus visible and ordered; pressed/disabled behave correctly
* Test over busy/photo backgrounds and with reduce-transparency / reduced-motion enabled
Source: Figma “Aurora AppKit – Components” · ButtonGlass page · Specification, Developer Handover, Accessibility Review & Changelog frames. Styled with the Aurora vibe package. Compiled 30.6.2026.