Empty state

Empty states are the moment between nothing and something. Settld treats them as warm invitations — never cold error pages. The tone is always specific, contextual, and forward-pointing. The art uses ASCII in monospace to stay on-brand without importing illustration libraries.

Variants

₹ · · · · [ ] · · · · · ₹ · · · · · ·
No expenses yet
Split your first one — even the ₹40 chai counts.
· · · · · ✓ · · · · · · · · · · ✓ · ·
All settled up ✓
No one owes anyone. Enjoy that guilt-free chai.
· [ ] · · · · · · · · · · · · · [ ] · ·
No groups
Create one for your next trip, dinner, or flat.

Default is the standard empty state — warm ASCII art, a specific headline, a human description, and an optional CTA button. Used for "no expenses", "no groups", "no search results".

Settled is the celebration variant — same structure, but the headline turns teal and the CTA becomes teal too. Used exclusively for the "all settled up" state. It should feel like a small win, not just an absence of data.

Both variants accept any combination of art + title + description + CTA. The CTA is optional — some empty states (search results, filters) don't need one.

Context sizing

₹ · · · · · · [ ] · · · · · · · · ₹ · · ·
No expenses yet
Split your first one. Even the ₹40 chai counts.

₹ · · · · [ ] · · · · ₹
No splits here
Add the first one.

Empty states scale to their container. Full-screen empties (when a whole view is empty) use 80px vertical padding and full prose. Inline empties (inside a card or panel) use 24px padding and abbreviated text — no CTA.

States

With CTA
₹ · · · · [ ] · · · · ₹
No expenses
Start splitting.
Without CTA
? · · · · · · · · · · · ? · ·
No results
Try a different name or UPI ID.
StateWhen to useHas CTA?
Default (no content)No items exist yet — first useYes — add/create action
SettledAll balances are zeroYes — start next group/expense
No search resultsFilter/search returned nothingNo — user should modify their query
Inline emptyA card/panel has no dataUsually no

On dark surfaces

₹ · · · · [ ] · · · · · ₹ ·
No expenses yet
Split your first one.
· ✓ · · · · · · · · · ✓ · ·
All settled up ✓
Enjoy that guilt-free chai.

On dark surfaces, the art block uses --dark-elevated background with a --dark-border dashed border. Text shifts to the dark text tokens. The settled variant's title uses a lighter teal tint (#5fc7a8) instead of the full --teal to maintain contrast on dark.

Anatomy

① Illustration area (ASCII art in mono)
· ₹ · · · · · [ ] · · · · · ₹
② Headline (display, 20px/600)
No expenses yet
③ Description (body, 14px, muted — max 28ch)
Split your first one. Even the ₹40 chai counts.
④ CTA (optional — pill button)
PartElementNotes
Illustration.empty-state-artMonospace ASCII art in a dashed border box. Max 5 lines × 16 chars. Warm background --s-warm.
Headline.empty-state-titleDisplay font, 20px/600. Specific — names the thing that's missing. Sentence case.
Description.empty-state-descBody font, 14px, --ink-mute. Max 28ch. One sentence. Forward-pointing — tells the user what to do, not what failed.
CTA.empty-state-actionOptional. Pill button, ink fill. Verb-led. One CTA maximum per empty state.

Usage

Do Name the specific missing thing: "No expenses yet", "No groups". Be warm and concrete. "Even the ₹40 chai counts" is Settld voice — it's specific about the product's value and uses Indian context.
Don't Don't write cold technical copy: "No items found", "Empty list", "0 results". Don't reference technical causes ("Error fetching data", "Network timeout"). Empty states are UX moments, not error logs.
Do Use the .settled variant exclusively for the "all settled up" state. This is a celebrated outcome — the teal headline and CTA signal it positively. It's the app's signature happy path.
Don't Don't put a CTA on a "no search results" empty state. The user needs to change their query, not add a new item. A button here is noise.

Accessibility

Screen readers The ASCII art block is decorative. Add aria-hidden="true" to .empty-state-art. The headline and description carry the full meaning — the art is purely visual mood.
CTA button .empty-state-action should be a <button> for actions or <a> for navigation. The label must be specific: "Add expense" not just "Add". Avoid generic "Get started" — it fails for users who navigate by button list.
Live regions When an empty state replaces content dynamically (e.g., a search returns no results), wrap it in aria-live="polite" so screen readers announce the change without interrupting the user.

Code

HTML

<!-- Default empty state -->
<div class="empty-state">
  <div class="empty-state-art" aria-hidden="true">  ₹ · · ·
 · [ ] · ·
· · · ₹ · </div>
  <div class="empty-state-title">No expenses yet</div>
  <div class="empty-state-desc">Split your first one. Even the ₹40 chai counts.</div>
  <button class="empty-state-action">Add expense →</button>
</div>

<!-- Settled variant -->
<div class="empty-state settled">
  <div class="empty-state-art" aria-hidden="true">  · · ✓ ·
 · · · · ·
· · ✓ · · </div>
  <div class="empty-state-title">All settled up ✓</div>
  <div class="empty-state-desc">No one owes anyone. Enjoy that guilt-free chai.</div>
  <button class="empty-state-action">New group →</button>
</div>

CSS classes

ClassPurpose
.empty-stateCentered column flex container
.empty-state.settledCelebration variant — teal headline and CTA
.empty-state-artMono ASCII art block with dashed border
.empty-state-titleDisplay headline — 20px/600
.empty-state-descBody description — 14px, muted, max 28ch
.empty-state-actionOptional CTA — pill button, ink fill

Design tokens used

TokenValueRole
--font-monoJetBrains MonoASCII art typeface
--s-warm#F1E9D5Art block background
--ink-line#DDD2B8Art block dashed border
--ink-mute#8A8276Art text and description color
--teal#0E7C66Settled title and CTA
--r-lg24pxArt block border-radius
--r-pill999pxCTA border-radius