Typographic principles
Three principles that guide every type choice in the system.
Principle 01
Optimize for readability
Body copy is set at 16 px with generous leading. Cap line length at ~70 characters. Use heading levels for structure, never bold weight as a stand-in.
Principle 02
Create visual harmony
One scale across the whole product. Tailwind defaults — text-base, text-2xl, text-xl — keep prototypes consistent without per-page tuning.
Principle 03
Match the surface
Branding surfaces lean on Founders Grotesk. Product surfaces lean on Inter Tight. Data surfaces lean on Martian Mono. The right family for the right job, never mixed.
Brand fonts
Brand typography is for marketing and brand-leaning surfaces — the docs hero, login, the Flatpay homepage. It exists to signal identity in the rare moments a user is meeting the brand, not the product.
Founders Grotesk X Condensed
Money in.
Stress out.
Klim Type Foundry. Bold weight only. Always set in ALL CAPS. Reserved for one H1 per surface — never for body, eyebrows, or anything readers spend more than a beat on.
UI fonts
UI typography is for the product. It carries body, headings, labels, navigation, and the dense data views where readability and consistency matter more than identity.
Inter Tight
Type that gets out of the way.
Variable weight 100–900. The default for everything that isn't a brand H1 or code: H2, H3, page H1s in product UI, body, eyebrows, navigation, form labels, table headings.
Martian Mono
2.055,00 kr
Variable weight + width. Code, repo paths, model identifiers, command snippets, and tabular data. Tabular numerals are wired in by default via the .font-mono selector.
Headings
Page H1s set the stage. They're the only place Founders Grotesk appears at full size — Bold, ALL CAPS, on a line of its own. Every heading below an H1 is Inter Tight: a level-by-level descent in size, no shouting required.
Balance
Overview of your currently available banking balance
H1 — Founders, ALL CAPS
Transfers
All sub-headings, including section titles inside a page, use Inter Tight Semibold. Sentence case, never ALL CAPS.
H2 — Inter Tight, sentence case
Body copy
Inter Tight at text-base (16 px) for prose, text-sm (14 px) for dense product UI. Generous leading (1.625) makes paragraphs scan; cap line length around 65–75 characters.
Running a business isn't easy. But with Flatpay, at least it's easy getting paid. Simple rates and no hidden fees, with daily payouts straight to your bank.
Secondary text uses the same family at a smaller size and reduced contrast — for descriptions, captions, and the explanatory text that sits below a heading.
Text colour
Primary text colour is the default for almost all text. Reach for it first; switch only when the text is genuinely supporting another element. Hierarchy is built from weight, size, and position — not from greying content out.
Primary
Aa — text-foreground
The default. Body copy, headings, list-row labels, button text, menu items, nav, TOC entries, table cells. If the text is the main thing on its row, it’s primary.
Secondary
Aa — text-muted-foreground
Supporting text only. The description below a heading, the caption below an image, the meta line below a row label. Always paired with a primary element directly above or beside it.
Disabled / muted
Aa — text-foreground/35
Disabled controls and placeholder text. Carries reduced contrast by design — not an option for content the user is meant to read.
Interactive UI rule
Anything the user clicks, taps, focuses, or navigates with — buttons, menu items, nav rows, tabs, links inside chrome, TOC entries — sets text in primary colour at 16 px or larger (text-baseminimum). Don’t muted-grey an interactive label to make it feel quieter; a quiet interactive element is a missed affordance and an accessibility regression. If a control needs to recede, lighten the background or drop the border — keep the type sharp.
Do
- Overview
- Variants
- Anatomy
- Accessibility
Every TOC entry is primary colour at 16 px. Active distinguishes itself with semibold + the 1 px bar.
Don’t
- Overview
- Variants
- Anatomy
- Accessibility
Inactive entries muted, type below 16 px. The eye reads “one live thing in a list of ghosts” instead of “one current thing in a list of options.”
Links
Two link patterns, used distinctly. Inline links inside running prose carry an underline by default — eyes scanning a paragraph need the underline to spot the affordance. Standalone links sitting next to a heading don't — their position already telegraphs that they're actionable.
Inline (in prose)
Read more about payouts and how settlements work on the help center, or browse all daily reports for this period.
Underlined by default. Underline thickens on hover. Color: text.link — blue.700.
Standalone
Transfers
See allAnchored to a section heading or button-adjacent. No underline at rest — the position carries the affordance. Underline appears on hover.
Currency
Money is the product. Every metric inherits a strict typesetting recipe: European number format, tabular numerals, slashed zero, and color tokens that distinguish incoming from outgoing money. Get this right at the system level so every screen inherits it.
Format
1.234.567,89
Period thousands. Comma decimal.
Symbol
€ 10.095,00
1.075,25 €
Prefix on hero displays, suffix in tables. Always a space.
Sign
€ -200,00
-200,00 €
Minus before the number. Never parentheses.
In the product
Three real surfaces. Each shows the same content at a different size — and how Founders, Inter Tight, and the color tokens play together.
Balance
Overview of your currently available banking balance
Available balance
€ 10.095,00
Transfers
See allToday
Bank account
Transfer sent
€ -200,00
Settlement account
Transfer received
€ 200,00
Vendor name
Payment sent
€ -200,00
Customer name
Payment received
€ 200,00
- 2010 Feb 2025 18:401.114,00 €
- 1910 Feb 2025 14:321.075,25 €
- 1814 Feb 2025 14:323.000,00 €
- 1715 Feb 2025 14:321.050,75 €
Color rules
- Positive — green. Refunds received, payouts in, credits, positive deltas.
text.numeric.positive. - Negative — orange. Payments out, fees, transfers sent.
text.numeric.negative. - Default — neutral. Totals, balances at rest, table cells with no directional meaning.
text.numeric.primary.
Why orange, not red, for negatives
Outgoing money is normal product motion — a payout, a fee, a payment. Painting it red puts it in the same visual register as errors and destructive actions, which dulls the warning value of red where it actually matters. Orange reads as outgoing without sounding alarms.
Text styles and tokens
The system exposes four families of text tokens — heading, body, metric, code. Each has a consistent shape: a token name, a weight, a size, and a line height.
Rem units
Font sizes are quoted in remso they respect a user's browser font-size preference. 1 rem = 16 px at the default root. The pixel column in each table is informational; consume the rem value in code.
Heading
Use heading styles for structure — they're critical for accessibility. Bold weight or a larger size on a paragraph is not a heading.
- AAheading.displayBold3.75 rem / 60 px0.92 / 55 px
- Aaheading.xxlSemibold2.25 rem / 36 px1.1 / 40 px
- Aaheading.xlSemibold1.875 rem / 30 px1.15 / 35 px
- Aaheading.lgSemibold1.5 rem / 24 px1.2 / 29 px
- Aaheading.mdSemibold1.25 rem / 20 px1.3 / 26 px
- Aaheading.smSemibold1 rem / 16 px1.4 / 22 px
Body
Default to body (16 px) for prose, body.sm (14 px) for product UI rows. Each body style ships with an opinionated paragraph-spacing value so stacked paragraphs sit consistently across the system.
- Aabody.lgRegular1.125 rem / 18 px1.625 / 29 px20 px
- AabodyRegular1 rem / 16 px1.625 / 26 px16 px
- Aabody.smRegular0.875 rem / 14 px1.5 / 21 px12 px
- Aabody.xsRegular0.75 rem / 12 px1.5 / 18 px8 px
Metric
For numeric emphasis — totals, deltas, KPIs, the big number on a dashboard tile. Always set with tabular numerals.
- € 10.095metric.displayBold (Founders)3.75 rem / 60 px0.95 / 57 px
- 12.345metric.xlSemibold3 rem / 48 px1.05 / 50 px
- 12.345metric.lgSemibold2 rem / 32 px1.1 / 35 px
- 12.345metric.mdMedium1.25 rem / 20 px1.3 / 26 px
- 12.345metric.smMedium0.875 rem / 14 px1.5 / 21 px
Code
Use Martian Mono for code blocks, repo paths, model names, and any inline identifier. The .font-mono selector enables tabular numerals automatically.
- AacodeRegular0.8125 rem / 13 px1.5 / 20 px
- Aacode.smRegular0.6875 rem / 11 px1.5 / 17 px
Related
Page history
4 revisions- DocumentedDerek Fidler@derekfidler
Added Currency section with real product specimens (Balance, Transfers, EOD report). Negatives clarified as orange, not red.
- DocumentedDerek Fidler@derekfidler
Restructured to mirror Atlassian's IA — three principles, brand vs UI fonts, simpler Aa scale, sub-pages for Typefaces and Tokens.
- DocumentedDerek Fidler@derekfidler
Founders rule tightened: H1 + display only, ALL CAPS + Bold.
- DocumentedDerek Fidler@derekfidler
First documented version. Three families wired via next/font/local.