Browse all of Kata

Content format

Source docs/design/foundations/content-format.mdMarkdown

On this page

Dates, numbers, names, counts, and what happens when something does not fit.

Part of the Konjo design language. The laws in the spine apply here unless this chapter contradicts them.

Formatting decisions get made per-screen by whoever is building it, and that is how one app ends up showing "2 days ago", "Aug 20", "20/08/2026" and "2026-08-20T14:00:00Z" on four adjacent surfaces. These are settled here so they stop being decisions.

Dates and times

Choose by how the person will use the fact.

Situation Format Example
Something upcoming, within a week Weekday and time Thu 6:30pm
Something upcoming, further out Date and time Sep 4, 6:30pm
Something upcoming with no time of day Date alone, no filler Sep 4
Something that just happened, under an hour Relative 12 min ago
Something that happened today or yesterday Named day and time Yesterday 7:15pm
Something older Absolute date Aug 20
Older than the current year Date with year Aug 20, 2025

A date with no time is written as a date, never padded to look like one. A birthday, a test date, a due date, a trial expiry — none of these has a clock, and every "upcoming" row above carried one until round 8 needed four date-only fields on one screen. Never write Sep 4, 12:00am, Sep 4 (all day), or Sep 4 —.

  • Relative time stops at "yesterday". "23 days ago" makes a person do arithmetic to recover a date they could have just been shown.
  • Never both. "Aug 20 (2 days ago)" is two answers to one question.
  • Times are local to the reader and lowercase — 6:30pm, not 6:30 PM or 18:30.
  • A range collapses what repeats: Thu 6:30–7:30pm, Sep 4–6.
  • Absolute, always, for anything with consequence. A waiver signature, a promotion date, a payment — those show the full date including the year, Aug 22, 2026, even in the current year. The table above drops the year for ordinary dates because the reader supplies it from context; a record is read later, out of context, sometimes years later, and a date without a year stops being a record.

Numbers

  • Counts are plain integers up to 999, then abbreviated: 1.2k, 14k.
  • A badge count caps at 99+. The exact number stopped mattering long before that, and the dot has a fixed size.
  • Money always shows currency and two decimals: $45.00, never $45. A price that changes shape between rows is a price people distrust.
  • Percentages are whole numbers unless the fraction is the point. 73%, not 73.2%.
  • A percent delta needs a base of at least 10 (ten dollars, for money). Off a smaller base one unit of movement swings the figure by double digits — “+3100% vs 1” reads as a bug, not a trend. Show the absolute change instead: “+31 vs 1”. In code: formatYoyDelta in Studio's homeDashboard.ts.
  • Zero is written, not hidden. "0 students" beats an empty cell, which reads as a bug.
  • Never a decimal on something uncountable. "4.5 classes" is not a thing.

Durations

Time at something, as opposed to time since something.

  • Months up to two years, then years and months: 14 months, 2 years 3 months, 5 years. Never 1.2 years, never 427 days.
  • Under a month, use weeks: 3 weeks. Under a week, the app almost never needs a duration — use a date. If what you actually want is how long has this been sitting, that is dwell, not a duration, and it has its own rules.
  • Round down, never up. Someone at a rank for 13 months and 29 days has been there 13 months; rounding up overstates a fact people care about.
  • Unknown is a legitimate value and is rendered as such, not as zero. A student who trained elsewhere before joining has an unknown time at rank, and Unknown is the honest answer — this is the case content missing exists for.

Dwell — how long this has been sitting

A third kind of time, and the one every queue in Studio needs: leads, dunning, sub requests, the at-risk list, the waiver chase. Not time at something (a duration — an achievement) and not time since an event (relative time — which stops at "yesterday"). Dwell is a debt: how long a thing has been waiting for a person to act on it.

  • Always days, plainly. Today · 1 day · 13 days · 47 days · 90+ days.
  • Never weeks or months. Applying the duration rules above to a dwell renders a 13-day stall as "1 week" — because durations round down — which understates exactly the fact the screen exists to surface. A duration rounds down because overstating time-at-rank flatters someone; a dwell must never round down, because understating a stall hides work.
  • Never relative phrasing. "13 days ago" makes a person do arithmetic (see above); "13 days" is the answer they wanted.
  • One format at every age, so a column of them sorts by eye. A format that changes shape at day 7 makes the column unscannable, which is the one thing it is for.
  • Cap the display, not the value. Past 90 days write 90+ days and keep sorting on the real number.
  • Dwell is never a colour on its own. Whether a number of days is a warning is an SLA question, which is a product fact, not a palette one.

Pluralisation

Write both forms; never student(s), never 1 students. For zero, prefer words over the digit where the sentence allows: "No classes this week" beats "0 classes this week" in prose, while a stat tile keeps the numeral.

Names and people

  • A person is their full name the first time and in any list. Not "A. Torres", not a username.
  • Initials are two characters, first and last. One name gives one initial.
  • Never truncate a name mid-word. If it does not fit, the layout is wrong — a name is the one string a person will always notice being mangled.
  • Honorifics come from the art: sensei, sifu, and whatever the dojo's style uses. Konjo is multi-style; do not hardcode one tradition's title into a shared component. See rank.

Truncation

Truncation is not a layout strategy. It is what happens when a layout already failed.

  • Never truncate: a person's name, a belt rank, an error message, a price, a date, a primary action's label.
  • May truncate at two lines: a post body, a description, a note — with the full text one tap away.
  • May truncate at one line: a secondary metadata line where the leading words carry the meaning.
  • If it does not fit, it reflows. A title wraps to three lines and then steps down a type size; it does not get an ellipsis.
  • Ellipsis at the end, never the middle, except for a filename where the extension is the useful part.

Combined with text scaling: whatever you test at 100%, retest at 200%, where every one of these gets harder. See accessibility.

Empty and unknown

  • Missing optional data shows nothing — no "—", no "N/A", no empty label. The row is shorter.
  • Missing required data is an error, not a dash. If a class has no time, that is a bug the screen should surface, not smooth over.
  • "Unknown" is only correct when unknown-ness is the fact — an unrecognised belt from a visiting student, for instance.

Lists of things

  • Two items join with "and": Kata and Footwork. Three or more use commas with a final "and".
  • Long lists cut at three and count the rest: Ana, Marcus, Priya and 4 others.
  • Order by what the reader is looking for — soonest first for events, most recent first for a feed, alphabetical only when there is no better answer.