Skip to content

Fix button.fill color contrast (LS-2937) - #41

Open
brandonmarshal wants to merge 5 commits into
developfrom
feature/ls-2937-fix-button-fill-color-contrast
Open

Fix button.fill color contrast (LS-2937)#41
brandonmarshal wants to merge 5 commits into
developfrom
feature/ls-2937-fix-button-fill-color-contrast

Conversation

@brandonmarshal

@brandonmarshal brandonmarshal commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

An axe-core accessibility audit of LS-2937 flagged a WCAG AA color-contrast failure on the theme's secondary filled button style. This fixes it, along with a related hover-state failure and an outline-button variant of the same failure, both found while tracing the fix.

Color contrast — filled button

  • theme.json's button.fill.background/border was brand-500 (#1E6AFF) against button.fill.text (base, #FAFAFA) — 4.41:1, below the 4.5:1 minimum for normal text. This affects every use of is-style-button-secondary: the 404 page's "Back to homepage" button, the Work archive's "Ready to discuss a project?" CTA, and the mobile menu's "Start a project" button.
  • Changed to brand-600 (#1C5EE4) — 5.34:1, passes with real margin. This isn't an arbitrary pick: brand-600 is already the exact token used everywhere else this brand blue needs to be accessible (text.brand, link.accent/link.decoration-start, card.platform.wordpress), so this also removes a pre-existing inconsistency where buttons used a slightly different, non-accessible shade of the same blue than everything else.

Hover-state contrast

  • While tracing the fix, found that text-hover (contrast, #080808, near-black) against background-hover (the same blue) was already failing today at 4.35:1 — axe-core doesn't trigger :hover states, so the original BugHerd scan never caught it. Applying only the background swap above would have made this worse (3.6:1).
  • Changed text-hover to base (white), matching the resting state's text color. Resting and hover now share the same brand-600/base color pair, so both are 5.34:1.

Color contrast — outline button

  • button.outline.text/border/background-hover were also brand-500, causing the same 4.41:1 failure on is-style-button-secondary-outline in both its resting state (text on a transparent/light background) and hover state (white text on a brand-500 background).
  • Changed all three to brand-600 — 5.34:1 in both states, consistent with the filled button fix above.

Investigated, not changed

  • Dark mode's equivalent button tokens (cta-500/cta-400 against contrast), for both the filled and outline styles, were checked and already pass comfortably (15.57:1 resting, 13.1:1 hover) — no dark-mode change needed.
  • The header's "Start a project →" gradient CTA (ls-button-cta-gradient in patterns/header.php) is unaffected by this change — it uses its own custom gradient background, not button.fill.background.
  • The other 3 BugHerd tasks originally grouped under LS-2937 (color-contrast on /blog/, ARIA link-name on 4 content pages, ARIA issues inside an embedded YouTube iframe) are out of scope for this PR: the blog color-contrast issue traced back to a value (text.brand = brand-600) that's already correct in this repo and appears to be a stale cache on the live dev site rather than a code bug; the ARIA link-name issues are content authored directly in post bodies, not theme code; and the YouTube iframe issues are entirely inside third-party embed markup this theme has no control over.

Test plan

  • npm run lint:json — all JSON valid
  • Verified live on a local Studio instance running this exact branch: the 404 page's button renders with background-color: rgb(28, 94, 228) (#1C5EE4, brand-600) and color: rgb(250, 250, 250) (base) — matches the intended fix
  • Computed contrast ratios directly (WCAG relative-luminance formula) for every value before and after: brand-600 vs base = 5.34:1 (both filled and outline, resting and hover), dark mode cta-500/cta-400 vs contrast = 15.57:1/13.1:1
  • Re-run the Playwright standing suite / axe-core scan against the deployed site once this is merged, to confirm task 237 (404 page) passes

Part of LS-2937 — this PR resolves the color-contrast portion only (task 237). LS-2937's other tasks (blog contrast cache issue, ARIA content fixes, third-party YouTube embed) remain open and are tracked separately; please don't auto-close the issue on merge.

Bug fix
- Change button.fill background/border from brand-500 to
  brand-600, fixing a 4.41:1 contrast failure (needs 4.5:1)
- Change text-hover from contrast to base, fixing a pre-existing
  hover-state contrast failure axe didn't catch (4.35:1)
Documentation
- Document button.fill color contrast fix per repo convention
@brandonmarshal brandonmarshal added area:theme Theme & styles (templates, template parts, FSE) comp:color-palette Palette tokens/usage comp:theme-json Tokens, presets, settings lang:json JSON config/content priority:normal Default priority for most issues. status:needs-review Awaiting code review labels Sep 3, 2026
@linear-code

linear-code Bot commented Sep 3, 2026

Copy link
Copy Markdown

LS-2937

@brandonmarshal brandonmarshal self-assigned this Sep 3, 2026
…x-button-fill-color-contrast

# Conflicts:
#	CHANGELOG.md

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

button.outline hover/rest token values remain on brand-500, which is likely to continue failing WCAG AA contrast for the secondary outline button style used in the theme.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes an accessibility colour-contrast failure by updating the theme’s semantic button colour tokens for the secondary filled button style.

Changes:

  • Updated settings.custom.color.button.fill.* tokens in theme.json from brand-500 to brand-600, and adjusted the hover text token to maintain WCAG AA contrast.
  • Added a detailed [Unreleased] changelog entry documenting the contrast ratios and scope for LS-2937.
File summaries
File Description
theme.json Adjusts button.fill custom colour tokens to improve WCAG AA contrast for the secondary filled button style.
CHANGELOG.md Documents the accessibility fix and the computed contrast ratios under a new Unreleased entry.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread theme.json
Bug fix
- Change button.outline text/border/background-hover from
  brand-500 to brand-600, fixing a 4.41:1 contrast failure in
  both resting and hover states (Copilot review, PR #41)
- Dark mode's outline tokens (cta-500/cta-400) already pass and
  are untouched
Documentation
- Correct wrong contrast ratio (4.98:1 -> 5.34:1); resting and
  hover states share the same colour pair, not two different ones
- Add missing outline-button fix entry, omitted from the
  original changelog entry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:theme Theme & styles (templates, template parts, FSE) comp:color-palette Palette tokens/usage comp:theme-json Tokens, presets, settings lang:json JSON config/content priority:normal Default priority for most issues. status:needs-review Awaiting code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants