# Uppercase Is for Labels, Not Prose

**NEVER** · **ID:** `content-impeccable-all-caps-body` · **Category:** content
**Source:** [impeccable](https://impeccable.style/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/content-impeccable-all-caps-body

> NEVER: Apply `text-transform: uppercase` to running text — flagged on any non-heading over 30 characters, because capitals erase the word shape readers recognize. Reserve uppercase for short labels and headings, and give those 0.05em–0.12em of letter-spacing.

Keep running text in sentence case and reserve uppercase for short labels and headings

Fluent readers identify words by their silhouette, and capitals flatten every word into the same rectangle, forcing letter-by-letter decoding. impeccable's detector flags text-transform: uppercase on any non-heading element carrying more than 30 characters, which is why the all-caps legal disclaimer, the format chosen precisely to look important, is the one nobody reads. The companion rule matters too: short all-caps labels do need 5-12% letter-spacing (0.05em to 0.12em), because capitals are spaced to sit beside lowercase letters and crowd each other at default tracking.

## Bad — do not do this

`content-impeccable-all-caps-body-bad`

```tsx
export function ImpeccableAllCapsBodyBad() {
  return (
    <div className="space-y-3">
      <div className="rounded-lg border border-border bg-card p-4">
        <p className="text-sm uppercase leading-[1.6] text-foreground">
          The seller makes no warranty of merchantability or fitness for a particular purpose. Any
          liability arising from the use of this product is limited to the amount paid for it in the
          twelve months preceding the claim. Some jurisdictions do not allow this limitation.
        </p>
      </div>

      <p className="text-xs text-error">
        265 characters of prose set in <code className="rounded bg-muted px-1 font-mono">uppercase</code>{' '}
        — the detector fires on text-transform: uppercase on any non-heading over 30 characters. We
        recognize words by their outline: the ascenders of “l” and “h”, the descenders of “p” and
        “y”. Capitals flatten every word into the same rectangle, so you are forced to read letter
        by letter. Ironically, this is exactly the copy people set in caps to make it feel more
        legally binding.
      </p>
    </div>
  );
}
```

## Good — do this

`content-impeccable-all-caps-body-good`

```tsx
export function ImpeccableAllCapsBodyGood() {
  return (
    <div className="space-y-3">
      <div className="rounded-lg border border-border bg-card p-4">
        {/* The legitimate use: a SHORT label, with tracking added back */}
        <p className="mb-2 text-[0.6875rem] uppercase tracking-[0.08em] text-muted-foreground">
          Limitation of liability
        </p>
        <p className="text-sm leading-[1.6] text-foreground">
          The seller makes no warranty of merchantability or fitness for a particular purpose. Any
          liability arising from the use of this product is limited to the amount paid for it in the
          twelve months preceding the claim. Some jurisdictions do not allow this limitation.
        </p>
      </div>

      <p className="text-xs text-success">
        The disclaimer drops to sentence case, so word shapes come back and it can be skimmed. The
        eyebrow above it stays uppercase — that is the legitimate use: short labels and headings.
        Note it also carries{' '}
        <code className="rounded bg-muted px-1 font-mono">letter-spacing: 0.08em</code>. Capitals
        are drawn to sit next to lowercase letters, so at default tracking they crowd each other;
        short all-caps labels need 5–12% extra spacing to breathe.
      </p>
    </div>
  );
}
```

## References

- [impeccable](https://impeccable.style/)
- [MDN: text-transform](https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform)
- [Practical Typography: All caps](https://practicaltypography.com/all-caps.html)
