Typography
Typography establishes visual hierarchy and readability. Tessera UI uses a constrained type system with two font families and a fixed size scale.
Font Families
Section titled “Font Families”| Token | Value | Usage |
|---|---|---|
--ts-font-family-base | 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif | All body text, labels, buttons |
--ts-font-family-mono | 'JetBrains Mono', 'Fira Code', 'Consolas', monospace | Code blocks, technical content |
Plus Jakarta Sans is the primary typeface — it’s a geometric sans-serif designed for screen readability with open letterforms and a modern, friendly aesthetic.
Type Scale
Section titled “Type Scale”The type scale uses rem units based on a 16px root size. Each step provides a meaningful visual distinction.
| Token | Size | Pixels | Usage |
|---|---|---|---|
--ts-font-size-2xs | 0.6875rem | 11px | M3 label-small |
--ts-font-size-xs | 0.75rem | 12px | M3 body-small, label-medium, captions |
--ts-font-size-sm | 0.875rem | 14px | M3 body-medium, label-large, title-small |
--ts-font-size-md | 1rem | 16px | M3 body-large, title-medium |
--ts-font-size-lg | 1.375rem | 22px | M3 title-large |
--ts-font-size-xl | 1.5rem | 24px | M3 headline-small |
--ts-font-size-2xl | 1.75rem | 28px | M3 headline-medium |
--ts-font-size-3xl | 2rem | 32px | M3 headline-large |
--ts-font-size-4xl | 2.8125rem | 45px | M3 display-small |
--ts-font-size-5xl | 3.5625rem | 57px | M3 display-medium |
--ts-font-size-6xl | 5.5rem | 88px | M3 display-large, marketing hero |
Font Weights
Section titled “Font Weights”| Token | Value | Usage |
|---|---|---|
--ts-font-weight-regular | 400 | Body text, descriptions |
--ts-font-weight-medium | 500 | Labels, input labels, emphasized text |
--ts-font-weight-semi | 600 | Buttons, headings, badge labels |
--ts-font-weight-bold | 700 | Strong emphasis, display text |
Line Heights
Section titled “Line Heights”| Token | Value | Usage |
|---|---|---|
--ts-line-height-tight | 1.25 | Headings, labels |
--ts-line-height-normal | 1.43 | Body text (M3: 20/14, 24/16) |
--ts-line-height-loose | 1.5 | Display text (M3: 64/57, 96/88) |
Letter Spacing
Section titled “Letter Spacing”Letter spacing tokens adjust tracking for different typographic contexts. Display sizes use tighter spacing for visual density; labels and captions use wider spacing for legibility at small sizes.
| Token | Value | Usage |
|---|---|---|
--ts-letter-spacing-tighter | -0.02em | Display text |
--ts-letter-spacing-tight | -0.01em | Headings |
--ts-letter-spacing-normal | 0em | Body text, default (M3: 0 for most sizes) |
--ts-letter-spacing-wide | 0.006em | ~0.1px at 16px — M3 body-small/label |
--ts-letter-spacing-wider | 0.009em | ~0.1px at 11px — small labels |
--ts-letter-spacing-widest | 0.05em | All-caps text, legal fine print |
Composite Type Roles
Section titled “Composite Type Roles”Type roles combine size, weight, line height, and letter spacing into a single semantic purpose. Use these roles to maintain consistent typography across your application rather than assembling individual tokens.
| Role | Size Token | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
| display-lg | clamp(2.8125rem, 5vw + 1rem, 5.5rem) (45px-88px) | semi (600) | 1.09 | normal (0em) | Marketing hero, landing page headlines |
| display-md | clamp(2rem, 4vw + 1rem, 3.5625rem) (32px-57px) | semi (600) | 1.12 | normal (0em) | Section hero, feature highlights |
| display-sm | clamp(1.75rem, 3vw + 0.75rem, 2.8125rem) (28px-45px) | semi (600) | 1.16 | normal (0em) | Page titles, onboarding headers |
| heading-lg | clamp(1.5rem, 2vw + 0.5rem, 2rem) (24px-32px) | semi (600) | 1.25 | normal (0em) | Page section headers |
| heading-md | clamp(1.25rem, 1.5vw + 0.5rem, 1.75rem) (20px-28px) | semi (600) | 1.29 | normal (0em) | Card headers, dialog titles |
| heading-sm | xl (24px) | semi (600) | 1.33 | normal (0em) | Subsection headers |
| title-lg | lg (22px) | regular (400) | 1.36 | normal (0em) | Card headers, dialog titles, nav items |
| title-md | md (16px) | medium (500) | 1.5 | normal (0em) | List item titles, section labels |
| title-sm | sm (14px) | medium (500) | 1.43 | normal (0em) | Compact titles, tab labels |
| body-lg | md (16px) | regular (400) | 1.5 | normal (0em) | Introductory paragraphs, lead text |
| body-md | sm (14px) | regular (400) | 1.43 | normal (0em) | Default body text |
| body-sm | xs (12px) | regular (400) | 1.33 | wide (0.006em) | Secondary body text, descriptions |
| label-lg | sm (14px) | medium (500) | 1.43 | normal (0em) | Form labels (lg), button text, navigation items |
| label-md | xs (12px) | medium (500) | 1.33 | wide (0.006em) | Form labels (md), small button text |
| label-sm | 2xs (11px) | medium (500) | 1.45 | wider (0.009em) | Badge labels, helper text, overlines |
| caption | xs (12px) | regular (400) | 1.33 | wide (0.006em) | Timestamps, footnotes, fine print |
Each role is defined as a set of four CSS custom properties (e.g., --ts-type-display-lg-size, --ts-type-display-lg-weight, --ts-type-display-lg-line, --ts-type-display-lg-spacing), making them easy to apply and override.
Responsive Typography
Section titled “Responsive Typography”Display and heading type role sizes use CSS clamp() by default, providing fluid scaling between mobile and desktop viewports without any extra configuration:
| Role | Min (mobile) | Max (desktop) |
|---|---|---|
| display-lg | 45px (2.8125rem) | 88px (5.5rem) |
| display-md | 32px (2rem) | 57px (3.5625rem) |
| display-sm | 28px (1.75rem) | 45px (2.8125rem) |
| heading-lg | 24px (1.5rem) | 32px (2rem) |
| heading-md | 20px (1.25rem) | 28px (1.75rem) |
/* The tokens are already fluid — just use them: */h1 { font-size: var(--ts-type-display-lg-size); /* scales automatically */}To override with a fixed size, reassign the token:
:root { --ts-type-display-lg-size: 5.5rem; /* fixed 88px, no scaling */}Guidelines:
- Body text (
body-sm,body-md,body-lg) remains fixed — fluid scaling at reading sizes harms readability heading-smalso remains fixed since it is small enough that scaling is unnecessary- Display and heading sizes scale fluidly by default via
clamp()
CJK and Arabic Typography
Section titled “CJK and Arabic Typography”When supporting CJK (Chinese, Japanese, Korean) or Arabic scripts:
- Append CJK-specific font families to
--ts-font-family-base::root {--ts-font-family-base: 'Plus Jakarta Sans', 'Noto Sans SC', 'Noto Sans JP', sans-serif;} - CJK text typically needs
line-height: 1.7–1.8instead of the default1.43 - Arabic and Hebrew scripts require RTL layout — see the Internationalization page
- Avoid
letter-spacingadjustments for CJK — the glyphs are already monospaced by design
Hierarchy in Components
Section titled “Hierarchy in Components”Components use the type scale consistently to establish hierarchy:
Button sizes map to font sizes
Section titled “Button sizes map to font sizes”| Button Size | Font Size | Weight |
|---|---|---|
xs | --ts-font-size-xs | semi (600) |
sm | --ts-font-size-sm | semi (600) |
md | --ts-font-size-md | semi (600) |
lg | --ts-font-size-lg | semi (600) |
xl | --ts-font-size-xl | semi (600) |
Input typography by size
Section titled “Input typography by size”| Input Size | Font Size | Label Size |
|---|---|---|
sm | --ts-font-size-sm | sm / medium |
md | --ts-font-size-md | sm / medium |
lg | --ts-font-size-lg | sm / medium |
xl | --ts-font-size-xl | sm / medium |
Other components
Section titled “Other components”| Component | Font Size | Weight |
|---|---|---|
| Modal header | lg | semi |
| Modal body | md | regular |
| Alert message | sm | regular |
| Tooltip | xs | medium |
| Badge | xs | semi |
| Toggle label | sm | regular |
Best Practices
Section titled “Best Practices”- Use the type scale, not arbitrary sizes. The eleven-step scale (2xs through 6xl) covers all needs from label-small to display-large.
- Pair size with weight for hierarchy. Avoid using weight alone to differentiate text — use size steps.
- Prefer
medium(500) overbold(700) for emphasis. Bold should be reserved for strong semantic emphasis. - Use
tightline height for single-line text (headings, labels). Usenormalfor multi-line body content.