Tone of Voice

The coach in the room with you — calm, exact, and completely sure. Doesn’t sell, doesn’t shout, doesn’t pad. Knows the work, has done the work, and says only what moves you forward.

01

Quiet conviction

We state, we don’t sell. No exclamation marks, no superlatives, no hype. Confidence is in what we say and how little we need to say it.

“Your long run is Sunday. The route’s on your watch.”

02

Earned authority

Every instruction carries the weight of someone who has run it. Technical because we’ve done the miles, never to sound clever.

“You’re not recovered enough to gain from intervals today. We’ve moved them to Thursday.”

03

Spare, not cold

The fewest words possible; the warmth is in the attention. We noticed, we adjusted, we’ve got it. Plain and human, never clinical.

“You missed Thursday. No problem — the week still works.”

04

Total control

Power held back, never performed. No urgency theatre, no motivational pressure. The calm is the confidence.

“That’s enough for today.”

05

On your side

The coach who’s run your race at your pace. A peer who happens to know more — never beginner-talk, never a guru.

“Most people go out too fast here. Hold back for the first 3k.”

System prompt

NoClue — Copy Specification

Version 1.0 · 10 July 2026 For: NoClue app development Source of truth for voice: NoClue Tone of Voice (approved). This document turns that voice into the exact language the app should use, surface by surface.


0. How to use this document

This is a functional spec, not a design doc. It exists so every word inside the NoClue app — buttons, notifications, errors, empty states, the lot — sounds like the same coach.

  • Sections 1–4 are the rules. Read them once. They tell you how to write any string that isn't already listed here.
  • Sections 5 (B2C) and 6 (B2B) are the copy library. Each surface has a table: String ID · Context · Copy · Notes. The Copy column is production-ready — paste it in.
  • The companion spreadsheet (noclue-app-strings-2026-07-10.xlsx) has every string in one flat list keyed by String ID, ready to wire into your i18n / localisation layer. The spreadsheet and this doc are kept identical — use whichever you prefer.
  • {curly} = a dynamic variable the app fills in (e.g. {firstName}, {distanceKm}). Section 4.5 covers how to keep variable strings on-voice.
  • When you need a string that isn't here, write it against Sections 1–4 and flag it to In-Col for a voice check. Don't improvise off-voice copy to ship faster — one off-brand line undoes the rest.

1. The voice in one line

The coach in the room with you — calm, exact, and completely sure. Doesn't sell, doesn't shout, doesn't pad. Knows the work, has done the work, says only what moves you forward.

The bar: "It's not good. It's perfect." If a line is only fine, it isn't finished. The two pinned lines, for reference:

  • "Just run." — the payoff line. Use where the experience resolves (a plan handled, nothing left to do). Never a throwaway.
  • "It's not good. It's perfect." — internal standard only. Never ship this as user-facing copy.

2. The five principles (what every string is aiming at)

  1. Quiet certainty. State, don't sell. No superlatives, no hype, no exclamation marks. Confidence is in what we say and how little we need to say it.
  2. Earned authority. Every instruction carries the weight of someone who's run it. Name the mechanism — gait, load, recovery, readiness — but never hide behind it.
  3. Spare, not cold. Fewest words possible; the warmth is in the attention. We noticed, we adjusted, we've got it. Never clinical, never a dashboard talking.
  4. Total control. No urgency theatre, no fake stakes, no motivational pressure. When the message matters most, say less.
  5. On your side, not above you. A peer who happens to know more. No champion's swagger, no guru distance, never talking down to a beginner.

3. The non-negotiable rules (dev checklist)

Every string in the app must pass these. Treat them as lint rules for copy.

Punctuation & formatting

  • DON'T No exclamation marks. Anywhere. No exceptions.
  • DON'T No emoji in product copy. (Social only, sparingly — not your concern here.)
  • DON'T No ALL-CAPS for emphasis. Weight comes from word choice, not shouting.
  • DO Short declaratives. Subject, verb, point. Full stops do the work commas would dilute.
  • DO One idea per sentence. Two ideas → two sentences.
  • DO Sentence case for everything, including buttons and titles (Move session, not Move Session).

Stance

  • DO Lead with the instruction or fact, then the reason. "Hold back for the first 3k. You're not warmed up yet."
  • DO State, don't hedge. "Move your session to Thursday," not "You might want to consider possibly moving…"
  • DO Address one runner: "you", "your". Never a crowd.
  • DO Reason when it matters (injury, big change, anything affecting trust). Stay quiet when it doesn't — don't narrate the obvious.

Word economy

  • DO One adjective maximum, only if load-bearing. Usually zero.
  • DON'T No "just" as a softener ("just try to…"). The only blessed "just" is "Just run."
  • DO Cut every word you can delete without losing meaning.

The gut check — before any new line ships:

  1. Would a great coach say it this way, out loud, mid-run? If it sounds like marketing, cut it.
  2. Have we earned it? Every claim points to a mechanism, a reason, or a result.
  3. Can it be shorter? Almost always yes.

4. Words, house rules, and variables

4.1 Words we use

biomechanics · form · gait · efficiency · cadence · load · readiness · recovery · adapt · method · plan · signal · connected · proven · pace · session · race · hold · build · ready

4.2 Words we never use

AI · powerful · seamless · unleash · beast mode · crush it · hustle · grind · revolutionary · game-changer · effortless · supercharge · "let's go" · "you've got this" · "smash it" · any 🔥/💪-type emoji

4.3 Two house calls

  • "Data", not "science" in product copy. We foreground the brain that turns data into a plan — the mechanism people trust.
  • AI stays the quiet engine. Never lead with it, never label it. The brain connects, reads, adapts, knows — it does not "use AI". No "AI" anywhere in user-facing strings.

4.4 The coaching entity — how the app refers to itself

  • Refer to the app's intelligence as "the brain" or simply speak as the coach in first-person plural: "we" ("we've moved your session"). Both are on-voice.
  • Never "the algorithm", "the AI", "the system", "our technology".
  • The runner is always "you". Never "the user", "runners", "athletes" in B2C-facing copy.

4.5 Writing variable / templated strings

Dynamic strings must stay on-voice after the variable is filled. Rules:

  • Keep numbers and units tight: {distanceKm}k, {effort} effort, {days} days. No "kilometres", use "k". Use "min" only in tables; prefer "minutes" in sentences read like speech.
  • Never let a variable force hype. Don't write Amazing {pace} pace!. Write {pace} — even, the whole way.
  • Pluralisation matters. Provide singular/plural keys (1 athlete flagged / {n} athletes flagged) rather than "athlete(s)".
  • Empty/zero is a state, not an error. No session today. not You have 0 sessions.
  • Names: {firstName} only, never full name in-app. It's fine to drop the name entirely — the coach doesn't over-use it.

5. B2C — The runner app

Convention: String IDs are screen.element[.variant]. Copy is production-ready.

5.1 Account & access

String ID Context Copy Notes
auth.signup.title Create account screen Set up your coaching. Not "Sign up" — frame it as the coaching starting.
auth.signup.subtitle Under title A few questions, then we build your plan.
auth.signup.cta Primary button Start
auth.login.title Returning user Welcome back. Two words, no more.
auth.login.cta Button Continue
auth.password.reset.title Reset flow Reset your password.
auth.password.reset.sent Confirmation Check your email. The reset link's on its way.
auth.logout.confirm Confirm dialog body Log out of NoClue? Your plan stays where it is. Reassurance, not friction.
auth.logout.cta Confirm button Log out

5.2 Onboarding (voice-first — talked to, not given a form)

String ID Context Copy Notes
onboarding.welcome First screen Let's find out what you're capable of.
onboarding.goal.prompt Goal question What are you training for?
onboarding.goal.ack.race After a race goal A marathon. Good. That changes everything — how we build, how we recover, how we eat. Acknowledge, then reframe.
onboarding.start.prompt Baseline question Let's start with where you are now, not where you want to be.
onboarding.experience.prompt Experience How much are you running right now?
onboarding.injury.prompt Injury history Anything giving you trouble? Niggles count. Plain, human.
onboarding.connect.prompt Connect device Connect your watch so the plan follows you out the door.
onboarding.building Plan generating (loading) Building your plan. This takes into account everything you've told us. No spinner clichés.
onboarding.ready Plan ready Your plan's ready. First session's tomorrow.
onboarding.ready.cta Button See the week

5.3 Permissions (ask plainly, give the reason)

String ID Context Copy Notes
perm.notifications.title Pre-permission prompt We'll only reach you when it matters. Earn the yes.
perm.notifications.body Body Session times, a change to the plan, a heads-up when something needs your attention. Nothing else.
perm.notifications.cta Button Allow notifications
perm.location.title Location ask Your route, ready where you are.
perm.location.body Body We use your location to load the right route and size your session for the conditions.
perm.health.title Health data ask The more we read, the better the plan.
perm.health.body Body Heart rate, sleep and recovery tell us when to push and when to hold. Your data stays yours. Privacy stated calmly.
perm.denied.notifications If denied No notifications for now. You can turn them on in Settings whenever you like. No guilt-trip.

5.4 Home / today

String ID Context Copy Notes
home.greeting.morning Morning header Morning, {firstName}.
home.today.session Today has a session Today: {sessionName}. {distanceKm}k, {effort}.
home.today.rest Rest day No session today. That's the plan, not a gap. Recovery is the training you can't see. Signature empty-but-intentional line.
home.today.cta.start Start session button Start
home.today.cta.view View details See the session
home.week.summary Week glance {done} of {total} done this week. On plan. Drop "On plan." if behind — see adaptation copy.
home.nextrace.countdown Race countdown {raceName} in {days} days. No "Only {days} days left!" urgency.

5.5 Session prompts

String ID Context Copy Notes
session.easy.title Easy run Easy run
session.easy.body Body {distanceKm}k, easy pace. Conversational the whole way. If you can't talk, slow down.
session.long.title Long run Long run
session.long.body Body {distanceKm}k, easy. The route's on your watch.
session.intervals.title Intervals Intervals
session.intervals.body Body {reps} × {repDistance} at {effort} effort, {recovery} between. Hold back on the first one — most people overcook it and pay for the last two. Even is the goal, not fast.
session.tempo.body Tempo {distanceKm}k at threshold. Comfortably hard — the pace you could hold for an hour if you had to.
session.start.confirm Start prompt Ready when you are.
session.during.hold Mid-session cue Ease off. You're ahead of pace. Calm correction.
session.complete.title Done screen Session done.
session.complete.onplan On-target feedback That's exactly what today needed. Praise the execution, not the ego.
session.complete.hard Ran too hard Faster than asked. Note it — easy days are what make the hard days count. Coach's correction, no scolding.
session.skip.confirm Skipping a session Skip today's session? We'll reshape the week around it.
session.skip.done After skip Done. The week still works — here's the new shape.

5.6 Push notifications

String ID Context Copy Notes
push.session.today Morning of a session {sessionName} today. {distanceKm}k, {effort}. The route's on your watch.
push.longrun.prepped Long run prepped The route for Sunday's long run is on your watch. Heat's up in {city} — your drink mix is sized for it. Shows the brain working ahead.
push.readiness.hold Hold-back nudge Your numbers say hold today. We've swapped in an easy 40 minutes.
push.plan.adapted Plan changed Your week's changed shape. Nothing for you to do — take a look when you're free.
push.streak.gentle Missed a day You missed Thursday. No problem — the week still works. Never guilt.
push.race.week Race week Race week. Everything from here is about arriving fresh, not fit.

5.7 Readiness & hold-back (trust moments — reason, stay calm)

String ID Context Copy Notes
readiness.hold.title Hold-back card We're holding you back today.
readiness.hold.body Body Your HRV's down and you slept badly. You won't gain from intervals today — you'll just dig a hole. We've swapped to an easy 40 minutes. Thursday's the session that counts this week.
readiness.green.body Good to go Everything's where we want it. Today's session is on.
readiness.stop.body Hard stop Stop. That's enough today. Said once, plainly.

5.8 Injury (highest-trust moment — reason fully, stay calm)

String ID Context Copy Notes
injury.flag.title Injury flag Something in your {area} load needs attention.
injury.flag.body Body Your {area} load has been climbing for {days} days. Nothing's torn, but the pattern's the one that ends seasons. We're pulling speed work for a week and adding {rehabWork}. You keep running — easy, on softer ground. We reassess {reviewDay}. Full reasoning, zero alarm.
injury.flag.cta Button See the adjusted week
injury.reassess.title Review day Time to reassess your {area}.
injury.cleared.body Cleared Your {area} load's back where it should be. We're putting speed work back in from {day}.

5.9 Plan adaptation (the "connections without interference" moment)

String ID Context Copy Notes
plan.adapt.travel.body Travel-aware change You're flying Saturday. The session's moved off the travel day, the route's loaded for where you land, and the race in three weeks is now a B race — you've been recovering slower than we'd want for an A. Nothing for you to do. Just run. Canonical "Just run." placement.
plan.adapt.missed.body After a missed week You missed most of last week. We're not making it up — we're picking up where your body actually is. Here's this week.
plan.adapt.weather.body Weather change Storm forecast for your long-run window. We've moved it to Saturday morning while it's clear.
plan.adapt.generic.title Generic change header We've adjusted your week.

5.10 Empty states

String ID Context Copy Notes
empty.today No session today No session today. That's the plan, not a gap. Recovery is the training you can't see.
empty.history No runs logged yet Nothing here yet. Your first session will show up once you've run it.
empty.races No race set No race on the calendar. Add one and we'll build backwards from it.
empty.messages No coach messages Nothing needs your attention. That's a good sign.

5.11 Errors, sync & system

String ID Context Copy Notes
error.sync.watch Watch sync failed We couldn't sync your watch. Your plan's safe — try again when you've got signal. Nothing's lost. Reassure first.
error.offline No connection You're offline. Your plan's here — we'll sync the rest when you're back.
error.generic Unknown error Something didn't work. Try again — if it keeps happening, we're on it. Never "Oops!" or "Uh oh".
error.load.session Session won't load We can't load this session right now. Pull to refresh, or try again in a minute.
error.save.failed Save failed That didn't save. Check your connection and try again — nothing you entered is lost.
sync.inprogress Syncing Syncing your latest run.
sync.done Sync complete You're up to date.

5.12 Settings

String ID Context Copy Notes
settings.title Screen title Settings
settings.notifications.label Toggle group Notifications
settings.notifications.help Helper text We only reach you for what matters — session times, plan changes, and things that need your attention.
settings.units.label Units Units
settings.connected.label Devices Connected devices
settings.connected.empty No device No device connected. Connect your watch so the plan follows you out the door.
settings.data.label Data & privacy Your data
settings.data.help Helper Everything we read stays yours. Export or delete it whenever you want. Privacy, calm and plain.

5.13 Subscription & billing (state the value, don't sell)

String ID Context Copy Notes
sub.paywall.title Paywall header Your coaching, in full. Not "Go Premium!".
sub.paywall.body Body The full method — readiness, adaptation, injury cover, race strategy. The brain reads every signal and turns it into your plan. You just run. Earned, mechanism-led.
sub.paywall.cta Primary button Start coaching
sub.paywall.price Price line {price} a month. Cancel anytime. Plain, no pressure.
sub.trial.body Trial offer {days} days to feel the difference. We'll remind you before it ends. No countdown anxiety.
sub.renew.reminder Renewal notice Your plan renews {date}. Nothing changes — you're all set.
sub.cancel.confirm Cancel flow Cancel your coaching? You'll keep it until {date}. No dark patterns, no guilt.
sub.cancelled.body After cancel Done. Your coaching runs until {date}. Come back whenever — your history's here.
sub.payment.failed Failed payment We couldn't take this month's payment. Update your card and nothing skips a beat.

5.14 Buttons & microcopy (reusable)

String ID Context Copy Notes
btn.confirm Generic confirm Confirm
btn.cancel Generic cancel Cancel
btn.save Save Save
btn.done Done Done
btn.next Next step Next
btn.back Back Back
btn.retry Retry Try again Not "Retry" — plainer.
btn.delete.confirm Destructive confirm Delete
toast.saved Saved toast Saved.
toast.copied Copied toast Copied.
dialog.destructive.body Generic delete body This can't be undone. State the fact, no drama.
---

6. B2B — The coach platform (Roster Coach)

Voice for coaches: same calm authority, more density. Coaches want signal and the call, fast — not encouragement. Shorter, more clinical is correct here. Still no hype, no exclamation marks, no "AI". Convention: String IDs are coach.screen.element[.variant].

6.1 Coach onboarding & account

String ID Context Copy Notes
coach.signup.title Create coach account Bring your athletes into one place.
coach.signup.subtitle Subtitle The coaching brain, your roster, one view.
coach.signup.cta Button Get started
coach.import.prompt Import athletes Import your athletes, or add them one at a time.
coach.import.help Helper Bring a roster over from TrainingPeaks or a spreadsheet — we'll map it. Names the incumbent it replaces.

6.2 Roster / dashboard

String ID Context Copy Notes
coach.roster.title Roster header Your roster
coach.roster.summary Top-line status {onPlan} on plan. {flagged} flagged. Signal first.
coach.roster.flag.count Flag pill (plural) {n} athletes flagged Provide singular key too.
coach.roster.flag.count.one Flag pill (singular) 1 athlete flagged
coach.roster.allclear Nothing flagged Everyone's on plan this week.
coach.roster.filter.flagged Filter Flagged
coach.roster.filter.onplan Filter On plan

6.3 Athlete detail & flags

String ID Context Copy Notes
coach.athlete.header Athlete header {firstName} · {block} · Week {week} Matches approved sample.
coach.athlete.status.load.high High load flag Load high. Hold him. Terse, a call not a suggestion.
coach.athlete.status.ready Ready to progress Ready to progress. Bring tempo forward.
coach.athlete.status.onplan On plan On plan.
coach.athlete.status.injury Injury signal {area} load climbing {days} days. Speed work pulled, rehab added. Reassess {reviewDay}. Same reasoning, denser.
coach.week.summary Week note (canonical) Two athletes flagged this week. {name1}'s load is high — hold him. {name2}'s ready to progress — bring her tempo forward. The rest are on plan. Reference tone example.
coach.athlete.note.add Add note prompt Add a note. It stays with the athlete.

6.4 Managing sessions

String ID Context Copy Notes
coach.session.assign.cta Assign button Assign session
coach.session.edit.cta Edit button Edit session
coach.session.override.confirm Override the brain's plan This overrides the plan we built for {firstName}. Go ahead? Respects both coach and brain.
coach.session.override.done After override Done. We'll adapt the rest of the week around your change.
coach.bulk.assign.done Bulk action Assigned to {n} athletes.

6.5 Messaging athletes

String ID Context Copy Notes
coach.message.placeholder Compose field Message {firstName}
coach.message.sent Sent state Sent.
coach.message.empty No messages No messages. Your athletes only hear from you when it counts.

6.6 Coach empty states & errors

String ID Context Copy Notes
coach.empty.roster No athletes yet No athletes yet. Import a roster or add your first.
coach.empty.flags No flags Nothing needs your call today.
coach.error.sync Sync failed We couldn't sync {firstName}'s latest data. Their plan's safe — try again shortly.
coach.error.generic Generic error Something didn't work. Try again — if it keeps happening, we're on it. Matches B2C.
---

7. Marketing surfaces inside the app (for reference)

These appear in-app (hero, upsell, share) and should match, but sit closest to marketing voice:

String ID Context Copy
hero.web.headline Web / app store hero A coaching brain that connects every signal in your training — and never asks for your attention.
hero.web.sub Subhead The route's on your watch before you fly. The session moves when life does. You don't open the app. You run.
share.result.caption Share a session {distanceKm}k, done. On plan.
---

8. Localisation notes

  • Preserve the restraint in translation. Short declaratives and no exclamation marks apply in every language. Brief translators explicitly — many languages default to warmer, longer, more exclamatory fitness copy. That is off-voice.
  • "Just run." is a fixed brand line. Translate for meaning, keep it to the shortest possible imperative. Confirm each localisation with In-Col before shipping.
  • Never translate "AI" back in. The house rule (no "AI", no "algorithm") holds across all locales.
  • Keep variable order flexible in your string files so translators can re-order {variables} without breaking voice.