Skip to content

design-system 3.2.0: control boundaries clear SC 1.4.11's 3:1 via --control-border - #18

Merged
malinfossum merged 1 commit into
mainfrom
fix/control-border-contrast
Aug 28, 2026
Merged

design-system 3.2.0: control boundaries clear SC 1.4.11's 3:1 via --control-border#18
malinfossum merged 1 commit into
mainfrom
fix/control-border-contrast

Conversation

@malinfossum

Copy link
Copy Markdown
Owner

Closes #16.

.input/.textarea/.select and the bordered .btn variants drew their edge with --border, which measures 1.22–1.50:1 against the page in every theme and palette — under WCAG 2.2 SC 1.4.11 (AA)'s 3:1 for the visual information that identifies a control. No existing border token clears the bar, so this adds the dedicated control-boundary token the issue called for, per Malin's 2026-08-21 decision: fixed upstream, synced out, no consumer-local overrides.

What changed

  • New token --control-border, set per theme and per palette, hue-matched to each ground, clearing 3:1 against both --page-bg and the --surface-2 field with headroom (every value ≥3.15:1). tidsro aliases its --border-strong, which was already tuned as its control affordance (4.17:1). Light mode carries one shared value since palettes keep the base light surfaces; wend needs its own dark value (the base one only reaches 2.7:1 on its lifted ground). classic and gold inherit :root's correctly and stay untouched.
  • Controls point at it: .input/.textarea/.select and base .btn (so .btn-ghost too) directly; .btn-secondary/.btn-danger keep their hue by color-mixing 28% of their tint over the token, which keeps the floor. Hovers strengthen toward the text ink — --border-strong now sits below the resting boundary, so pointing hover at it would dim the edge.
  • Decorative edges do not move: .card/.alert/.table/.toast/.modal keep --border, per the issue's scope, and a test pins that they never adopt the control token. --border/--border-strong values are unchanged.
  • Tests (written first, watched fail): a new contrast loop asserts the 3:1 floor for the token and the composed secondary/danger borders across every theme × palette. The scope builder was extracted and now also covers tidsro and the _oled.css foundation, which the contrast loops had never checked. Floors, not equalities.
  • DS 3.1.0 → 3.2.0, CHANGELOG entry, both web scaffolds re-extracted (bump-then-extract, per the Add the Kenaz and Tidsro brand palettes #13/design-system 2.1.0: stamp the Kenaz and Tidsro palettes, re-sync scaffolds #14 gotcha).

Verification

  • node --test "tools/*.test.mjs": 68/68 pass locally (was 67; +1 new, and the extended kenaz/scope coverage rides existing tests). Link check green.
  • Cascade verified in a real engine: computed border-color of a live .input and .btn-secondary checked across 11 palette × theme combos in the gallery via headless browser — every combo resolves the intended value, including wend's light mode falling back to the shared light token and tidsro's --border-strong alias.

Visual note: every input and bordered button gets a visibly stronger edge in every theme — that is the point of the fix, but it's a look change worth an eyeball in the gallery before merging.

…11's 3:1

--border measured 1.22-1.50:1 against the page in every theme and palette,
under WCAG 2.2 SC 1.4.11's 3:1 for the visual information that identifies
a control, and no decorative border token cleared the bar (#16).

- New per-theme/per-palette token --control-border, hue-matched to each
  ground, clearing 3:1 against both --page-bg and the --surface-2 field
  with headroom (3.15:1+). tidsro aliases its --border-strong, already
  tuned as its control affordance. One shared light-mode value, since
  palettes keep the base light surfaces; wend carries its own dark value
  (the base one only reaches 2.7:1 on its lifted ground).
- .input/.textarea/.select and the bordered .btn variants point at it.
  .btn-secondary/.btn-danger keep their hue by color-mixing 28% of the
  tint over the token; hovers strengthen toward the text ink because
  --border-strong now sits below the resting boundary.
- Decorative edges (.card/.alert/.table/.toast/.modal) keep --border,
  per the issue's scope, and a test pins that they never adopt the token.
- New contrast-loop test asserts the 3:1 floor for the token and the
  composed secondary/danger borders across every theme x palette; tidsro
  and the _oled.css foundation joined the shared scope builder.
- Scaffolds re-synced (web-vite, web-react-ts) at 3.2.0.

Closes #16
@malinfossum
malinfossum merged commit 6392088 into main Aug 28, 2026
6 checks passed
@malinfossum
malinfossum deleted the fix/control-border-contrast branch August 28, 2026 14:03
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.

Control boundaries drawn with --border are 1.2-1.5:1, under SC 1.4.11's 3:1

1 participant