Skip to main content
Conty’s typography system provides a carefully crafted type scale with accessible font sizes and a modern font stack.

Font Family

Conty uses a system font stack with Inter as the primary typeface:
fontFamily.sans
string
default:"Inter, system-ui, sans-serif"
Primary sans-serif font stack
semanticTokens.typography.fontFamily.sans
// "Inter, system-ui, sans-serif"
Fallback chain:
  1. Inter - Modern, highly legible typeface optimized for UI
  2. system-ui - Native system font (San Francisco on macOS/iOS, Segoe UI on Windows)
  3. sans-serif - Generic sans-serif fallback

Why Inter?

Inter was chosen for several key advantages:
  • Optimized for screens - Designed specifically for digital interfaces
  • Excellent legibility - Clear at small sizes with distinct letterforms
  • Wide language support - Comprehensive Unicode coverage
  • Variable font support - Smooth weight and optical size adjustments
  • Open source - Free to use in any project

Font Loading

Conty recommends loading Inter via Google Fonts or self-hosting:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">

Text Size Scale

Conty provides a three-step type scale optimized for UI components:
text.sm
string
default:"0.875rem"
Small text size (14px at default font size)
semanticTokens.typography.text.sm // "0.875rem"
Use cases:
  • Captions and helper text
  • Secondary labels
  • Meta information (timestamps, counts)
  • Dense data tables
Line height recommendation: 1.25 (1.09375rem)
text.base
string
default:"1rem"
Base text size (16px at default font size)
semanticTokens.typography.text.base // "1rem"
Use cases:
  • Body text
  • Form inputs
  • Button labels
  • Default UI text
Line height recommendation: 1.5 (1.5rem)Note: This is the recommended minimum size for body text to ensure readability and accessibility.
text.lg
string
default:"1.125rem"
Large text size (18px at default font size)
semanticTokens.typography.text.lg // "1.125rem"
Use cases:
  • Subheadings
  • Emphasized text
  • Lead paragraphs
  • Card titles
Line height recommendation: 1.5 (1.6875rem)

Visual Type Scale

text.sm    14px  The quick brown fox jumps
text.base  16px  The quick brown fox jumps
text.lg    18px  The quick brown fox jumps

Usage Examples

import { semanticTokens } from '@conty/tokens'

function Typography() {
  return (
    <div style={{ fontFamily: semanticTokens.typography.fontFamily.sans }}>
      <h2 style={{ fontSize: semanticTokens.typography.text.lg }}>
        Card Title
      </h2>
      <p style={{ fontSize: semanticTokens.typography.text.base }}>
        This is the main body text.
      </p>
      <span style={{ fontSize: semanticTokens.typography.text.sm }}>
        Posted 2 hours ago
      </span>
    </div>
  )
}

Real-World Examples

Here’s how typography tokens are used in actual Conty components:
// From packages/ui/src/components/card.tsx
function CardTitle({ className, ...props }) {
  return (
    <div
      className="leading-none font-semibold"  // Uses inherited text size
      {...props}
    />
  )
}

function CardDescription({ className, ...props }) {
  return (
    <div
      className="text-muted-foreground text-sm"  // text-sm = 0.875rem
      {...props}
    />
  )
}

Legacy Typography Aliases

For backward compatibility, Conty provides flat aliases:
// From packages/tokens/src/index.ts
export const typography = {
  fontFamily: semanticTokens.typography.fontFamily.sans,
  textSm: semanticTokens.typography.text.sm,      // "0.875rem"
  textBase: semanticTokens.typography.text.base,  // "1rem"
  textLg: semanticTokens.typography.text.lg       // "1.125rem"
} as const
New projects should use the semantic token paths for better organization and extensibility.

Font Weight Guidelines

While not defined as tokens, Conty follows consistent font weight conventions:
  • 400 (Regular) - Body text, descriptions, paragraphs
  • 500 (Medium) - Button labels, active states, emphasis
  • 600 (Semibold) - Headings, card titles, section headers
  • 700 (Bold) - Major headings, high emphasis (use sparingly)
// Example usage
<h1 style={{ fontWeight: 600 }}>Page Title</h1>
<button style={{ fontWeight: 500 }}>Click Me</button>
<p style={{ fontWeight: 400 }}>Body text content</p>

Line Height Recommendations

Proper line height improves readability:
/* Small text - tighter leading */
.text-sm {
  font-size: 0.875rem;
  line-height: 1.25; /* 1.09375rem / ~17.5px */
}

/* Base and large text - comfortable reading */
.text-base {
  font-size: 1rem;
  line-height: 1.5; /* 1.5rem / 24px */
}

.text-lg {
  font-size: 1.125rem;
  line-height: 1.5; /* 1.6875rem / ~27px */
}

/* Headings - tighter for impact */
h1, h2, h3 {
  line-height: 1.2;
}

Responsive Typography

Typography tokens scale with user font size preferences:
function ResponsiveText() {
  return (
    <div style={{ fontSize: semanticTokens.typography.text.base }}>
      {/* This text automatically scales if user changes browser font size */}
      This respects user preferences
    </div>
  )
}
Always use rem units for font sizes instead of px. This is critical for accessibility and user preferences.

Accessibility Considerations

Never use text smaller than text.sm (0.875rem / 14px) for body content. This ensures readability for users with visual impairments.
// Good - uses text.sm for secondary content
<span style={{ fontSize: semanticTokens.typography.text.sm }}>
  Helper text
</span>

// Avoid - text too small
<span style={{ fontSize: '0.75rem' }}>
  Hard to read
</span>
Pair typography tokens with appropriate color tokens for sufficient contrast:
// Good contrast
<p style={{
  fontSize: semanticTokens.typography.text.base,
  color: semanticTokens.color.text.default  // High contrast
}}>
  Primary content
</p>

// Lower contrast - only for secondary content
<p style={{
  fontSize: semanticTokens.typography.text.sm,
  color: semanticTokens.color.text.muted  // Reduced contrast
}}>
  Secondary information
</p>
Limit line length to 60-80 characters for optimal readability:
.prose {
  max-width: 65ch; /* ~65 characters wide */
  font-size: 1rem;
  line-height: 1.5;
}

Complete Typography Reference

// From packages/tokens/src/index.ts
export const semanticTokens = {
  typography: {
    fontFamily: {
      sans: "Inter, system-ui, sans-serif"
    },
    text: {
      sm: "0.875rem",   // 14px
      base: "1rem",     // 16px
      lg: "1.125rem"    // 18px
    }
  }
} as const

// Legacy aliases
export const typography = {
  fontFamily: semanticTokens.typography.fontFamily.sans,
  textSm: semanticTokens.typography.text.sm,
  textBase: semanticTokens.typography.text.base,
  textLg: semanticTokens.typography.text.lg
} as const

Best Practices

1

Use the type scale

Stick to the three defined sizes for UI consistency. Don’t create custom font sizes between these steps.
2

Set base size on root

Apply text.base as your default body text size:
body {
  font-family: Inter, system-ui, sans-serif;
  font-size: 1rem;
  line-height: 1.5;
}
3

Pair with semantic colors

Combine typography tokens with color tokens for accessible, themed text:
<p style={{
  fontSize: semanticTokens.typography.text.base,
  color: semanticTokens.color.text.default
}}>
  Accessible text
</p>
4

Consider line height

Adjust line height based on text size and context (1.25 for small, 1.5 for body, 1.2 for headings).

Next Steps

Color Tokens

Learn about text color tokens and contrast ratios

Theming

Implement dark mode and custom typography themes

Build docs developers (and LLMs) love