fix(blocks): nav CTA legibility — on-primary text wins the cascade - #70
Merged
Conversation
Two contrast fixes: - nav: `.blk-nav .links a` (0,2,1) out-specified `.blk-nav .cta` (0,2,0), so the CTA rendered muted-on-primary — 1.32:1 on the default palette, failing WCAG AA on all 6 presets and 133/160 starter templates. The generic link rules now exclude the CTA via `:not(.cta)`, and the CTA gains its own hover affordance (brightness) to replace the accidental hover recolour. - tokens: `readableOn` flipped black/white at luminance 0.45, but the contrast crossover is ~0.19 — mid-tone fills got white text below AA (e.g. #4c8dff: 3.2:1) where near-black passes (5.7:1). It now returns whichever side clears the higher WCAG ratio. Regression tests: emitted nav CSS may not recolour the CTA from a generic link rule; readableOn is swept over an RGB grid asserting the picked side always beats the rejected one and clears 4.5:1 wherever either can. Fixes #69 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 wrokin code reviewFixes nav CTA text color specificity (issue #69) and improves text contrast selection for mid-tone fills by using explicit ratio comparison instead of luminance threshold. No high-signal issues — the changes are correct and well tested. Model: deepseek/deepseek-v4-pro · your key, your model (BYOK) |
🤖 wrokin security auditNo security-relevant findings in this diff. Model: deepseek/deepseek-v4-pro · your key, your model (BYOK) |
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.
Fixes #69
What
The nav's highlighted CTA button rendered its label in
var(--muted)instead ofvar(--on-primary)— near-invisible text on the primary fill across all 6 presets and 133/160 starter templates (113 below 3:1).1. Cascade fix —
src/blocks/nav.tsThe CTA anchor lives inside
<div class="links">, and.blk-nav .links a(specificity 0-2-1) out-ranked.blk-nav .cta(0-2-0). The generic link rules now exclude the CTA::not(.cta)both excludes and out-specifies, so the CTA keeps its on-fill colour in every state. The CTA also gains a proper hover affordance (brightness) replacing the accidental hover recolour — which on themonopreset used to turn the label#111on a#111fill (1.00:1, fully invisible).2.
readableOncrossover fix —src/tokens.tsThe black/white pick flipped at luminance 0.45, but the true contrast crossover is ~0.19 — mid-tone fills got white text below AA where near-black passes. It now returns whichever side clears the higher WCAG ratio, which is optimal by construction.
Note: this changes
--on-primary/--on-accentfrom white to near-black on mid-tone fills (midnight#4c8dff: 3.20:1 → 5.90:1;candy#e0468b: 3.88:1 → 4.87:1) for all on-fill consumers (hero, pricing, forms, …) — an intentional, contrast-improving visual change on those palettes.Measured result (CTA text on primary)
sandmidnightforestmonocandyoceanAll 133 affected templates inherit the fix (shared block CSS — no per-template changes needed).
Tests
render.test.ts: renders nav + CTA and asserts no emitted.blk-navrule recolours the CTA from a generic.links aselector, and that.ctasetscolor:var(--on-primary)— the cascade bug cannot silently return.roadmap.test.ts:readableOnmid-tone cases + an RGB-grid sweep asserting the picked side always beats-or-matches the rejected one and clears 4.5:1 wherever either choice can.npm test: 180/180 pass.🤖 Generated with Claude Code