# EmptyState

> Three variants. Always one next action.

Source: https://lopifi.com/components/empty-state
Part of: Lopifi — US GAAP books on autopilot, reviewed by a CPA (https://lopifi.com)

---

- **Family:** System & states — ---
- **Status:** Implemented
- **Spec:** https://lopifi.com/docs/catalog/08-system-states

## Install

```bash
npx shadcn@latest add @lopifi/theme
npx shadcn@latest add @lopifi/empty-state
```

## Specification

Three variants, and they are genuinely different components:

| Variant | Illustration | Content |
|---|---|---|
| `first-run` | Isometric spot, 160px | "No transactions yet" + explanation + **one** primary action |
| `filtered` | **None** | "No transactions match these filters" + "Clear filters" |
| `period` | None | "No transactions between 1–30 Sep 2026" + "Widen the period" |

An illustration on the `filtered` variant is condescending — the user knows exactly what happened and wants the fix, not a picture.

**Always exactly one clear next action.** An empty state with no action is a dead end.

`description` is one line. The particulars — which three filters are active, what the import actually does before anything posts — go in `detail`, behind the ⓘ on the title. An empty state is read at a glance.

Illustration entrance: back-to-front, 60ms stagger, 8px translate, 320ms `--ease-out`, total capped at 480ms, **never loops**. [Spec](../foundations/08-imagery-and-isometric.md).

## Rules this component obeys

Money is minor units, never floats. `null` is not `0` and neither is redacted. Negatives render in accounting parentheses with the parenthesis column reserved on both sides. Debit and credit are two columns. Per-currency decimal places. Polarity is explicit — up is not always good. Every figure states its period, entity, currency, basis and as-of.
