Foundations

Typography

Typography is our system of fonts and text styles. It supports communication, reinforces the Flatpay brand, and gives every product surface — from a printed receipt to a dashboard chart — a shared rhythm.

Documentedby Derek Fidler

Typographic principles

Three principles that guide every type choice in the system.

AaAaAa

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.

14 px
16 px
18 px

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.”

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 all

Anchored 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 all

Today

  • Bank account

    Transfer sent

    € -200,00

  • Settlement account

    Transfer received

    € 200,00

  • Vendor name

    Payment sent

    € -200,00

  • Customer name

    Payment received

    € 200,00

IDEnd dateNet sales
  • 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.

PreviewTokenWeightSizeLine height
  • 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.

PreviewTokenWeightSizeLine heightParagraph
  • 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.

PreviewTokenWeightSizeLine height
  • € 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.

PreviewTokenWeightSizeLine height
  • AacodeRegular0.8125 rem / 13 px1.5 / 20 px
  • Aacode.smRegular0.6875 rem / 11 px1.5 / 17 px

Page history

4 revisions
  1. Documented
    Derek Fidler@derekfidler

    Added Currency section with real product specimens (Balance, Transfers, EOD report). Negatives clarified as orange, not red.

  2. Documented
    Derek Fidler@derekfidler

    Restructured to mirror Atlassian's IA — three principles, brand vs UI fonts, simpler Aa scale, sub-pages for Typefaces and Tokens.

  3. Documented
    Derek Fidler@derekfidler

    Founders rule tightened: H1 + display only, ALL CAPS + Bold.

  4. Documented
    Derek Fidler@derekfidler

    First documented version. Three families wired via next/font/local.