States

Every screen defines all five required states — loading, empty, error, success, permission-denied.


States

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.

Loading

  • 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.

Empty

  • 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.

Error

  • 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.

Success

  • 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.

Permission-denied

  • 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".

Why all five

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.