Typography

A complete type system built on design tokens. Font families, type scale, preset classes, responsive sizing, and prose styling — all customizable with one variable change.

Why a typography system?

Most libraries give you font sizes and leave the rest to you. nnuikit's typography is token-driven — every size, weight, line-height, and letter-spacing is a CSS variable. Change --font-sans once, the entire UI updates. Sizes auto-scale across breakpoints. Preset classes bundle everything so you never mismatched a line-height with a font-size.

Token-driven

Every value is a CSS variable. Swap fonts, adjust scale — components auto-adapt.

Responsive

Display and heading sizes scale at 1024px and 1440px breakpoints automatically.

Preset classes

One class = size + weight + line-height + tracking. No mismatches.

How to use

Three ways to use the typography system, depending on your needs:

<!-- 1. Preset classes — recommended for most cases -->
<h1 class="type-display-lg">Hero heading</h1>
<p class="type-body-md">Paragraph text with proper line-height built in.</p>
<span class="type-label-sm">Form label</span>
<span class="type-overline">Section label</span>

<!-- 2. Tailwind utilities — use the registered text-* classes -->
<h2 class="text-heading-lg font-semibold tracking-tight">Section title</h2>
<p class="text-body-md leading-relaxed">Body copy</p>

<!-- 3. CSS tokens directly — for custom components -->
<style>
  .custom-title {
    font-size: var(--text-heading-md);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-snug);
    letter-spacing: var(--tracking-normal);
  }
</style>

Font Families

Change --font-sans to swap the entire UI's typeface. Works with your brand font — just update the Google Fonts import and the token.

TokenValueUsage
--font-sansHost Grotesk, system-ui, sans-serifBody text, headings, UI labels
--font-monoJetBrains Mono, monospaceCode blocks, tokens, CLI commands
--font-displayHost Grotesk, system-ui, sans-serifHero text, display headings
/* Override in your CSS to change the global font */
:root {
  --font-sans: 'Inter', system-ui, sans-serif;
  --font-display: 'Cal Sans', 'Inter', sans-serif;
  --font-mono: 'Fira Code', monospace;
}

Display Scale

Responsive

Hero headings and landing page text. Sizes auto-scale at 1024px and 1440px breakpoints.

The quick brown fox jumps over the lazy dog.

.type-display-2xl 56px → 80px

The quick brown fox jumps over the lazy dog.

.type-display-xl 48px → 64px

The quick brown fox jumps over the lazy dog.

.type-display-lg 40px → 52px

The quick brown fox jumps over the lazy dog.

.type-display-md 36px → 44px

The quick brown fox jumps over the lazy dog.

.type-display-sm 32px → 40px

Heading Scale

Partially responsive

Heading XL

.type-heading-xl 30px → 40px

Heading LG

.type-heading-lg 24px → 32px

Heading MD

.type-heading-md 20px → 24px

Heading SM

.type-heading-sm 18px

Heading XS

.type-heading-xs 16px

Body

.type-body-lg 18px

The quick brown fox jumps over the lazy dog.

.type-body-md 16px

The quick brown fox jumps over the lazy dog.

.type-body-sm 14px

The quick brown fox jumps over the lazy dog.

.type-body-xs 12px

The quick brown fox jumps over the lazy dog.

Label

.type-label-lg 14px

Label LG

.type-label-md 13px

Label MD

.type-label-sm 12px

Label SM

.type-label-xs 11px

Label XS

.type-overline 10px

Overline text

.type-caption 11px

Caption text for supplementary info

Code Presets

const theme = 'nnuikit';

.type-code

npm install nnuikit

.type-code-sm

Responsive type scale

Display and heading sizes automatically grow at larger viewports. No media queries in your components — the tokens handle it.

TokenMobileTablet (1024px)Desktop (1440px)
display-2xl56px72px80px
display-xl48px60px64px
display-lg40px48px52px
heading-xl30px36px40px
heading-lg24px28px32px
heading-md20px22px24px

Body and label sizes stay fixed — they don't need responsive scaling.

Letter Spacing

The quick brown fox jumps over
tracking-tighter -0.05em
The quick brown fox jumps over
tracking-tight -0.025em
The quick brown fox jumps over
tracking-normal 0em
The quick brown fox jumps over
tracking-wide 0.025em
The quick brown fox jumps over
tracking-wider 0.05em
The quick brown fox jumps over
tracking-widest 0.1em

Line Height

Labels, badges
leading-none 1
Display headings
leading-tight 1.15
Section headings
leading-snug 1.3
Small body text
leading-normal 1.5
Body paragraphs
leading-relaxed 1.625
Long-form content
leading-loose 1.8

Font Weights

The quick brown fox jumps over the
font-light 300
The quick brown fox jumps over the
font-normal 400
The quick brown fox jumps over the
font-medium 500
The quick brown fox jumps over the
font-semibold 600
The quick brown fox jumps over the
font-bold 700
The quick brown fox jumps over the
font-extrabold 800

Text Truncation

.text-truncate

The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.

.text-clamp-2

The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.

Prose styling

Apply .nn-prose to containers with raw HTML or markdown content. Headings, paragraphs, lists, code, blockquotes, and tables are all styled automatically.

<div class="nn-prose">
  {@html markdownContent}
</div>

Live preview

Getting started

This is a paragraph inside .nn-prose. Links like this one are styled automatically. Bold text gets the primary color.

Design tokens make theming composable. Change one variable, the cascade handles the rest.
  • Headings scale from h1 to h4
  • Code blocks get mono font + background
  • Tables, lists, and blockquotes — all covered
npx nnuikit add button

Token reference

All typography tokens live in src/lib/styles/typography.css. Override any token in your project's CSS to customize.

/* Change the font globally */
:root {
  --font-sans: 'Inter', system-ui, sans-serif;
}

/* Adjust the display scale */
:root {
  --text-display-lg: 2.75rem;
}
@media (min-width: 1024px) {
  :root { --text-display-lg: 3.5rem; }
}

/* Tighten body line-height */
:root {
  --leading-relaxed: 1.5;
}