# Build Complete Theme

**SHOULD** · **ID:** `design-complete-theme` · **Category:** design
**Source:** [Tailwind](https://tailwindcss.com/docs)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/design-complete-theme

> SHOULD: Define complete token pairs: background + foreground, ring, border for each semantic color

Define all interactive states and component variants

A partial theme leads to inconsistency. Complete themes include: background/foreground pairs, border variants, ring/focus colors, and state variants (hover, active, disabled).

## Bad — do not do this

`design-complete-theme-bad`

```tsx
export function CompleteThemeBad() {
  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">Incomplete Token Set</h4>
        <div className="space-y-2">
          <div className="flex items-center justify-between p-2 bg-blue-600 text-white rounded">
            <span className="text-sm">primary</span>
            <span className="text-xs text-blue-200">hardcoded white</span>
          </div>
          <div className="flex items-center justify-between p-2 bg-gray-200 text-gray-800 rounded">
            <span className="text-sm">secondary</span>
            <span className="text-xs text-gray-500">hardcoded gray-800</span>
          </div>
          <div className="flex items-center justify-between p-2 bg-gray-100 text-gray-600 rounded">
            <span className="text-sm">muted</span>
            <span className="text-xs text-gray-400">no foreground token</span>
          </div>
          <div className="flex items-center justify-between p-2 bg-red-600 text-white rounded">
            <span className="text-sm">destructive</span>
            <span className="text-xs text-red-200">hardcoded white</span>
          </div>
        </div>
        <div className="mt-3 pt-3 border-t border-border">
          <input
            type="text"
            placeholder="No ring color defined"
            className="w-full px-3 py-2 border border-gray-300 rounded focus:outline-hidden focus:ring-2 focus:ring-blue-500"
          />
        </div>
      </div>
      <p className="text-xs text-error">
        Missing foreground tokens; hardcoded colors everywhere
      </p>
    </div>
  );
}
```

## Good — do this

`design-complete-theme-good`

```tsx
export function CompleteThemeGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4 space-y-4">
        <div>
          <h4 className="font-medium mb-2">Background and foreground pairs</h4>
          <div className="space-y-2">
            {[
              ['bg-primary text-primary-foreground', 'primary'],
              ['bg-secondary text-secondary-foreground', 'secondary'],
              ['bg-muted text-muted-foreground', 'muted'],
              ['bg-destructive text-destructive-foreground', 'destructive'],
            ].map(([cls, name]) => (
              <div key={name} className={`flex items-center justify-between p-2 rounded ${cls}`}>
                <span className="text-sm">{name}</span>
                <span className="text-xs opacity-80">+ foreground</span>
              </div>
            ))}
          </div>
        </div>

        <div className="pt-3 border-t border-border">
          <h4 className="font-medium mb-2">State variants</h4>
          <div className="flex flex-wrap gap-2">
            <button className="px-3 py-1.5 rounded-md text-sm bg-primary text-primary-foreground transition-colors hover:bg-primary/90 active:bg-primary/80">
              Hover and press me
            </button>
            <button
              disabled
              className="px-3 py-1.5 rounded-md text-sm bg-primary text-primary-foreground disabled:opacity-50 disabled:cursor-not-allowed"
            >
              Disabled
            </button>
          </div>
          <input
            type="text"
            placeholder="Focus to see the ring"
            className="mt-2 w-full px-3 py-2 bg-background border border-border rounded focus:outline-hidden focus:ring-2 focus:ring-ring"
          />
        </div>
      </div>

      <p className="text-xs text-success">
        A complete theme: every background has a matching foreground, plus tokens for the hover, active, disabled and
        focus-ring states
      </p>
    </div>
  );
}
```

## References

- [shadcn/ui Theming](https://ui.shadcn.com/docs/theming)
