Skip to content

v1.5.0 — fg-* text-emphasis roles

Choose a tag to compare

@yutaro-shirai yutaro-shirai released this 13 Jun 02:51
· 70 commits to main since this release

v1.5.0 — fg-* text-emphasis roles

Upstreams the foreground emphasis ladder i-willink.com grew during its dark rollout (v1.5 Outcome 3) into the Design System as official semantic roles. The DS previously shipped only fg (strongest body) and muted (weakest supporting) — with no in-between steps, consumers reached into mode-invariant text-neutral-* for emphasis, which froze light grays under a dark root. These five roles close that gap and flip in dark mode like every other semantic role.

New roles (between fg and muted)

role utility light dark contrast contract (on bg)
fg-strong text-fg-strong neutral-800 neutral-100 ≥ 7 (AAA) — headings / strong runs
fg-emphasis text-fg-emphasis neutral-700 neutral-200 ≥ 7 (AAA) — labels / links
fg-secondary text-fg-secondary neutral-600 neutral-300 ≥ 4.5 (AA) — secondary body
fg-subtle text-fg-subtle neutral-400 neutral-500 documented baseline — captions / meta / placeholders (non-body)
fg-faint text-fg-faint neutral-300 neutral-600 documented baseline — disabled text / separators (non-text)

fg and muted are unchanged (the ladder's anchors). Each role is a neutral-step alias + a willink.dark extension, so it rides the existing ADR-0013 dark-flip + consumer-override machinery with no new mechanism.

Packages (npm lockstep 1.4.1 → 1.5.0)

  • @willink-labs/tokens@1.5.0 — 5 new semantic roles
  • @willink-labs/tailwind-preset@1.5.0 — light decls + both dark blocks + text-fg-* safelist
  • @willink-labs/css-tokens@1.5.0 — regen (5 vars in tokens.css/tokens.semantic.css, flipped in tokens.dark.css)
  • @willink-labs/react@1.5.0 — lockstep marker (no component change)

No flutter-v* tag — zero Flutter changes (willink_theme stays 1.5.0 per ADR-0011).

pnpm add @willink-labs/tokens@1.5.0 @willink-labs/tailwind-preset@1.5.0 @willink-labs/react@1.5.0 @willink-labs/css-tokens@1.5.0

For consumers

Replace local fg-* definitions (or text-neutral-* used for body emphasis) with the new text-fg-* utilities — they render byte-identical in light (the DS neutral scale is the slate scale) and gain a correct dark flip. A separate task migrates i-willink.com's local fg-* block to these roles.

Contrast policy

scripts/check-contrast.mjs enforces the per-role targets in both modes: fg-strong/fg-emphasis ≥ 7 (AAA) and fg-secondary ≥ 4.5 (AA) are required; fg-subtle/fg-faint are documented report-only baselines below the body-text floor (non-body tiers — not for content text).

Out of scope (v1.7)

Pastel-chip semantic pass, naskit diagram theming, theme-toggle UX (all i-willink.com consumer-side follow-ups).

Links