# Inconsistent Shadow Usage

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

> SHOULD: Use consistent elevation/shadow tokens to convey hierarchy. Ensure shadows have sufficient contrast in both light and dark themes. Avoid mixing shadow styles.

Apply shadows consistently to establish visual hierarchy

Same upstream bullet as design-rams-border-radius — one line under "Components" — read here for its shadow half; the explanation is ours. A shadow is a claim about where an element sits in space, and the room only holds together if every claim assumes the same light source. Hand-rolled shadows with different blur, offset, and direction put three cards under three different suns, and the eye reads that as noise rather than depth. Assign elevation by role — resting cards one step, dropdowns and popovers a step above, modals the top — and take the values from one ramp (see design-ibelick-default-shadows for the Tailwind scale, and design-layered-shadows for building a two-layer shadow when you do need a custom one).

## Bad — do not do this

`design-rams-shadow-consistency-bad`

```tsx
export function RamsShadowConsistencyBad() {
  return (
    <div className="space-y-4">
      {/* Same light plate as the Good example, so the comparison is fair. */}
      <div className="rounded-xl bg-neutral-100 p-6">
        <div className="grid gap-5">
          <div
            className="flex items-center justify-between rounded-lg bg-white px-4 py-3"
            style={{ boxShadow: '0 0 24px rgba(37, 99, 235, 0.55)' }}
          >
            <span className="text-sm font-medium text-neutral-900">Blue glow</span>
            <code className="text-xs text-neutral-500">coloured shadow</code>
          </div>
          <div className="flex items-center justify-between rounded-lg bg-white px-4 py-3 shadow-2xl">
            <span className="text-sm font-medium text-neutral-900">Way too heavy</span>
            <code className="text-xs text-neutral-500">shadow-2xl</code>
          </div>
          <div
            className="flex items-center justify-between rounded-lg bg-white px-4 py-3"
            style={{ boxShadow: '6px 6px 0 #111827' }}
          >
            <span className="text-sm font-medium text-neutral-900">Hard offset</span>
            <code className="text-xs text-neutral-500">6px 6px 0</code>
          </div>
        </div>
      </div>
      <p className="text-xs text-destructive">
        Three unrelated shadows — different colour, blur and light direction. With no system, elevation stops meaning anything
      </p>
    </div>
  );
}
```

## Good — do this

`design-rams-shadow-consistency-good`

```tsx
const levels = [
  { name: 'Card', token: 'shadow-sm', cls: 'shadow-sm' },
  { name: 'Dropdown', token: 'shadow-md', cls: 'shadow-md' },
  { name: 'Modal', token: 'shadow-lg', cls: 'shadow-lg' },
];

export function RamsShadowConsistencyGood() {
  return (
    <div className="space-y-4">
      {/* A light plate, so the elevation ramp is actually legible in either theme. */}
      <div className="rounded-xl bg-neutral-100 p-6">
        <div className="grid gap-5">
          {levels.map((l) => (
            <div
              key={l.token}
              className={`flex items-center justify-between rounded-lg bg-white px-4 py-3 ${l.cls}`}
            >
              <span className="text-sm font-medium text-neutral-900">{l.name}</span>
              <code className="text-xs text-neutral-500">{l.token}</code>
            </div>
          ))}
        </div>
      </div>
      <p className="text-xs text-success">
        One shadow scale, one light source — elevation reads as a clear ramp: card → dropdown → modal
      </p>
    </div>
  );
}
```

## References

- [Rams design review skill](https://rams.ai/rams.md)
- [Box Shadow](https://tailwindcss.com/docs/box-shadow)
