--- name: contrast-readability-guard description: Prevent unreadable same-color or low-contrast text/background combinations before shipping UI. Use when building, editing, or QAing web pages, landing pages, cards, buttons, hero sections, screenshots, or any visual design with foreground text over a colored/image/gradient background. triggers: - contrast check - readability check - text on background - white on white - unreadable text - font color background color - visual QA contrast - WCAG contrast --- # Contrast Readability Guard ## Contract Before claiming a UI is ready, this skill guarantees: - Text is visibly readable against its actual rendered background, not just theoretically styled. - Large text, normal text, buttons, cards, nav, overlays, and mobile sticky CTAs are checked separately. - Same-color and near-same-color foreground/background mistakes are caught before deploy. - Image and gradient overlays are treated as risky until verified visually or with computed styles. - Failures produce exact fix instructions: selector/location, current colors, required replacement, and proof needed. ## Required standard Use WCAG contrast as the floor, not the ceiling: - Normal text under 24px regular / 18.66px bold: minimum 4.5:1. - Large text at least 24px regular or 18.66px bold: minimum 3:1. - UI components and focus states: minimum 3:1. - For customer-facing marketing pages, prefer 7:1 for body text when practical. If text appears unreadable in a screenshot, the screenshot wins over code intent. ## Workflow 1. **List all text surfaces.** Include hero, cards, badges, buttons, nav, mobile nav, footer, overlays, forms, and any horizontal scroll cards. 2. **Find inherited color risk.** Flag containers where text color is inherited from a dark parent but child background is light, or vice versa. This is the classic `text-white` parent + `bg-white` card bug. 3. **Check actual pairings.** For each surface, compare foreground text color against the rendered background color/gradient/image overlay behind it. 4. **Handle images/gradients conservatively.** Require a dark/light overlay strong enough for the worst area behind the text. If uncertain, use a solid text panel or stronger overlay. 5. **Patch explicitly.** Put text color on the same component that owns the background. Do not rely on distant inheritance for cards or buttons. 6. **Verify after patch.** Rebuild/reload and inspect the actual rendered page or screenshot. Run a forbidden low-contrast scan where possible and visually inspect mobile. ## Implementation rules - Every light card must set a dark text color on the card or heading itself. - Every dark card must set a light text color on the card or heading itself. - Avoid `text-white` unless the immediate background is dark or has a verified dark overlay. - Avoid `text-[var(...)]` unless the variable is known at that component boundary. - For reusable components used in both light and dark sections, pass an explicit `tone`/`variant` prop or set local text colors inside the component. - Never put a light-background component inside a dark `text-white` parent without resetting text color on the component. - Verify hover/focus states too; a button can pass at rest and fail on hover. ## Quick code patterns ### Bad ```tsx

Call Before You Go

``` The card inherits `text-white`, making white text on white background. ### Good ```tsx

Call Before You Go

``` ### Better reusable component ```tsx function FeatureCard({ tone = 'light' }) { const toneClass = tone === 'light' ? 'bg-white text-[#24170f]' : 'bg-[#24170f] text-white'; return
...
; } ``` ## QA checklist - [ ] Desktop hero headline readable. - [ ] Mobile hero headline readable. - [ ] Every card heading readable. - [ ] Every card body paragraph readable. - [ ] Every CTA readable at rest, hover, and focus. - [ ] Mobile sticky nav readable. - [ ] Footer readable. - [ ] No `text-white` inherited into `bg-white` or light cards. - [ ] No dark text inherited into dark cards. - [ ] Screenshot inspected for real-world readability. ## Output format ```text Contrast verdict: PASS / FAIL Failures: - Location: Problem: on is unreadable / below ratio Fix: Proof required: Passed surfaces: - ... ``` ## Anti-patterns - Assuming Tailwind class intent equals rendered contrast. - Checking only the hero and ignoring cards/buttons/mobile nav. - Relying on inherited text color in reusable cards. - Using `text-white` over pale image areas without a verified overlay. - Saying “looks fine” without screenshot or computed evidence. - Shipping customer-facing pages with selected/highlighted-looking text caused by color collisions.