> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/kapishdima/fonttrio/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<ResponseField name="name" type="string" required>
  Unique identifier for the pairing, typically prefixed with `pairing-`

  **Example**: `"pairing-minimal"`, `"pairing-brutalist"`
</ResponseField>

<ResponseField name="type" type="string" required>
  Registry type identifier. Always `"registry:style"` for pairings.
</ResponseField>

<ResponseField name="extends" type="string" required>
  Base style to extend from. Use `"none"` for standalone pairings.
</ResponseField>

<ResponseField name="title" type="string" required>
  Human-readable title showing the pairing name and font combination

  **Format**: `"{Name} — {Heading} + {Body} + {Mono}"`

  **Example**: `"Minimal — Geist + Geist + Geist Mono"`
</ResponseField>

<ResponseField name="description" type="string" required>
  Descriptive text explaining the pairing's aesthetic and design philosophy
</ResponseField>

<ResponseField name="categories" type="string[]" required>
  Array of category tags for filtering and discovery

  **Common categories**: `"sans-serif"`, `"serif"`, `"minimal"`, `"modern"`, `"brutalist"`, `"display"`, `"bold"`
</ResponseField>

### Dependencies

<ResponseField name="registryDependencies" type="string[]" required>
  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"`
</ResponseField>

### CSS Variables

<ResponseField name="cssVars" type="object" required>
  Defines CSS custom properties for theme integration

  <ResponseField name="theme" type="object" required>
    Theme-level CSS variables

    <ResponseField name="--font-heading" type="string" required>
      CSS variable reference for heading font

      **Example**: `"var(--font-geist)"`
    </ResponseField>

    <ResponseField name="--font-body" type="string" required>
      CSS variable reference for body font

      **Example**: `"var(--font-inter)"`
    </ResponseField>

    <ResponseField name="--font-mono" type="string" required>
      CSS variable reference for monospace font

      **Example**: `"var(--font-geist-mono)"`
    </ResponseField>
  </ResponseField>
</ResponseField>

### CSS Styles

<ResponseField name="css" type="object" required>
  Complete typography styles for all HTML elements. Keys are CSS selectors, values are style objects.

  <ResponseField name="h1" type="object" required>
    Styles for primary headings

    <ResponseField name="font-family" type="string" required>
      Font family, typically referencing `var(--font-heading)`
    </ResponseField>

    <ResponseField name="font-size" type="string" required>
      Font size in rem, em, or px

      **Example**: `"2.25rem"`
    </ResponseField>

    <ResponseField name="line-height" type="string" required>
      Unitless line height value

      **Example**: `"1.15"`
    </ResponseField>

    <ResponseField name="letter-spacing" type="string" required>
      Letter spacing in em units

      **Example**: `"-0.025em"`
    </ResponseField>

    <ResponseField name="font-weight" type="string" required>
      Font weight value (100-900)

      **Example**: `"700"`
    </ResponseField>
  </ResponseField>

  <ResponseField name="h2, h3, h4, h5, h6" type="object">
    Similar structure to h1, can target multiple selectors
  </ResponseField>

  <ResponseField name="body, p" type="object" required>
    Styles for body text and paragraphs

    <ResponseField name="font-family" type="string" required>
      Body font family, typically `var(--font-body)`
    </ResponseField>

    <ResponseField name="line-height" type="string" required>
      Line height for body text

      **Example**: `"1.6"`
    </ResponseField>
  </ResponseField>

  <ResponseField name="code, pre" type="object" required>
    Styles for code elements

    <ResponseField name="font-family" type="string" required>
      Monospace font family, typically `var(--font-mono)`
    </ResponseField>
  </ResponseField>
</ResponseField>

### Metadata

<ResponseField name="meta" type="object">
  Additional metadata for preview and categorization

  <ResponseField name="preview" type="string">
    Sample text for font preview

    **Default**: `"The quick brown fox jumps over the lazy dog"`
  </ResponseField>

  <ResponseField name="mood" type="string[]">
    Array of mood descriptors

    **Examples**: `["modern", "minimal"]`, `["raw", "brutalist"]`
  </ResponseField>

  <ResponseField name="useCase" type="string[]">
    Suggested use cases for the pairing

    **Examples**: `["SaaS", "developer tools"]`, `["portfolio", "art"]`
  </ResponseField>
</ResponseField>

## 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<string, string>;
  };
  css: Record<string, Record<string, string>>;
}

export async function loadPairing(
  name: string,
  overrides?: Record<string, string>
): Promise<PairingConfig> {
  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

<CardGroup cols={2}>
  <Card title="Font Schema" icon="font" href="/api/font-schema">
    Schema for individual font configurations
  </Card>

  <Card title="API Endpoints" icon="code" href="/api/endpoints">
    Complete endpoint reference with examples
  </Card>
</CardGroup>
