Some_claude_skills color-contrast-auditor
Detects and fixes color contrast violations using WCAG 2.1 guidelines and perceptual analysis. Expert in contrast ratio calculation, color blindness simulation, and providing accessible alternatives.
git clone https://github.com/curiositech/some_claude_skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/curiositech/some_claude_skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/color-contrast-auditor" ~/.claude/skills/curiositech-some-claude-skills-color-contrast-auditor && rm -rf "$T"
.claude/skills/color-contrast-auditor/SKILL.mdColor Contrast Auditor
Detects color contrast violations that make text unreadable and provides WCAG-compliant fixes. Uses both mathematical contrast ratio analysis and perceptual evaluation via vision capabilities.
When to Use
Activate on:
- Screenshots of websites/apps with suspected contrast issues
- CSS/Tailwind files for color audit
- "I can't read this" or "this is hard to see"
- Pre-launch accessibility checks
- Design system color validation
NOT for:
- Choosing brand colors (use
)web-design-expert - Color harmony/aesthetics (use
)color-theory-palette-harmony-expert - Non-visual accessibility (screen readers, keyboard nav)
WCAG 2.1 Contrast Requirements
Minimum Ratios (AA - Required)
| Text Type | Minimum Ratio | Example |
|---|---|---|
| Normal text (<24px, <18.66px bold) | 4.5:1 | Body copy, labels, buttons |
| Large text (≥24px or ≥18.66px bold) | 3:1 | Headlines, hero text |
| UI components (borders, icons) | 3:1 | Form inputs, icons, focus rings |
| Graphical objects | 3:1 | Charts, infographics |
Enhanced Ratios (AAA - Recommended)
| Text Type | Minimum Ratio |
|---|---|
| Normal text | 7:1 |
| Large text | 4.5:1 |
Non-Text Elements
| Element | Requirement |
|---|---|
| Focus indicators | 3:1 against adjacent colors |
| Form field borders | 3:1 against background |
| Icons conveying meaning | 3:1 against background |
| Disabled elements | No requirement (but consider UX) |
Contrast Ratio Formula
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05) Where L1 = lighter color's relative luminance L2 = darker color's relative luminance
Calculating Relative Luminance
function relativeLuminance(r, g, b) { // Convert 0-255 to 0-1 let [rs, gs, bs] = [r, g, b].map(c => c / 255); // Apply gamma correction const gamma = c => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); const [R, G, B] = [rs, gs, bs].map(gamma); // Weighted sum (human eye sensitivity) return 0.2126 * R + 0.7152 * G + 0.0722 * B; } function contrastRatio(color1, color2) { const l1 = relativeLuminance(...color1); const l2 = relativeLuminance(...color2); const lighter = Math.max(l1, l2); const darker = Math.min(l1, l2); return (lighter + 0.05) / (darker + 0.05); }
Common Failing Patterns
1. Light Text on Light Background
❌ FAILING EXAMPLE (from user screenshot): ┌─────────────────────────────────────────────┐ │ Background: #F5F2E8 (beige/cream) │ │ Text: #C8FF00 (lime green) │ │ │ │ "Scan. Crawl. Match. Report." │ │ ← UNREADABLE │ │ │ │ Calculated Ratio: ~1.5:1 │ │ Required: 4.5:1 (normal) or 3:1 (large) │ │ Verdict: FAIL by 3x │ └─────────────────────────────────────────────┘ ✅ FIXED OPTIONS: • Darken text to #5A7300 → Ratio: 4.5:1 • Darken background to #2A2A2A → Ratio: 12:1 • Use dark green #1A4D00 → Ratio: 8:1
2. Gray Text Syndrome
❌ COMMON FAILURE: Background: #FFFFFF Text: #AAAAAA (light gray) Ratio: 2.3:1 ← FAIL ✅ FIXES: • Text: #767676 → Ratio: 4.5:1 (minimum AA) • Text: #595959 → Ratio: 7:1 (AAA)
3. Saturated Colors That Look Bright
❌ DECEPTIVE FAILURE: Background: #FFF8E7 (warm white) Text: #FF6B6B (coral/salmon) Ratio: 2.8:1 ← FAIL (looks "colorful" but fails) ✅ FIXES: • Text: #C62828 (darker red) → Ratio: 5.2:1 • Text: #8B0000 (dark red) → Ratio: 8.1:1
4. Trendy Low-Contrast Aesthetic
❌ "MINIMALIST" FAILURE: Background: #FAFAFA Text: #E0E0E0 Ratio: 1.3:1 ← SEVERELY FAILING This is NOT minimalism. This is inaccessible. ✅ MINIMALIST + ACCESSIBLE: Background: #FAFAFA Text: #616161 → Ratio: 5.7:1
5. Placeholder Text Too Light
❌ COMMON FORM FAILURE: Input background: #FFFFFF Placeholder: #CCCCCC Ratio: 1.6:1 ← FAIL ✅ FIX: Placeholder: #757575 → Ratio: 4.6:1
6. Gradient Backgrounds
❌ VARIABLE CONTRAST: Gradient: #FFFFFF → #000080 Text: #FFFFFF (fixed) Top of gradient: 1:1 (invisible!) Bottom of gradient: 8.6:1 (good) ✅ SOLUTIONS: • Add text shadow/outline • Use semi-transparent overlay behind text • Ensure ALL gradient stops pass contrast
Audit Methodology
Step 1: Visual Scan (Screenshot Analysis)
When given a screenshot, identify:
-
Text elements by size:
- Headlines (large text → 3:1 required)
- Body copy (normal text → 4.5:1 required)
- UI labels (buttons, links → 4.5:1)
- Captions/fine print (4.5:1 required)
-
Interactive elements:
- Button borders/backgrounds
- Form field borders
- Focus states
- Icons with meaning
-
Red flags to look for:
- Light text on light backgrounds
- Gray text on white
- Colored text on colored backgrounds
- Text over images without overlay
Step 2: Extract Colors
From CSS/code:
# Find all color declarations grep -E "(color:|background:|#[0-9a-fA-F]{3,8}|rgb|hsl)" styles.css
From Tailwind:
# Find text/bg color classes grep -E "(text-|bg-)" *.tsx *.jsx
Step 3: Calculate Ratios
For each text/background pair:
- Convert colors to RGB
- Calculate relative luminance
- Compute contrast ratio
- Compare to WCAG requirement
Step 4: Generate Report
# Contrast Audit Report ## Summary - Total color pairs tested: X - Passing (AA): Y - Failing: Z - Critical failures (<2:1): N ## Failures by Severity ### Critical (Ratio < 2:1) | Location | Foreground | Background | Ratio | Required | Fix | |----------|------------|------------|-------|----------|-----| | Hero tagline | #C8FF00 | #F5F2E8 | 1.5:1 | 3:1 | #5A7300 | ### Moderate (Ratio 2:1 - 3:1) ... ### Minor (Ratio 3:1 - 4.5:1, normal text only) ... ## Recommended Fixes [Specific color replacements with new ratios]
Color Blindness Considerations
Contrast requirements help but don't fully address color blindness. Additional checks:
Types to Consider
| Type | Affected | Consideration |
|---|---|---|
| Deuteranopia | 6% of males | Red/green confusion |
| Protanopia | 2% of males | Red appears dark |
| Tritanopia | <1% | Blue/yellow confusion |
Best Practices
-
Never rely on color alone for meaning
- Add icons, patterns, or text labels
- Red/green for error/success needs icons too
-
Test problematic pairs:
- Red + Green (stop/go)
- Blue + Purple
- Green + Brown
- Light green + Yellow
-
Use sufficient lightness difference
- Even with same hue, different lightness helps
Quick Reference: Safe Color Pairs
On White (#FFFFFF)
| Use Case | Color | Hex | Ratio |
|---|---|---|---|
| Body text | Dark gray | #333333 | 12.6:1 |
| Secondary text | Medium gray | #767676 | 4.5:1 |
| Links | Blue | #0066CC | 5.3:1 |
| Success | Green | #2E7D32 | 5.1:1 |
| Error | Red | #C62828 | 6.0:1 |
| Warning | Orange-brown | #E65100 | 4.5:1 |
On Black (#000000)
| Use Case | Color | Hex | Ratio |
|---|---|---|---|
| Body text | Light gray | #E0E0E0 | 13.4:1 |
| Secondary | Medium gray | #9E9E9E | 6.3:1 |
| Accent | Light blue | #90CAF9 | 7.3:1 |
On Dark Gray (#1A1A1A)
| Use Case | Color | Hex | Ratio |
|---|---|---|---|
| Body text | Off-white | #F5F5F5 | 14.1:1 |
| Secondary | Light gray | #BDBDBD | 8.3:1 |
Tools & Validation
Online Checkers
Browser DevTools
// Chrome DevTools: Elements → Styles → hover color swatch // Shows contrast ratio automatically // Firefox: Accessibility Inspector // Shows color contrast issues
Automated Testing
// axe-core (popular a11y testing library) const axe = require('axe-core'); axe.run(document, { rules: ['color-contrast'] }); // Lighthouse (built into Chrome) // Performance → Accessibility → Color contrast
CLI Tools
# Lighthouse CLI npx lighthouse https://example.com --only-categories=accessibility # Pa11y npx pa11y https://example.com
Integration with This Skill
When analyzing a screenshot or codebase:
- I will identify all text/background color pairs
- I will calculate contrast ratios for each
- I will flag anything below WCAG AA thresholds
- I will suggest specific hex values that pass
- I will provide before/after comparisons
For the example screenshot (lime on beige):
AUDIT RESULT: CRITICAL FAILURE Element: Hero tagline "Scan. Crawl. Match. Report." Foreground: ~#C8FF00 (lime green) Background: ~#F5F2E8 (beige) Calculated Ratio: ~1.5:1 Required (large text): 3:1 Required (normal text): 4.5:1 Status: ❌ FAILS BY 2-3x RECOMMENDED FIXES: 1. Darken text to #5A7300 (olive) → 4.8:1 ✓ 2. Darken text to #3D5C00 (dark olive) → 7.1:1 ✓✓ 3. Keep lime, darken BG to #3D3D3D → 8.2:1 ✓✓ 4. Use #1B5E20 (dark green) → 8.4:1 ✓✓
Checklist for New Designs
Before shipping:
- All body text has ≥4.5:1 contrast
- All large text has ≥3:1 contrast
- All form borders have ≥3:1 contrast
- All icons conveying meaning have ≥3:1 contrast
- Placeholder text is readable (≥4.5:1)
- Focus states are clearly visible (≥3:1)
- Links are distinguishable without color alone
- Error/success states use icons, not just color
- Tested with color blindness simulators
- Automated accessibility scan passes
Philosophy: Beautiful design and accessibility are not mutually exclusive. High contrast can be striking, dramatic, and intentional. Low contrast isn't "minimalist"—it's exclusionary. Every unreadable word is a user lost.