# API Endpoints Source: https://kapishdima-fonttrio.mintlify.app/api/endpoints Complete reference for all Fonttrio Registry API endpoints ## GET /api/r/\[name] Retrieve a font pairing or individual font configuration from the registry. ### Path Parameters The registry item name. Can be a pairing name (e.g., `minimal`, `brutalist`) or font name (e.g., `inter`, `roboto`). The `.json` extension is optional and will be automatically stripped if provided. ### Resolution Logic The API searches for registry items in the following order: 1. **Pairings directory** with exact name: `/registry/pairings/{name}.json` 2. **Pairings directory** without `pairing-` prefix: `/registry/pairings/{name-without-prefix}.json` 3. **Fonts directory**: `/registry/fonts/{name}.json` This allows flexible naming: * `/api/r/minimal` → finds `pairings/minimal.json` * `/api/r/pairing-minimal` → finds `pairings/minimal.json` * `/api/r/inter` → finds `fonts/inter.json` ### Query Parameters Override CSS properties for specific HTML elements in font pairings. Query parameters are ignored for individual font requests. #### Parameter Format Parameters follow the pattern: `{selector}-{property}={value}` **Supported Selectors:** * `h1`, `h2`, `h3`, `h4`, `h5`, `h6` — Heading levels * `body` — Body text * `code` — Inline code * `pre` — Code blocks **Supported Properties:** Font size (e.g., `2rem`, `18px`, `1.5em`) Font weight (e.g., `400`, `700`, `bold`) Font family (e.g., `Inter`, `var(--font-custom)`) Line height (e.g., `1.6`, `1.8`, `2`) Aliases: `line-height` Letter spacing (e.g., `-0.02em`, `0.05em`) Aliases: `letter-spacing` #### Example Query Parameters ``` ?h1-size=3rem&h1-weight=800&body-lh=1.8 ``` This will: * Set H1 font size to `3rem` * Set H1 font weight to `800` * Set body line height to `1.8` ### Response Returns either a [pairing schema](/api/pairing-schema) or [font schema](/api/font-schema) depending on the requested item. Error message describing why the request failed ### Cache Headers #### Without Query Parameters ```http theme={null} Cache-Control: public, max-age=86400, s-maxage=86400 ``` Responses are cached for 24 hours (86400 seconds) by browsers and CDNs. #### With Query Parameters ```http theme={null} Cache-Control: no-cache ``` Dynamic responses with overrides are not cached to ensure customizations are always applied. ## Examples ### Fetch Default Pairing ```bash cURL theme={null} curl https://www.fonttrio.xyz/api/r/minimal ``` ```javascript JavaScript theme={null} const response = await fetch('https://www.fonttrio.xyz/api/r/minimal'); const pairing = await response.json(); console.log(pairing.title); // "Minimal — Geist + Geist + Geist Mono" console.log(pairing.css.h1['font-size']); // "2.25rem" ``` ```python Python theme={null} import requests response = requests.get('https://www.fonttrio.xyz/api/r/minimal') pairing = response.json() print(pairing['title']) # "Minimal — Geist + Geist + Geist Mono" ``` ```typescript TypeScript theme={null} interface Pairing { name: string; title: string; css: Record>; } const response = await fetch('https://www.fonttrio.xyz/api/r/minimal'); const pairing: Pairing = await response.json(); ``` ### Fetch with Overrides ```bash cURL theme={null} curl "https://www.fonttrio.xyz/api/r/brutalist?h1-size=3.5rem&body-lh=1.7" ``` ```javascript JavaScript theme={null} const params = new URLSearchParams({ 'h1-size': '3.5rem', 'h1-weight': '900', 'body-lh': '1.7', 'body-ls': '0.01em' }); const response = await fetch( `https://www.fonttrio.xyz/api/r/brutalist?${params}` ); const pairing = await response.json(); // CSS properties are now overridden console.log(pairing.css.h1['font-size']); // "3.5rem" console.log(pairing.css.h1['font-weight']); // "900" ``` ```typescript TypeScript theme={null} interface TypographyOverrides { 'h1-size'?: string; 'h1-weight'?: string; 'body-lh'?: string; 'body-ls'?: string; } function buildPairingUrl( name: string, overrides?: TypographyOverrides ): string { const base = `https://www.fonttrio.xyz/api/r/${name}`; if (!overrides) return base; const params = new URLSearchParams( Object.entries(overrides).filter(([_, v]) => v !== undefined) as [string, string][] ); return `${base}?${params}`; } const url = buildPairingUrl('brutalist', { 'h1-size': '3.5rem', 'body-lh': '1.7' }); ``` ### Fetch Individual Font ```bash cURL theme={null} curl https://www.fonttrio.xyz/api/r/inter ``` ```javascript JavaScript theme={null} const response = await fetch('https://www.fonttrio.xyz/api/r/inter'); const font = await response.json(); console.log(font.font.family); // "Inter" console.log(font.font.provider); // "google" console.log(font.font.weight); // ["100", "200", ...] ``` ```typescript TypeScript theme={null} interface FontConfig { name: string; type: 'registry:font'; font: { family: string; provider: string; import: string; variable: string; weight: string[]; subsets: string[]; }; } const response = await fetch('https://www.fonttrio.xyz/api/r/roboto'); const font: FontConfig = await response.json(); ``` ### Error Handling ```javascript JavaScript theme={null} try { const response = await fetch('https://www.fonttrio.xyz/api/r/nonexistent'); if (!response.ok) { const error = await response.json(); console.error(error.error); // "Registry item \"nonexistent\" not found" return; } const data = await response.json(); // Process data... } catch (err) { console.error('Network error:', err); } ``` ```typescript TypeScript theme={null} interface ApiError { error: string; } async function fetchPairing(name: string) { const response = await fetch( `https://www.fonttrio.xyz/api/r/${name}` ); if (!response.ok) { const error: ApiError = await response.json(); throw new Error(error.error); } return response.json(); } try { const pairing = await fetchPairing('minimal'); } catch (error) { if (error instanceof Error) { console.error('Failed to fetch pairing:', error.message); } } ``` ## Implementation Details The endpoint is implemented in Next.js as a dynamic route handler: **Source**: `app/api/r/[name]/route.ts:8` Key behaviors: * Strips `.json` extension if provided in the URL * Searches pairings directory first, then fonts directory * Handles `pairing-` prefix automatically * Applies CSS overrides from query parameters only to matching selectors * Returns 404 if no matching registry item is found ## See Also Detailed schema for font pairing responses Schema for individual font configurations # Font Schema Source: https://kapishdima-fonttrio.mintlify.app/api/font-schema JSON schema for individual font configurations in the Fonttrio registry ## Overview Individual font configurations define a single typeface with all necessary metadata for loading it from a font provider (typically Google Fonts). Each font includes provider information, variable names, weights, and character subsets. ## Schema Structure ### Root Fields Unique identifier for the font, typically the font family name in lowercase with hyphens **Examples**: `"inter"`, `"roboto"`, `"source-code-pro"` Registry type identifier. Always `"registry:font"` for individual fonts. Human-readable font name, typically the proper font family name **Examples**: `"Inter"`, `"Roboto"`, `"Source Code Pro"` Brief description of the font, typically including classification **Format**: `"{Title} — {Classification} font."` **Examples**: * `"Inter — Sans Serif font."` * `"Roboto — Sans Serif font."` * `"Playfair Display — Serif font."` ### Font Configuration Complete font configuration for loading and usage The font family name as it should appear in CSS **Examples**: `"Inter"`, `"Roboto"`, `"Source Code Pro"` Font provider service **Value**: `"google"` (Google Fonts is the primary provider) Import name for loading the font from the provider Typically matches the `family` field **Examples**: `"Inter"`, `"Roboto"`, `"Source_Code_Pro"` CSS custom property name for the font **Format**: `"--font-{name}"` **Examples**: `"--font-inter"`, `"--font-roboto"`, `"--font-source-code-pro"` Array of available font weights **Values**: Weight values from `"100"` to `"900"` in increments of 100 **Example**: `["100", "200", "300", "400", "500", "600", "700", "800", "900"]` Not all fonts include all weights. Some fonts may only have: * `["400"]` — Single regular weight * `["400", "700"]` — Regular and bold * `["300", "400", "500", "600", "700"]` — Common range Array of character subsets supported by the font **Common subsets**: * `"menu"` — Basic menu characters * `"latin"` — Latin alphabet * `"latin-ext"` — Extended Latin characters * `"cyrillic"` — Cyrillic alphabet * `"cyrillic-ext"` — Extended Cyrillic * `"greek"` — Greek alphabet * `"greek-ext"` — Extended Greek * `"vietnamese"` — Vietnamese characters * `"arabic"` — Arabic script * `"hebrew"` — Hebrew script * `"japanese"` — Japanese characters * `"korean"` — Korean characters * `"chinese-simplified"` — Simplified Chinese * `"chinese-traditional"` — Traditional Chinese * `"devanagari"` — Devanagari script * `"thai"` — Thai script * `"math"` — Mathematical symbols * `"symbols"` — Additional symbols ## Complete Examples ### Inter Font A popular sans-serif font with extensive language support: ```json theme={null} { "name": "inter", "type": "registry:font", "title": "Inter", "description": "Inter — Sans Serif font.", "font": { "family": "Inter", "provider": "google", "import": "Inter", "variable": "--font-inter", "weight": [ "100", "200", "300", "400", "500", "600", "700", "800", "900" ], "subsets": [ "menu", "cyrillic", "cyrillic-ext", "greek", "greek-ext", "latin", "latin-ext", "vietnamese" ] } } ``` ### Roboto Font Google's ubiquitous Android font with comprehensive subset support: ```json theme={null} { "name": "roboto", "type": "registry:font", "title": "Roboto", "description": "Roboto — Sans Serif font.", "font": { "family": "Roboto", "provider": "google", "import": "Roboto", "variable": "--font-roboto", "weight": [ "100", "200", "300", "400", "500", "600", "700", "800", "900" ], "subsets": [ "menu", "cyrillic", "cyrillic-ext", "greek", "greek-ext", "latin", "latin-ext", "math", "symbols", "vietnamese" ] } } ``` ### Source Code Pro (Monospace) A monospace font designed for coding: ```json theme={null} { "name": "source-code-pro", "type": "registry:font", "title": "Source Code Pro", "description": "Source Code Pro — Monospace font.", "font": { "family": "Source Code Pro", "provider": "google", "import": "Source_Code_Pro", "variable": "--font-source-code-pro", "weight": [ "200", "300", "400", "500", "600", "700", "800", "900" ], "subsets": [ "menu", "cyrillic", "cyrillic-ext", "greek", "greek-ext", "latin", "latin-ext", "vietnamese" ] } } ``` ## Usage in Next.js ### Basic Font Loading ```typescript theme={null} import { NextResponse } from 'next/server'; interface FontConfig { name: string; type: 'registry:font'; title: string; font: { family: string; provider: string; import: string; variable: string; weight: string[]; subsets: string[]; }; } export async function loadFont(name: string): Promise { const response = await fetch(`https://www.fonttrio.xyz/api/r/${name}`); if (!response.ok) { throw new Error(`Font "${name}" not found`); } return response.json(); } // Usage const inter = await loadFont('inter'); console.log(inter.font.family); // "Inter" console.log(inter.font.variable); // "--font-inter" ``` ### Dynamic Font Loading with next/font/google ```typescript theme={null} import { NextResponse } from 'next/server'; interface FontConfig { font: { family: string; import: string; variable: string; weight: string[]; subsets: string[]; }; } async function loadFontConfig(name: string): Promise { const response = await fetch(`https://www.fonttrio.xyz/api/r/${name}`); return response.json(); } // In your app const config = await loadFontConfig('inter'); // Generate next/font configuration const fontConfig = { weight: config.font.weight, subsets: config.font.subsets.filter(s => s !== 'menu'), variable: config.font.variable, display: 'swap' as const, }; console.log(fontConfig); // { // weight: ["100", "200", ...], // subsets: ["latin", "latin-ext", ...], // variable: "--font-inter", // display: "swap" // } ``` ### Loading Multiple Fonts for a Pairing ```typescript theme={null} interface PairingDependencies { registryDependencies: string[]; } async function loadPairingFonts(pairingName: string) { // First, get the pairing to find dependencies const pairingResponse = await fetch( `https://www.fonttrio.xyz/api/r/${pairingName}` ); const pairing: PairingDependencies = await pairingResponse.json(); // Extract font names from URLs const fontNames = pairing.registryDependencies.map( url => url.split('/').pop()?.replace('.json', '') || '' ); // Load all fonts in parallel const fonts = await Promise.all( fontNames.map(name => fetch(`https://www.fonttrio.xyz/api/r/${name}`) .then(res => res.json()) ) ); return fonts; } // Usage const fonts = await loadPairingFonts('minimal'); console.log(fonts.map(f => f.font.family)); // ["Geist", "Geist Mono"] ``` ## Font Classification Fonts in the registry are typically classified as: | Classification | Description | Examples | | --------------- | ---------------------------------------- | -------------------------------------------- | | **Sans Serif** | Modern, clean fonts without serifs | Inter, Roboto, Work Sans | | **Serif** | Traditional fonts with decorative serifs | Playfair Display, PT Serif, Source Serif 4 | | **Monospace** | Fixed-width fonts for code | Source Code Pro, Roboto Mono, JetBrains Mono | | **Display** | Decorative fonts for headlines | Archivo Black, Bebas Neue | | **Handwriting** | Script and handwritten styles | Pacifico, Satisfy | ## Weight Ranges ### Full Range (100-900) Most variable fonts and comprehensive font families: ```json theme={null} ["100", "200", "300", "400", "500", "600", "700", "800", "900"] ``` ### Standard Range (300-700) Common for many sans-serif fonts: ```json theme={null} ["300", "400", "500", "600", "700"] ``` ### Basic (400, 700) Minimal font files with regular and bold: ```json theme={null} ["400", "700"] ``` ### Single Weight Display or specialized fonts: ```json theme={null} ["400"] ``` ## Common Subset Combinations ### Western Languages ```json theme={null} ["menu", "latin", "latin-ext"] ``` ### Western + European ```json theme={null} ["menu", "cyrillic", "cyrillic-ext", "greek", "latin", "latin-ext"] ``` ### Comprehensive (Most Google Fonts) ```json theme={null} [ "menu", "cyrillic", "cyrillic-ext", "greek", "greek-ext", "latin", "latin-ext", "vietnamese" ] ``` ### With Symbols ```json theme={null} [ "menu", "latin", "latin-ext", "math", "symbols" ] ``` ## Fetching Font Data ### Direct API Call ```bash cURL theme={null} curl https://www.fonttrio.xyz/api/r/inter ``` ```javascript JavaScript theme={null} const response = await fetch('https://www.fonttrio.xyz/api/r/inter'); const font = await response.json(); console.log(font.font.family); // "Inter" console.log(font.font.weight); // ["100", "200", ...] ``` ```python Python theme={null} import requests response = requests.get('https://www.fonttrio.xyz/api/r/roboto') font = response.json() print(font['font']['family']) # "Roboto" print(font['font']['subsets']) # ["menu", "latin", ...] ``` ## See Also Schema for complete font pairings Complete endpoint reference with examples # getAllGoogleFontsUrls Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-all-google-fonts-urls Get all Google Fonts URLs used across font pairings # getAllGoogleFontsUrls Returns an array of all unique Google Fonts URLs used across all font pairings in the registry. ## Function Signature ```typescript lib/pairings.ts theme={null} export function getAllGoogleFontsUrls(): string[] ``` ## Returns Array of all unique Google Fonts URLs across all pairings ## Description The `getAllGoogleFontsUrls()` function extracts and returns all unique Google Fonts URLs from every pairing in the registry. Each URL contains the font families and weights needed for a pairing. This is useful for preloading fonts, analyzing font usage, or building font loading strategies. ## Usage Examples ### Basic Usage ```typescript theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' const urls = getAllGoogleFontsUrls() console.log(urls) // Output: [ // 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700...', // 'https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700...', // ... // ] ``` ### Preload All Fonts ```tsx theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' export function FontPreloader() { const urls = getAllGoogleFontsUrls() return ( <> {urls.map(url => ( ))} ) } ``` ### Generate Font Loading Stylesheet ```typescript theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' export function generateFontStylesheet(): string { const urls = getAllGoogleFontsUrls() return urls .map(url => `@import url('${url}');`) .join('\n') } // Usage const stylesheet = generateFontStylesheet() console.log(stylesheet) // Output: // @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500...'); // @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600...'); ``` ### Check Font Loading Performance ```typescript theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' async function analyzeFontLoadTimes() { const urls = getAllGoogleFontsUrls() const results = [] for (const url of urls) { const start = performance.now() await fetch(url) const duration = performance.now() - start results.push({ url, duration }) } return results.sort((a, b) => b.duration - a.duration) } ``` ### Generate Next.js Font Configuration ```typescript theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' function extractFontFamilies(urls: string[]) { return urls.map(url => { const match = url.match(/family=([^:&]+)/) return match ? match[1].replace(/\+/g, ' ') : null }).filter(Boolean) } const urls = getAllGoogleFontsUrls() const families = extractFontFamilies(urls) console.log(families) // Output: ['Inter', 'Playfair Display', 'Source Serif 4', ...] ``` ### Build Font Subset Optimizer ```typescript theme={null} import { getAllGoogleFontsUrls } from '@/lib/pairings' function optimizeFontUrls(urls: string[], subsets: string[] = ['latin']) { return urls.map(url => { const hasSubset = url.includes('subset=') if (hasSubset) return url const separator = url.includes('?') ? '&' : '?' return `${url}${separator}display=swap&subset=${subsets.join(',')}` }) } const urls = getAllGoogleFontsUrls() const optimized = optimizeFontUrls(urls, ['latin', 'latin-ext']) ``` ## URL Format Each Google Fonts URL follows this format: ``` https://fonts.googleapis.com/css2?family=Font+Name:wght@weights&display=swap ``` Example: ``` https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap ``` URLs typically include multiple font families (heading, body, mono) with their respective weights combined in a single request for optimal loading performance. ## Related Functions Get Google Fonts URL for a specific pairing Get all available pairings ## Notes * URLs are extracted from the `googleFontsUrl` field of each pairing * The function deduplicates URLs automatically using a Set * Returns an array of strings in no particular order * Pairings without a `googleFontsUrl` are skipped (though all current pairings include this field) * Each URL is already optimized with `display=swap` for better performance * Performance: O(n) where n is the number of pairings ## Best Practices Add preconnect hints in your HTML head to speed up font loading: ```html theme={null} ``` All Fonttrio URLs include `display=swap` by default, which shows fallback text immediately while fonts load. Consider adding subset parameters if you only need specific character sets (latin, latin-ext, cyrillic, etc.). ## Source Reference Implementation: `lib/pairings.ts:53-61` # getAllMoods Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-all-moods Get all mood tags used across font pairings # getAllMoods Returns an array of all unique mood tags used across all font pairings in the registry. ## Function Signature ```typescript lib/pairings.ts theme={null} export function getAllMoods(): string[] ``` ## Returns Array of all unique mood tags across all pairings ## Description The `getAllMoods()` function extracts and returns all unique mood values from the mood arrays of every pairing in the registry. This is useful for building filter UIs, discovering available mood categories, or analyzing the collection. ## Usage Examples ### Basic Usage ```typescript theme={null} import { getAllMoods } from '@/lib/pairings' const moods = getAllMoods() console.log(moods) // Output: ['minimal', 'modern', 'editorial', 'literary', 'bold', ...] ``` ### Build a Filter UI ```tsx theme={null} import { getAllMoods } from '@/lib/pairings' export function MoodFilter({ onSelect }: { onSelect: (mood: string) => void }) { const moods = getAllMoods() return (
{moods.map(mood => ( ))}
) } ``` ### Count Pairings Per Mood ```typescript theme={null} import { getAllMoods, getPairingsByMood } from '@/lib/pairings' const moods = getAllMoods() const moodStats = moods.map(mood => ({ mood, count: getPairingsByMood(mood).length })) console.log(moodStats) // Output: [{ mood: 'minimal', count: 5 }, { mood: 'editorial', count: 8 }, ...] ``` ### Generate Mood Tag Cloud ```tsx theme={null} import { getAllMoods, getPairingsByMood } from '@/lib/pairings' export function MoodCloud() { const moods = getAllMoods() return (
{moods.map(mood => { const count = getPairingsByMood(mood).length const size = Math.min(20 + count * 2, 36) return ( {mood} ) })}
) } ``` ### Validate Mood Input ```typescript theme={null} import { getAllMoods } from '@/lib/pairings' function isValidMood(mood: string): boolean { const validMoods = getAllMoods() return validMoods.includes(mood) } // Usage in API route export async function GET(request: Request) { const { searchParams } = new URL(request.url) const mood = searchParams.get('mood') if (mood && !isValidMood(mood)) { return Response.json({ error: 'Invalid mood' }, { status: 400 }) } // ... rest of handler } ``` ## Common Mood Tags The registry includes moods such as: * **Style**: `minimal`, `modern`, `clean`, `brutalist`, `nordic` * **Tone**: `editorial`, `literary`, `professional`, `friendly`, `playful` * **Usage**: `structured`, `systematic`, `versatile`, `readable` * **Character**: `bold`, `impactful`, `sophisticated`, `warm`, `distinctive` The exact list of moods may change as new pairings are added to the registry. Always call `getAllMoods()` to get the current list. ## Related Functions Filter pairings by a specific mood tag Get all available pairings ## Notes * Moods are extracted from the `mood` array field of each pairing * The function deduplicates moods automatically using a Set * Returns an array of strings in no particular order * Empty array is returned only if no pairings exist (should never happen in production) * Performance: O(n × m) where n is number of pairings and m is average moods per pairing ## Source Reference Implementation: `lib/pairings.ts:47-51` # getAllPairings Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-all-pairings Retrieve all available font pairings from the Fonttrio registry ## Function Signature ```typescript theme={null} function getAllPairings(): PairingData[] ``` ## Description Returns the complete array of all font pairings available in Fonttrio. This function provides access to the entire curated collection of typography combinations, each with detailed configuration including heading fonts, body fonts, monospace fonts, mood tags, use cases, and typography scales. ## Parameters This function takes no parameters. ## Return Value An array of all available font pairings. Each `PairingData` object contains: Unique identifier for the pairing (e.g., "agency", "architect") Font family name for headings (e.g., "Schibsted Grotesk") Category of the heading font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for body text (e.g., "Karla") Category of the body font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for monospace/code text (e.g., "Fira Code") Array of mood tags (e.g., \["minimal", "nordic"]) Array of recommended use cases (e.g., \["agency", "design", "portfolio"]) Human-readable description of the pairing's aesthetic and personality Complete typography scale with configurations for h1-h6 and body text, including size, weight, line height, and letter spacing Ready-to-use Google Fonts URL with all required font weights ## Usage Examples ```typescript Basic Usage theme={null} import { getAllPairings } from '@/lib/pairings'; const allPairings = getAllPairings(); console.log(`Total pairings available: ${allPairings.length}`); ``` ```typescript List All Pairing Names theme={null} import { getAllPairings } from '@/lib/pairings'; const pairings = getAllPairings(); const names = pairings.map(p => p.name); console.log('Available pairings:', names); // Output: ['agency', 'architect', ...] ``` ```typescript Display Pairing Options theme={null} import { getAllPairings } from '@/lib/pairings'; function PairingSelector() { const pairings = getAllPairings(); return ( ); } ``` ```typescript Filter by Font Category theme={null} import { getAllPairings } from '@/lib/pairings'; const allPairings = getAllPairings(); const serifHeadings = allPairings.filter( p => p.headingCategory === 'serif' ); console.log(`Pairings with serif headings: ${serifHeadings.length}`); ``` ```typescript Get Google Fonts URLs theme={null} import { getAllPairings } from '@/lib/pairings'; const pairings = getAllPairings(); const googleFontsUrls = pairings.map(p => p.googleFontsUrl); // Preload all fonts googleFontsUrls.forEach(url => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = url; document.head.appendChild(link); }); ``` ## Example Response ```json theme={null} [ { "name": "agency", "heading": "Schibsted Grotesk", "headingCategory": "sans-serif", "body": "Karla", "bodyCategory": "sans-serif", "mono": "Fira Code", "mood": ["minimal", "nordic"], "useCase": ["agency", "design", "portfolio"], "description": "Nordic minimalism meets grotesque warmth. Schibsted Grotesk's Scandinavian clarity in headlines paired with Karla's quirky grotesque personality for body text that feels human.", "scale": { "h1": { "size": "2.25rem", "weight": 700, "lineHeight": "1.15", "letterSpacing": "-0.03em" }, "h2": { "size": "1.875rem", "weight": 600, "lineHeight": "1.2", "letterSpacing": "-0.025em" }, "body": { "size": "1rem", "lineHeight": "1.6", "weight": 400 } }, "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@400;500;600;700&family=Karla:wght@400;500;600&family=Fira+Code:wght@400;500&display=swap" } ] ``` ## Notes **Performance**: This function returns the entire pairings array. The data is loaded once from `pairings-data.ts` and cached in memory, making subsequent calls very fast. **Data Source**: The pairings data is auto-generated from `registry/pairings/*.json` files. Do not edit `lib/pairings-data.ts` manually. For filtered results, consider using specialized functions like [`getPairingsByMood`](/api/functions/get-pairings-by-mood) or [`getPairingsByCategory`](/api/functions/get-pairings-by-category) instead of filtering manually. # getPairing Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-pairing Retrieve a specific font pairing by its unique name ## Function Signature ```typescript theme={null} function getPairing(name: string): PairingData | undefined ``` ## Description Retrieves a single font pairing by its unique identifier. This function searches through the Fonttrio registry and returns the matching pairing configuration, or `undefined` if no pairing with the given name exists. ## Parameters The unique identifier of the pairing to retrieve. Examples include: * `"agency"` - Nordic minimalism with Schibsted Grotesk * `"architect"` - Structured design with Outfit * `"minimal"` - Clean, modern aesthetics Name matching is case-sensitive and must match exactly. ## Return Value Returns the matching `PairingData` object if found, or `undefined` if no pairing exists with the given name. Unique identifier for the pairing Font family name for headings Category of the heading font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for body text Category of the body font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for monospace/code text Array of mood tags describing the aesthetic Array of recommended use cases Human-readable description of the pairing Complete typography scale with h1-h6 and body configurations Ready-to-use Google Fonts URL ## Usage Examples ```typescript Basic Usage theme={null} import { getPairing } from '@/lib/pairings'; const agencyPairing = getPairing('agency'); if (agencyPairing) { console.log(`Heading: ${agencyPairing.heading}`); console.log(`Body: ${agencyPairing.body}`); } else { console.log('Pairing not found'); } ``` ```typescript With Error Handling theme={null} import { getPairing } from '@/lib/pairings'; function loadPairing(pairingName: string) { const pairing = getPairing(pairingName); if (!pairing) { throw new Error(`Pairing "${pairingName}" not found`); } return pairing; } try { const pairing = loadPairing('agency'); console.log('Loaded:', pairing.name); } catch (error) { console.error(error.message); } ``` ```typescript Apply Typography Scale theme={null} import { getPairing } from '@/lib/pairings'; function applyPairingStyles(pairingName: string) { const pairing = getPairing(pairingName); if (!pairing) return; // Apply to CSS custom properties document.documentElement.style.setProperty( '--font-heading', pairing.heading ); document.documentElement.style.setProperty( '--font-body', pairing.body ); document.documentElement.style.setProperty( '--h1-size', pairing.scale.h1.size ); document.documentElement.style.setProperty( '--h1-weight', pairing.scale.h1.weight.toString() ); } applyPairingStyles('architect'); ``` ```typescript Load Google Fonts theme={null} import { getPairing } from '@/lib/pairings'; function loadPairingFonts(pairingName: string): boolean { const pairing = getPairing(pairingName); if (!pairing) return false; const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = pairing.googleFontsUrl; document.head.appendChild(link); return true; } loadPairingFonts('agency'); ``` ```typescript React Component theme={null} import { getPairing } from '@/lib/pairings'; import { useEffect, useState } from 'react'; function PairingPreview({ name }: { name: string }) { const [pairing, setPairing] = useState(getPairing(name)); useEffect(() => { setPairing(getPairing(name)); }, [name]); if (!pairing) { return
Pairing not found
; } return (

{pairing.heading}

{pairing.description}

const example = true;
); } ```
## Example Response ```json theme={null} { "name": "architect", "heading": "Outfit", "headingCategory": "sans-serif", "body": "Libre Baskerville", "bodyCategory": "serif", "mono": "IBM Plex Mono", "mood": ["structured", "professional"], "useCase": ["portfolio", "agency", "architecture"], "description": "Structured meets refined. Outfit's geometric precision in headings contrasts beautifully with Libre Baskerville's warm readability, like blueprints meeting handwritten notes.", "scale": { "h1": { "size": "2.5rem", "weight": 700, "lineHeight": "1.1", "letterSpacing": "-0.03em" }, "h2": { "size": "2rem", "weight": 600, "lineHeight": "1.15", "letterSpacing": "-0.025em" }, "body": { "size": "1rem", "lineHeight": "1.6", "weight": 400 } }, "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Libre+Baskerville:wght@400;700&family=IBM+Plex+Mono:wght@400;500&display=swap" } ``` ## Notes **Case Sensitivity**: Pairing names are case-sensitive. `"Agency"` will not match `"agency"`. Always use lowercase names as defined in the registry. **Performance**: This function uses `Array.find()` which has O(n) complexity. For repeated lookups, consider caching the result or using a Map-based lookup if you need frequent access. Always check for `undefined` before using the returned value. TypeScript will help enforce this check at compile time. ## Related Functions * [`getAllPairings`](/api/functions/get-all-pairings) - Get all available pairings * [`getPairingsByMood`](/api/functions/get-pairings-by-mood) - Filter pairings by mood * [`getPairingsByCategory`](/api/functions/get-pairings-by-category) - Filter pairings by font category # getPairingGoogleFontsUrl Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-pairing-google-fonts-url Get the Google Fonts URL for a specific font pairing # getPairingGoogleFontsUrl Returns the Google Fonts URL for a specific font pairing by name. ## Function Signature ```typescript lib/pairings.ts theme={null} export function getPairingGoogleFontsUrl(name: string): string | null ``` ## Parameters The name of the pairing (e.g., "editorial", "minimal", "brutalist") ## Returns The Google Fonts URL for the pairing, or `null` if the pairing is not found or has no URL configured ## Description The `getPairingGoogleFontsUrl()` function retrieves the Google Fonts URL for a specific pairing. This URL includes all three fonts (heading, body, mono) with their required weights, optimized for loading in a single request. ## Usage Examples ### Basic Usage ```typescript theme={null} import { getPairingGoogleFontsUrl } from '@/lib/pairings' const url = getPairingGoogleFontsUrl('editorial') console.log(url) // Output: "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&family=Source+Serif+4:wght@400;600&family=JetBrains+Mono:wght@400;500&display=swap" ``` ### Load Fonts Dynamically ```typescript theme={null} import { getPairingGoogleFontsUrl } from '@/lib/pairings' function loadPairingFonts(pairingName: string) { const url = getPairingGoogleFontsUrl(pairingName) if (!url) { console.error(`No Google Fonts URL found for pairing: ${pairingName}`) return } // Create and inject stylesheet const link = document.createElement('link') link.rel = 'stylesheet' link.href = url document.head.appendChild(link) } // Usage loadPairingFonts('minimal') ``` ### Preload Pairing Fonts ```tsx theme={null} import { getPairingGoogleFontsUrl } from '@/lib/pairings' export function PairingFontLoader({ pairing }: { pairing: string }) { const url = getPairingGoogleFontsUrl(pairing) if (!url) return null return ( ) } // Usage in layout ``` ### Next.js Font Loading ```tsx theme={null} 'use client' import { useEffect, useState } from 'react' import { getPairingGoogleFontsUrl } from '@/lib/pairings' export function DynamicFontLoader({ pairing }: { pairing: string }) { const [loaded, setLoaded] = useState(false) useEffect(() => { const url = getPairingGoogleFontsUrl(pairing) if (!url) return const link = document.createElement('link') link.rel = 'stylesheet' link.href = url link.onload = () => setLoaded(true) document.head.appendChild(link) return () => { document.head.removeChild(link) } }, [pairing]) return loaded ? (
Fonts loaded!
) : (
Loading fonts...
) } ``` ### Error Handling ```typescript theme={null} import { getPairingGoogleFontsUrl } from '@/lib/pairings' function getFontsUrlSafely(pairingName: string): string { const url = getPairingGoogleFontsUrl(pairingName) if (!url) { throw new Error(`Pairing "${pairingName}" not found or has no Google Fonts URL`) } return url } // Usage with try/catch try { const url = getFontsUrlSafely('nonexistent') console.log(url) } catch (error) { console.error(error.message) // Fallback to default fonts } ``` ### Generate Font Preconnect Tags ```tsx theme={null} import { getPairingGoogleFontsUrl } from '@/lib/pairings' export function FontPreconnect({ pairing }: { pairing: string }) { const url = getPairingGoogleFontsUrl(pairing) if (!url) return null return ( <> ) } ``` ## URL Format The returned URL follows the Google Fonts API v2 format: ``` https://fonts.googleapis.com/css2?family=Font1:wght@weights&family=Font2:wght@weights&display=swap ``` Example for the "Editorial" pairing: ``` https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&family=Source+Serif+4:wght@400;600&family=JetBrains+Mono:wght@400;500&display=swap ``` This URL includes: * **Heading font**: Playfair Display (weights: 600, 700) * **Body font**: Source Serif 4 (weights: 400, 600) * **Mono font**: JetBrains Mono (weights: 400, 500) * **Display strategy**: swap (shows fallback text immediately) ## Return Value * Returns the full Google Fonts URL as a string if the pairing exists * Returns `null` if: * The pairing name is not found in the registry * The pairing exists but has no `googleFontsUrl` field (rare) Always check for `null` before using the returned URL to avoid runtime errors. ## Related Functions Get full pairing data including fonts and scale Get all Google Fonts URLs across pairings ## Notes * The function internally calls `getPairing()` to fetch the pairing data * Pairing names are case-sensitive (use lowercase names like "editorial", not "Editorial") * All current pairings include a Google Fonts URL, but the function returns `null` for safety * URLs include `display=swap` for optimal loading performance * Performance: O(n) where n is the number of pairings (linear search) ## Common Pairings * `editorial` - Playfair Display + Source Serif 4 + JetBrains Mono * `literary` - EB Garamond + Crimson Text + Inconsolata * `newspaper` - Playfair Display + DM Sans + JetBrains Mono * `minimal` - Inter + Inter + JetBrains Mono * `modern-clean` - Space Grotesk + Space Grotesk + Space Mono * `swiss` - Work Sans + Work Sans + Source Code Pro * `brutalist` - Space Grotesk + Space Grotesk + Space Mono * `impact` - Bebas Neue + Barlow + Fira Code * `poster` - Alfa Slab One + Assistant + Roboto Mono ## Source Reference Implementation: `lib/pairings.ts:63-66` # getPairingsByCategory Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-pairings-by-category Retrieve font pairings filtered by heading font category ## Function Signature ```typescript theme={null} function getPairingsByCategory(category: FontCategory): PairingData[] ``` ## Description Filters and returns all font pairings where the heading font matches the specified category. This is useful when you want to enforce a specific typographic style for headings, such as all serif headings for a traditional look or sans-serif for modern designs. The function filters based on the `headingCategory` property, not the body font category. ## Parameters The font category to filter by. Must be one of: * `"serif"` - Traditional fonts with decorative strokes (e.g., Libre Baskerville, Merriweather) * `"sans-serif"` - Modern fonts without decorative strokes (e.g., Outfit, Schibsted Grotesk) * `"monospace"` - Fixed-width fonts for code and technical content (e.g., IBM Plex Mono, Fira Code) Category matching is case-sensitive and must match exactly. ## Return Value An array of font pairings where the heading font belongs to the specified category. Returns an empty array if no pairings match. Each `PairingData` object contains: Unique identifier for the pairing Font family name for headings Category of the heading font (matches the search parameter) Font family name for body text Category of the body font (may differ from heading category) Font family name for monospace/code text Array of mood tags Array of recommended use cases Human-readable description of the pairing Complete typography scale configuration Ready-to-use Google Fonts URL ## Usage Examples ```typescript Basic Usage theme={null} import { getPairingsByCategory } from '@/lib/pairings'; const sansSerifPairings = getPairingsByCategory('sans-serif'); console.log(`Found ${sansSerifPairings.length} sans-serif pairings`); sansSerifPairings.forEach(p => { console.log(`${p.name}: ${p.heading} (${p.headingCategory})`); }); ``` ```typescript Category Filter Component theme={null} import { getPairingsByCategory } from '@/lib/pairings'; import { useState } from 'react'; import type { FontCategory } from '@/lib/pairings'; function CategoryFilter() { const [category, setCategory] = useState('sans-serif'); const pairings = getPairingsByCategory(category); return (
{pairings.map(pairing => (

{pairing.heading}

+ {pairing.body}

))}
); } ``` ```typescript Find Contrasting Pairings theme={null} import { getPairingsByCategory } from '@/lib/pairings'; import type { PairingData } from '@/lib/pairings'; // Find pairings where heading and body have different categories function getContrastingPairings(): PairingData[] { const allCategories: FontCategory[] = ['serif', 'sans-serif', 'monospace']; const contrasting: PairingData[] = []; allCategories.forEach(category => { const pairings = getPairingsByCategory(category); const filtered = pairings.filter( p => p.bodyCategory !== p.headingCategory ); contrasting.push(...filtered); }); return contrasting; } const contrasting = getContrastingPairings(); console.log(`${contrasting.length} pairings with contrasting categories`); ``` ```typescript Category Statistics theme={null} import { getPairingsByCategory } from '@/lib/pairings'; import type { FontCategory } from '@/lib/pairings'; function getCategoryStats() { const categories: FontCategory[] = ['serif', 'sans-serif', 'monospace']; return categories.map(category => ({ category, count: getPairingsByCategory(category).length, pairings: getPairingsByCategory(category) .map(p => p.name) .join(', ') })); } const stats = getCategoryStats(); stats.forEach(({ category, count, pairings }) => { console.log(`${category}: ${count}`); console.log(` ${pairings}`); }); ``` ```typescript Type-Safe Category Selection theme={null} import { getPairingsByCategory } from '@/lib/pairings'; import type { FontCategory, PairingData } from '@/lib/pairings'; interface DesignPreferences { headingStyle: FontCategory; modernLook: boolean; } function selectPairingByPreferences( prefs: DesignPreferences ): PairingData | null { const candidates = getPairingsByCategory(prefs.headingStyle); if (prefs.modernLook) { // Prefer sans-serif body fonts for modern look const modern = candidates.filter(p => p.bodyCategory === 'sans-serif'); return modern[0] || candidates[0] || null; } return candidates[0] || null; } const pairing = selectPairingByPreferences({ headingStyle: 'sans-serif', modernLook: true }); if (pairing) { console.log(`Selected: ${pairing.name}`); } ``` ```typescript Get All Categories with Counts theme={null} import { getPairingsByCategory } from '@/lib/pairings'; import type { FontCategory } from '@/lib/pairings'; function getCategoryCounts(): Record { return { 'serif': getPairingsByCategory('serif').length, 'sans-serif': getPairingsByCategory('sans-serif').length, 'monospace': getPairingsByCategory('monospace').length }; } const counts = getCategoryCounts(); console.log('Pairings by category:', counts); // Output: { serif: 5, sans-serif: 12, monospace: 1 } ```
## Example Response ```json theme={null} [ { "name": "agency", "heading": "Schibsted Grotesk", "headingCategory": "sans-serif", "body": "Karla", "bodyCategory": "sans-serif", "mono": "Fira Code", "mood": ["minimal", "nordic"], "useCase": ["agency", "design", "portfolio"], "description": "Nordic minimalism meets grotesque warmth. Schibsted Grotesk's Scandinavian clarity in headlines paired with Karla's quirky grotesque personality for body text that feels human.", "scale": { "h1": { "size": "2.25rem", "weight": 700, "lineHeight": "1.15", "letterSpacing": "-0.03em" }, "body": { "size": "1rem", "lineHeight": "1.6", "weight": 400 } }, "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@400;500;600;700&family=Karla:wght@400;500;600&family=Fira+Code:wght@400;500&display=swap" }, { "name": "architect", "heading": "Outfit", "headingCategory": "sans-serif", "body": "Libre Baskerville", "bodyCategory": "serif", "mono": "IBM Plex Mono", "mood": ["structured", "professional"], "useCase": ["portfolio", "agency", "architecture"], "description": "Structured meets refined. Outfit's geometric precision in headings contrasts beautifully with Libre Baskerville's warm readability, like blueprints meeting handwritten notes.", "scale": { "h1": { "size": "2.5rem", "weight": 700, "lineHeight": "1.1", "letterSpacing": "-0.03em" }, "body": { "size": "1rem", "lineHeight": "1.6", "weight": 400 } }, "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Libre+Baskerville:wght@400;700&family=IBM+Plex+Mono:wght@400;500&display=swap" } ] ``` ## Notes **Heading Category Only**: This function filters by `headingCategory`, not `bodyCategory`. The body font may be in a different category, which often creates interesting typographic contrast. **Type Safety**: Use the `FontCategory` type from `@/lib/pairings` to ensure type safety. Invalid category strings will still execute but return an empty array. For modern web designs, `sans-serif` heading categories are most popular. For traditional or editorial designs, consider `serif` categories. **Performance**: This function filters the entire pairings array on each call. Consider caching results if calling repeatedly with the same category. ## Common Patterns ### Serif Headings Serif heading fonts create a traditional, authoritative, or editorial feel. Common for: * News and magazine sites * Academic publications * Literary content * Traditional brands ### Sans-serif Headings Sans-serif heading fonts create a modern, clean, minimal feel. Common for: * Tech startups * SaaS products * Modern agencies * Portfolio sites ### Monospace Headings Monospace heading fonts create a technical, code-focused feel. Common for: * Developer tools * Technical documentation * Code-heavy sites * Retro/terminal aesthetics ## Related Functions * [`getAllPairings`](/api/functions/get-all-pairings) - Get all available pairings * [`getPairing`](/api/functions/get-pairing) - Get a specific pairing by name * [`getPairingsByMood`](/api/functions/get-pairings-by-mood) - Filter by mood tag # getPairingsByMood Source: https://kapishdima-fonttrio.mintlify.app/api/functions/get-pairings-by-mood Retrieve font pairings filtered by mood tag ## Function Signature ```typescript theme={null} function getPairingsByMood(mood: string): PairingData[] ``` ## Description Filters and returns all font pairings that include the specified mood tag. Each pairing can have multiple mood tags, and this function returns all pairings where the specified mood appears in the `mood` array. Mood tags describe the aesthetic feeling and personality of a font pairing, such as "minimal", "professional", "playful", "elegant", etc. ## Parameters The mood tag to filter by. Common mood values include: * `"minimal"` - Clean, uncluttered aesthetic * `"professional"` - Business-appropriate and formal * `"nordic"` - Scandinavian-inspired simplicity * `"structured"` - Organized and geometric * `"playful"` - Fun and creative * `"elegant"` - Refined and sophisticated Mood matching is case-sensitive and must match exactly. ## Return Value An array of font pairings that contain the specified mood tag. Returns an empty array if no pairings match the mood. Each `PairingData` object contains: Unique identifier for the pairing Font family name for headings Category of the heading font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for body text Category of the body font: `"serif"`, `"sans-serif"`, or `"monospace"` Font family name for monospace/code text Array of mood tags (includes the searched mood) Array of recommended use cases Human-readable description of the pairing Complete typography scale configuration Ready-to-use Google Fonts URL ## Usage Examples ```typescript Basic Usage theme={null} import { getPairingsByMood } from '@/lib/pairings'; const minimalPairings = getPairingsByMood('minimal'); console.log(`Found ${minimalPairings.length} minimal pairings`); minimalPairings.forEach(p => { console.log(`- ${p.name}: ${p.heading} + ${p.body}`); }); ``` ```typescript Filter UI Component theme={null} import { getPairingsByMood } from '@/lib/pairings'; import { useState } from 'react'; function MoodFilter() { const [selectedMood, setSelectedMood] = useState('minimal'); const pairings = getPairingsByMood(selectedMood); return (
{pairings.map(pairing => (

{pairing.name}

{pairing.description}

))}
); } ``` ```typescript Check If Mood Exists theme={null} import { getPairingsByMood } from '@/lib/pairings'; function hasPairingsForMood(mood: string): boolean { return getPairingsByMood(mood).length > 0; } if (hasPairingsForMood('nordic')) { console.log('Nordic pairings available'); } else { console.log('No nordic pairings found'); } ``` ```typescript Get Multiple Moods theme={null} import { getPairingsByMood } from '@/lib/pairings'; function getPairingsByMoods(moods: string[]): PairingData[] { const results = new Map(); moods.forEach(mood => { const pairings = getPairingsByMood(mood); pairings.forEach(p => results.set(p.name, p)); }); return Array.from(results.values()); } // Get all pairings that are either minimal OR professional const versatilePairings = getPairingsByMoods(['minimal', 'professional']); console.log(`Found ${versatilePairings.length} versatile pairings`); ``` ```typescript Mood-Based Recommendation theme={null} import { getPairingsByMood } from '@/lib/pairings'; function recommendPairingForProject( projectType: 'startup' | 'corporate' | 'creative' ): PairingData | null { const moodMap = { startup: 'minimal', corporate: 'professional', creative: 'playful' }; const mood = moodMap[projectType]; const pairings = getPairingsByMood(mood); // Return first matching pairing return pairings[0] || null; } const recommended = recommendPairingForProject('startup'); if (recommended) { console.log(`Recommended: ${recommended.name}`); } ``` ```typescript Display Mood Statistics theme={null} import { getPairingsByMood, getAllMoods } from '@/lib/pairings'; function getMoodStatistics() { const allMoods = getAllMoods(); return allMoods.map(mood => ({ mood, count: getPairingsByMood(mood).length })).sort((a, b) => b.count - a.count); } const stats = getMoodStatistics(); stats.forEach(({ mood, count }) => { console.log(`${mood}: ${count} pairings`); }); ```
## Example Response ```json theme={null} [ { "name": "agency", "heading": "Schibsted Grotesk", "headingCategory": "sans-serif", "body": "Karla", "bodyCategory": "sans-serif", "mono": "Fira Code", "mood": ["minimal", "nordic"], "useCase": ["agency", "design", "portfolio"], "description": "Nordic minimalism meets grotesque warmth. Schibsted Grotesk's Scandinavian clarity in headlines paired with Karla's quirky grotesque personality for body text that feels human.", "scale": { "h1": { "size": "2.25rem", "weight": 700, "lineHeight": "1.15", "letterSpacing": "-0.03em" }, "body": { "size": "1rem", "lineHeight": "1.6", "weight": 400 } }, "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@400;500;600;700&family=Karla:wght@400;500;600&family=Fira+Code:wght@400;500&display=swap" } ] ``` ## Notes **Multiple Moods**: Each pairing can have multiple mood tags. A pairing tagged with `["minimal", "nordic"]` will be returned when searching for either "minimal" or "nordic". **Case Sensitivity**: Mood matching is case-sensitive. `"Minimal"` will not match `"minimal"`. Always use lowercase mood values as defined in the registry. Use the `getAllMoods()` function to get a complete list of available mood tags in the registry. **Performance**: This function filters the entire pairings array on each call. For frequently accessed mood filters in production, consider caching the results. ## Related Functions * [`getAllPairings`](/api/functions/get-all-pairings) - Get all available pairings * [`getPairing`](/api/functions/get-pairing) - Get a specific pairing by name * [`getPairingsByCategory`](/api/functions/get-pairings-by-category) - Filter by font category * `getAllMoods` - Get all available mood tags (see lib/pairings.ts:47) # API Overview Source: https://kapishdima-fonttrio.mintlify.app/api/overview Access Fonttrio font pairings and fonts through a simple REST API ## Introduction The Fonttrio Registry API provides programmatic access to curated font pairings and individual font configurations. The API serves JSON files from the registry that can be directly integrated into your projects. ## Base URL ``` https://www.fonttrio.xyz/api/r/ ``` All API endpoints are relative to this base URL. ## Authentication No authentication is required. The API is publicly accessible and free to use. ## Rate Limiting There are no explicit rate limits, but please be respectful of the service. The API is designed for: * Build-time fetching of font configurations * Client-side dynamic loading of font pairings * CLI tools and automation scripts ## Caching The API implements intelligent caching behavior: ### Static Requests (No Query Parameters) * **Cache-Control**: `public, max-age=86400, s-maxage=86400` * Cached for 24 hours by browsers and CDNs * Ideal for production deployments ### Dynamic Requests (With Query Parameters) * **Cache-Control**: `no-cache` * Not cached to ensure parameter overrides are always applied * Used for customizing font styles on-the-fly ## Common Use Cases ### 1. Fetch a Font Pairing Retrieve a complete font pairing configuration with heading, body, and mono fonts: ```javascript theme={null} const response = await fetch('https://www.fonttrio.xyz/api/r/minimal'); const pairing = await response.json(); ``` ### 2. Fetch an Individual Font Get configuration for a single font: ```javascript theme={null} const response = await fetch('https://www.fonttrio.xyz/api/r/inter'); const font = await response.json(); ``` ### 3. Customize Typography On-The-Fly Override specific CSS properties using query parameters: ```javascript theme={null} const response = await fetch( 'https://www.fonttrio.xyz/api/r/minimal?h1-size=3rem&body-lh=1.8' ); const customPairing = await response.json(); ``` ### 4. Build-Time Integration Use in Next.js or other frameworks during build: ```typescript theme={null} import { NextResponse } from 'next/server'; export async function GET() { const pairing = await fetch('https://www.fonttrio.xyz/api/r/brutalist') .then(res => res.json()); return NextResponse.json(pairing); } ``` ## Response Format All API responses return JSON with either: * A [pairing schema](/api/pairing-schema) for font combination configurations * A [font schema](/api/font-schema) for individual font definitions ## Error Handling The API returns standard HTTP status codes: | Status Code | Description | | ----------- | ----------------------- | | `200` | Successful request | | `404` | Registry item not found | | `500` | Server error | ### Error Response Format ```json theme={null} { "error": "Registry item \"invalid-name\" not found" } ``` ## Next Steps Explore all available API endpoints and parameters Learn the structure of font pairing responses Understand individual font configuration format # Pairing Schema Source: https://kapishdima-fonttrio.mintlify.app/api/pairing-schema JSON schema for font pairing configurations in the Fonttrio registry ## Overview Font pairings combine three fonts (heading, body, and mono) with complete CSS configurations for typography across all HTML elements. Each pairing includes metadata, dependencies, CSS variables, and styles. ## Schema Structure ### Root Fields Unique identifier for the pairing, typically prefixed with `pairing-` **Example**: `"pairing-minimal"`, `"pairing-brutalist"` Registry type identifier. Always `"registry:style"` for pairings. Base style to extend from. Use `"none"` for standalone pairings. Human-readable title showing the pairing name and font combination **Format**: `"{Name} — {Heading} + {Body} + {Mono}"` **Example**: `"Minimal — Geist + Geist + Geist Mono"` Descriptive text explaining the pairing's aesthetic and design philosophy Array of category tags for filtering and discovery **Common categories**: `"sans-serif"`, `"serif"`, `"minimal"`, `"modern"`, `"brutalist"`, `"display"`, `"bold"` ### Dependencies Array of URLs pointing to font configurations in the registry Each URL typically references 2-3 fonts: * Heading font * Body font * Monospace font **Format**: `"https://www.fonttrio.xyz/r/{font-name}.json"` ### CSS Variables Defines CSS custom properties for theme integration Theme-level CSS variables CSS variable reference for heading font **Example**: `"var(--font-geist)"` CSS variable reference for body font **Example**: `"var(--font-inter)"` CSS variable reference for monospace font **Example**: `"var(--font-geist-mono)"` ### CSS Styles Complete typography styles for all HTML elements. Keys are CSS selectors, values are style objects. Styles for primary headings Font family, typically referencing `var(--font-heading)` Font size in rem, em, or px **Example**: `"2.25rem"` Unitless line height value **Example**: `"1.15"` Letter spacing in em units **Example**: `"-0.025em"` Font weight value (100-900) **Example**: `"700"` Similar structure to h1, can target multiple selectors Styles for body text and paragraphs Body font family, typically `var(--font-body)` Line height for body text **Example**: `"1.6"` Styles for code elements Monospace font family, typically `var(--font-mono)` ### Metadata Additional metadata for preview and categorization Sample text for font preview **Default**: `"The quick brown fox jumps over the lazy dog"` Array of mood descriptors **Examples**: `["modern", "minimal"]`, `["raw", "brutalist"]` Suggested use cases for the pairing **Examples**: `["SaaS", "developer tools"]`, `["portfolio", "art"]` ## Complete Examples ### Minimal Pairing A clean, modern single-font pairing using Geist: ```json theme={null} { "name": "pairing-minimal", "type": "registry:style", "extends": "none", "title": "Minimal — Geist + Geist + Geist Mono", "description": "Ultra-minimal Vercel-style pairing. One font family for everything, clean and modern.", "categories": ["sans-serif", "minimal", "modern"], "registryDependencies": [ "https://www.fonttrio.xyz/r/geist.json", "https://www.fonttrio.xyz/r/geist-mono.json" ], "cssVars": { "theme": { "--font-heading": "var(--font-geist)", "--font-body": "var(--font-geist)", "--font-mono": "var(--font-geist-mono)" } }, "css": { "h1": { "font-family": "var(--font-heading)", "font-size": "2.25rem", "line-height": "1.15", "letter-spacing": "-0.025em", "font-weight": "700" }, "h2": { "font-family": "var(--font-heading)", "font-size": "1.875rem", "line-height": "1.2", "letter-spacing": "-0.02em", "font-weight": "600" }, "h3": { "font-family": "var(--font-heading)", "font-size": "1.5rem", "line-height": "1.3", "letter-spacing": "-0.015em", "font-weight": "500" }, "h4, h5, h6": { "font-family": "var(--font-heading)", "letter-spacing": "-0.01em" }, "body, p": { "font-family": "var(--font-body)", "line-height": "1.6" }, "code, pre": { "font-family": "var(--font-mono)" } }, "meta": { "preview": "The quick brown fox jumps over the lazy dog", "mood": ["modern", "minimal", "Vercel-style"], "useCase": ["SaaS", "developer tools", "Vercel-style"] } } ``` ### Brutalist Pairing A bold, high-contrast pairing with Archivo Black: ```json theme={null} { "name": "pairing-brutalist", "type": "registry:style", "extends": "none", "title": "Brutalist — Archivo Black + Archivo + Source Code Pro", "description": "Raw typographic power. Archivo Black's heavy weight fills every pixel of the headline, while regular Archivo maintains the same DNA in a readable body weight. No decoration, pure function.", "categories": ["display", "brutalist", "bold"], "registryDependencies": [ "https://www.fonttrio.xyz/r/archivo-black.json", "https://www.fonttrio.xyz/r/archivo.json", "https://www.fonttrio.xyz/r/source-code-pro.json" ], "cssVars": { "theme": { "--font-heading": "var(--font-archivo-black)", "--font-body": "var(--font-archivo)", "--font-mono": "var(--font-source-code-pro)" } }, "css": { "h1": { "font-family": "var(--font-heading)", "font-size": "2.75rem", "line-height": "1.05", "letter-spacing": "-0.035em", "font-weight": "800" }, "h2": { "font-family": "var(--font-heading)", "font-size": "2.25rem", "line-height": "1.1", "letter-spacing": "-0.025em", "font-weight": "700" }, "h3": { "font-family": "var(--font-heading)", "font-size": "1.75rem", "line-height": "1.2", "letter-spacing": "-0.02em", "font-weight": "700" }, "h4, h5, h6": { "font-family": "var(--font-heading)", "letter-spacing": "-0.01em" }, "body, p": { "font-family": "var(--font-body)", "line-height": "1.6" }, "code, pre": { "font-family": "var(--font-mono)" } }, "meta": { "preview": "The quick brown fox jumps over the lazy dog", "mood": ["raw", "brutalist"], "useCase": ["portfolio", "art", "experimental"] } } ``` ## CSS Override Behavior When query parameters are provided to the API endpoint, the CSS properties are dynamically overridden: ### Example Request ``` GET /api/r/minimal?h1-size=3rem&body-lh=1.8 ``` ### Resulting CSS The returned JSON will have modified CSS: ```json theme={null} { "css": { "h1": { "font-family": "var(--font-heading)", "font-size": "3rem", // ← Overridden from 2.25rem "line-height": "1.15", "letter-spacing": "-0.025em", "font-weight": "700" }, "body, p": { "font-family": "var(--font-body)", "line-height": "1.8" // ← Overridden from 1.6 } } } ``` **Implementation**: `app/api/r/[name]/route.ts:47-85` ## Usage in Next.js ```typescript theme={null} import { NextResponse } from 'next/server'; interface PairingConfig { name: string; title: string; cssVars: { theme: Record; }; css: Record>; } export async function loadPairing( name: string, overrides?: Record ): Promise { const params = new URLSearchParams(overrides); const url = `https://www.fonttrio.xyz/api/r/${name}${ params.toString() ? `?${params}` : '' }`; const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to load pairing: ${name}`); } return response.json(); } // Usage const pairing = await loadPairing('minimal'); const customPairing = await loadPairing('brutalist', { 'h1-size': '3.5rem', 'body-lh': '1.7' }); ``` ## See Also Schema for individual font configurations Complete endpoint reference with examples # Academic Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/academic Scholarly typography with refined readability, universal language support, and academic precision for research and education. # Academic Collection The Academic collection features scholarly, refined pairings designed for research publications, educational platforms, and documentation. These combinations prioritize exceptional readability, universal language support, and typographic traditions rooted in academic publishing. ## Style Characteristics Academic pairings are characterized by: * **Academic & Scholarly**: Typography rooted in publishing traditions * **Refined**: Carefully tuned for long-form reading and comprehension * **Readable**: Exceptional legibility optimized for extended reading * **Universal**: Comprehensive language and character support ## Pairings in this Collection EB Garamond + Inter + Source Code Pro Noto Serif + Noto Sans + Inconsolata Lexend + Lexend + Inconsolata ## Featured Pairing: Scholar Academic precision meets digital clarity — EB Garamond's Renaissance roots lend authority to headings, while Inter ensures perfect screen readability for long-form content. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/scholar.json ``` ### Font Stack * **Heading**: EB Garamond — Classic old-style serif with Renaissance heritage * **Body**: Inter — Optimized for screen readability * **Mono**: Source Code Pro — Technical precision for code ### Typography Specs * **H1**: 2.5rem, line-height 1.15, letter-spacing -0.015em, weight 400 * **H2**: 2rem, line-height 1.2, letter-spacing -0.01em, weight 400 * **H3**: 1.5rem, line-height 1.3, letter-spacing 0em, weight 400 * **Body/Paragraph**: Inter, line-height 1.75 (generous for reading) * **Code**: Source Code Pro family ### Design Philosophy Scholar pairs Renaissance elegance with modern screen optimization. EB Garamond brings 500 years of typographic tradition to headings, while Inter's extensive hinting and kerning ensure body text remains crisp at any size. ## Use Cases Academic publications and research documentation Learning management systems and course materials Technical documentation and knowledge bases Digital libraries and archival collections Academic institutional websites Scholarly publishing and journal platforms ## Quick Comparison | Pairing | Heading Font | Body Font | Strength | | -------- | ------------ | --------- | ------------------------------------ | | Scholar | EB Garamond | Inter | Academic authority + screen clarity | | Thesis | Noto Serif | Noto Sans | Universal language support | | Handbook | Lexend | Lexend | Scientifically optimized readability | ## Typography Details **Noto Serif + Noto Sans + Inconsolata** The universal pairing. Noto's unified design system ensures consistent rendering across every language and script — from Latin to Chinese, Arabic to Devanagari. Truly global typography with no tofu (missing glyph boxes). **Personality**: Universal, professional, comprehensive **Language Support**: 1,000+ languages across 150+ writing systems **Use Cases**: International documentation, i18n applications, global education platforms ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/thesis.json ``` **Typography Specs:** * H1: 2.25rem, weight 700, optimized for all scripts * Body: line-height 1.65, consistent across languages **Lexend + Lexend + Inconsolata** Designed for readability research. Lexend's variable font axes were fine-tuned through scientific studies to reduce visual noise and increase reading proficiency. Particularly effective for readers with dyslexia. **Personality**: Accessible, clear, research-backed **Research Foundation**: Based on studies by Dr. Bonnie Shaver-Troup and Thomas Jockin **Use Cases**: Education, accessibility-focused sites, documentation, e-learning ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/handbook.json ``` **Typography Specs:** * H1: 2.25rem, weight 600, optimized spacing * Body: line-height 1.65, enhanced for comprehension ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/scholar.json npx shadcn@latest add https://www.fonttrio.xyz/r/thesis.json npx shadcn@latest add https://www.fonttrio.xyz/r/handbook.json ``` ## Design Characteristics ### Generous Line Height Academic pairings use the most generous line-height in the collection: ```css theme={null} /* Academic readability standards */ body { line-height: 1.75; /* Scholar */ line-height: 1.65; /* Thesis, Handbook */ } ``` This creates comfortable reading for extended sessions and improves comprehension. ### Conservative Letter Spacing Academic headings use minimal or zero letter-spacing to preserve traditional typographic rhythm: ```css theme={null} h1 { letter-spacing: -0.015em; } /* Subtle */ h2 { letter-spacing: -0.01em; } /* Very subtle */ h3 { letter-spacing: 0em; } /* None */ ``` ### Moderate Font Weights Academic typography avoids ultra-heavy weights, preferring regular (400) or semi-bold (600) for hierarchy: * **Scholar**: Uses weight 400 for all headings (traditional) * **Thesis**: Uses weight 700 for H1, 600 for H2-H3 * **Handbook**: Uses weight 600 for H1-H2, 500 for H3 ## Readability Research Optimal: 60-80 characters per line. Academic pairings shine at these comfortable reading lengths. Use 1.5-2em spacing between paragraphs to create clear visual breaks. Minimum 16px for body text. Academic content benefits from 18-20px. WCAG AAA compliance (7:1 contrast ratio) recommended for academic content. ## Language Support ### Scholar Pairing * **EB Garamond**: Full Latin character set, extensive diacritics * **Inter**: Latin, Cyrillic, Greek, Vietnamese ### Thesis Pairing * **Noto Family**: 1,000+ languages including: * All Latin-based languages * Chinese (Simplified & Traditional) * Japanese, Korean * Arabic, Hebrew * Devanagari, Bengali, Tamil * Cyrillic, Greek * And 140+ more scripts ### Handbook Pairing * **Lexend**: Comprehensive Latin character set with full diacritic support ## Accessibility Features **Handbook (Lexend)** is specifically designed through research to support readers with dyslexia: * Increased character spacing * Distinctive letterforms * Optimized stroke widths * Variable font axes for personalization **Scholar (Inter)** features extensive screen optimization: * Hand-hinted at all sizes * Optical corrections for small sizes * Excellent anti-aliasing * Clear at high and low DPI **Thesis (Noto)** ensures accessible typography across cultures: * Consistent metrics across scripts * No missing glyphs (no tofu) * Proper rendering of complex scripts * Cultural sensitivity in design ## Typography Best Practices ### For Long-Form Reading ```css theme={null} /* Recommended academic article styles */ article { max-width: 65ch; /* Optimal line length */ font-size: 18px; /* Comfortable reading size */ line-height: 1.75; /* Generous spacing */ color: #1a1a1a; /* Soft black, not pure black */ } p + p { margin-top: 1.5em; /* Clear paragraph breaks */ } ``` ### For Citations and References ```css theme={null} /* Academic citation styles */ .citation { font-size: 0.875rem; /* Smaller but still readable */ line-height: 1.6; color: #555; /* Slightly muted */ } ``` ### For Footnotes ```css theme={null} .footnote { font-size: 0.8125rem; /* 13px minimum */ line-height: 1.5; } ``` ## When to Use Academic Pairings ✅ **Do use when:** * Publishing research or academic content * Building educational platforms * Creating documentation sites * Supporting multiple languages * Prioritizing accessibility and readability * Long-form reading is primary use case ❌ **Avoid when:** * Building marketing landing pages * Creating bold, impactful designs * Targeting young/playful audiences * Space is limited (mobile cards, etc.) * Quick scanning is more important than deep reading Academic pairings work best with ample whitespace, clear hierarchy, and generous margins. Let the content breathe — these typefaces reward patient reading. Consider using larger base font sizes (18-20px) for academic content. The generous line-height and refined letterforms support comfortable extended reading sessions. # Bold Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/bold Impactful and commanding typography with brutalist aesthetics, condensed displays, and raw typographic power. # Bold Collection The Bold collection features impactful, commanding typography designed for maximum visual impact. These pairings embrace brutalist design, condensed displays, and raw typographic power for portfolios, media sites, and experimental designs. ## Style Characteristics Bold pairings are characterized by: * **Bold & Impactful**: Heavy weights and condensed forms that dominate the viewport * **Commanding**: Typography that arrests attention and demands to be read * **Raw & Brutalist**: Unpolished, function-first aesthetics * **Dramatic**: High-contrast pairings with theatrical presence ## Pairings in this Collection Archivo Black + Archivo + Source Code Pro Fjalla One + Josefin Sans + Fira Code Oswald + Barlow + Inconsolata Anton + Work Sans + Roboto Mono ## Featured Pairing: Brutalist Raw typographic power with Archivo Black's heavy weight filling every pixel of the headline, balanced by regular Archivo for readable body text. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/brutalist.json ``` ### Font Stack * **Heading**: Archivo Black — Ultra-heavy condensed display * **Body**: Archivo — Same family in readable weight * **Mono**: Source Code Pro — Clean, technical monospace ### Typography Specs * **H1**: 2.75rem, line-height 1.05, letter-spacing -0.035em, weight 800 * **H2**: 2.25rem, line-height 1.1, letter-spacing -0.025em, weight 700 * **H3**: 1.75rem, line-height 1.2, letter-spacing -0.02em, weight 700 * **Body/Paragraph**: Archivo, line-height 1.6 * **Code**: Source Code Pro family ### Design Philosophy Brutalist typography rejects ornamentation in favor of pure function. Archivo Black's condensed forms pack maximum impact into minimum horizontal space, while the superfamily approach ensures visual cohesion across weights. ## Use Cases Artist and designer portfolios with bold statements Experimental and contemporary art platforms Sports, entertainment, and news with high impact Landing pages and campaign sites demanding attention Conference and event sites with theatrical presence Band sites and music platforms with edgy aesthetics ## Quick Comparison | Pairing | Heading Font | Body Font | Character | | --------- | ------------- | ------------ | ------------------------- | | Brutalist | Archivo Black | Archivo | Raw, unpolished power | | Impact | Fjalla One | Josefin Sans | Condensed Nordic strength | | Poster | Oswald | Barlow | Tall, commanding presence | | Headline | Anton | Work Sans | Bold and unapologetic | ## Typography Details **Fjalla One + Josefin Sans + Fira Code** Condensed power meets art deco elegance. Fjalla One's Nordic condensed forms dominate headlines, while Josefin Sans adds vintage geometric character. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json ``` **Oswald + Barlow + Inconsolata** Condensed impact with tall proportions. Oswald makes every headline a statement, balanced by Barlow's slightly rounded approachability. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/poster.json ``` **Anton + Work Sans + Roboto Mono** Bold and unapologetic. Anton's narrow impactful letterforms dominate the viewport, grounded by Work Sans's humanist warmth. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/headline.json ``` ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/brutalist.json npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json npx shadcn@latest add https://www.fonttrio.xyz/r/poster.json npx shadcn@latest add https://www.fonttrio.xyz/r/headline.json ``` Bold pairings require careful use of whitespace and hierarchy. Use sparingly for maximum impact — too much bold typography can overwhelm users. ## Design Considerations ### Line Height Bold pairings use aggressive line-height (1.05-1.1) in headings to create tight, impactful stacking. This creates vertical rhythm that feels powerful rather than airy. ### Letter Spacing Negative letter-spacing (-0.035em) is more pronounced than in clean styles, creating optical density and visual weight. ### Font Weight Most headings use weight 700-800, creating maximum contrast with body text. This dramatic hierarchy guides the eye forcefully through the content. All bold pairings work best against high-contrast backgrounds (black/white) or with large images that can balance the typographic weight. # Clean Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/clean Minimal and modern sans-serif pairings for SaaS dashboards, web applications, and contemporary digital products. # Clean Collection The Clean collection features minimal, neutral, and modern sans-serif pairings perfect for SaaS dashboards, developer tools, and contemporary web applications. These combinations prioritize clarity, readability, and a Vercel-style aesthetic. ## Style Characteristics Clean pairings are characterized by: * **Minimal**: Stripped-down aesthetics with no unnecessary ornamentation * **Neutral**: Unbiased, systematic typography that gets out of the way * **Modern**: Contemporary sans-serif designs optimized for screens * **Vercel-style**: Influenced by modern design systems and tech aesthetics ## Pairings in this Collection Geist + Geist + Geist Mono Inter + Inter + Geist Mono Urbanist + Libre Franklin + JetBrains Mono Manrope + DM Sans + Fira Code Inter Tight + Open Sans + IBM Plex Mono ## Featured Pairing: Minimal The ultimate minimal pairing uses Geist for everything — a single font family for the entire design system, Vercel-style. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json ``` ### Font Stack * **Heading**: Geist — Ultra-minimal modern sans-serif * **Body**: Geist — Same family for cohesive design * **Mono**: Geist Mono — Matching monospace companion ### Typography Specs * **H1**: 2.25rem, line-height 1.15, letter-spacing -0.025em, weight 700 * **H2**: 1.875rem, line-height 1.2, letter-spacing -0.02em, weight 600 * **H3**: 1.5rem, line-height 1.3, letter-spacing -0.015em, weight 500 * **Body/Paragraph**: Geist, line-height 1.6 * **Code**: Geist Mono family ## Use Cases Clean, minimal interfaces for web applications Technical products with Vercel-style aesthetics Data visualization and analytics interfaces Backend interfaces and control panels Modern single-page applications Technical docs with clean, readable typography ## Quick Comparison | Pairing | Heading Font | Body Font | Style | | ------------ | ------------ | -------------- | -------------------------- | | Minimal | Geist | Geist | Single-family Vercel-style | | Modern Clean | Inter | Inter | Neutral SaaS aesthetic | | SaaS | Urbanist | Libre Franklin | Product-focused pairing | | Dashboard | Manrope | DM Sans | Data-driven clarity | | Swiss | Inter Tight | Open Sans | Neo-grotesque precision | ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json npx shadcn@latest add https://www.fonttrio.xyz/r/modern-clean.json npx shadcn@latest add https://www.fonttrio.xyz/r/saas.json npx shadcn@latest add https://www.fonttrio.xyz/r/dashboard.json npx shadcn@latest add https://www.fonttrio.xyz/r/swiss.json ``` Clean pairings work best with ample whitespace, generous padding, and subtle color palettes. They're designed to enhance content, not compete with it. ## Typography Best Practices Clean pairings use tighter line-height (1.6) compared to editorial styles for more compact, scannable layouts. Negative letter-spacing (-0.025em to -0.03em) in headings creates tighter, more modern appearance. Use weight variation (700 for H1, 600 for H2, 500 for H3) to create hierarchy without dramatic size changes. # Corporate Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/corporate Professional, trustworthy, and systematic typography for enterprise applications, government sites, and corporate communications. # Corporate Collection The Corporate collection features professional, trustworthy typography designed for enterprise applications, corporate communications, and systematic design systems. These pairings prioritize reliability, readability, and institutional trust. ## Style Characteristics Corporate pairings are characterized by: * **Professional**: Conservative, time-tested typefaces that convey competence * **Corporate**: Suitable for business communications and enterprise software * **Trustworthy**: Typography that inspires confidence and credibility * **Systematic**: Well-defined type systems with comprehensive weight ranges ## Pairings in this Collection Roboto + Roboto + Roboto Mono Roboto Slab + Roboto + Roboto Mono Outfit + IBM Plex Sans + IBM Plex Mono Saira + Ubuntu + IBM Plex Mono ## Featured Pairing: Corporate Google's complete type system — Roboto's mechanical skeleton with friendly curves creates a cohesive experience from headlines to fine print. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/corporate.json ``` ### Font Stack * **Heading**: Roboto — Google's systematic sans-serif * **Body**: Roboto — Same family for consistency * **Mono**: Roboto Mono — Matching monospace ### Typography Specs * **H1**: 2.25rem, line-height 1.15, letter-spacing -0.03em, weight 700 * **H2**: 1.875rem, line-height 1.2, letter-spacing -0.025em, weight 600 * **H3**: 1.5rem, line-height 1.25, letter-spacing -0.02em, weight 600 * **Body/Paragraph**: Roboto, line-height 1.6 * **Code**: Roboto Mono family ### Design Philosophy Roboto's dual nature — mechanical skeleton with friendly curves — makes it versatile enough for both enterprise dashboards and consumer-facing products. The de facto standard for Material Design. ## Use Cases Business applications and internal tools Company websites and investor relations Financial services and fintech platforms Public sector and civic technology Medical systems and health tech Learning management and institutional sites ## Quick Comparison | Pairing | Heading Font | Body Font | Primary Use | | --------- | ------------ | ------------- | ------------------------ | | Corporate | Roboto | Roboto | Material Design, Android | | Manifesto | Roboto Slab | Roboto | Enterprise documentation | | Fintech | Outfit | IBM Plex Sans | Banking, finance | | Protocol | Saira | Ubuntu | Developer tools, Linux | ## Typography Details **Roboto Slab + Roboto + Roboto Mono** The complete Roboto system with slab serif headlines bringing gravitas. A three-weight system that works everywhere, from Android to enterprise dashboards. **Use Cases**: Enterprise documentation, Material Design, systematic applications ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/manifesto.json ``` **Outfit + IBM Plex Sans + IBM Plex Mono** Trust through typography. Outfit's geometric clarity inspires confidence in headings, while IBM Plex's rigorous design system ensures readability in data-heavy financial interfaces. **Use Cases**: Fintech, banking, enterprise applications ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/fintech.json ``` **Saira + Ubuntu + IBM Plex Mono** Racing DNA meets open-source philosophy. Saira's motorsport-inspired geometry powers through headlines, while Ubuntu's distinctive humanist forms make body text unmistakably modern. **Use Cases**: Developer tools, Linux applications, open source projects ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/protocol.json ``` ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/corporate.json npx shadcn@latest add https://www.fonttrio.xyz/r/manifesto.json npx shadcn@latest add https://www.fonttrio.xyz/r/fintech.json npx shadcn@latest add https://www.fonttrio.xyz/r/protocol.json ``` ## Design Best Practices ### Hierarchy Through Weight Corporate pairings rely on weight variation rather than size to create hierarchy. Use the full range of weights (300-700) available in these superfamilies. ```css theme={null} /* Example hierarchy using Roboto */ h1 { font-weight: 700; } /* Bold */ h2 { font-weight: 600; } /* Semi-bold */ h3 { font-weight: 600; } /* Semi-bold */ body { font-weight: 400; } /* Regular */ .caption { font-weight: 300; } /* Light */ ``` ### Systematic Spacing Corporate typography benefits from mathematical spacing systems (8pt grid, modular scale) that create predictable, professional layouts. ### Accessibility These pairings prioritize legibility: * Generous line-height (1.6) for body text * Clear weight differentiation for hierarchy * Excellent screen rendering at all sizes * WCAG AAA compliant at recommended sizes Corporate pairings work best with neutral color palettes (grays, blues) and ample whitespace. They're designed to feel trustworthy and established. All corporate pairings include comprehensive weight ranges (typically 9 weights from thin to black) enabling precise typographic control for complex interfaces. # Creative Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/creative Distinctive geometric pairings with curated aesthetics for design studios, agencies, and creative portfolios. # Creative Collection The Creative collection features distinctive, geometric pairings designed for design studios, creative agencies, and portfolio sites. These combinations balance geometric precision with artistic flair, creating memorable and curated typographic experiences. ## Style Characteristics Creative pairings are characterized by: * **Creative & Distinctive**: Typefaces with unique personality and character * **Geometric**: Circles, triangles, and mathematical proportions * **Curated**: Thoughtfully selected combinations that feel designed * **Nordic**: Scandinavian-inspired minimalism with character ## Pairings in this Collection Space Grotesk + DM Sans + Fira Code Bricolage Grotesque + Figtree + Fira Code Outfit + Libre Baskerville + IBM Plex Mono ## Featured Pairing: Creative Playful geometric pairing with Space Grotesk's distinctive letterforms commanding attention in headlines, balanced by DM Sans's friendly body text. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/creative.json ``` ### Font Stack * **Heading**: Space Grotesk — Geometric grotesk with character * **Body**: DM Sans — Friendly, readable sans-serif * **Mono**: Fira Code — Developer-focused monospace ### Typography Specs * **H1**: 2.5rem, line-height 1.15, letter-spacing -0.03em, weight 700 * **H2**: 2rem, line-height 1.2, letter-spacing -0.02em, weight 600 * **H3**: 1.5rem, line-height 1.3, letter-spacing -0.015em, weight 600 * **Body/Paragraph**: DM Sans, line-height 1.6 * **Code**: Fira Code with programming ligatures ### Design Philosophy Space Grotesk brings geometric playfulness without sacrificing readability. Its distinctive letterforms (especially the 'a' and 'g') create memorable headings, while DM Sans keeps body text approachable and professional. ## Use Cases Creative agency sites and design portfolios Landing pages with personality and innovation Personal branding for creatives and makers Marketing and branding agency websites Architectural firms and design-build companies Product design and innovation consultancies ## Quick Comparison | Pairing | Heading Font | Body Font | Character | | --------- | ------------------- | ----------------- | ------------------------- | | Creative | Space Grotesk | DM Sans | Playful geometric startup | | Studio | Bricolage Grotesque | Figtree | Distinctive ink traps | | Architect | Outfit | Libre Baskerville | Structured precision | ## Typography Details **Bricolage Grotesque + Figtree + Fira Code** Design-forward pairing with distinctive ink traps and angular terminals that command attention, softened by Figtree's friendly geometric body text. **Personality**: Creative, distinctive, design studio aesthetic **Use Cases**: Design studios, creative agencies, experimental portfolios ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/studio.json ``` **Outfit + Libre Baskerville + IBM Plex Mono** Structured meets refined. Outfit's geometric precision in headings contrasts beautifully with Libre Baskerville's warm readability — like blueprints meeting handwritten notes. **Personality**: Structured, professional, architectural precision **Use Cases**: Architecture firms, portfolio sites, professional services ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/architect.json ``` ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/creative.json npx shadcn@latest add https://www.fonttrio.xyz/r/studio.json npx shadcn@latest add https://www.fonttrio.xyz/r/architect.json ``` ## Design Characteristics ### Geometric Foundations Creative pairings are built on geometric principles — circles, squares, and triangles form the basis of letterforms. This mathematical foundation creates visual harmony while allowing for distinctive character. ### Distinctive Features Distinctive 'a' and 'g', geometric construction with humanist warmth Ink traps, angular terminals, architectural precision Perfect circles, geometric clarity, optical adjustments Low contrast, friendly geometry, compact efficiency ## Typography Best Practices ### Scale and Hierarchy Creative pairings benefit from dramatic scale differences between headings and body text: ```css theme={null} /* Recommended scale */ h1 { font-size: 2.5rem; } /* 40px */ h2 { font-size: 2rem; } /* 32px */ h3 { font-size: 1.5rem; } /* 24px */ p { font-size: 1rem; } /* 16px */ ``` ### Letter Spacing Geometric typefaces often benefit from slight negative tracking in headings to create optical tightness: * **H1**: -0.03em * **H2**: -0.02em * **H3**: -0.015em * **Body**: default (0em) ### Whitespace Creative pairings need room to breathe. Use generous margins and padding to let the distinctive letterforms shine. Creative pairings work best with bold color choices and strong visual identity. Don't be afraid to use color, gradients, or patterns to enhance the geometric character. ## When to Use Creative Pairings ✅ **Do use when:** * Building a portfolio or personal brand * Creating a design studio website * Launching an innovative product * Showcasing creative work * Building a startup landing page ❌ **Avoid when:** * Building enterprise software * Creating government or civic sites * Designing financial applications * Long-form reading (novels, articles) * Accessibility is the primary concern While creative pairings have strong personality, they maintain professional readability. They're distinctive without sacrificing usability. # Editorial Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/editorial Classic editorial pairings with high-contrast serifs and sophisticated typography for magazines, blogs, and narrative content. # Editorial Collection The Editorial collection features sophisticated typographic pairings designed for magazines, blogs, and narrative content. These combinations emphasize high-contrast serifs, dramatic display faces, and refined readability for long-form storytelling. ## Style Characteristics Editorial pairings are characterized by: * **Literary & Narrative**: High-contrast serif headings with readable body text * **Dramatic**: Bold display faces that command attention * **Sophisticated**: Refined typographic choices that convey authority * **Traditional**: Classic serif pairings with timeless appeal ## Pairings in this Collection Playfair Display + Source Serif 4 + JetBrains Mono EB Garamond + Crimson Text + Inconsolata Playfair Display + DM Sans + JetBrains Mono Cormorant Garamond + Lora + JetBrains Mono Cormorant Garamond + Raleway + Roboto Mono ## Featured Pairing: Editorial The flagship pairing of this collection combines Playfair Display's high-contrast serifs with Source Serif 4's contemporary readability. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` ### Font Stack * **Heading**: Playfair Display — Classic editorial with high-contrast serifs * **Body**: Source Serif 4 — Readable serif body text for long-form content * **Mono**: JetBrains Mono — Modern monospace for code blocks ### Typography Specs * **H1**: 2.25rem, line-height 1.2, letter-spacing -0.025em, weight 700 * **H2**: 1.875rem, line-height 1.25, letter-spacing -0.02em, weight 600 * **H3**: 1.5rem, line-height 1.3, letter-spacing -0.015em, weight 600 * **Body/Paragraph**: Source Serif 4, line-height 1.65 * **Code**: JetBrains Mono family ## Use Cases High-contrast editorial design for print-inspired digital magazines Sophisticated long-form content and storytelling Traditional newspaper-style layouts with modern readability Book-quality typography for digital publishing platforms Authoritative technical documentation with classic appeal Writer and journalist portfolios with literary sophistication ## Quick Comparison | Pairing | Heading Font | Body Font | Style | | --------- | ------------------ | -------------- | ---------------------- | | Editorial | Playfair Display | Source Serif 4 | Classic editorial | | Literary | EB Garamond | Crimson Text | Pure serif harmony | | Newspaper | Playfair Display | DM Sans | Modern contrast | | Novel | Cormorant Garamond | Lora | Narrative storytelling | | Gazette | Cormorant Garamond | Raleway | Elegant drama | ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json npx shadcn@latest add https://www.fonttrio.xyz/r/literary.json npx shadcn@latest add https://www.fonttrio.xyz/r/newspaper.json npx shadcn@latest add https://www.fonttrio.xyz/r/novel.json npx shadcn@latest add https://www.fonttrio.xyz/r/gazette.json ``` All editorial pairings are optimized for readability with generous line-height (1.65-1.75) and carefully tuned letter-spacing for long-form reading. # Friendly Collection Source: https://kapishdima-fonttrio.mintlify.app/collections/friendly Approachable and warm typography with rounded terminals and playful character for consumer apps and startups. # Friendly Collection The Friendly collection features approachable, warm pairings designed for consumer applications, startup landing pages, and products targeting everyday users. These combinations use rounded terminals, humanist proportions, and playful geometry to create inviting, accessible experiences. ## Style Characteristics Friendly pairings are characterized by: * **Friendly & Approachable**: Rounded terminals and warm letterforms * **Warm**: Humanist proportions that feel inviting rather than mechanical * **Playful**: Geometric character with toy-like friendliness * **Startup**: Modern but approachable, innovative but accessible ## Pairings in this Collection Nunito + Nunito Sans + Fira Code Quicksand + Cabin + Inconsolata Sora + Public Sans + Fira Code ## Featured Pairing: Startup Friendly and approachable — Nunito's rounded terminals give headings warmth, while Nunito Sans straightens out for professional body text. ### Installation ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/startup.json ``` ### Font Stack * **Heading**: Nunito — Rounded, friendly sans-serif * **Body**: Nunito Sans — Straighter companion for readability * **Mono**: Fira Code — Modern monospace with ligatures ### Typography Specs * **H1**: 2.5rem, line-height 1.1, letter-spacing -0.03em, weight 700 * **H2**: 2rem, line-height 1.15, letter-spacing -0.025em, weight 600 * **H3**: 1.5rem, line-height 1.25, letter-spacing -0.015em, weight 600 * **Body/Paragraph**: Nunito Sans, line-height 1.6 * **Code**: Fira Code with programming ligatures ### Design Philosophy Nunito's rounded terminals create immediate warmth and approachability. The superfamily approach ensures visual cohesion — headlines feel friendly, while body text remains professional and readable. ## Use Cases Mobile and web apps for everyday users Product launches and startup websites User-friendly software products Learning platforms and educational apps Family-friendly and children's applications Wellness and healthcare consumer apps ## Quick Comparison | Pairing | Heading Font | Body Font | Character | | ------- | ------------ | ----------- | ------------------------------------------ | | Startup | Nunito | Nunito Sans | Rounded warmth, grows with your product | | Playful | Quicksand | Cabin | Toy-like friendliness with professionalism | | Launch | Sora | Public Sans | Confident geometry, accessible standards | ## Typography Details **Quicksand + Cabin + Inconsolata** Rounded and inviting. Quicksand's perfectly circular counters give headings a toy-like friendliness, while Cabin's humanist proportions keep body text grounded and professional. **Personality**: Playful, approachable, consumer-friendly **Use Cases**: Kids' apps, education, consumer products, playful brands ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/playful.json ``` **Typography Specs:** * H1: 2.25rem, weight 600, letter-spacing -0.02em * Body: line-height 1.65 for comfortable reading **Sora + Public Sans + Fira Code** Launch-ready confidence. Sora's geometric precision with optical adjustments makes bold headlines pop, while Public Sans — born from US government accessibility standards — ensures every word lands clearly. **Personality**: Modern, confident, accessible **Use Cases**: Startup launches, product pages, accessible applications ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/launch.json ``` **Typography Specs:** * H1: 2.5rem, weight 700, letter-spacing -0.03em * Body: line-height 1.6, optimized for accessibility ## Installation Commands ```bash theme={null} # Install any pairing from this collection npx shadcn@latest add https://www.fonttrio.xyz/r/startup.json npx shadcn@latest add https://www.fonttrio.xyz/r/playful.json npx shadcn@latest add https://www.fonttrio.xyz/r/launch.json ``` ## Design Characteristics ### Rounded Terminals The defining feature of friendly typography is rounded terminals — where strokes end in gentle curves rather than sharp angles: Fully rounded terminals create soft, approachable character Circular counters and geometric roundness Optical adjustments balance geometry with readability Humanist proportions with subtle warmth ### Humanist Proportions Friendly typefaces often incorporate humanist features: * Slight variations in stroke width * Open apertures for better legibility * Calligraphic influence in letter shapes * Organic rather than mechanical feeling ## Typography Best Practices ### Font Weight Selection Friendly pairings work best with moderate weights: ```css theme={null} /* Recommended weights */ h1 { font-weight: 700; } /* Bold but not heavy */ h2 { font-weight: 600; } /* Semi-bold */ h3 { font-weight: 600; } /* Semi-bold */ body { font-weight: 400; } /* Regular */ ``` Avoid ultra-heavy weights (800-900) which can make rounded typefaces feel cartoonish. ### Color and Contrast Friendly typography pairs well with: * Warm color palettes (oranges, yellows, soft blues) * Medium contrast (avoid pure black on white) * Gradient backgrounds * Playful illustrations ### Line Height and Spacing Generous spacing enhances approachability: ```css theme={null} /* Friendly spacing */ body { line-height: 1.65; /* More generous than corporate */ letter-spacing: 0em; /* No negative tracking */ } h1 { line-height: 1.1; /* Tight but not cramped */ letter-spacing: -0.02em; /* Subtle negative tracking */ } ``` ## Accessibility Considerations Friendly typefaces with rounded terminals often have larger x-heights, improving readability at small sizes. This makes them excellent for mobile-first designs. Many friendly typefaces (especially Quicksand and Nunito) have distinctive letterforms that help readers with dyslexia differentiate similar characters. While friendly designs often use softer colors, maintain WCAG AA standards (4.5:1 for body text, 3:1 for large text) for accessibility. ## When to Use Friendly Pairings ✅ **Do use when:** * Targeting consumer audiences * Building educational products * Creating family-friendly applications * Launching startup products * Emphasizing approachability over authority ❌ **Avoid when:** * Building financial/banking applications * Creating legal or government sites * Designing luxury/premium brands * Targeting corporate/B2B audiences * Emphasizing security and trust Friendly pairings work best with playful microcopy, illustrations, and animations. The typography sets a warm tone — reinforce it throughout the entire experience. Balance friendliness with professionalism. Use rounded typefaces for headings but pair with more neutral body text to maintain credibility. # CSS Variables Source: https://kapishdima-fonttrio.mintlify.app/concepts/css-variables Learn how Fonttrio uses CSS variables for flexible and customizable typography # CSS Variables Fonttrio uses CSS custom properties (CSS variables) to provide a flexible, maintainable system for applying font pairings to your project. This approach makes it easy to swap fonts, customize scales, and maintain consistency across your entire application. ## Why CSS Variables? CSS variables offer several advantages for managing typography: * **Single source of truth**: Define fonts once, use everywhere * **Easy theming**: Switch entire pairings by changing a few variables * **Dynamic updates**: Change typography at runtime without recompiling * **Scoped customization**: Override variables for specific components * **Framework agnostic**: Works with any CSS-based framework ## Core Font Variables Every Fonttrio pairing defines three core CSS variables for the font families: ```css theme={null} :root { --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); --font-mono: var(--font-jetbrains-mono); } ``` These three variables are then referenced throughout your stylesheets to apply the fonts consistently. ## Variable Structure in Pairings Each pairing in the Fonttrio registry defines its CSS variables in the `cssVars` section: ```json Editorial Pairing theme={null} { "name": "pairing-editorial", "cssVars": { "theme": { "--font-heading": "var(--font-playfair-display)", "--font-body": "var(--font-source-serif-4)", "--font-mono": "var(--font-jetbrains-mono)" } }, "css": { "h1": { "font-family": "var(--font-heading)", "font-size": "2.25rem", "line-height": "1.2", "letter-spacing": "-0.025em", "font-weight": "700" }, "h2": { "font-family": "var(--font-heading)", "font-size": "1.875rem", "line-height": "1.25", "letter-spacing": "-0.02em", "font-weight": "600" }, "h3": { "font-family": "var(--font-heading)", "font-size": "1.5rem", "line-height": "1.3", "letter-spacing": "-0.015em", "font-weight": "600" }, "h4, h5, h6": { "font-family": "var(--font-heading)", "letter-spacing": "-0.01em" }, "body, p": { "font-family": "var(--font-body)", "line-height": "1.65" }, "code, pre": { "font-family": "var(--font-mono)" } } } ``` ```json Minimal Pairing theme={null} { "name": "pairing-minimal", "cssVars": { "theme": { "--font-heading": "var(--font-geist)", "--font-body": "var(--font-geist)", "--font-mono": "var(--font-geist-mono)" } }, "css": { "h1": { "font-family": "var(--font-heading)", "font-size": "2.25rem", "line-height": "1.15", "letter-spacing": "-0.025em", "font-weight": "700" }, "h2": { "font-family": "var(--font-heading)", "font-size": "1.875rem", "line-height": "1.2", "letter-spacing": "-0.02em", "font-weight": "600" }, "h3": { "font-family": "var(--font-heading)", "font-size": "1.5rem", "line-height": "1.3", "letter-spacing": "-0.015em", "font-weight": "500" }, "h4, h5, h6": { "font-family": "var(--font-heading)", "letter-spacing": "-0.01em" }, "body, p": { "font-family": "var(--font-body)", "line-height": "1.6" }, "code, pre": { "font-family": "var(--font-mono)" } } } ``` ## How Variables are Applied Fonttrio uses a two-layer variable system for maximum flexibility: ### Layer 1: Font Family Variables Individual fonts define their own CSS variable: ```css theme={null} /* Each font gets its own variable */ --font-playfair-display: 'Playfair Display', serif; --font-source-serif-4: 'Source Serif 4', serif; --font-jetbrains-mono: 'JetBrains Mono', monospace; ``` ### Layer 2: Semantic Variables Pairings reference these font variables through semantic names: ```css theme={null} /* Pairing maps semantic names to specific fonts */ --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); --font-mono: var(--font-jetbrains-mono); ``` This two-layer approach means you can: * Switch pairings by changing only 3 variables * Override specific fonts while keeping others * Create variations of existing pairings ## Using Variables in Your CSS Once a pairing is installed, use the semantic variables in your stylesheets: ```css theme={null} /* Headings use the heading font */ h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); } /* Body text uses the body font */ body, p, li, td { font-family: var(--font-body); } /* Code uses the monospace font */ code, pre, kbd, samp { font-family: var(--font-mono); } ``` ## Fonttrio's Global CSS Setup Here's how Fonttrio sets up its own CSS variable system in `/home/daytona/workspace/source/app/globals.css:85-98`: ```css app/globals.css theme={null} @theme inline { --color-bg: var(--bg); --color-text: var(--text); --color-text-muted: var(--text-muted); --color-text-subtle: var(--text-subtle); --color-surface-border: var(--surface-border); --color-surface-border-strong: var(--surface-border-strong); --color-surface: var(--surface); --color-surface-hover: color-mix(in oklch, var(--surface) 80%, var(--foreground) 20%); --font-display: var(--font-bebas-neue), system-ui, sans-serif; --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; } ``` This shows how Fonttrio extends CSS variables beyond just fonts to include colors and other design tokens. ## Typography-Specific Variables Beyond font families, you can create variables for the entire typography scale: ```css theme={null} :root { /* Font families */ --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); --font-mono: var(--font-jetbrains-mono); /* Typography scale */ --font-size-h1: 2.25rem; --font-size-h2: 1.875rem; --font-size-h3: 1.5rem; --font-size-body: 1rem; /* Line heights */ --line-height-heading: 1.2; --line-height-body: 1.65; /* Letter spacing */ --letter-spacing-tight: -0.025em; --letter-spacing-normal: 0em; } h1 { font-family: var(--font-heading); font-size: var(--font-size-h1); line-height: var(--line-height-heading); letter-spacing: var(--letter-spacing-tight); } ``` ## Scoped Customization CSS variables can be scoped to specific elements or components: ```css theme={null} /* Global default */ :root { --font-heading: var(--font-inter); --font-body: var(--font-inter); } /* Override for marketing section */ .marketing-hero { --font-heading: var(--font-playfair-display); } /* Override for documentation */ .docs-content { --font-body: var(--font-source-serif-4); --line-height-body: 1.75; /* More readable for long-form */ } /* Both h1 elements use var(--font-heading) but get different fonts */ h1 { font-family: var(--font-heading); } ``` Scoped variables allow you to use different pairings in different parts of your site without conflicts. ## Dark Mode Support CSS variables make theme switching trivial. Here's how Fonttrio handles dark mode in `/home/daytona/workspace/source/app/globals.css:7-50`: ```css app/globals.css theme={null} :root { --bg: #fafafa; --text: #0a0a0a; --text-muted: #666666; --surface-border: #eaeaea; /* ...more light mode colors */ } .dark { --bg: #0a0a0a; --text: #ededed; --text-muted: #888888; --surface-border: #1f1f1f; /* ...more dark mode colors */ } ``` The variables automatically update when the `.dark` class is applied, without touching font definitions. ## Dynamic Updates with JavaScript You can change CSS variables programmatically: ```typescript theme={null} // Switch to a different pairing at runtime function switchPairing(pairing: 'editorial' | 'minimal' | 'brutalist') { const root = document.documentElement; if (pairing === 'editorial') { root.style.setProperty('--font-heading', 'var(--font-playfair-display)'); root.style.setProperty('--font-body', 'var(--font-source-serif-4)'); root.style.setProperty('--font-mono', 'var(--font-jetbrains-mono)'); } else if (pairing === 'minimal') { root.style.setProperty('--font-heading', 'var(--font-geist)'); root.style.setProperty('--font-body', 'var(--font-geist)'); root.style.setProperty('--font-mono', 'var(--font-geist-mono)'); } // Changes apply instantly across the entire site } // Adjust font size dynamically function setFontSize(scale: number) { document.documentElement.style.setProperty('--font-size-body', `${scale}rem`); } ``` ## Fallback Fonts Always provide fallback fonts for better loading experience: ```css theme={null} :root { /* Fonttrio fonts with system fallbacks */ --font-heading: var(--font-playfair-display), Georgia, serif; --font-body: var(--font-source-serif-4), Georgia, serif; --font-mono: var(--font-jetbrains-mono), 'Courier New', monospace; /* Fonttrio uses system fallbacks */ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; } ``` ## Tailwind CSS Integration If you're using Tailwind, extend your config to use CSS variables: ```javascript tailwind.config.js theme={null} module.exports = { theme: { extend: { fontFamily: { heading: ['var(--font-heading)'], body: ['var(--font-body)'], mono: ['var(--font-mono)'], }, }, }, } ``` Then use in your HTML: ```html theme={null}

Heading

Body text

Code ``` ## Next.js Font Integration Fonttrio works seamlessly with Next.js font optimization: ```typescript app/layout.tsx theme={null} import { Playfair_Display, Source_Serif_4, JetBrains_Mono } from 'next/font/google'; const playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-playfair-display', display: 'swap', }); const sourceSerif = Source_Serif_4({ subsets: ['latin'], variable: '--font-source-serif-4', display: 'swap', }); const jetbrainsMono = JetBrains_Mono({ subsets: ['latin'], variable: '--font-jetbrains-mono', display: 'swap', }); export default function RootLayout({ children }) { return ( {children} ); } ``` ## Variable Naming Conventions Fonttrio follows these naming conventions: ```css theme={null} /* ✅ Good: Semantic, purpose-driven names */ --font-heading --font-body --font-mono /* ❌ Avoid: Font-specific names */ --font-playfair --font-source /* ✅ Good: Scale-specific variables */ --font-size-h1 --line-height-body --letter-spacing-tight /* ❌ Avoid: Non-descriptive names */ --size-1 --lh-a --ls-small ``` ## Best Practices **Use Semantic Names**: Prefer `--font-heading` over `--font-playfair` so you can swap fonts without changing references. **Layer Your Variables**: Create base variables for individual fonts, then semantic variables that reference them. **Provide Fallbacks**: Always include fallback fonts in case custom fonts fail to load. **Scope Strategically**: Use scoped variables for component-level customization without affecting global styles. **Test Everywhere**: CSS variables work in all modern browsers, but test your fallbacks in older environments. ## Common Patterns ### Pattern 1: Pairing Switcher ```css theme={null} /* Define multiple pairings */ .pairing-editorial { --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); } .pairing-minimal { --font-heading: var(--font-geist); --font-body: var(--font-geist); } /* Apply to body or root element */ body { font-family: var(--font-body); } ``` ### Pattern 2: Responsive Typography ```css theme={null} :root { --font-size-h1: 2rem; } @media (min-width: 768px) { :root { --font-size-h1: 2.5rem; } } h1 { font-size: var(--font-size-h1); } ``` ### Pattern 3: User Preferences ```css theme={null} /* Default */ :root { --font-size-base: 1rem; } /* User selected large text */ body.text-large { --font-size-base: 1.25rem; } /* All sizes scale proportionally */ body { font-size: var(--font-size-base); } ``` ## Next Steps Learn about Fonttrio's pairing structure Understand how typography scales work Install Fonttrio and start using CSS variables Customize pairings for your project # Font Pairings Source: https://kapishdima-fonttrio.mintlify.app/concepts/font-pairings Learn about Fonttrio's three-font pairing system for creating harmonious typography # Font Pairings Font pairings are the foundation of Fonttrio. Each pairing combines three carefully selected fonts that work together to create a cohesive typographic system for your project. ## What are Font Pairings? A font pairing in Fonttrio consists of three distinct fonts, each serving a specific purpose: * **Heading font**: Used for titles, headlines, and emphasis * **Body font**: Used for paragraphs, descriptions, and readable content * **Monospace font**: Used for code blocks, technical content, and UI elements This three-font approach provides visual hierarchy and flexibility while maintaining design cohesion. ## Why Font Pairings Matter Choosing the right combination of fonts can make or break your design. Good font pairings: * Create visual hierarchy through contrast and harmony * Enhance readability across different content types * Establish brand personality and mood * Ensure consistency across your entire project Fonttrio offers 50+ curated pairings designed by typography experts, so you don't have to be a type designer to achieve professional results. ## Pairing Structure Each pairing in Fonttrio follows a consistent structure defined in the registry: ```json registry/pairings/editorial.json theme={null} { "name": "pairing-editorial", "type": "registry:style", "title": "Editorial — Playfair Display + Source Serif 4 + JetBrains Mono", "description": "Classic editorial pairing. High-contrast serif headings with readable serif body text.", "categories": ["serif", "editorial", "elegant"], "registryDependencies": [ "https://www.fonttrio.xyz/r/playfair-display.json", "https://www.fonttrio.xyz/r/source-serif-4.json", "https://www.fonttrio.xyz/r/jetbrains-mono.json" ], "cssVars": { "theme": { "--font-heading": "var(--font-playfair-display)", "--font-body": "var(--font-source-serif-4)", "--font-mono": "var(--font-jetbrains-mono)" } }, "meta": { "mood": ["elegant", "traditional", "authoritative"], "useCase": ["blog", "editorial", "magazine", "documentation"] } } ``` ```json registry/pairings/minimal.json theme={null} { "name": "pairing-minimal", "type": "registry:style", "title": "Minimal — Geist + Geist + Geist Mono", "description": "Ultra-minimal Vercel-style pairing. One font family for everything, clean and modern.", "categories": ["sans-serif", "minimal", "modern"], "registryDependencies": [ "https://www.fonttrio.xyz/r/geist.json", "https://www.fonttrio.xyz/r/geist-mono.json" ], "cssVars": { "theme": { "--font-heading": "var(--font-geist)", "--font-body": "var(--font-geist)", "--font-mono": "var(--font-geist-mono)" } }, "meta": { "mood": ["modern", "minimal", "Vercel-style"], "useCase": ["SaaS", "developer tools", "Vercel-style"] } } ``` ## TypeScript Interface Fonttrio uses TypeScript to provide type safety for font pairings. Here's the interface from `/home/daytona/workspace/source/lib/pairings.ts:3-25`: ```typescript lib/pairings.ts theme={null} export type FontCategory = "serif" | "sans-serif" | "monospace"; export interface TypographyScale { h1: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h2: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h3: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h4: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h5: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h6: { size: string; weight: number; lineHeight: string; letterSpacing: string }; body: { size: string; lineHeight: string; weight: number }; } export interface PairingData { name: string; heading: string; headingCategory: FontCategory; body: string; bodyCategory: FontCategory; mono: string; mood: string[]; useCase: string[]; description: string; scale: TypographyScale; googleFontsUrl: string; } ``` ## Pairing Categories Fonttrio organizes pairings by their heading font category: Traditional and elegant, serif pairings work well for editorial content, blogs, and formal documentation. **Examples**: Editorial, Classic, Gazette Modern and clean, sans-serif pairings are perfect for SaaS applications, dashboards, and contemporary websites. **Examples**: Minimal, Modern Clean, Dashboard Combine serif and sans-serif fonts for contrast and visual interest. Great for portfolios and creative projects. **Examples**: Architect, Scholar, Curator Some pairings use monospace for headings to create a technical, developer-focused aesthetic. **Examples**: DevTool, Technical ## Working with Pairings Fonttrio provides utility functions to work with pairings: ```typescript lib/pairings.ts theme={null} // Get all available pairings export function getAllPairings(): PairingData[] // Get a specific pairing by name export function getPairing(name: string): PairingData | undefined // Filter pairings by mood export function getPairingsByMood(mood: string): PairingData[] // Filter pairings by font category export function getPairingsByCategory(category: FontCategory): PairingData[] // Get all unique moods export function getAllMoods(): string[] // Get Google Fonts URL for a pairing export function getPairingGoogleFontsUrl(name: string): string | null ``` ## Mood and Use Cases Each pairing is tagged with moods and use cases to help you find the right fit: Pairings are categorized by emotional tone and design personality: * **Editorial**: elegant, traditional, authoritative * **Clean**: modern, minimal, neutral, SaaS * **Bold**: impactful, commanding, raw, brutalist * **Friendly**: approachable, warm, playful, startup * **Corporate**: professional, trustworthy, systematic * **Creative**: distinctive, geometric, curated, nordic * **Academic**: scholarly, refined, readable, universal Pairings are optimized for specific project types: * **blog**, **editorial**, **magazine** - Content-heavy sites * **SaaS**, **dashboard**, **web app** - Applications and tools * **landing page**, **startup**, **product** - Marketing sites * **portfolio**, **agency**, **design** - Creative showcases * **documentation**, **developer tools** - Technical content ## Example: Accessing Pairing Data Here's how pairing data is structured in the codebase: ```typescript lib/pairings-data.ts theme={null} { name: "editorial", heading: "Playfair Display", headingCategory: "serif", body: "Source Serif 4", bodyCategory: "serif", mono: "JetBrains Mono", mood: ["elegant", "traditional", "authoritative"], useCase: ["blog", "editorial", "magazine", "documentation"], description: "Classic editorial pairing. High-contrast serif headings with readable serif body text.", scale: { h1: { size: "2.25rem", weight: 700, lineHeight: "1.2", letterSpacing: "-0.025em" }, // ... other heading levels body: { size: "1rem", lineHeight: "1.65", weight: 400 } }, googleFontsUrl: "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Serif+4:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" } ``` ## Next Steps Learn how Fonttrio's typography scales create visual hierarchy Discover how to customize font pairings with CSS variables Explore all 50+ curated font pairings Install Fonttrio and start using pairings in your project # Typography Scale Source: https://kapishdima-fonttrio.mintlify.app/concepts/typography-scale Understanding Fonttrio's typography scale system for creating visual hierarchy # Typography Scale Typography scales are the backbone of visual hierarchy in web design. Fonttrio includes carefully crafted scales for each pairing, ensuring consistent and harmonious sizing across all text elements. ## What is a Typography Scale? A typography scale defines the size, weight, line height, and letter spacing for all text elements in your design system. It creates a predictable rhythm and hierarchy that guides readers through your content. In Fonttrio, every pairing includes a complete scale with settings for: * Six heading levels (h1 through h6) * Body text * Line heights optimized for readability * Letter spacing (tracking) for optical balance * Font weights for proper emphasis ## Scale Structure Each typography scale in Fonttrio follows this TypeScript interface from `/home/daytona/workspace/source/lib/pairings.ts:3-11`: ```typescript lib/pairings.ts theme={null} export interface TypographyScale { h1: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h2: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h3: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h4: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h5: { size: string; weight: number; lineHeight: string; letterSpacing: string }; h6: { size: string; weight: number; lineHeight: string; letterSpacing: string }; body: { size: string; lineHeight: string; weight: number }; } ``` ## Scale Examples Different pairings use different scales to match their personality and use case. Here are real examples from Fonttrio's registry: ```typescript Editorial Scale theme={null} { h1: { size: "2.25rem", // 36px weight: 700, lineHeight: "1.2", letterSpacing: "-0.025em" }, h2: { size: "1.875rem", // 30px weight: 600, lineHeight: "1.25", letterSpacing: "-0.02em" }, h3: { size: "1.5rem", // 24px weight: 600, lineHeight: "1.3", letterSpacing: "-0.015em" }, h4: { size: "1.25rem", // 20px weight: 500, lineHeight: "1.35", letterSpacing: "-0.01em" }, h5: { size: "1.125rem", // 18px weight: 500, lineHeight: "1.4", letterSpacing: "0em" }, h6: { size: "1rem", // 16px weight: 500, lineHeight: "1.5", letterSpacing: "0em" }, body: { size: "1rem", // 16px lineHeight: "1.65", weight: 400 } } ``` ```typescript Brutalist Scale theme={null} { h1: { size: "2.75rem", // 44px - Larger, bolder weight: 800, lineHeight: "1.05", // Tighter for impact letterSpacing: "-0.035em" }, h2: { size: "2.25rem", // 36px weight: 700, lineHeight: "1.1", letterSpacing: "-0.025em" }, h3: { size: "1.75rem", // 28px weight: 700, lineHeight: "1.2", letterSpacing: "-0.02em" }, h4: { size: "1.25rem", weight: 500, lineHeight: "1.35", letterSpacing: "-0.01em" }, h5: { size: "1.125rem", weight: 500, lineHeight: "1.4", letterSpacing: "0em" }, h6: { size: "1rem", weight: 500, lineHeight: "1.5", letterSpacing: "0em" }, body: { size: "1rem", lineHeight: "1.6", // Slightly tighter weight: 400 } } ``` ```typescript Minimal Scale theme={null} { h1: { size: "2.25rem", weight: 700, lineHeight: "1.15", // Very tight, modern letterSpacing: "-0.025em" }, h2: { size: "1.875rem", weight: 600, lineHeight: "1.2", letterSpacing: "-0.02em" }, h3: { size: "1.5rem", weight: 500, // Lighter weight lineHeight: "1.3", letterSpacing: "-0.015em" }, h4: { size: "1.25rem", weight: 500, lineHeight: "1.35", letterSpacing: "-0.01em" }, h5: { size: "1.125rem", weight: 500, lineHeight: "1.4", letterSpacing: "0em" }, h6: { size: "1rem", weight: 500, lineHeight: "1.5", letterSpacing: "0em" }, body: { size: "1rem", lineHeight: "1.6", weight: 400 } } ``` ## Scale Anatomy Let's break down the components of a typography scale: ### Font Size Font sizes in Fonttrio use `rem` units, which scale relative to the root font size (typically 16px): * **h1**: 2.25rem - 2.75rem (36px - 44px) - Large, attention-grabbing * **h2**: 1.875rem - 2.25rem (30px - 36px) - Section headers * **h3**: 1.5rem - 1.75rem (24px - 28px) - Subsection headers * **h4-h6**: 1rem - 1.25rem (16px - 20px) - Minor headings * **body**: 1rem (16px) - Optimal reading size Using `rem` units ensures your typography scales proportionally when users adjust their browser's font size, improving accessibility. ### Line Height Line height (leading) affects readability and visual rhythm: * **Headings**: 1.05 - 1.4 - Tighter for impact and compactness * **Body text**: 1.6 - 1.75 - Looser for comfortable reading ```typescript theme={null} // Tight line height for bold impact h1: { lineHeight: "1.05" } // Brutalist style // Generous line height for readability body: { lineHeight: "1.75" } // Gazette style ``` ### Letter Spacing Letter spacing (tracking) adjusts the space between characters: * **Negative tracking** (-0.035em to -0.01em) - Tightens large headings for optical balance * **Neutral tracking** (0em) - Natural spacing for smaller text * **Positive tracking** (rare) - Opens up compressed fonts ```typescript theme={null} // Large headings need negative tracking h1: { letterSpacing: "-0.035em" } // Smaller text uses neutral spacing h5: { letterSpacing: "0em" } ``` ### Font Weight Font weights create hierarchy through visual emphasis: * **800**: Extra bold - Used in brutalist and impact styles * **700**: Bold - Common for h1 and strong emphasis * **600**: Semi-bold - Versatile for h2-h3 * **500**: Medium - Subtle emphasis for h4-h6 * **400**: Regular - Standard body text weight ## Scale Patterns Fonttrio uses different scale ratios depending on the pairing's personality: **Use case**: Balanced, versatile This scale provides moderate contrast between sizes, suitable for most applications. ``` 16px → 20px → 25px → 31px → 39px 1rem → 1.25rem → 1.56rem → 1.95rem → 2.44rem ``` Used in: Editorial, Modern Clean, Dashboard **Use case**: Strong hierarchy Creates more dramatic size differences for better visual separation. ``` 16px → 21px → 28px → 37px → 49px 1rem → 1.31rem → 1.75rem → 2.31rem → 3.06rem ``` Used in: Brutalist, Impact, Headline **Use case**: Subtle, refined Gentle size progression for sophisticated, minimalist designs. ``` 16px → 19px → 23px → 28px → 33px 1rem → 1.19rem → 1.44rem → 1.73rem → 2.07rem ``` Used in: Minimal, Handbook, Document ## Responsive Scales While Fonttrio's base scales work great across devices, you can adjust them for mobile: ```css theme={null} /* Base scale */ h1 { font-size: 2.25rem; line-height: 1.2; } /* Mobile optimization */ @media (max-width: 768px) { h1 { font-size: 1.875rem; /* Slightly smaller */ line-height: 1.25; /* Slightly looser */ } } ``` ## Real-World Examples Here's how different pairings use scales to match their purpose: **Purpose**: Long-form reading * Generous line height (1.65+) * Moderate font sizes * High contrast between h1 and body **Purpose**: Data-dense interfaces * Compact line heights * Smaller size jumps * Consistent weights for scanning **Purpose**: Marketing impact * Large, bold h1 (2.5rem+) * Dramatic size progression * Tight line heights for hero text **Purpose**: Technical content * Readable body text (1rem, 1.65 line height) * Clear hierarchy for nested sections * Monospace integration for code ## Accessing Scale Data You can access typography scale data programmatically: ```typescript theme={null} import { getPairing } from '@/lib/pairings'; const editorial = getPairing('editorial'); if (editorial) { console.log(editorial.scale.h1); // { // size: "2.25rem", // weight: 700, // lineHeight: "1.2", // letterSpacing: "-0.025em" // } } ``` ## Scale Constants Fonttrio provides predefined size options for customization in `/home/daytona/workspace/source/lib/constants.ts:19-28`: ```typescript lib/constants.ts theme={null} export const FONT_SIZES = [ { value: 14, label: "14" }, { value: 18, label: "18" }, { value: 24, label: "24" }, { value: 32, label: "32" }, { value: 48, label: "48" }, { value: 64, label: "64" }, { value: 96, label: "96" }, { value: 128, label: "128" }, ] as const; ``` ## Best Practices **Readability First**: Body text should be at least 16px (1rem) with line height of 1.5 or greater for comfortable reading. **Optical Adjustments**: Large headings benefit from negative letter spacing and tighter line heights to maintain visual balance. **Consistent Rhythm**: Use the same scale ratio throughout your design to maintain visual harmony. **Test at Scale**: Always preview your typography at actual size on real devices—what looks good in Figma might need adjustment in production. ## Next Steps Learn about Fonttrio's three-font pairing system Apply typography scales using CSS variables Learn how to customize scales for your project Explore scales across all font pairings # Browsing Font Pairings Source: https://kapishdima-fonttrio.mintlify.app/guides/browsing-pairings Learn how to explore and discover the perfect font combination for your project using the Fonttrio preview site. The Fonttrio website provides an interactive preview experience to help you find the perfect font pairing for your shadcn/ui project. With 49 curated combinations spanning from editorial to corporate styles, you can browse, filter, and test each pairing before installing. ## Preview Site Features Visit [fonttrio.xyz](https://www.fonttrio.xyz) to explore all available pairings. Each pairing includes: * Live preview with actual fonts loaded from Google Fonts * Complete typography scale visualization (h1 through body text) * Interactive type tester for custom text * Context previews showing the pairing in blog, landing page, and documentation layouts * One-click install command ## Filtering Pairings The preview site includes powerful filtering options to help you narrow down your search: ### Filter by Type Pairings are organized by their heading font category: Traditional, editorial, and elegant pairings featuring serif heading fonts like Playfair Display, Merriweather, and Crimson Text. Modern, clean, and minimal pairings using sans-serif fonts like Inter, Space Grotesk, and Work Sans. Bold, high-impact pairings with display fonts like Bebas Neue and Anton for marketing and landing pages. ### Filter by Style Pairings are grouped by mood and use case: * **Editorial** — Sophisticated combinations for content-heavy sites (blogs, magazines, editorial content) * **Clean** — Minimal, modern combinations for apps and SaaS products * **Bold** — High-impact combinations for marketing and landing pages * **Corporate** — Professional combinations for business and enterprise applications * **Creative** — Unique combinations for portfolios and creative work ### Active Filters When filters are active, the site displays: * The current number of matching pairings * A "Clear" button to reset all filters * Filtered results in a responsive grid layout The filter bar is sticky and remains visible as you scroll through results, making it easy to refine your search without losing your place. ## Pairing Cards Each pairing is displayed as a card in the grid, showing: ```tsx theme={null} // Each card displays: - Pairing name (e.g., "Editorial", "Minimal") - Description of the combination - Heading font sample - Body font sample - Monospace font sample - Quick copy install command ``` ### Card Layout Cards are organized in a responsive grid: * **Mobile**: Single column * **Tablet**: 2 columns * **Desktop**: 3 columns Click any card to view the full pairing detail page. ## Using the Type Tester The type tester allows you to preview fonts with your own text before installing. Click any pairing card to open the detailed pairing page. Scroll down to the "Type Tester" section on the pairing detail page. Choose which font to preview: heading, body, or mono. Select from preset sizes: 14, 18, 24, 32, 48, 64, 96, or 128px. Click through available weights: Light (300), Regular (400), Medium (500), SemiBold (600), and Bold (700). Use the editable specimen area to type your own text and see it rendered in real-time. ### Type Tester Interface The type tester provides a comprehensive preview experience: ```tsx theme={null} // Type tester features: const DEFAULT_TEXT = "The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs."; const WEIGHTS = [ { value: 300, label: "Light" }, { value: 400, label: "Regular" }, { value: 500, label: "Medium" }, { value: 600, label: "SemiBold" }, { value: 700, label: "Bold" }, ]; const SIZES = [14, 18, 24, 32, 48, 64, 96, 128]; ``` Each weight displays: * Weight label and numeric value * Full specimen text at selected size * Hover effects for better interaction Not all fonts support all weight values. If a weight isn't available for a specific font, the browser will use the closest available weight. ## Context Previews The context preview section shows how your chosen pairing looks in real-world scenarios: ### Blog Context Shows the pairing in an article layout with: * Article title and date * Multiple heading levels (h1, h2) * Body paragraphs * Blockquotes * Code blocks ### Landing Page Context Demonstrates the pairing in a marketing layout with: * Large hero heading * Subheading and call-to-action * Feature cards * Buttons and interactive elements ### Documentation Context Previews the pairing in a docs layout featuring: * Sidebar navigation * Multiple heading levels * Lists and inline code * Installation commands Context previews use the actual typography scale defined in the pairing, giving you an accurate representation of how the fonts will look in your project. ## Typography Scale Preview Each pairing detail page includes a complete typography scale preview showing: * **h1 through h6**: All heading levels with their configured size, weight, line height, and letter spacing * **Body text**: Paragraph styling with appropriate line height * **Monospace**: Code and preformatted text styling The scale preview displays: ```css theme={null} /* Example scale values */ h1: { size: "2.25rem", weight: 700, lineHeight: "1.2", letterSpacing: "-0.025em" } h2: { size: "1.875rem", weight: 600, lineHeight: "1.25", letterSpacing: "-0.02em" } body: { size: "1rem", lineHeight: "1.65", weight: 400 } ``` ## Search and Discovery While there's no dedicated search box, you can quickly find pairings by: 1. **Using filters** to narrow by type and style 2. **Scrolling through the grid** to visually scan options 3. **Reading descriptions** on each card for use case guidance The grid displays all pairings sorted alphabetically, with animated loading for a smooth browsing experience. ## Mobile Experience The preview site is fully responsive: * Touch-friendly filter buttons with proper hit areas (min 44px height) * Horizontal scroll for style filters on narrow screens * Optimized font sizes that scale with viewport * Single-column layout on mobile devices * Sticky filter bar that adapts to mobile layout ## Next Steps Once you've found the perfect pairing: Learn how to add the pairing to your project using the shadcn CLI. Adjust the typography scale to match your design requirements. # Customizing Typography Source: https://kapishdima-fonttrio.mintlify.app/guides/customizing-typography Learn how to customize typography scales, override defaults, and create your own font combinations in Fonttrio. While Fonttrio pairings come with carefully crafted typography scales, every project has unique design requirements. This guide shows you how to customize font sizes, weights, line heights, and create custom combinations. ## Understanding the Typography Scale Each Fonttrio pairing includes a complete typography scale defined in CSS: ```css theme={null} /* Default Editorial pairing scale */ h1 { font-family: var(--font-heading); font-size: 2.25rem; /* 36px */ line-height: 1.2; letter-spacing: -0.025em; font-weight: 700; } h2 { font-family: var(--font-heading); font-size: 1.875rem; /* 30px */ line-height: 1.25; letter-spacing: -0.02em; font-weight: 600; } h3 { font-family: var(--font-heading); font-size: 1.5rem; /* 24px */ line-height: 1.3; letter-spacing: -0.015em; font-weight: 600; } /* h4, h5, h6, body, code... */ ``` This scale is applied globally through your `globals.css` file. ## Customizing the Scale You can customize any part of the typography scale by editing `globals.css`: ### Adjusting Font Sizes Override specific heading sizes: ```css app/globals.css theme={null} @layer base { /* Make h1 larger for landing pages */ h1 { font-size: 3rem; /* Changed from 2.25rem */ } /* Reduce h2 size for tighter hierarchy */ h2 { font-size: 1.75rem; /* Changed from 1.875rem */ } } ``` ### Adjusting Font Weights Change weights for different emphasis: ```css app/globals.css theme={null} @layer base { /* Lighter headings for a more elegant feel */ h1 { font-weight: 600; /* Changed from 700 */ } /* Bolder body text for better readability */ body, p { font-weight: 500; /* Changed from 400 */ } } ``` ### Adjusting Line Heights Modify line heights for better readability: ```css app/globals.css theme={null} @layer base { /* Tighter line height for display headings */ h1 { line-height: 1.1; /* Changed from 1.2 */ } /* More spacious body text */ body, p { line-height: 1.75; /* Changed from 1.65 */ } } ``` ### Adjusting Letter Spacing Fine-tune letter spacing (tracking): ```css app/globals.css theme={null} @layer base { /* Tighter tracking for bold headings */ h1 { letter-spacing: -0.03em; /* Changed from -0.025em */ } /* Looser tracking for better legibility at small sizes */ body, p { letter-spacing: 0.01em; /* Added tracking */ } } ``` Changes to `globals.css` affect all instances of these elements throughout your app. For component-specific overrides, use Tailwind classes or CSS modules. ## Using Tailwind Classes for Overrides For component-specific customizations, use Tailwind utility classes: ### Override Font Size ```tsx theme={null}

{/* Overrides default h1 size */} Large Hero Heading

{/* Smaller h2 for cards */} Card Title

``` ### Override Font Weight ```tsx theme={null}

{/* 300 instead of default 700 */} Light Heading

{/* 600 instead of default 400 */} Emphasized paragraph

``` ### Override Line Height ```tsx theme={null}

{/* Tighter than default */} Compact Heading

{/* More spacious */} Relaxed paragraph

``` ### Override Letter Spacing ```tsx theme={null}

{/* Tighter tracking */} Condensed Heading

{/* Looser tracking */} Spaced paragraph

``` ### Combining Overrides ```tsx theme={null}

Fully Custom Heading

``` ## Creating Responsive Typography Use Tailwind's responsive prefixes to create adaptive typography: ```tsx theme={null}

Responsive Heading

Responsive body text

``` Or use clamp() in CSS for fluid typography: ```css app/globals.css theme={null} @layer base { h1 { font-size: clamp(2rem, 5vw, 4rem); } body, p { font-size: clamp(0.875rem, 1.5vw, 1.125rem); } } ``` Be careful with `clamp()` values. Test across multiple screen sizes to ensure text remains readable on both mobile and desktop. ## Customizing CSS Variables You can override the font family variables to create custom combinations: ### Swap Fonts Within a Pairing ```css app/globals.css theme={null} @layer base { :root { /* Use body font for headings instead */ --font-heading: var(--font-source-serif-4); /* Use heading font for body */ --font-body: var(--font-playfair-display); } } ``` ### Create Dark Mode Font Variations ```css app/globals.css theme={null} @layer base { :root { --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); } .dark { /* Lighter weights for dark mode */ --font-heading-weight: 600; /* Custom variable */ --font-body-weight: 300; } } ``` Then reference in your components: ```tsx theme={null}

Adapts to dark mode

``` ## Creating Custom Font Pairings You can mix and match individual fonts from different pairings: Install pairings that contain the fonts you want to mix. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json ``` Override the CSS variables to create your custom combination. ```css app/globals.css theme={null} @layer base { :root { /* Playfair Display from Editorial */ --font-heading: var(--font-playfair-display); /* Inter from Minimal */ --font-body: var(--font-inter); /* Keep JetBrains Mono from either */ --font-mono: var(--font-jetbrains-mono); } } ``` Import the fonts in your layout. ```tsx app/layout.tsx theme={null} import { playfairDisplay } from "@/registry/fonts/playfair-display"; import { inter } from "@/registry/fonts/inter"; import { jetbrainsMono } from "@/registry/fonts/jetbrains-mono"; export default function RootLayout({ children }) { return ( {children} ); } ``` Adjust typography scale to match your custom pairing. ```css app/globals.css theme={null} @layer base { h1 { font-family: var(--font-heading); font-size: 3rem; font-weight: 700; /* Playfair works well at 700 */ line-height: 1.1; letter-spacing: -0.03em; } body, p { font-family: var(--font-body); font-size: 1rem; font-weight: 400; /* Inter default weight */ line-height: 1.6; } } ``` When creating custom pairings, test thoroughly to ensure the fonts complement each other. Consider contrast (serif vs sans), weight, and x-height compatibility. ## Using the Typography Customizer (Preview Site) The Fonttrio preview site includes an interactive typography customizer: ```tsx theme={null} // The customizer lets you adjust: interface TypographyScale { h1: { size: string; // e.g., "2.25rem" weight: number; // 100-900 lineHeight: string; // e.g., "1.2" letterSpacing: string; // e.g., "-0.025em" }; // h2-h6, body... } ``` Experiment with the customizer, then copy the resulting CSS to your project. The customizer on the preview site is for experimentation only. Changes are not saved or exported automatically. Note your preferred values and apply them manually to `globals.css`. ## Advanced Customization Techniques ### Creating Context-Specific Scales Define different scales for different sections: ```css app/globals.css theme={null} @layer components { /* Landing page hero scale */ .hero h1 { font-size: 4rem; font-weight: 800; line-height: 1; letter-spacing: -0.04em; } /* Blog content scale */ .article h1 { font-size: 2.5rem; font-weight: 700; line-height: 1.2; letter-spacing: -0.02em; } /* Documentation scale */ .docs h1 { font-size: 2rem; font-weight: 600; line-height: 1.3; letter-spacing: -0.015em; } } ``` ### Using CSS Custom Properties for Dynamic Scales Create adjustable scales with CSS variables: ```css app/globals.css theme={null} @layer base { :root { --scale-ratio: 1.25; /* Major third */ --base-size: 1rem; --text-xs: calc(var(--base-size) / var(--scale-ratio) / var(--scale-ratio)); --text-sm: calc(var(--base-size) / var(--scale-ratio)); --text-base: var(--base-size); --text-lg: calc(var(--base-size) * var(--scale-ratio)); --text-xl: calc(var(--base-size) * var(--scale-ratio) * var(--scale-ratio)); } h1 { font-size: var(--text-xl); } h2 { font-size: var(--text-lg); } body { font-size: var(--text-base); } } ``` Change the entire scale by adjusting one variable: ```css theme={null} @layer base { /* Larger scale for marketing */ .marketing { --scale-ratio: 1.414; /* Augmented fourth */ } /* Compact scale for dense interfaces */ .app { --scale-ratio: 1.125; /* Major second */ } } ``` ### Extending Tailwind Config Add custom font sizes to Tailwind: ```js tailwind.config.js theme={null} module.exports = { theme: { extend: { fontSize: { 'display-1': ['4.5rem', { lineHeight: '1', letterSpacing: '-0.04em' }], 'display-2': ['3.75rem', { lineHeight: '1.05', letterSpacing: '-0.035em' }], 'heading-1': ['3rem', { lineHeight: '1.1', letterSpacing: '-0.03em' }], }, fontFamily: { heading: 'var(--font-heading)', body: 'var(--font-body)', mono: 'var(--font-mono)', }, }, }, } ``` Use in components: ```tsx theme={null}

Custom Display Heading

``` ## Best Practices Use the pairing's default scale first. Only customize after seeing how it works in your actual content. Ensure h1 is always larger than h2, h2 larger than h3, etc. Keep a clear visual hierarchy. Verify your customizations work on mobile, tablet, and desktop. Use responsive utilities or clamp(). Adjust line height based on line length. Longer lines need more line height (1.6-1.8), shorter lines can be tighter (1.4-1.5). Don't just test with "Lorem ipsum". Use actual headings and paragraphs from your content. Add comments in `globals.css` explaining why you customized specific values. ## Common Customization Patterns ### Marketing Landing Pages ```css theme={null} /* Larger, bolder headings with tight spacing */ h1 { font-size: 4rem; font-weight: 800; line-height: 1; } h2 { font-size: 2.5rem; font-weight: 700; line-height: 1.1; } body { font-size: 1.125rem; line-height: 1.6; } ``` ### Blog and Editorial ```css theme={null} /* Comfortable reading with generous spacing */ h1 { font-size: 2.5rem; font-weight: 700; line-height: 1.2; } body { font-size: 1.125rem; line-height: 1.75; } ``` ### Documentation Sites ```css theme={null} /* Clear hierarchy with moderate sizes */ h1 { font-size: 2rem; font-weight: 600; line-height: 1.25; } h2 { font-size: 1.5rem; font-weight: 600; line-height: 1.3; } body { font-size: 1rem; line-height: 1.65; } code { font-size: 0.875rem; } ``` ### SaaS Dashboards ```css theme={null} /* Compact, efficient use of space */ h1 { font-size: 1.75rem; font-weight: 600; line-height: 1.25; } h2 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; } body { font-size: 0.875rem; line-height: 1.5; } ``` ## Next Steps Learn how to install and switch between multiple font pairings. Apply your custom typography to shadcn/ui components. # Installing Font Pairings Source: https://kapishdima-fonttrio.mintlify.app/guides/installing-pairings Complete guide to installing Fonttrio font pairings in your shadcn/ui project using the CLI. Fonttrio uses the shadcn/ui registry system to deliver font pairings directly to your project. Installation takes seconds and requires no manual configuration. ## Prerequisites Before installing a Fonttrio pairing, ensure your project has: Fonttrio pairings use `next/font/google` for optimal font loading. ```bash theme={null} npx create-next-app@latest my-app ``` The shadcn CLI must be configured in your project. ```bash theme={null} npx shadcn@latest init ``` Tailwind should be configured as part of your Next.js or shadcn setup. If you haven't set up shadcn/ui yet, follow the [official installation guide](https://ui.shadcn.com/docs/installation/next) first. ## Installation Command Install any pairing using the shadcn CLI: ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` Replace `editorial` with any pairing name from the collection. ### Package Manager Options Fonttrio supports all major package managers: ```bash npm theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` ```bash yarn theme={null} yarn dlx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` ```bash pnpm theme={null} pnpm dlx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` ```bash bun theme={null} bunx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` ## What Gets Installed When you install a pairing, the shadcn CLI automatically adds the following to your project: ### 1. Font Imports Three font files are created in your project with `next/font/google` imports: ```tsx theme={null} // Example: registry/fonts/playfair-display.tsx import { Playfair_Display } from "next/font/google"; export const playfairDisplay = Playfair_Display({ subsets: ["latin"], weight: ["400", "500", "600", "700", "800"], variable: "--font-playfair-display", }); ``` ```tsx theme={null} // registry/fonts/source-serif-4.tsx import { Source_Serif_4 } from "next/font/google"; export const sourceSerif4 = Source_Serif_4({ subsets: ["latin"], weight: ["300", "400", "500", "600", "700"], variable: "--font-source-serif-4", }); ``` ```tsx theme={null} // registry/fonts/jetbrains-mono.tsx import { JetBrains_Mono } from "next/font/google"; export const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], weight: ["300", "400", "500", "600", "700"], variable: "--font-jetbrains-mono", }); ``` ### 2. Pairing Configuration A pairing file that combines all three fonts: ```tsx theme={null} // registry/pairings/editorial.tsx import { playfairDisplay } from "@/registry/fonts/playfair-display"; import { sourceSerif4 } from "@/registry/fonts/source-serif-4"; import { jetbrainsMono } from "@/registry/fonts/jetbrains-mono"; export const editorial = { heading: playfairDisplay, body: sourceSerif4, mono: jetbrainsMono, }; ``` ### 3. CSS Variables The pairing adds CSS custom properties to your `globals.css`: ```css theme={null} @layer base { :root { --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); --font-mono: var(--font-jetbrains-mono); } } ``` ### 4. Typography Scale CSS rules for all heading and body elements: ```css theme={null} @layer base { h1 { font-family: var(--font-heading); font-size: 2.25rem; line-height: 1.2; letter-spacing: -0.025em; font-weight: 700; } h2 { font-family: var(--font-heading); font-size: 1.875rem; line-height: 1.25; letter-spacing: -0.02em; font-weight: 600; } h3 { font-family: var(--font-heading); font-size: 1.5rem; line-height: 1.3; letter-spacing: -0.015em; font-weight: 600; } h4, h5, h6 { font-family: var(--font-heading); letter-spacing: -0.01em; } body, p { font-family: var(--font-body); line-height: 1.65; } code, pre { font-family: var(--font-mono); } } ``` The typography scale is applied globally. If you have existing font styles, they will be overridden. See the [customization guide](/guides/customizing-typography) to adjust the scale. ## Applying Fonts to Your Layout After installation, apply the fonts in your root layout: ```tsx app/layout.tsx theme={null} import { editorial } from "@/registry/pairings/editorial"; import "./globals.css"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` This makes the font variables available throughout your entire application. ## Using Fonts in Components Once installed, use the CSS variables in your components: ### With Tailwind Classes ```tsx theme={null}

Your Heading

Your body text

const code = true; ``` ### With Inline Styles ```tsx theme={null}

Your Heading

``` ### With CSS Modules ```css styles.module.css theme={null} .heading { font-family: var(--font-heading); } .body { font-family: var(--font-body); } ``` Because the typography scale is applied globally via `globals.css`, all `

` through `

` and `

` elements automatically use the pairing fonts. You only need to explicitly set fonts for custom components. ## Installation Options The shadcn CLI provides several options for customizing the installation: ### Overwrite Existing Files If you've already installed a pairing and want to replace it: ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json --overwrite ``` ### Silent Mode Skip confirmation prompts: ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json --yes ``` ### Custom Path Install to a different directory: ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json --path ./src ``` ## Available Pairings Here are some popular pairings you can install: ### Editorial ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` Playfair Display + Source Serif 4 + JetBrains Mono — Classic editorial pairing ### Minimal ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json ``` Inter + Inter + JetBrains Mono — Clean, modern, minimal ### Corporate ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/corporate.json ``` Raleway + Open Sans + Roboto Mono — Professional and trustworthy ### Impact ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json ``` Bebas Neue + Barlow + Fira Code — High-impact marketing ### Protocol ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/protocol.json ``` Sora + Inter + JetBrains Mono — Modern fintech and SaaS Visit [fonttrio.xyz](https://www.fonttrio.xyz) to browse all 49 available pairings with live previews. ## Verifying Installation After installation, verify everything is set up correctly: Confirm the font files exist in `registry/fonts/` and the pairing exists in `registry/pairings/`. Verify CSS variables and typography scale rules were added. Add the font variables to your root layout as shown above. Run your dev server and inspect headings in the browser DevTools to confirm fonts are loading from Google Fonts. ## Troubleshooting ### Fonts Not Loading If fonts aren't appearing in your browser: 1. Check that font variables are added to the `` element in your layout 2. Verify `globals.css` is imported in your root layout 3. Clear your browser cache and reload 4. Check the Network tab in DevTools to confirm Google Fonts are loading ### CSS Variables Not Working If `var(--font-heading)` isn't resolving: 1. Ensure the font variables are applied to the `` element, not `` 2. Check that the variable names match exactly (case-sensitive) 3. Verify Tailwind is configured to recognize the arbitrary values ### Existing Fonts Conflict If you have existing font configurations: 1. Remove or comment out old font imports 2. Clear the old CSS variables from `globals.css` 3. Reinstall the Fonttrio pairing 4. Update your layout to use the new font variables ## Next Steps Adjust font sizes, weights, and spacing to match your design. Learn how to install and switch between multiple pairings. # Mixing Multiple Pairings Source: https://kapishdima-fonttrio.mintlify.app/guides/mixing-pairings Learn how to install multiple font pairings, switch between them, and create custom combinations in your shadcn/ui project. Fonttrio allows you to install multiple pairings in the same project, making it easy to switch between different font combinations or use different pairings for different sections of your application. ## Why Mix Pairings? Installing multiple pairings is useful for: * **A/B testing** different typography styles before committing * **Multi-section apps** where different areas need different moods (e.g., marketing landing page + documentation + app dashboard) * **Theme switching** to let users choose their preferred reading experience * **Custom combinations** by mixing fonts from different pairings ## Installing Multiple Pairings You can install as many pairings as you want. Each pairing adds its fonts to the `registry/` directory: Start with your primary pairing. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` This installs: * `registry/fonts/playfair-display.tsx` * `registry/fonts/source-serif-4.tsx` * `registry/fonts/jetbrains-mono.tsx` * `registry/pairings/editorial.tsx` Add another pairing for comparison or mixing. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json ``` This adds: * `registry/fonts/inter.tsx` (new) * `registry/fonts/jetbrains-mono.tsx` (skipped, already exists) * `registry/pairings/minimal.tsx` (new) Keep adding pairings as needed. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/corporate.json npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json ``` Shared fonts (like JetBrains Mono, which appears in many pairings) are only installed once. Subsequent pairings will reuse the existing font file. ## Switching Between Pairings Once you have multiple pairings installed, you can switch between them in your layout: ### Method 1: Direct Import Swap The simplest way is to change which pairing you import: ```tsx app/layout.tsx theme={null} // Switch this import to change the active pairing import { editorial } from "@/registry/pairings/editorial"; // import { minimal } from "@/registry/pairings/minimal"; // import { corporate } from "@/registry/pairings/corporate"; import "./globals.css"; export default function RootLayout({ children }) { return ( {children} ); } ``` To switch pairings: 1. Comment out the current import 2. Uncomment the desired pairing import 3. Update the className to use the new pairing's variables ### Method 2: Environment-Based Selection Use environment variables to select pairings: ```tsx app/layout.tsx theme={null} import { editorial } from "@/registry/pairings/editorial"; import { minimal } from "@/registry/pairings/minimal"; import { corporate } from "@/registry/pairings/corporate"; import "./globals.css"; const pairings = { editorial, minimal, corporate, }; const activePairing = pairings[ (process.env.NEXT_PUBLIC_FONT_PAIRING as keyof typeof pairings) || "editorial" ]; export default function RootLayout({ children }) { return ( {children} ); } ``` Set in `.env.local`: ```bash .env.local theme={null} NEXT_PUBLIC_FONT_PAIRING=minimal ``` ### Method 3: User-Selectable Themes Allow users to switch fonts dynamically: ```tsx app/providers.tsx theme={null} "use client"; import { createContext, useContext, useState, ReactNode } from "react"; import { editorial } from "@/registry/pairings/editorial"; import { minimal } from "@/registry/pairings/minimal"; import { corporate } from "@/registry/pairings/corporate"; type PairingName = "editorial" | "minimal" | "corporate"; const pairings = { editorial, minimal, corporate }; const FontContext = createContext<{ pairing: PairingName; setPairing: (name: PairingName) => void; }>({ pairing: "editorial", setPairing: () => {}, }); export function FontProvider({ children }: { children: ReactNode }) { const [pairing, setPairing] = useState("editorial"); const activePairing = pairings[pairing]; return (

{children}
); } export const useFontPairing = () => useContext(FontContext); ``` Use in layout: ```tsx app/layout.tsx theme={null} import { FontProvider } from "./providers"; import "./globals.css"; export default function RootLayout({ children }) { return ( {children} ); } ``` Create a font switcher component: ```tsx components/font-switcher.tsx theme={null} "use client"; import { useFontPairing } from "@/app/providers"; export function FontSwitcher() { const { pairing, setPairing } = useFontPairing(); return (
); } ``` User-selectable fonts can cause a flash of unstyled content (FOUC) during hydration. Consider storing the preference in localStorage and applying it before the initial render. ## Using Different Pairings in Different Sections You can apply different pairings to different parts of your app: ### Method 1: Section-Specific Classes Import all pairings and apply their variables to specific sections: ```tsx app/layout.tsx theme={null} import { editorial } from "@/registry/pairings/editorial"; import { minimal } from "@/registry/pairings/minimal"; import { impact } from "@/registry/pairings/impact"; import "./globals.css"; export default function RootLayout({ children }) { return ( {children} ); } ``` Create section-specific CSS: ```css app/globals.css theme={null} /* Default to Editorial for blog content */ @layer base { :root { --font-heading: var(--font-playfair-display); --font-body: var(--font-source-serif-4); --font-mono: var(--font-jetbrains-mono); } } /* Use Minimal for dashboard */ .dashboard { --font-heading: var(--font-inter); --font-body: var(--font-inter); } /* Use Impact for landing page */ .landing { --font-heading: var(--font-bebas-neue); --font-body: var(--font-barlow); } ``` Apply to sections: ```tsx theme={null}

Dashboard

{/* Uses Inter */}

Analytics data

Welcome

{/* Uses Bebas Neue */}

Get started

``` ### Method 2: Route-Based Pairings Apply different pairings to different route groups: ```tsx app/(blog)/layout.tsx theme={null} import { editorial } from "@/registry/pairings/editorial"; export default function BlogLayout({ children }) { return (
{children}
); } ``` ```tsx app/(dashboard)/layout.tsx theme={null} import { minimal } from "@/registry/pairings/minimal"; export default function DashboardLayout({ children }) { return (
{children}
); } ``` ## Creating Custom Combinations Mix and match individual fonts from different pairings: Install pairings that contain the fonts you want. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json ``` Import only the fonts you need. ```tsx app/layout.tsx theme={null} // Heading from Impact pairing import { bebasNeue } from "@/registry/fonts/bebas-neue"; // Body from Minimal pairing import { inter } from "@/registry/fonts/inter"; // Mono from Editorial pairing import { jetbrainsMono } from "@/registry/fonts/jetbrains-mono"; ``` Create your own pairing object. ```tsx app/layout.tsx theme={null} const customPairing = { heading: bebasNeue, body: inter, mono: jetbrainsMono, }; export default function RootLayout({ children }) { return ( {children} ); } ``` Point the variables to your chosen fonts. ```css app/globals.css theme={null} @layer base { :root { --font-heading: var(--font-bebas-neue); --font-body: var(--font-inter); --font-mono: var(--font-jetbrains-mono); } } ``` When mixing fonts, ensure they work well together. Consider contrast (serif vs sans), weight compatibility, and x-height. Test thoroughly with real content. ## Common Use Cases ### Marketing Site + Documentation Use a bold pairing for the landing page and a readable pairing for docs: ```tsx theme={null} // Landing page uses Impact pairing

Bold Marketing Message

// Docs use Editorial pairing

Documentation Title

Detailed technical content...

``` ### Multi-Brand Application Different brands within the same app: ```tsx theme={null} const brandPairings = { brandA: editorial, brandB: minimal, brandC: corporate, }; function BrandSection({ brand, children }) { const pairing = brandPairings[brand]; return (
{children}
); } ``` ### A/B Testing Fonts Randomly assign pairings for testing: ```tsx theme={null} const pairings = [editorial, minimal, corporate]; const randomPairing = pairings[Math.floor(Math.random() * pairings.length)]; // Or use a proper A/B testing framework const pairing = useABTest('font-test', { control: editorial, variant: minimal, }); ``` ### Seasonal Themes Switch pairings based on time of year: ```tsx theme={null} function getSeasonalPairing() { const month = new Date().getMonth(); if (month >= 10 || month <= 1) return cozyWinterPairing; if (month >= 2 && month <= 4) return freshSpringPairing; if (month >= 5 && month <= 7) return brightSummerPairing; return warmAutumnPairing; } const pairing = getSeasonalPairing(); ``` ## Managing Multiple Pairings ### Keep Track of Installed Pairings Maintain a list of your active pairings: ```ts lib/pairings.ts theme={null} import { editorial } from "@/registry/pairings/editorial"; import { minimal } from "@/registry/pairings/minimal"; import { corporate } from "@/registry/pairings/corporate"; import { impact } from "@/registry/pairings/impact"; export const PAIRINGS = { editorial, minimal, corporate, impact, } as const; export type PairingName = keyof typeof PAIRINGS; export function getPairing(name: PairingName) { return PAIRINGS[name]; } ``` ### Load Fonts on Demand For performance, only load fonts when needed: ```tsx theme={null} import dynamic from "next/dynamic"; const EditorialFonts = dynamic(() => import("@/registry/pairings/editorial").then(m => m.editorial) ); const MinimalFonts = dynamic(() => import("@/registry/pairings/minimal").then(m => m.minimal) ); ``` Dynamic font loading can cause layout shifts. This approach is only recommended for user-selectable fonts, not for initial page load. ### Update Typography Scale per Pairing Each pairing may need different CSS adjustments: ```css app/globals.css theme={null} /* Editorial: Generous spacing for reading */ .editorial h1 { font-size: 2.5rem; line-height: 1.2; } .editorial p { line-height: 1.75; } /* Minimal: Compact and efficient */ .minimal h1 { font-size: 2rem; line-height: 1.25; } .minimal p { line-height: 1.6; } /* Impact: Large and bold */ .impact h1 { font-size: 4rem; line-height: 1; } .impact p { line-height: 1.5; } ``` ## Best Practices Don't install too many pairings. 2-4 is usually enough. Each pairing adds to your bundle size. If using multiple pairings, ensure they're used consistently across similar contexts. Don't randomly switch fonts. Monitor page load times when adding multiple pairings. Each font adds HTTP requests and increases bundle size. Comment your code to explain why you're using specific pairings in specific contexts. If allowing users to switch fonts, persist their choice in localStorage and respect their preference across sessions. ## Performance Considerations ### Font Loading Impact Each pairing typically includes 3 fonts. If you install 3 pairings, you could have up to 9 fonts (though duplicates are shared). ```tsx theme={null} // Editorial: 3 fonts // Minimal: 2 new fonts (shares mono) // Corporate: 2 new fonts (shares mono) // Total: 7 unique fonts loaded ``` ### Optimize Font Loading Use `next/font` optimizations: ```tsx theme={null} import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"], display: "swap", // Prevent invisible text preload: true, // Preload critical fonts fallback: ["system-ui"], // Fallback fonts }); ``` ### Subset Fonts Only load required character sets: ```tsx theme={null} const font = Font({ subsets: ["latin"], // Not latin-ext, cyrillic, etc. weight: ["400", "700"], // Only weights you use }); ``` ## Troubleshooting ### Fonts Not Switching If changing pairings doesn't update fonts: 1. Verify font variables are applied to the correct element (usually ``) 2. Check that CSS variables in `globals.css` point to the right fonts 3. Clear browser cache and reload 4. Restart your dev server ### CSS Variables Conflicting If multiple pairings conflict: 1. Use scoped classes instead of global `:root` variables 2. Ensure each section has unique class names 3. Check specificity in DevTools to see which styles are winning ### Performance Issues If page load is slow with multiple pairings: 1. Reduce the number of installed pairings 2. Only load fonts needed for the current page 3. Use font subsetting to reduce file sizes 4. Consider using a variable font instead of multiple weights ## Next Steps Adjust typography scales for each pairing. Apply mixed pairings to shadcn/ui components. # Using Fonttrio with shadcn/ui Source: https://kapishdima-fonttrio.mintlify.app/guides/using-with-shadcn Learn how to integrate Fonttrio font pairings with shadcn/ui components and apply custom typography across your component library. Fonttrio is designed specifically for shadcn/ui projects. This guide shows you how to apply font pairings to shadcn/ui components, customize component typography, and follow best practices for a cohesive design system. ## Why Fonttrio Works with shadcn/ui Fonttrio uses the same distribution system as shadcn/ui: * **Registry-based installation** via the shadcn CLI * **Next.js + Tailwind** as the foundation * **CSS variables** for theming and customization * **Copy-paste components** that you fully own and can modify Because both use CSS variables, fonts integrate seamlessly with shadcn/ui's theming system. ## Prerequisites Before integrating Fonttrio with shadcn/ui: Set up shadcn/ui in your Next.js project. ```bash theme={null} npx shadcn@latest init ``` Add your chosen font pairing. ```bash theme={null} npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json ``` Add font variables to your root layout. ```tsx app/layout.tsx theme={null} import { editorial } from "@/registry/pairings/editorial"; import "./globals.css"; export default function RootLayout({ children }) { return ( {children} ); } ``` ## Applying Fonts to Components Once fonts are installed, they automatically apply to shadcn/ui components through CSS variables. ### Typography Components Heading and text components inherit fonts from the typography scale: ```tsx theme={null} import { Button } from "@/components/ui/button"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; export function Example() { return ( Card Title {/* Uses --font-heading */}

Card content text

{/* Uses --font-body */}
); } ``` ### Button Components Buttons use body font by default: ```tsx theme={null} import { Button } from "@/components/ui/button"; {/* Uses --font-body */} ``` Override with heading font for emphasis: ```tsx theme={null} ``` ### Form Components Input fields, labels, and form elements use body font: ```tsx theme={null} import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea";
{/* Uses --font-body */} {/* Uses --font-body */}