# Microcopy — the words on the screen

Every string a person reads inside an application: labels, buttons, headings, stat cards, table headers, form help, empty, loading and error states, toasts, confirmations, tooltips, status chips, and the messages a server sends back for the interface to show. The package's voice pack (`data/voices/<id>.md`, named by the design.md's §9) sets the personality and tone map; this file sets the rules every voice obeys. **On a conflict, the voice wins on register and this file wins on mechanics** — a voice may be brisk or warm, but no voice puts a period on a button or an error code in a sentence.

Distilled from the Mailchimp Content Style Guide (styleguide.mailchimp.com, CC BY-NC 4.0: voice and tone, writing principles, grammar and mechanics, web elements, writing about people, accessibility, translation) and the documentation skill's style guide (noun-phrase labels, present tense, the stability test), adapted to operator interfaces.

## Principles

Every rule below follows from these; cite them by number when you record a copy decision.

1. **Clear before clever.** A string exists so a person can act. Personality is allowed only where it costs no clarity, and never in an error.
2. **The work, in the user's words — never the machine.** A string that would change when a table, route, service, error code, environment variable or function is renamed is mechanism leaking into the interface (the documentation skill's stability test, applied to the screen). "Check that the Worker is running" and "BAD_CREDENTIALS: …" are the code talking; "Couldn't reach the server. Retry in a moment." is the product talking.
3. **Labels name, actions command, messages explain.** The grammatical form is set by the element, never by taste: a label is a noun phrase with no verb and no pronoun; an action is an imperative verb with its object; a message is full sentences. Mixing them is the commonest source of copy that reads "weird".
4. **One concept, one word.** The product's glossary binds every surface: if the record is a *candidate* on one page it is never an *applicant*, *person* or *profile* on the next, and a status is spelled the same in the chip, the filter and the toast. Never vary a term for elegance.
5. **Present tense, current state.** Copy describes what is, now. No narration of change ("moved to", "now supports", "new!"), no temporal hedges ("currently", "for now", "still") unless the state genuinely waits on a known event, and no talk about the product's own progress.
6. **Tone follows the reader's state.** Voice is constant; tone dials with the situation (§ Tone map). Calm and specific when something fails, brief when something succeeds, plain when something is destroyed.
7. **Every message answers the next question.** What happened, why — when the reason is known and useful — and what to do now. An error with no way forward is unfinished.
8. **Short, never cryptic.** Cut every word that carries nothing ("successfully", "please note", "in order to"); keep the small words that carry grammar ("the", "to", "that"), because a fragment stripped of them is ambiguous and translates badly. Front-load the word the reader scans for.
9. **People are people.** Singular *they* for anyone whose pronouns are unknown; no disability idioms; no blame ("You entered an invalid date" → "Enter a date after today"); no hype, no exclamation in failure, no condescension.
10. **Readable without the screen.** Copy never depends on position or colour ("the button on the right", "the red items"); link text names its destination; a label stays visible — a placeholder is never the label.

## Elements

Each element has one grammatical form (principle 3). Sentence case everywhere — page titles, navigation, buttons and headings included — because one case scheme cannot drift and reads calmer in a dense interface; proper nouns and product names keep their own casing.

| Element | Form | Rules | ❌ → ✅ |
| --- | --- | --- | --- |
| Page title | Noun phrase | Names the place or the record; matches its navigation entry word for word | "Manage your jobs here" → "Jobs" |
| Section heading | Noun phrase | Names the contents; a question only when the section answers one the user asked | "Here's what needs you" → "Your queue" |
| Navigation item, tab | Noun | The place, not an action; plural for a collection; never "My …" beside "Your …" | "View reports" → "Reports" |
| Table column header | Noun phrase, 1–3 words | Units live in the header, never in every cell; no "#" or "No." for counts | "How long in stage (days)" → "Days in stage" |
| Stat card | Label + numeral + optional caption + optional action | The **label** names what is counted, scope and threshold included; the **value** is a numeral, and zero is `0`; the **caption** adds one fact the number cannot carry (the oldest item's age, a trend, a target) and never restates the value in words; the **action** is a verb and its destination | "0 · Screenings to review · Nothing waiting" → "Awaiting screening · 0"; "Waiting too long · In one stage 13 days or more" → "Stalled 14+ days · 3 · oldest 21 days" |
| Button, menu action | Verb + object | The specific verb ("Publish job", never "Submit" or "OK"); the confirm button repeats the trigger's verb; no end punctuation; an ellipsis only when the action opens a further step that asks for input | "Submit" → "Send offer"; "Yes" → "Delete 3 candidates" |
| Link | The destination or the action | Never "click here", never a bare "Learn more" without its object; the article stays outside the link | "Click here for the audit log" → "Open the audit log" |
| Form label | Noun phrase | Always visible; mark whichever of required/optional is the minority, the same way on every form | "Please enter your email" → "Email" |
| Help text | One sentence | Below the field; states format, limit or consequence — never repeats the label | "Your password" → "At least 12 characters" |
| Placeholder | An example value, or nothing | Never instructions, never the label | "Enter email here" → "name@company.com" |
| Inline validation | Instruction | At the field; says what to enter, not what was wrong | "Invalid email" → "Enter an email like name@company.com" |
| Error (banner, toast, page) | Title + sentence | Title: "Couldn't {verb} {object}"; body: the reason in the user's terms, then the next step; codes and stack detail only behind a details/copy affordance for support | "Error 500: INTERNAL" → "Couldn't save the job. Retry in a moment — your changes are still here." |
| Permission refusal | Title + sentence | Says what the person can't do and who can; never a lecture, never "Access denied" alone | "403 Forbidden" → "Only admins can change integrations. Ask an admin for access." |
| Empty state | Heading + one sentence + at most one action | Distinguish the three causes, each with its own copy: **first use** (what will appear and how to start), **filtered to nothing** (say so and offer to clear filters), **failed to load** (that is an error, not emptiness) | "No data" → "No candidates yet" / "Candidates appear here when someone applies or you add one." / [Add candidate] |
| Loading | Noun phrase, or nothing | Silent under a second; past that, name what is loading; never "Please wait" | "Please wait…" → "Loading candidates…" |
| Success toast | Past-tense statement | Names the object and the outcome; offers Undo where the action is reversible; no "successfully", no exclamation | "Job was successfully published!" → "Job published" |
| Confirmation dialog | Question title + consequence + verb buttons | Title names the action and its object; body states what is lost and whether it can be undone; buttons are the verb and "Cancel"; never "Are you sure?" | "Are you sure?" [Yes] [No] → "Delete 3 candidates?" / "Their applications and notes are deleted too. This can't be undone." / [Delete candidates] [Cancel] |
| Tooltip | One sentence or noun phrase | Supplementary only — nothing a person needs is hidden in it; describes what the control does | "Click to toggle" → "Collapse the sidebar" |
| Status chip, badge | 1–2 words | Adjective or past participle from the glossary's status vocabulary, identical wherever the status appears | "In Progress", "in-progress", "Ongoing" → "In progress" |
| Count and pagination | Numeral + noun | "12 candidates", "1–25 of 340"; singular and plural both handled | "Showing results: 12" → "12 candidates" |
| Notification, email from the product | Subject names the event | Who did what to which object; the body links straight to it | "Update" → "Priya submitted feedback on Ana Silva" |

## Mechanics

| Matter | Rule |
| --- | --- |
| Person | Sentences may address the user as "you". Labels contain no pronouns. The product refers to itself rarely; "we" only when a human team acts (support, review). A system failure is phrased as the event ("Couldn't send the invite"), never as "We encountered an error". |
| Contractions | In sentences, yes ("can't", "you'll") — they read human. Never in labels or buttons. |
| Numbers | Numerals always, 1–9 included. Thousands separators. Abbreviate (`1.2k`) only where space forces it, and never in a value someone acts on. Percent as `%`. Ranges with an en dash (`3–5 days`). Currency per locale; a code (`USD`) wherever more than one currency can appear. |
| Dates and times | Relative for the recent past ("5 min ago", "Yesterday"), absolute beyond a week ("12 Oct", the year added only when it differs from the current one). A time zone wherever two people could read the same time differently. The package's formatting foundations decide the exact shapes. |
| Punctuation | No end punctuation on labels, buttons, headings, chips or single-fragment tooltips; full sentences end with a period. Exclamation points never in errors or warnings and at most one, rarely, in success. Em dash: one per message at most, never as a joint between clauses. Oxford comma. Curly quotes. No ampersand unless it is part of a name. |
| Abbreviations | Spell out on first use unless universal to the audience (URL, PDF, ID, CSV). Internal acronyms and code names never appear. |
| Truncation | Truncate text at the end with the full value on hover; never truncate a number, a date or the distinguishing end of an identifier. |
| Inclusion | Singular *they*; neutral role nouns; age, disability and health only when relevant, and then person-first unless the person prefers otherwise; no idioms built on disability ("blind spot", "falls on deaf ears"). |
| Translation-ready | Subject–verb–object sentences, active voice; no idioms, slang or puns; repeat the noun rather than lean on an ambiguous "it"; no strings assembled from fragments, because word order differs by language; leave room for 30% longer text. |

### Word choices

Pick one of each pair for the whole product and never mix them.

| Use | Not | Because |
| --- | --- | --- |
| Sign in / sign out (verb), sign-in (noun) | log in, login, log on | One pair across every surface |
| Select, choose | click, tap | Device-neutral |
| Create (a new record) | add, make, new | *Add* is for attaching something that already exists |
| Add (attach existing) | create, assign | Keeps *create* meaning "new record" |
| Delete (destroys) | remove | *Remove* detaches and leaves the record; the two must never be swapped |
| Remove (detaches) | delete | As above |
| Archive (hides, reversible) | delete | Tells the person it can come back |
| Cancel (abandons an action) | close, dismiss | *Close* only dismisses something with nothing to lose |
| Save (keeps changes) | submit, apply | *Send*, *Publish*, *Invite* when the action reaches someone else |
| Set up (verb), setup (noun) | — | Verb and noun differ |
| Email | e-mail, E-mail | — |
| Can't, couldn't | unable to, failed to | Plain, human, shorter |

## Tone map

Voice holds; tone moves with the reader's state (principle 6). The voice pack's own tone map refines these defaults for its register.

| Situation | Reader's state | Tone | Pattern |
| --- | --- | --- | --- |
| Routine labels and actions | Focused, scanning | Neutral, brisk | Noun phrases and verbs; nothing extra |
| First use, empty | Orienting | Encouraging, factual | What appears here and the one way to start |
| Success | Satisfied, moving on | Brief | Past tense, object named, Undo if reversible |
| Error the person can fix | Mildly frustrated | Calm, specific | What to enter or change, at the place it applies |
| Failure that isn't theirs | Frustrated, blocked | Accountable, steady | What failed, that their work is safe if it is, what to do (retry, wait), no internals |
| Destructive confirmation | Cautious | Plain, explicit | The object, the loss, whether it can be undone — the plainness is the safeguard |
| Warning before a consequence | Attentive | Direct | The consequence first, then the choice |
| Permission refusal | Blocked, possibly annoyed | Respectful | What they can't do, who can, how to ask |
| Long wait | Uncertain | Reassuring | What is happening and, if known, how long |
| Milestone | Pleased | Warm, never hyped | One sentence of acknowledgement, no fanfare |

## The copy pass on an existing app

When the ask is to fix an app's wording, run this as the improve step's content scope (`existing-apps.md`). An explicit ask to correct the copy lifts the never-silently-change protection from navigation labels; legal copy stays protected unless the ask names it.

1. **Inventory by surface, rendered.** Read each surface's strings in the source and drive the surface, so conditional strings (empty, error, refused, loading) are seen as well as the happy path.
2. **Fix the glossary first.** List the domain nouns, the status vocabulary and the verbs the app uses; choose one word per concept (principle 4) and record the list in `product.md` under its vocabulary, where every later string is checked against it.
3. **Rewrite by element.** Take each string's element from § Elements and apply its form and rules; the server messages that reach the interface are in scope, because a person reads them.
4. **Keep the contract honest.** A test that asserts a string is updated with it — the copy is the promise it checks, so a changed string is an intended behaviour change, never a weakened test. A feature document that quotes promised wording is updated in the same change.
5. **Sweep for the tells** below before calling the pass done.

### Copy tells

Each is a near-certain defect; fix it or record why it stays.

| Tell | Principle |
| --- | --- |
| "Successfully", "Please", "Oops", "Uh oh", "Whoops" | 8, 1 |
| "Are you sure?", "Click here", a bare "Learn more", "Submit", "OK" as a confirm button | 3, 10 |
| "Invalid …", "Error:" as a prefix, an error code or an exception name inside a sentence | 2, 7 |
| An exclamation point in an error or a warning | 6 |
| Title Case On A Button Or Heading; a period on a label or button | Elements |
| "Currently", "for now", "new", "now supports", "has been moved" | 5 |
| A service, table, route, environment variable or library named in user-facing copy | 2 |
| Two words for one concept across surfaces, or one status spelled two ways | 4 |
| A stat caption that restates its value in words ("0 · Nothing waiting") | Elements |
| A placeholder doing a label's job; help text repeating its label | 10 |
| A sentence assembled from fragments joined at runtime | Mechanics |
