# Microcopy And States

> The words in a data interface - labels, empty and error states, tooltips, disclosure and provenance lines, and the disclaimers a finance UI needs. Covers writing states that tell the reader what happened and what to do, and naming things so two people reading the same number agree on what it is. Trigger on "empty state", "error message", "what should this say", "label", "tooltip text", "wording", "microcopy", "disclaimer", "footnote", "caption".

- Skill: `lukehle/microcopy-and-states` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lukehle/microcopy-and-states`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lukehle/microcopy-and-states/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Lukehle (https://skillmd.com/u/lukehle)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lukehle/microcopy-and-states

---


# Microcopy and states

The words are load-bearing. A page with perfect layout and a state that says "No data" is a page
that will generate a support message, or worse, a wrong assumption.

---

## Labels: name the thing precisely

Ambiguous labels are how two people read the same number differently.

| Vague | Precise |
|---|---|
| Revenue | Subscription revenue (ASC 606) |
| Churn | Logo churn, trailing 12 months |
| Growth | ARR growth, YoY |
| Customers | Paying customers at period end |
| Total | Total, excluding intercompany |
| Last updated | Data as of 2026-08-19 14:20 ET |

Rules:
- **Include the basis** where more than one is plausible — recognized vs billed, gross vs net, logo
  vs revenue, period-end vs average.
- **Include the period and the unit** in the label or the header, once, not on every cell.
- **Use the organization's canonical name for a metric.** If the definitions page calls it NRR, the
  dashboard does not call it Net Retention.
- Sentence case reads faster than Title Case and much faster than ALL CAPS. Reserve caps for small
  muted labels where the size already signals subordination.

---

## Empty states are four different states

Each needs different words. Using one message for all four is the most common microcopy failure.

**Genuine empty** — the query worked, there is nothing:
> **No transactions in July 2026.**
> This account had no activity in the period. Prior period had 42 transactions.

**Filtered to nothing** — the user did this and can undo it:
> **No results for these filters.**
> Enterprise + EMEA + closed-won returned 0 of 14,882 rows.
> [Clear region] [Clear all filters]

**Not yet loaded** — nothing has been requested:
> **Choose a period to begin.**

**Not available** — the data cannot be obtained here:
> **Live data is unavailable in this view.**
> Showing the built-in snapshot as of 2026-08-19 14:20 ET.

Notice each one says **what happened** and **what to do next**. A bare "No data" says neither.

---

## Error states

Three parts, in order: what happened, what it means for the reader, what to do.

```
Could not load the GL summary.
The connector returned an authorization error, so no figures are shown.
[Retry]   If this persists, your access to the finance dataset may have changed.
```

Never:
- **A raw error string.** `TypeError: Cannot read property 'rows' of undefined` tells the reader
  nothing and looks broken.
- **"Something went wrong."** True and useless.
- **A blank region.** Silence reads as zero.
- **Stale data with no notice.** The worst option: it looks correct and is not.

**Distinguish retryable from not.** Offering Retry on a permission error trains people to click a
button that will never work.

---

## Provenance lines

Every data page carries one. This is what makes a figure checkable rather than assertable.

```
Data as of 2026-08-19 14:20 ET · Period Jul 2026 (closed)
Source: finance.gl_summary, snapshot 2026-08-05
Subscription revenue agrees to GL account 4100 · variance $0.00
```

- **Timezone always.** "14:20" is not a time.
- **Period status matters** — "(open)" tells the reader the number can still move.
- If a figure has been proven against a source, **say so and give the variance.** That single line
  changes how the number is received.

---

## Numbers in prose

- **Absolute alongside percentage**, always. "+340%" from 5 to 22 is noise.
- **Percentage points versus percent.** "NRR fell 4 points" and "NRR fell 4%" are different claims.
- **Name the comparison.** "Up 12%" — versus what? Prior month, prior year, plan, forecast?
- **Do not round in prose and show unrounded in the table**, or the reader will think one is wrong.

---

## Tooltips

Add information; never restate. If a bar is labelled "Professional fees $178K", the tooltip should
carry what the label cannot: exact value, comparison, share of total, transaction count.

Keep them short. A tooltip is a glance, not a paragraph.

---

## Disclosure in a finance UI

Some things must be said, and saying them plainly builds more trust than omitting them:

- **Suppressed cells**: mark them as suppressed, with the reason. A blank cell reads as zero.
  > `—` *fewer than 5 customers; suppressed*
- **Estimates and unaudited figures**: label them at the point of use, not in a footnote nobody
  reads.
- **Definition changes**: annotate the series where it changed. A smooth line across a definition
  change is a false continuity claim.
- **Benchmarks**: state the source, the vintage, and the stage they apply to. A mid-market benchmark
  shown against an early-stage company misleads even when the numbers are right.
- **Scope exclusions**: if intercompany, a subsidiary, or a period is excluded, the page says so
  near the number, not only in the appendix.

---

## Buttons and actions

- **Verb + object**: "Export 42 rows", not "Export". The scope is the useful part.
- **Confirmations name the consequence**: "Clear all filters — this resets the view" beats
  "Are you sure?".
- **Disabled controls explain themselves**, ideally in a tooltip on the control itself.
- Loading buttons state what is happening: "Exporting…" rather than a spinner alone.

---

## Voice

Plain, specific, unhedged. This audience reads financial documents all day and reacts badly to
padding.

| Avoid | Prefer |
|---|---|
| "Oops! Looks like there's nothing here 🤔" | "No transactions in this period." |
| "We're working on getting your data…" | "Loading July GL summary." |
| "Awesome! Export complete 🎉" | "Exported 42 rows." |
| "Please note that figures may vary" | "Figures are unaudited." |

No exclamation marks, no emoji in system messages, no apologising. State the fact.

---

## Related skills

- `app-interaction-patterns` — the state machine these words fill
- `chart-annotation` — captions, titles, and footnotes on charts
- `data-typography` — how numbers are set
- `ui-antipatterns` — false precision and hedged language

