Every screen defines all five — loading, empty, error, success, permission-denied.
A screen without all five states isn't done. The default-only view is the shape; the other four are where most product trust is won or lost.
- Skeleton with a 200ms delay. Never block the screen with a centered spinner.
- Skeleton shape matches the eventual content. A list shows skeleton rows; a card shows a skeleton card.
- For long-running operations (>3s), show progress, not just animation.
- Icon + one-line "what this is" + single primary CTA.
- Never leave blank. Never "Nothing to show" or "No data".
- Title leads with the noun: "No segments yet", not "There's nothing here".
- CTA copy is action-oriented: "Create your first segment".
- Background uses
color-surface-subtle; padding uses the surface's default scale.
- What went wrong + why (if knowable) + the action that moves the user forward.
- Never raw API errors or stack traces.
- Primary action is a recovery path: "Re-upload corrected file", "Reconnect account". Not "Dismiss" or "OK".
- For partial results, lead with what succeeded:
8,556 of 12,403 rows imported. Then name the gap. Then name the action. "Failure" framing overstates the damage when most of the operation worked.
- Non-trivial recoveries get a three-action footer: dismiss, detail (
View error log), fix — right-aligned, in that order.
- No "Sorry" or "Oops". Apologize by fixing the underlying issue.
- Snackbar toast (3s auto-dismiss) for ephemeral confirmations.
- Inline checkmark for in-place edits.
- Never a modal or banner for routine success — those are reserved for state changes the user needs to acknowledge.
- Show the feature disabled with a tooltip explaining the role required. Do not hide the feature.
- The point is to make the path to access discoverable. "This requires admin access" is more useful than the absence of a button.
- Tooltip names the specific permission, not a vague "ask your admin".
The default-only view is the easy case. The other four are where the work feels designed.
- Loading without a skeleton looks broken.
- Empty without a CTA looks abandoned.
- Error without recovery looks hostile.
- Success without acknowledgment looks unresponsive.
- Permission-denied without explanation looks arbitrary.
Spec-attached output names every one. Vanilla output names two at best.