Typography

Basalt UI uses the @tailwindcss/typography plugin with opt-in semantic HTML styling via the .prose class. Content areas like blog posts and articles get automatic typography, while UI components stay clean and conflict-free. Three font families — Lato for headings, Nunito Sans for body, and JetBrains Mono for code — support the warm, professional aesthetic.

Using .prose for Content Areas

This h2 is styled automatically within .prose

This paragraph looks great without extra classes. Basalt UI uses the official @tailwindcss/typography plugin with the .prose class for opt-in semantic styling. Perfect for blog posts, articles, and documentation.

This is an h3 heading

Notice how headings use Lato (bold) and body text uses Nunito Sans (regular). The spacing, sizing, and colors are all automatic within .prose containers.

Links are styled automatically too, with the blue accent color and subtle underline that responds to hover.

  • Lists work automatically
  • No classes needed
  • Just semantic HTML
Blockquotes are styled with the primary blue border and muted text, creating subtle visual hierarchy.

Inline code elements get monospace font with background highlighting.

👆 All the typography above uses semantic HTML with the .prose class on the container.

Why Opt-In with .prose?

Basalt UI uses opt-in typography to avoid conflicts with component libraries like ShadCN and Tremor. Global semantic HTML defaults would interfere with:

  • Tremor Table components (expect unstyled <table> elements)
  • ShadCN Buttons (shouldn't inherit link <a> styles)
  • Navigation links (don't want automatic blue underlines)
  • Component padding/spacing (conflicts with global paragraph margins)

With the .prose class, you choose where semantic HTML styling applies:

<!-- Content areas: Use .prose -->
<article >
  <h2>Article Title</h2>
  <p>Automatically styled content...</p>
</article>

<!-- UI components: No .prose -->
<Table>...</Table>
<Button>Click Me</Button>
<nav><a href="#">Link</a></nav>

Font Families

Lato (Headings)
The quick brown fox jumps over the lazy dog
font-heading • Weights: 400, 700
Used for all headings (h1-h6), display text, and hero sections
Nunito Sans (Body)
The quick brown fox jumps over the lazy dog
font-body • Weight: 400
Used for paragraph text, descriptions, and general content
JetBrains Mono (Code)
The quick brown fox
font-mono • Weight: 400
Used for code blocks, inline code, and technical content

Typography Scale

Display Text
text-display • 64px / 77px line-height • Lato Bold • -0.5px tracking
Used for hero sections and large marketing headlines (requires .text-display class)
Hero Text
text-hero • 48px / 58px line-height • Lato Bold
Subhero sections and large page headers (requires .text-hero class)

Heading 1

h1 element • 40px / 48px line-height • Lato Bold
Primary page heading (automatic styling, no class needed)

Heading 2

h2 element • 32px / 42px line-height • Lato Bold
Section headers (automatic styling, no class needed)

Heading 3

h3 element • 24px / 34px line-height • Lato Bold
Subsection headers (automatic styling)

Heading 4

h4 element • 20px / 28px line-height • Lato Bold
Card titles (automatic styling)
Heading 5
h5 element • 18px / 27px line-height • Lato Bold
Small section headings (automatic styling)
Heading 6
h6 element • 16px / 24px line-height • Lato Bold
Tiny section headings (automatic styling)

Body text: The quick brown fox jumps over the lazy dog. This is the default paragraph text style used throughout the design system. Nunito Sans provides a friendly, readable aesthetic.

p element • 16px / 24px line-height • Nunito Sans Regular
Paragraph text and general content (automatic styling, default)
Small text for metadata, captions, and secondary information
text-small • 14px / 20px line-height
Metadata and captions (requires .text-small class)
Caption text for legal disclaimers, footnotes, and fine print
text-caption • 12px / 16px line-height
Legal text and footnotes (requires .text-caption class)

Usage Guidelines

Semantic Typography

Recommended for content hierarchy

<!-- Semantic HTML (automatic styling) -->
<h1>Hero Title</h1>
<h2>Section Header</h2>
<p>Body paragraph text</p>

<!-- Custom sizes when needed -->
<div class="text-display">Extra Large Hero</div>
<span class="text-small">Metadata or caption</span>

<!-- Markup is cleaner, more semantic -->
Utility Classes

For flexible custom styling

<div class="text-2xl font-bold">
  Custom large text
</div>

<div class="text-base tracking-wide uppercase">
  Uppercase label
</div>

<code class="text-sm font-mono">
  Inline code snippet
</code>

Weights & Spacing

Font Weights
font-regular (400) - Body text
font-bold (700) - Headings and emphasis
Letter Spacing
tracking-tight (-0.5px) - Display text
tracking-normal (0px) - Default
tracking-wide (0.025em) - Uppercase

Implementation

Loading Google Fonts

Basalt UI uses an optimized font loading strategy to prevent layout shift and ensure fast page loads. Add these lines to your HTML <head>:

<!-- Preconnect to Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

<!-- Load fonts with display=swap for zero flicker -->
<link
  rel="preload"
  as="style"
  href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Nunito+Sans:wght@400&family=JetBrains+Mono:wght@400&display=swap"
  fetchpriority="high"
/>
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Nunito+Sans:wght@400&family=JetBrains+Mono:wght@400&display=swap"
  media="print"
  onload="this.media='all'"
/>
<noscript>
  <link
    rel="stylesheet"
    href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Nunito+Sans:wght@400&family=JetBrains+Mono:wght@400&display=swap"
  />
</noscript>

Performance Benefits:

  • Zero blocking: Fonts load asynchronously
  • Early connection: Preconnect reduces latency by 200-500ms
  • FOUT prevention: display=swap shows text immediately with fallbacks
  • Minimal CLS: Fallback fonts matched to web fonts