From ui-color-palette
Audit color pairs for contrast compliance against WCAG 2.1 and APCA standards. Use when the user wants to check accessibility, validate color pairings, or compute a global contrast score for a palette.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ui-color-palette:ui-color-palette-audit-palette <hex-colors...><hex-colors...>The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use the **ui-color-palette** MCP tool `get_palette` to generate a palette with contrast data, then analyze the results for WCAG and APCA compliance.
Use the ui-color-palette MCP tool get_palette to generate a palette with contrast data, then analyze the results for WCAG and APCA compliance.
Tool: get_palette
Input schema: see ui-color-palette-scale-palette for full base and themes field definitions. Key requirement: every theme must have textColorsTheme: { lightColor: "#FFFFFF", darkColor: "#000000" } for textContrast to be populated.
Always pass compact: true — returns a flat array of shade rows instead of the full nested PaletteData tree. Each row already has theme, color, shade, hex, contrast, and textContrast at the top level. All other color space values are omitted server-side.
Each shade includes pre-computed scores. Do NOT recalculate contrast — just read the values.
Do NOT read shade.contrast (shade vs palette background) — this skill only uses shade.textContrast (light/dark text on shade).
shade.textContrast — light & dark text on shade (requires textColorsTheme set in theme)| Field | Path | Type | Description |
|---|---|---|---|
| WCAG light ratio | textContrast.wcag.light.ratio | number | White text on shade |
| WCAG light score | textContrast.wcag.light.score | "A" | "AA" | "AAA" | WCAG level |
| WCAG dark ratio | textContrast.wcag.dark.ratio | number | Black text on shade |
| WCAG dark score | textContrast.wcag.dark.score | "A" | "AA" | "AAA" | WCAG level |
| APCA light Lc | textContrast.apca.light.lc | number | White text Lc |
| APCA light usage | textContrast.apca.light.recommendedUsage | string | Recommended usage |
| APCA dark Lc | textContrast.apca.dark.lc | number | Black text Lc |
| APCA dark usage | textContrast.apca.dark.recommendedUsage | string | Recommended usage |
With compact: true, the API already returns a flat array — one object per shade. No transformation needed before Step 3.
Each row in the flat array has these fields:
| Column | Source path | Description |
|---|---|---|
theme | Theme label | |
color | Color family name | |
shade | Shade label | |
hex | Display color | |
textContrast.wcag.light.ratio | White text WCAG ratio | |
textContrast.wcag.light.score | White text WCAG level | |
textContrast.wcag.dark.ratio | Black text WCAG ratio | |
textContrast.wcag.dark.score | Black text WCAG level | |
textContrast.apca.light.lc | White text APCA Lc | |
textContrast.apca.light.recommendedUsage | White text recommendation | |
textContrast.apca.dark.lc | Black text APCA Lc | |
textContrast.apca.dark.recommendedUsage | Black text recommendation | |
best_text | derived — LIGHT or DARK | |
wcag_pass | derived — true if light or dark passes AA | |
apca_pass | derived — true if light or dark has ` | Lc |
global_pass | derived — true if wcag_pass and apca_pass |
Prefer producing or reasoning from a compact CSV-like block instead of the original nested JSON:
theme,color,shade,hex,wcag_light_ratio,wcag_light_score,wcag_dark_ratio,wcag_dark_score,apca_light_lc,apca_light_usage,apca_dark_lc,apca_dark_usage,best_text,wcag_pass,apca_pass,global_pass
Light,primary,50,#F8FAFC,1.07,A,17.58,AAA,-4.2,AVOID,106.0,FLUENT_TEXT,DARK,true,true,true
Light,primary,100,#E2E8F0,1.32,A,13.16,AAA,-11.5,AVOID,95.2,FLUENT_TEXT,DARK,true,true,true
This flattened representation is the preferred input for audit reasoning, summary statistics, and visualization.
Before calling any tool, check whether a PaletteData slot is already populated in the conversation context (e.g. produced by ui-color-palette-scale-palette in the same session).
get_palette call with compact: true) is present → skip to Step 3. No API call needed.base + themes are present (no palette data) → continue to Step 1.Determine the minimum configuration required. Do not pass more themes than necessary.
Ask (or infer from context):
Which theme do you want to audit?
- Light (recommended)
- Dark
- Both If you do not answer, I will audit Light only.
If the user has multiple color families and only cares about a subset, ask which ones — otherwise include all.
Important: Pass only the scoped themes in the themes array. Removing unused themes significantly reduces the get_palette response size.
get_palette (targeted)Call get_palette with:
base configuration (unchanged)themes (not the full list if more exist)textColorsTheme set (e.g. { lightColor: "#FFFFFF", darkColor: "#000000" }) — required for textContrast to be populatedcompact: true — mandatory for this skill; returns a flat array and omits all raw color valuesThe compact: true response is already a flat array — no traversal needed. Pass it directly to Python to produce the audit CSV.
import json, sys
data = json.load(sys.stdin) # flat array of shade rows
FIELDS = [
"theme", "color", "shade", "hex",
"wcag_light_ratio", "wcag_light_score",
"wcag_dark_ratio", "wcag_dark_score",
"apca_light_lc", "apca_light_usage",
"apca_dark_lc", "apca_dark_usage",
"best_text", "wcag_pass", "apca_pass", "global_pass",
]
print(",".join(FIELDS))
for row in data:
tc = row.get("textContrast", {})
wl = tc.get("wcag", {}).get("light", {})
wd = tc.get("wcag", {}).get("dark", {})
al = tc.get("apca", {}).get("light", {})
ad = tc.get("apca", {}).get("dark", {})
wcag_pass = wl.get("score") in ("AA", "AAA") or wd.get("score") in ("AA", "AAA")
apca_pass = abs(al.get("lc", 0)) >= 60 or abs(ad.get("lc", 0)) >= 60
best_text = "DARK" if abs(ad.get("lc", 0)) > abs(al.get("lc", 0)) else "LIGHT"
out = [
row.get("theme", ""), row.get("color", ""), row.get("shade", ""), row.get("hex", ""),
wl.get("ratio", ""), wl.get("score", ""),
wd.get("ratio", ""), wd.get("score", ""),
al.get("lc", ""), al.get("recommendedUsage", ""),
ad.get("lc", ""), ad.get("recommendedUsage", ""),
best_text, wcag_pass, apca_pass, wcag_pass and apca_pass,
]
print(",".join(str(v) for v in out))
Reason only from the CSV output — the raw JSON array is no longer needed once the CSV is produced.
XX%$ARGUMENTS can be a list of hex colors to audit or a palette ID.
/ui-color-palette:audit-palette #1E293B #F8FAFC #3B82F6 #FFFFFF/ui-color-palette:audit-palette palette-id-abc123The response should have 3 layers: compact dataset, visual audit table, and global score.
Start with a short CSV-like block or markdown table containing only the flattened audit rows needed for interpretation.
theme,color,shade,hex,wcag_light_ratio,wcag_dark_ratio,apca_light_lc,apca_dark_lc,best_text,wcag_pass,apca_pass
Light,primary,50,#F8FAFC,1.07,17.58,-4.2,106.0,DARK,true,true
Light,primary,100,#E2E8F0,1.32,13.16,-11.5,95.2,DARK,true,true
Then present results per color as a visual table, one row per shade:
Color: {colorName} {sourceHex}
| Shade | Swatch | Hex | Light WCAG | Dark WCAG | Light APCA | Dark APCA | Best text | Status |
|---|---|---|---|---|---|---|---|---|
| 50 | [#F8FAFC] | #F8FAFC | 1.07 / A | 17.58 / AAA | -4.2 / AVOID | 106.0 / FLUENT_TEXT | Dark | Pass |
| 100 | [#E2E8F0] | #E2E8F0 | 1.32 / A | 13.16 / AAA | -11.5 / AVOID | 95.2 / FLUENT_TEXT | Dark | Pass |
| ... |
Light or Dark based on the highest WCAG score (prioritize AAA > AA > A), then highest APCA |Lc| as tiebreaker.Pass if the shade has at least one readable text color for both WCAG AA and APCA body text; otherwise Fail.╔══════════════════════════════════════════╗
║ GLOBAL CONTRAST SCORE ║
║ ║
║ 85% ║
║ ║
║ WCAG AA pass rate: 90% (27/30 shades) ║
║ APCA body text: 80% (24/30 shades) ║
║ ║
║ Failing shades: 3 ║
╚══════════════════════════════════════════╝
List every shade that fails both light and dark text for WCAG AA (ratio < 4.5) or APCA body text (|Lc| < 60):
| Color | Shade | Hex | Issue | Recommendation |
|---|---|---|---|---|
| primary | 400 | #60A5FA | Neither text passes AA | Darken to 500 or lighten to 300 |
End with the global score and recommendations.
shade.contrast, shade.rgb, shade.lch, shade.oklch, shade.lab, shade.oklab, shade.hsl, shade.hsluv, shade.hsv, shade.cmyk, shade.gl — they are not needed and inflate context size.themes array. Each extra theme multiplies the response size.PaletteData is already in context from a prior step, skip the API call entirely (Step 0).textColorsTheme is required: Ensure every theme has textColorsTheme set (e.g. { lightColor: "#FFFFFF", darkColor: "#000000" }) — otherwise textContrast will be absent and the audit cannot proceed.ColorConfiguration.rgb): divide each 0–255 channel by 255. E.g. #3B82F6 → { r: 0.23, g: 0.51, b: 0.96 }.Delegate this skill to palette-auditor.
The palette-auditor agent is optimized for WCAG/APCA contrast audits, global contrast scoring, risky pair detection, and remediation proposals. It knows the audit dataset schema defined in this skill and works from the flattened row representation rather than traversing full PaletteData.
npx claudepluginhub a-ng-d/claude-ui-color-paletteGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Resolves in-progress git merge or rebase conflicts by analyzing history, understanding intent, and preserving both changes where possible. Runs automated checks after resolution.