# Insufficient Text Contrast

**MUST** · **ID:** `design-rams-color-contrast` · **Category:** design
**Source:** [RAMS](https://www.rams.ai/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/design-rams-color-contrast

> MUST: Text needs >= 4.5:1 against its background (WCAG 1.4.3); large text (>= 24px, or >= 19px bold) may use 3:1. Secondary text, captions and disabled states are where this fails. For UI component boundaries and states, `design-non-text-contrast` sets the separate 3:1 bar (WCAG 1.4.11). Test in both themes.

Text must have sufficient contrast with its background — including secondary text

That is the whole upstream rule — one bullet under "Color & Contrast" in the Rams review. The number is WCAG 1.4.3 Level AA: 4.5:1 for body text, relaxed to 3:1 for large text (18pt / 14pt bold and above). The reasoning here is ours. The failures are almost never the headline; they are the quiet text — captions, helper text, placeholders, timestamps, and "muted" secondary copy, where a designer reached for light gray on white to make the layout calmer. Disabled controls are formally exempt from 1.4.3, but if the disabled label is the only thing telling a user why they cannot proceed, exempt is not the same as readable. Check with a contrast tool rather than by eye, and re-check in dark mode, where a token that passed on white can fail on near-black. This rule sets the floor for TEXT only. The parts of a control that are not text — an input outline, a checkbox in its off state, a focus ring, a chart line — are governed by design-non-text-contrast (WCAG 1.4.11), whose AA floor is 3:1, not 4.5:1. The two numbers are not in conflict; they measure different things.

## Bad — do not do this

`design-rams-color-contrast-bad`

```tsx
export function RamsColorContrastBad() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4">
        <h4 className="font-medium mb-3">Poor UI Contrast</h4>
        <div className="space-y-3 p-4 bg-background rounded-lg">
          <input
            type="text"
            placeholder="Hard to see border"
            className="w-full px-3 py-2 border border-gray-200 rounded-md bg-background text-sm"
          />
          <div className="flex gap-2">
            <button className="px-4 py-2 bg-gray-200 text-gray-400 rounded-md text-sm">
              Primary
            </button>
            <button className="px-4 py-2 border border-gray-200 text-gray-400 rounded-md text-sm">
              Secondary
            </button>
          </div>
        </div>
        <div className="mt-3 bg-muted rounded p-2 font-mono text-xs">
          <code className="text-error">border-gray-200 (~1.5:1 contrast)</code>
        </div>
      </div>
      <p className="text-xs text-error">
        UI elements nearly invisible - where are the boundaries?
      </p>
    </div>
  );
}
```

## Good — do this

`design-rams-color-contrast-good`

```tsx
export function RamsColorContrastGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4">
        <h4 className="font-medium mb-3">Good UI Contrast</h4>
        <div className="space-y-3 p-4 bg-background rounded-lg">
          <input
            type="text"
            placeholder="Visible border"
            className="w-full px-3 py-2 border-2 border-border rounded-md bg-background text-sm"
          />
          <div className="flex gap-2">
            <button className="px-4 py-2 bg-primary text-primary-foreground rounded-md text-sm">
              Primary
            </button>
            <button className="px-4 py-2 border-2 border-border rounded-md text-sm hover:bg-muted">
              Secondary
            </button>
          </div>
        </div>
        <div className="mt-3 bg-muted rounded p-2 font-mono text-xs">
          <code>border-2 border-border (3:1+ contrast)</code>
        </div>
      </div>
      <p className="text-xs text-success">
        UI elements clearly visible against background
      </p>
    </div>
  );
}
```

## References

- [Rams design review skill](https://rams.ai/rams.md)
- [WCAG 1.4.3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html)
