About brand-voice
A super-ux skill for defining and maintaining a product’s verbal identity, with ownership of `docs/brand/`. It derives voice guidance from UX foundations and uses structured records and validation to check coverage and consistency.
Key features
- 01Initializes brand documents and voice guidance
- 02Calibrates terminology, facts, and channel rules
- 03Updates positioning changes across text
- 04Checks coverage, consistency, and staleness
- 05Follows the brand document contract and statuses
Use cases
- 01Establish voice guidance for a new product
- 02Update brand records after positioning changes
- 03Check copy consistency across channels before launch
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ ssheleg/ super-ux --skill brand-voiceAfter installing, type/brand-voicein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/ai-tells.mdbrand-contract.mdchannel-playbooks.mdhooks.mdlocalization.mdmarketing-copy.mdresearch-outliers.mdseo-aeo-safety.mdstore-copy.mdsurface-registers.mdsystem-map.mdvideo-script.mdvoice-packs.mdtemplates/brand/channels.mdcopy-brief.mdfacts.mdlocale.mdREADME.mdstrings.mdterminology.mdvoice.mdDetails
From the project READMEbrand-voice — define and hold the verbal identity
Part of super-ux — see system-map.md for the whole pipeline. After changes, run
python3 docs/brand/lint.py.
docs/ux/ decides what the product does. This skill decides how it
speaks, and owns docs/brand/ in the target project.
Format contract: brand-contract.md
(brand-contract v1). Read it before writing or editing anything under
docs/brand/. Never deviate from its file names, field names or statuses —
the linter and the audit key off them.
The pack library: voice-packs.md — six archetypes, each with a declared failure mode. The register model: surface-registers.md. Locales: localization.md.
Triggers
The phrases that route to this skill, in English and Russian. The description keeps only the strongest of them so the skill listing stays inside its budget (2026-10-20); the family routing hook matches this list.
"tone of voice" / "тон оф войс", "brand voice" / "голос бренда", "brandbook" / "брендбук", "our terminology" / "наша терминология", "how should this sound" / "как это должно звучать", "the copy is inconsistent" / "текстовка разная везде", starting any marketing surface, onboarding a product into docs/brand/.
Invoked with no task → status, then one next action
- Report the state: is a pack recorded, what
voice.mdsays itsStatusis, how many facts carry⚠ TBDor no source, locale parity, and the linter's error and warning counts. - Name every unresolved fact. Never invent one to close a gap — an unknown is reported, not filled.
- Propose exactly one next action, usually the top open fact or the surface the user actually came for.
Where the voice comes from
The pack is derived from docs/ux/foundation.md — personas, jobs, and the
deciding input: what the user loses when the product fails. A voice that
charms when the stakes are a playlist is intolerable when the stakes are
payroll.
The dependency runs one way. A persona never changes because a tone was
appealing. With no foundation, work in degraded mode: stamp
Derived-from: inferred, say plainly that the WHY layer should be built, and
continue rather than blocking.
The route itself has a spoken opt-out: an operator saying "no brand" / «без бренда» declines it — proceed without the pack and say so, rather than dropping it silently.
Choosing a workflow
| Situation | Workflow |
|---|---|
No docs/brand/ | Init |
| Pack chosen, product specifics missing | Calibrate |
| Positioning, personas or facts changed | Update |
| Consistency questioned, or before a launch | Validate |
Announce which one you are running.
Init
- Read the foundation. Personas, JTBD, journeys, stakes. Where it is absent, interview: who is this for, what are they accountable for, what does failure cost them.
- Read what already exists. Interface strings, landing copy, README, store listing, recent posts. The current voice is data even when nobody chose it.
- Propose one pack with reasoning, plus one alternative. Name why the runner-up loses. Let the user pick.
- Seed
docs/brand/from this skill's owntemplates/brand/, and fill theSources:block first — nothing else can be checked until the linter knows where the project keeps its text. - Inventory sweep for
strings.md: routes, screens, buttons, states, errors, empty states. Every string gets a row with itsfile:lineand the scenario it serves. For a large codebase, use available read-only subagents in parallel, one area each; without delegation, inspect the same areas sequentially and keep the same evidence requirements. - Ask which humanization pass this project wants, and write the answer to
voice.md'sHumanization pass:field.ownis the default and the only one that reads this pack's registers and facts;npx sshlg-skills humanizersshows what else is installed and how to install what is not. Ask once — the field exists so nobody is asked twice, and it selects a pass, never a verdict. - Everything starts
Status: draft.
Calibrate
The pack is a starting position; this is where it becomes the product's own.
- Terminology. Which generic words does this product replace, and with what. Seed the banned table from weak verbs, hedging chains and ai-tells.md, then add what is specific here.
- Facts. Every number the product quotes, with a source, a checked date
and a review date. Mark internal figures
Public: no. - Channels. One record per surface the product actually has. Register as
deltas;
Forbidden:always carries both the physics and the brand half. - Ready lines. Six to ten, written for this product, not copied from the pack.
- Failure mode. Copy the pack's into
voice.mdso the audit can look for it by name. - The em dash invariant. Seed
voice.md's invariants with "no em dash (U+2014) in new text, in any language" (owner decision, 2026-10-18). It is not a voice choice a pack can relax: every pack inherits it, and only the grammatical Russian dash where no rewrite reads naturally survives (ai-tells.md AT-06,B062,B067).
Present section by section for approval. Approved moves draft →
validated.
Update
- Identify what changed — positioning, a persona, a price, a tier name, a new surface.
- Apply the edits. A changed entity name propagates to
terminology.md,strings.mdand every locale in the same change. - Changed files drop to
Status: draftuntil re-approved. - Re-stamp
Last calibrated.
Validate
- Integrity — every field the contract requires is present; statuses are
legal;
Derived-fromresolves against the foundation. - Coverage — every surface the product ships has a record; every locale declared has a file; every quoted number has a fact.
- Consistency — run
python3 docs/brand/lint.pyand fold its findings in. It proves the mechanical half; report what it cannot see as questions for/ux-audit copy. - Staleness — foundation newer than the last calibration, facts past review, physics rules past their checked date.
Definition of done
- Contract honored; the marker on every file.
- The user has seen and approved new or changed sections.
python3 docs/brand/lint.pyexits 0, or every remaining finding is reported with a reason.- Unknowns stated as unknowns. Nothing invented to make a table look full.
What else is in references/. This skill names 6 contract(s) directly; references/ holds 13, because a contract this skill names links others and the whole closure ships inside the skill — the skills CLI installs one directory and a sibling's file would arrive dangling. Open the ones named here; the rest are reached from them, by name, when a contract sends you.