
Oklch Skill
Check and fix text and UI contrast using OKLCH lightness with APCA defaults and WCAG 2 ratios for legal claims.
Overview
OKLCH Skill is an agent skill most often used in Build (also Ship, Operate) that guides accessible contrast checks and OKLCH-based color fixes using APCA and WCAG 2 thresholds.
Install
npx skills add https://github.com/jakubkrehel/oklch-skill --skill oklch-skillWhat is this skill?
- Contrast always evaluated as foreground on the nearest parent background
- APCA Lc thresholds table: normal text 60/75, large 45/60, UI components 30
- WCAG 2 AA/AAA ratio table for normal, large text, and UI graphical objects
- OKLCH-first fixes: adjust perceptual lightness instead of RGB trial-and-error
- Signed APCA Lc guidance with absolute value used for pass/fail comparison
- APCA pass Lc 60 (normal text), 45 (large text), 30 (UI components)
- WCAG 2 AA 4.5:1 normal text and 3:1 large/UI graphical
Adoption & trust: 1.2k installs on skills.sh; 132 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your UI palette looks fine in hex but fails perceptual contrast or WCAG claims because you measured the wrong background or tuned RGB by guesswork.
Who is it for?
Developers and designers using OKLCH/CSS color who want APCA-first contrast with a WCAG 2 legal fallback reference.
Skip if: Non-visual assets, print-only workflows with no OKLCH pipeline, or teams that refuse to identify parent background colors before testing.
When should I use this skill?
User adjusts UI colors in OKLCH, asks about APCA vs WCAG contrast, or needs accessible foreground-background pairs on web components.
What do I get? / Deliverables
You apply foreground-on-background checks with APCA Lc (and WCAG 2 when required) and adjust OKLCH lightness to reach documented pass levels.
- Contrast pass/fail against APCA and/or WCAG tables
- OKLCH lightness adjustment direction for failing pairs
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Build frontend is where color tokens and component styles get validated before ship. frontend covers contrast between foreground elements and their parent background colors in UI code.
Where it fits
Tune primary button text Lc against its card background before shipping the design system.
Re-verify large headings and icons against WCAG 3:1 UI component thresholds in a pre-launch audit.
After a dark-mode tweak, re-check signed APCA Lc on muted labels over nested surfaces.
How it compares
Perceptual contrast checker tied to OKLCH, not a generic SEO or marketing copy skill.
Common Questions / FAQ
Who is oklch-skill for?
Solo builders and frontend implementers working in OKLCH who need APCA-oriented contrast fixes and WCAG 2 ratio references in one procedural guide.
When should I use oklch-skill?
During Build frontend token work, Ship accessibility review before launch, and Operate iterate when theme or dark-mode changes break contrast on real parent backgrounds.
Is oklch-skill safe to install?
It is documentation-style color guidance; use the Security Audits panel on this Prism page before trusting any bundled tooling that measures contrast automatically.
SKILL.md
READMESKILL.md - Oklch Skill
# Accessibility & Contrast Contrast is always measured between a **foreground color** (text, icon, or UI element) and the **background color** it sits on. When checking contrast, identify the background the element will be rendered against — typically the nearest parent's background color. ## APCA thresholds (recommended) APCA (Accessible Perceptual Contrast Algorithm) is more perceptually accurate than WCAG 2 and pairs naturally with oklch since both are grounded in perceptual lightness. Use APCA as the default. Lc (Lightness Contrast) measures the perceived contrast between foreground and background. These are conservative approximations: | Content Type | Pass | Pass+ | | --- | --- | --- | | Normal text | Lc 60 | Lc 75 | | Large text | Lc 45 | Lc 60 | | UI components | Lc 30 | — | APCA's Lc value is signed — positive means light text on dark background, negative means dark text on light. Use the absolute value for threshold comparison. ## WCAG 2 thresholds (for legal compliance) WCAG 2 is still required when making formal WCAG 2.x conformance claims. It uses a luminance ratio that can be both too strict and too lenient depending on the color pair. | Content Type | AA | AAA | | --- | --- | --- | | Normal text (<18px / <14px bold) | 4.5:1 | 7:1 | | Large text (>=18px / >=14px bold) | 3:1 | 4.5:1 | | UI components & graphical objects | 3:1 | — | ## Fixing contrast with oklch In hex/rgb, fixing contrast means trial and error across three channels. In oklch, contrast is controlled by **lightness (L) alone** — adjust the L distance between the foreground and its background: ```css /* Failing: text too close in lightness to its background */ color: oklch(0.65 0.2 250); /* foreground */ background: oklch(0.75 0.05 250); /* background */ /* Fix: darken the text, keep C and H unchanged */ color: oklch(0.35 0.2 250); /* foreground — more L distance */ background: oklch(0.75 0.05 250); /* background — unchanged */ ``` Chroma has negligible effect on contrast — always adjust L, never C. ## Quick lightness gap guide - **Light background (L > 0.85):** foreground L should be below 0.45 - **Dark background (L < 0.25):** foreground L should be above 0.75 These are approximations — always verify with an actual contrast calculation. ## Light vs dark color detection A color is considered light when its oklch lightness exceeds 0.6: ``` if L > 0.6 → use dark text on this background if L <= 0.6 → use light text on this background ``` ## Hue drift detection To detect hue drift in an existing HSL palette: 1. Convert each step to oklch 2. Compare the H values across steps 3. If the hue spread is greater than 10°, the palette has visible drift ```css /* HSL blue ramp — hue shifts toward purple */ hsl(240, 80%, 20%) → oklch H ≈ 269 hsl(240, 80%, 50%) → oklch H ≈ 267 hsl(240, 80%, 90%) → oklch H ≈ 285 /* shifted 18° */ ``` # Color Conversion When converting existing colors to oklch, convert the color values but leave everything else unchanged — don't change gradient interpolation, don't restructure the CSS. ## Supported input formats | Format | Examples | | --- | --- | | Hex (3/6/8-digit) | `#f00`, `#ff0000`, `#ff000080` | | `rgb()` / `rgba()` | `rgb(255, 0, 0)`, `rgba(255, 0, 0, 0.5)` | | `hsl()` / `hsla()` | `hsl(0, 100%, 50%)`, `hsla(0, 100%, 50%, 0.5)` | ## Conversion examples ```css /* Before */ color: #3b82f6; background: #1e293b; border-color: #e2e8f0; /* After */ color: oklch(0.623 0.188 259.815); background: oklch(0.279 0.037 260.031); border-color: oklch(0.929 0.013 255.508); ``` ```css /* Before */ color: rgb(59, 130, 246); border: 1px solid rgba(0, 0, 0, 0.1); /* After */ color: oklch(0.623 0.188 259.815); border: 1px solid oklch(0 0 0 / 0.1); ``` Alpha uses the forward-slash syntax. Omit alpha when it's 1. ## What to leave alone - CSS keywords: `currentColor`, `inherit`, `initial`, `unset`, `transparent` - Gradient interpolation methods — only convert the color stops, not the function i