# Hairline Border or Soft Shadow, Not Both

**NEVER** · **ID:** `design-impeccable-hairline-plus-shadow` · **Category:** design
**Source:** [impeccable](https://impeccable.style/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/design-impeccable-hairline-plus-shadow

> NEVER: Pair a visible hairline border with a wide, diffuse shadow — it is a generated-UI signature. The two make contradictory claims: the hairline says the surface has a crisp edge in the plane, the soft shadow says it is floating above the plane with light wrapping its edge, so the border kills the lift and the shadow kills the line. Commit to one — a defined EDGE (crisp hairline, no shadow) or a soft ELEVATION (shadow, no border). The detector fires on >=2 sides at <=1.5px with border alpha >=0.28 while a shadow layer of alpha >=0.12 has blur >=16px: `border shadow-lg` fires, `border shadow-xs` does not. A single layered shadow that INCLUDES its ring (`0 0 0 1px …`, 0 blur) is not this pattern — see `design-layered-shadows`.

Commit a card to a defined edge or to a soft elevation — pairing a 1px border with a wide diffuse shadow is the "every card style I know" tell

The detector is precise about what counts: at least two sides carrying a VISIBLE hairline (width <= 1.5px with border-color alpha >= 0.28) while the element also has a box-shadow whose largest blur radius is >= 16px, measured only across shadow layers with alpha >= 0.12. So `border shadow-lg` on a card fires it; `border shadow-xs` does not, and neither does a shadow built entirely from near-invisible layers. The reason it reads as cheap is that the two devices make contradictory claims. A hairline says "this surface has a crisp, defined boundary and sits in the plane." A wide diffuse shadow says "this surface is floating above the plane, and its edge is soft because light wraps around it." Ship both and the edge fights the lift: the border stops the shadow from selling elevation, and the shadow stops the border from reading as a deliberate line. Pick one and mean it — a crisp hairline with no shadow (flat, precise, editorial), or a soft shadow with no border (lifted, tactile). Note the one legitimate exception, which is not this pattern: a shadow that INCLUDES its hairline as a 0-blur ring layer (`0 0 0 1px …`) is a single layered shadow, not a border plus a shadow — see design-layered-shadows.

## Bad — do not do this

`design-impeccable-hairline-plus-shadow-bad`

```tsx
/**
 * Bad: `border` + `shadow-lg` on the same card — a visible 1px hairline on all four
 * sides while a 16px+ blur spills underneath. That is exactly what impeccable's
 * detector fires on (>= 2 sides at <= 1.5px with alpha >= 0.28, plus a shadow layer
 * whose blur is >= 16px), and it is the "I applied every card style I know" tell.
 *
 * The plate is pinned light on purpose: a soft shadow only reads on a light surface.
 */
export function ImpeccableHairlinePlusShadowBad() {
  return (
    <div className="w-full space-y-3">
      <p className="text-xs text-muted-foreground">One card, both treatments</p>

      <div className="rounded-xl bg-neutral-100 p-6">
        {/* border-neutral-200 is a fully opaque hairline; shadow-lg blurs at 15px+ */}
        <div className="rounded-lg border border-neutral-200 bg-white p-4 shadow-lg">
          <p className="text-sm font-semibold text-neutral-900">Usage this month</p>
          <p className="mt-1 text-sm text-neutral-500">
            A crisp edge, and a soft lift, at the same time.
          </p>
        </div>
      </div>

      <div className="rounded bg-muted p-2 font-mono text-xs">
        <code className="text-error">border border-neutral-200 + shadow-lg</code>
      </div>

      <p className="text-xs text-error">
        The two devices contradict each other. The hairline says &ldquo;this surface has a defined
        boundary and sits in the plane&rdquo;; the wide blur says &ldquo;this surface is floating,
        and its edge is soft because light wraps around it.&rdquo; Ship both and the edge fights the
        lift &mdash; the border stops the shadow selling elevation, the shadow stops the border
        reading as a deliberate line, and the card reads as cheap.
      </p>
    </div>
  );
}
```

## Good — do this

`design-impeccable-hairline-plus-shadow-good`

```tsx
/**
 * Good: two cards, each committed to ONE device. Left — a crisp hairline and no
 * shadow: flat, precise, in-plane. Right — a soft shadow and no border: lifted,
 * tactile, edge softened by the light it implies. Either is a decision; together
 * on one element they are a hedge.
 *
 * The plate is pinned light on purpose: a soft shadow only reads on a light surface.
 */
export function ImpeccableHairlinePlusShadowGood() {
  return (
    <div className="w-full space-y-3">
      <p className="text-xs text-muted-foreground">Two cards, one treatment each</p>

      <div className="grid grid-cols-2 gap-4 rounded-xl bg-neutral-100 p-6">
        {/* Committed to the EDGE: hairline, no shadow */}
        <div className="rounded-lg border border-neutral-300 bg-white p-4">
          <p className="text-sm font-semibold text-neutral-900">Defined edge</p>
          <p className="mt-1 text-xs text-neutral-500">
            Hairline only. Sits in the plane, and says so.
          </p>
        </div>

        {/* Committed to the LIFT: soft shadow, no border */}
        <div className="rounded-lg bg-white p-4 shadow-lg">
          <p className="text-sm font-semibold text-neutral-900">Soft elevation</p>
          <p className="mt-1 text-xs text-neutral-500">
            Shadow only. Floats above the plane, and says so.
          </p>
        </div>
      </div>

      <div className="space-y-1 rounded bg-muted p-2 font-mono text-xs">
        <code className="block">border border-neutral-300 &mdash; no shadow</code>
        <code className="block">shadow-lg &mdash; no border</code>
      </div>

      <p className="text-xs text-success">
        Each card makes one claim and backs it. Note the exception that is NOT this anti-pattern:
        a single layered shadow that carries its own 0-blur ring (<code className="font-mono">0 0 0 1px</code>{' '}
        plus two soft depths) is one shadow, not a border plus a shadow &mdash; the ring is part of the
        lighting model rather than a second, competing device.
      </p>
    </div>
  );
}
```

## References

- [impeccable](https://impeccable.style/)
- [pbakaus/impeccable](https://github.com/pbakaus/impeccable)
- [MDN: box-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/box-shadow)
