Computed button states

Heart design system already had resting and hover button tokens mapped to color primitives. But we wanted to add a pressed state so clicks had clear, immediate feedback. This made me rethink how button states work across the system and how to best scale them for our white-labeling experience.

Criteria for new button states:

  1. Meet WCAG accessibility standards
  2. Scale for white-label brands, not just Heart’s palette
  3. Stay visually consistent across Primary, Secondary, and Tertiary variants
Resting#274a34Aa#ccf88e8.22:1 AA
Hover#1d3827Aa#ccf88e10.55:1 AA
Pressed#101e15Aa#ccf88e14.27:1 AA

What to know

Hover and pressed colors are computed from each button’s resting tokens.

  • Primary buttons shift the resting fill toward black or white based on relative luminance, so hover and pressed stay visually distinct from the resting color.
  • Secondary buttons pick a source color for the border; the label color is set separately. Hover and pressed then tint the page surface from that same source.
  • Tertiary buttons use the same state math as Secondary and only drop the border.

Heart Buttons

Computed button states applied to all button variants in the design system.

Primary

Default
Default on-strong
on-accent-blue-medium
on-accent-yellow-medium
on-accent-purple-medium
on-accent-pink-medium
on-informative
on-negative
on-positive

Secondary

Default
Default on-strong
on-brand-medium
on-accent-blue-medium
on-accent-yellow-medium
on-accent-purple-medium
on-accent-pink-medium
on-informative
on-negative
on-positive
on-tip
on-feature
on-neutral-subtle
on-media
on-overlay

Tertiary

Default
Default on-strong
on-brand-medium
on-accent-blue-medium
on-accent-yellow-medium
on-accent-purple-medium
on-accent-pink-medium