Typography
Live preview of the Typography tokens, brand-switchable from the header.
Typography tokens are organised into three categories — Display, Heading, and Text — each with normal and strong weight variants. Use the brand switcher in the header to preview tokens for KP, GWL, or WF.
Each specimen below renders against the actual CSS custom properties emitted by the build, so what you see is what your application gets.
Using the roles
Pick a role by intent, not by the size it happens to be at. Every role exposes a normal and a strong variant; the only difference is font weight. Reach for strong to add emphasis within a role without jumping to the next size up.
- Display — Marketing-scale type for hero banners, splash screens, and standalone callouts. Not for in-page content hierarchy.
- Headline — Page titles and the top of major content sections. Use a single
Headline 1per route, then step down for nested sections. - Title — Sub-section, card, dialog, and component titles. Use when a heading needs less presence than a Headline.
- Overline — Small uppercase eyebrow label that sits above a Headline or Title to categorise content.
- Body — Default running text.
Body 1is the page default;Body 2is for denser UI surfaces such as tables and settings rows. - Caption — Secondary metadata, image captions, and helper text under form fields.
- Tiny — Legal lines, footnotes, and dense micro-copy. Avoid for anything a reader needs to act on.
Font families
Three families ship per brand, mapped to role groups. KP and GWL share the same faces; WF uses different families for its Thai-first audience.
| Role group | KP / GWL | WF |
|---|---|---|
| Display / Heading / Title / CTA / Numeric | King Power Headline | Inter |
| Body / Caption / Tiny | King Power Text | Noto Looped Thai UI |
| Code | SF Mono | SF Mono |
Family aliases are exposed as CSS variables (--crown-typo-family-head, --crown-typo-family-text, --crown-typo-family-disp, --crown-typo-family-cta, --crown-typo-family-numeric, --crown-typo-family-code) and as Tailwind utilities (font-head, font-text, font-disp, font-cta, font-numeric). The full typography tokens documented below already resolve to the correct family per role — reach for the family aliases only when you need to set a font face without applying a full role.
Applying typography in code
Each role resolves to five CSS custom properties: font-family, font-size, line-height, font-weight, and letter-spacing. The variable name follows --crown-typo-{token}-{property}, where {token} is the id shown next to every specimen below (e.g. text-body-1-normal, head-headline-1-strong, disp-display-2-normal).
Semantic HTML
Pick the element from the document outline, not from the visual size of the role. A Display style can live on a <div> if it isn't acting as a heading, and a Title can sit on an <h2> if it heads a top-level section.
| Role | Suggested element |
|---|---|
| Display | <h1> for hero headings; <div> / <p> otherwise |
| Headline 1–5 | <h1>–<h5> |
| Title 1–2 | <h6>, or the contextual heading level (e.g. <h3> in a card) |
| Overline | <span> or <p> — paired above a heading, not a heading itself |
| Body 1–2 | <p> |
| Caption | <small>, <p>, or <figcaption> |
| Tiny | <small> or <p> |
Code
Using a CSS class:
.body-1 {
font-family: var(--crown-typo-text-body-1-normal-font-family);
font-size: var(--crown-typo-text-body-1-normal-font-size);
line-height: var(--crown-typo-text-body-1-normal-line-height);
font-weight: var(--crown-typo-text-body-1-normal-font-weight);
letter-spacing: var(--crown-typo-text-body-1-normal-letter-spacing);
}Using Tailwind arbitrary values:
<p
className="
[font-family:var(--crown-typo-text-body-1-normal-font-family)]
[font-size:var(--crown-typo-text-body-1-normal-font-size)]
[line-height:var(--crown-typo-text-body-1-normal-line-height)]
[font-weight:var(--crown-typo-text-body-1-normal-font-weight)]
[letter-spacing:var(--crown-typo-text-body-1-normal-letter-spacing)]
"
>
…
</p>A per-role Tailwind utility (e.g. text-body-1) is not shipped yet — until it lands, prefer a small CSS class per role over scattering arbitrary values across components.
Display
Display styles are the largest type sizes, used for hero sections and large callouts.
Display 1 currently inherits the heading font family, while Display 2–4 use the dedicated display family. This is inconsistent with the rest of the Display role and is tracked as a known issue — treat it as a bug to be reconciled rather than intended behaviour.
disp-display-1-normal · Display 1 · Normaldisp-display-1-strong · Display 1 · Strongdisp-display-2-normal · Display 2 · Normaldisp-display-2-strong · Display 2 · StrongHeading
Heading styles cover the full range from large section headers down to overlines and compact titles.
head-headline-1-normal · Headline 1 · Normalhead-headline-1-strong · Headline 1 · Stronghead-headline-3-normal · Headline 3 · Normalhead-headline-3-strong · Headline 3 · Stronghead-title-1-normal · Title 1 · Normalhead-title-1-strong · Title 1 · Stronghead-overline-normal · Overline · NormalText
Body and utility styles for UI copy, captions, and fine print.
text-body-1-normal · Body 1 · Normaltext-body-1-strong · Body 1 · Strongtext-body-2-normal · Body 2 · Normaltext-caption-normal · Caption · Normaltext-tiny-normal · Tiny · NormalType scale
Sizes follow a 1.125 modular scale (Major Second) anchored at 16 px for Body 1. Each step multiplies or divides the base by 1.125 before being rounded to an even pixel value, which is why no role lands on an awkward fractional size.
Line height is derived from the font size by role group:
| Role group | Multiplier |
|---|---|
| Display | × 1.4 |
| Heading / Title / Overline | × 1.6 |
| Body / Caption / Tiny | × 1.5 |
| CTA | × 1.5 |
| Numeric | × 1.2 |
Sizes are fixed across breakpoints — typography does not fluid-scale today. Adjust layout density at smaller viewports through spacing tokens, not by swapping type sizes.
Accessibility & best practices
- Match the heading element to the document outline, not the visual size. A
Display 1on a hero is often not an<h1>— only the heading that anchors the page's semantic outline should be. - Don't downsize below
Body 1for prose.Body 2,Caption, andTinyare for dense UI and metadata, not for content a reader has to consume linearly. - Cap line length at 60–80 characters for
Bodyroles. Constrain the container width — readability collapses past ~80ch even at the right size. - Avoid all-caps for sentences. Use
Overline(which applies the right text-transform) when you need uppercase labels; don't bolttext-transform: uppercaseonto aBodyorHeadlinerole. - No truncation without an expand affordance. If a label might overflow, give the reader a way back to the full text (tooltip, modal, "show more").
- Use the
strongvariant for emphasis, not the next size up. Hierarchy comes from the role ladder; weight is for emphasis within a role. Reach for color last — it carries state meaning.
Full token inventory
The table below lists every typography token emitted by the build. Use it to discover the complete set of available values.
No tokens match.