Skip to main content
Luke van Zyl·Updated March 27, 2026

Typography

Typography in Axon is organized into three groups: Header, Body, and Utility. Each group has a distinct role in the visual hierarchy, and all three share the same size scale: extra small, small, medium, and large.

Type Groups

Header styles are reserved for moments that need to command attention or establish a strong top-level hierarchy without competing with surrounding content.

StyleSizeWeight
header-xs20px700
header-sm24px700
header-md32px700
header-lg40px700

Use header styles for page-level headings, empty states, and zero states where there's significant whitespace and the text needs to anchor the view. On the Appointments calendar, the selected date in the top left uses a header style. The empty state on the same screen pairs a header style for the primary message with body-xs for the supporting description below it.

CleanShot_2026-03-26_at_17.53.38.png

CleanShot_2026-03-26_at_17.53.31.png

Body

Body styles cover most of the text in the app. They share the same size scale but differ by weight, which maps to three sub-groups. The right sub-group to reach for usually follows one of three rules:

  • If it's clickable, use an interactive style.
  • If it's body text, use a default body style.
  • If it's a title or primary identifier for a collection of data, use a title style. Title styles are used sparingly.

Size within each group is a judgment call based on context. Match the density and hierarchy of the surrounding layout, and err toward legibility over compression.

Default Body

Regular weight (400). The workhorse of the app. Use for values, descriptions, timestamps, dates, and any text that isn't interactive or needs to stand out as a primary label.

StyleSizeWeight
body-xs10px400
body-sm12px400
body-md14px400
body-lg16px400

body-sm appears throughout the app in table cells, appointment details, and timestamps. body-xs works for supporting text in empty states or fine-print copy. body-md and body-lg suit larger or more readable sections of copy where density isn't a concern.

Interactive

Medium weight (500). Use whenever text is clickable or needs to read as actionable.

StyleSizeWeight
body-interactive-xs10px500
body-interactive-sm12px500
body-interactive-md14px500
body-interactive-lg16px500

The size you choose should match the surrounding body text so interactive elements feel at home in the layout, not oversized.

Title

Bold weight (700). Use when a piece of text needs to serve as the primary identifier for a card or row within a collection of data. This is the rarest of the three body sub-groups.

StyleSizeWeight
body-title-xs10px700
body-title-sm12px700
body-title-md14px700
body-title-lg16px700

In the Diagnostic Requests view, the patient name uses a title style to anchor each row as a distinct record. Use title styles when weight alone is what distinguishes the label from its surrounding data.

CleanShot_2026-03-26_at_17.56.25.png

Utility

Utility styles are bold (700) and rendered in all caps via text-transform: uppercase. They're for labels that organize or categorize content, not for reading extended text.

StyleSizeWeight
utility-xs10px700
utility-sm12px700
utility-md14px700
utility-lg16px700

utility-md is the standard for column headers in most tables. On the Appointments calendar, columns like PROVIDER, TIME, PATIENT, STATUS, and VISIT REASON use utility styles.

utility-sm fits denser tables with more columns, like the Products admin table where PIMS ID, ITEM NAME, CLASS, TX SHEET CATEGORY, UNIT OF MEASURE, and DEFAULT PRICE all need to coexist at a tighter scale.

utility-xs is used for sub-labels inside panels, such as the field group headers in an appointment detail card: ALERTS, VISIT PROBLEMS/DX, TYPE, SERVICE, PROVIDER, and INV. TOTAL.

CleanShot_2026-03-26_at_17.55.09.png

CleanShot_2026-03-26_at_17.54.40.png

Usage Notes

  • The three body sub-groups are the most useful shorthand: clickable means interactive, body text means default, primary identifier means title.
  • Use header styles to anchor a view, not to label sections within a dense layout.
  • Utility always means all caps. If a label isn't rendered in all caps, it's not a utility style.
  • Avoid stacking multiple extra small or small styles in sequence. If a layout pushes you toward body-xs across long runs of text, reconsider the layout before reducing type size.
  • T-shirt size is a judgment call. Match the density and hierarchy of the surrounding context rather than trying to map every instance to an exact size. The goal is a clear, legible hierarchy, not uniformity for its own sake.

Text Styles

All text styles use Inter and are available as CSS custom properties (e.g. var(--font-size-body-md), var(--font-weight-body-md)). Click the copy icon on any token to copy the CSS variable name.

HeaderPage and section headings — weight 700.
--font-size-header-lgThe quick brown fox jumps over the lazy dog40px / 700
--font-size-header-mdThe quick brown fox jumps over the lazy dog32px / 700
--font-size-header-smThe quick brown fox jumps over the lazy dog24px / 700
--font-size-header-xsThe quick brown fox jumps over the lazy dog20px / 700
Body TitleInline headings and emphasis — weight 700.
--font-size-body-title-lgThe quick brown fox jumps over the lazy dog16px / 700
--font-size-body-title-mdThe quick brown fox jumps over the lazy dog14px / 700
--font-size-body-title-smThe quick brown fox jumps over the lazy dog12px / 700
--font-size-body-title-xsThe quick brown fox jumps over the lazy dog10px / 700
Body InteractiveLabels and interactive controls — weight 500.
--font-size-body-interactive-lgThe quick brown fox jumps over the lazy dog16px / 500
--font-size-body-interactive-mdThe quick brown fox jumps over the lazy dog14px / 500
--font-size-body-interactive-smThe quick brown fox jumps over the lazy dog12px / 500
--font-size-body-interactive-xsThe quick brown fox jumps over the lazy dog10px / 500
BodyDefault reading text — weight 400.
--font-size-body-lgThe quick brown fox jumps over the lazy dog16px / 400
--font-size-body-mdThe quick brown fox jumps over the lazy dog14px / 400
--font-size-body-smThe quick brown fox jumps over the lazy dog12px / 400
--font-size-body-xsThe quick brown fox jumps over the lazy dog10px / 400
UtilityBadges, metadata, and supporting labels — weight 700.
--font-size-utility-lgThe quick brown fox jumps over the lazy dog16px / 700
--font-size-utility-mdThe quick brown fox jumps over the lazy dog14px / 700
--font-size-utility-smThe quick brown fox jumps over the lazy dog12px / 700
--font-size-utility-xsThe quick brown fox jumps over the lazy dog10px / 700

Type Scale (font size, line height, letter spacing)

34 tokens

NameTypeValueDescription
typography/font/family/InterSTRINGInter
typography/font/family/Open/SansDeprecatedSTRINGOpen Sans
typography/font/family/Ubuntu/MonoSTRINGUbuntu Mono
typography/font/size/10FLOAT10px
typography/font/size/12FLOAT12px
typography/font/size/14FLOAT14px
typography/font/size/16FLOAT16px
typography/font/size/20FLOAT20px
typography/font/size/24FLOAT24px
typography/font/size/32FLOAT32px
typography/font/size/40FLOAT40px
typography/font/size/48FLOAT48px
typography/font/weight/BoldSTRINGBold
typography/font/weight/MediumSTRINGMedium
typography/font/weight/RegularSTRINGRegular
typography/font/weight/SemiboldSTRINGSemibold
typography/letter/spacing/NormalFLOAT0px
typography/letter/spacing/TightFLOAT-0.5px
typography/letter/spacing/TighterFLOAT-1px
typography/letter/spacing/WideFLOAT0.5px
typography/letter/spacing/WiderFLOAT1px
typography/line/height/104FLOAT104px
typography/line/height/12FLOAT12px
typography/line/height/16FLOAT16px
typography/line/height/20FLOAT20px
typography/line/height/24FLOAT24px
typography/line/height/28FLOAT28px
typography/line/height/32FLOAT32px
typography/line/height/36FLOAT36px
typography/line/height/42FLOAT42px
typography/line/height/48FLOAT48px
typography/line/height/52FLOAT52px
typography/line/height/64FLOAT64px
typography/line/height/80FLOAT80px

Font Family

4 tokens

NameTypeValueDescription
font/font/family/bodySTRINGvar(--typography-font-family-Inter)
font/font/family/displaySTRINGvar(--typography-font-family-Inter)
font/font/family/headingSTRINGvar(--typography-font-family-Inter)
font/font/family/utilitySTRINGvar(--typography-font-family-Inter)

Accessibility

Typography size directly affects the contrast ratio required to meet WCAG 2.2 AA (SC 1.4.3). WCAG defines two tiers:

  • Large text — regular weight at 24px or above, or bold weight at ~19px or above. Requires a minimum 3:1 contrast ratio.
  • Normal text — anything below those thresholds. Requires a minimum 4.5:1 contrast ratio.

The table below maps each Axon text style to its WCAG size classification and minimum required contrast ratio.

StyleSizeWeightWCAG classificationMin. contrast (AA)
header-lg40px700Large3:1
header-md32px700Large3:1
header-sm24px700Large3:1
header-xs20px700Large (bold ≥19px)3:1
body-lg / body-interactive-lg / body-title-lg16px400 / 500 / 700Normal4.5:1
body-md / body-interactive-md / body-title-md14px400 / 500 / 700Normal*4.5:1
body-sm / body-interactive-sm / body-title-sm12px400 / 500 / 700Normal4.5:1
body-xs / body-interactive-xs / body-title-xs10px400 / 500 / 700Normal4.5:1
utility-lg16px700Normal4.5:1
utility-md14px700Normal*4.5:1
utility-sm12px700Normal4.5:1
utility-xs10px700Normal4.5:1

body-title-md and utility-md are 14px bold. WCAG's bold large-text threshold is ~18.66px bold, so 14px bold does not qualify as large text and still requires 4.5:1.

What this means in practice:

  • Header styles get the most flexibility. You can use lighter foreground tokens like -fg-tertiary on header text more safely, though always verify with a contrast checker.
  • Extra small and small body styles are the highest risk. body-xs and body-sm at 10–12px require 4.5:1 and have less room for error. Avoid pairing them with low-opacity foreground tokens like -fg-tertiary (rgba(0,0,0,0.56)) unless the background is confirmed to pass.
  • Disabled text is exempt. WCAG does not require disabled UI text to meet contrast thresholds, which is why -fg-disabled (rgba(0,0,0,0.24)) exists as a deliberately low-contrast option.
  • Utility all-caps text may feel more legible at lower contrast due to letter spacing, but it is not exempt from WCAG requirements. The size-based thresholds still apply.