Typography & Prose
Relevant source files
The following files were used as context for generating this wiki page:
The typography system provides a structured approach to styling text and long-form content. It combines specific font pairings with the @tailwindcss/typography plugin to ensure consistent readability across the site. The system manages font families for body text, headings, and navigation while providing a "prose" mode for rendering Markdown and rich-text content.
Sources: src/assets/styles/typography.css:1-5, src/pages/dev/typography.md:14-25
Font Pairings
The system defines three primary font pairings: Work, Play, and Live. Each pairing specifies distinct font families for body text, headings, and navigation elements.
Configuration Structure
Each pairing is defined by a FontPairingConfig object which includes:
- Body: The primary font for paragraphs and general text.
- Heading: The font for
h1throughh6elements. - Nav: The font used for navigation and UI elements.
Sources: src/components/Settings/Font/pairings.ts:18-25, src/components/Settings/Font/pairings.ts:85-117
Available Pairings
| Pairing ID | Label | Heading Font | Body/Nav Font |
|---|---|---|---|
work | Work | Space Grotesk | IBM Plex Sans |
play | Play | Fredoka | Nunito |
live | Live | Lora | Source Sans 3 |
Sources: src/components/Settings/Font/pairings.ts:85-117
Font Pairing Flow
The following diagram illustrates how font pairings are selected, persisted, and applied to the document.
The system applies a data-font attribute to the document element and updates CSS variables to change the active typography.
Sources: src/components/Settings/Font/font.test.ts:98-118, src/components/Settings/Font/pairings.ts:175-185
Prose Styling
The project uses the @tailwindcss/typography plugin to style vanilla HTML content, such as that generated from Markdown files. Applying the .prose class to a container automatically styles headings, lists, code blocks, and blockquotes.
Sources: src/assets/styles/typography.css:1, src/pages/dev/typography.md:31-45
Color Variables
The .prose class uses a set of CSS variables to maintain consistency across light and dark modes.
| Variable | Light Mode Value | Dark Mode Value |
|---|---|---|
--tw-prose-body | color-primary-700 | color-primary-200 |
--tw-prose-headings | color-primary-950 | white |
--tw-prose-links | color-primary-950 | white |
--tw-prose-bold | color-primary-950 | white |
--tw-prose-pre-bg | color-primary-900 | rgb(0 0 0 / 50%) |
Sources: src/assets/styles/typography.css:7-40
Content Handling
The system handles specific typographic nuances:
- Stacked Headings: Reduces top margin on headings that immediately follow another heading.
- Nested Lists: Provides styling for nested unordered and ordered lists, though it recommends keeping structures flat for readability.
- Code Blocks: Styles
<code>and<pre>tags for technical content, providing a default look even without syntax highlighting. - Links: Uses dark gray with underlines that transition on hover, rather than standard blue.
Sources: src/pages/dev/typography.md:92-95, src/pages/dev/typography.md:124-142, src/pages/dev/typography.md:183-186
CSS Architecture
Typography styles are organized into layers to manage specificity and overrides.
Layer Utilities
.font-inherit: Ensures an element inherits the font weight of its parent..numbered-list: Manages counter resets and increments for custom list numbering.
Sources: src/assets/styles/typography.css:66-78
Selector Logic
The system uses the [data-font] attribute and the :where pseudo-class to apply styles without increasing specificity unnecessarily.
[data-font] :where(button, input, select, textarea, kbd) {
font-family: inherit;
}
:where(h1, h2, h3, h4, h5, h6) {
font-family: var(--font-heading, inherit);
}
Sources: src/assets/styles/typography.css:83-93
Dynamic CSS Generation
The typography system generates dynamic CSS based on the FONT_PAIRING_CONFIGS. This allows the application to switch between font sets by updating CSS variables mapped to specific data-font values.
Generation Sequence
The fontPairingCss function iterates through configurations to create rules for --default-font-family, --font-heading, and --font-ui.
Sources: src/components/Settings/Font/pairings.ts:175-201, src/components/Settings/Font/load-pairing.test.ts:68-75
The typography and prose system ensures that long-form content is legible and aesthetically consistent while allowing for user-defined font preferences that persist across sessions.