---
name: "typography_basics"
description: "Sets up working typography for a page, slide, or doc: pick body and display typefaces, pair them, build a type scale, and set line-height, letter-spacing, and paragraph spacing for screen readability. Triggers on: 'help me pick fonts', 'choose a font pairing', 'set up typography', 'fix my text spacing', 'design a type scale', 'make this readable', 'which fonts go together'."
metadata: { "includeInPrompt": true }
---

# Typography Basics

## Purpose

This skill gives a model a practical way to choose typefaces and set spacing so text reads well on screens. It covers picking body vs display fonts, pairing two typefaces, building a modular type scale, and the three spacing levers (line-height, letter-spacing, paragraph spacing). It does not cover print typography, logo design, variable-font axis tuning, or font licensing details beyond a note in the rules.

## Workflow

1. **Decide the job each font has to do.** Body text (paragraphs, captions, lists) needs legibility at small sizes: open apertures, generous x-height, regular or medium weights. Display text (headlines, hero lines, pull quotes) can trade some legibility for character. Never let one font do both jobs unless the typeface is explicitly designed for it (a text and display cut, like many superfamily fonts).

2. **Pick the body font first.** It carries 80% of the words, so it sets the tone. Shortlist 1-2 candidates from free, widely available sources: system stacks (system-ui, Georgia, Menlo) or Google Fonts staples (Inter, Source Serif 4, Roboto, Libre Franklin). Judge by reading a full paragraph at 16px, not by looking at the alphabet. If it reads easily for 300 words, it works.

3. **Pair a display font by contrast, not similarity.** A pairing works when the two faces differ in at least one clear axis (serif vs sans, geometric vs humanist, light vs heavy) while sharing one quiet trait (similar x-height, or similar stroke endings). Check: set a headline and a paragraph side by side. If the headline looks like it belongs to a different document, you overdid the contrast. If you cannot tell which is the headline, you underdid it. One serif plus one sans is the most forgiving combo; avoid pairing two serifs or two sans faces unless you know why.

4. **Cap the family count.** Two families covers nearly everything. Three is the absolute ceiling, and the third must earn its place (usually a mono for code/data, e.g. IBM Plex Mono, ui-monospace). Weight changes (regular to bold) are not new families.

5. **Build a type scale with one ratio.** Pick a base body size (16px for web is a solid default; 18px if the audience skews older or the layout is airy) and multiply up by a fixed ratio: 1.25 for quiet, readable layouts; 1.333 for a more editorial feel; 1.5 or 1.618 for big expressive hero layouts. Round to whole pixels. Do not hand-pick six unrelated sizes; the ratio is what makes it feel intentional. Run the helper script below to generate the scale and a ready-to-paste CSS block.

6. **Set line-height by size and line length.** Body text: 1.5 to 1.7 (use 1.6 as the default unless you have a reason not to). Headlines: 1.1 to 1.3, tighter as they get bigger. Keep body measure between 45 and 75 characters per line; past 75, either narrow the column or bump line-height slightly. Captions and labels can go to 1.4 with a smaller size.

7. **Use letter-spacing sparingly.** Default is 0 for body and headlines. Add slight positive tracking (0.05em to 0.1em) only for ALL-CAPS labels and eyebrows, and tighten slightly (-0.01em to -0.02em) only for very large display sizes where the default spacing looks gappy. Negative tracking on body text hurts readability; leave it alone.

8. **Space paragraphs by meaning.** Paragraph spacing should be smaller than the space between sections and bigger than line-height. A working default: paragraph gap = 1em, section gap = 2.5 to 3em. Indent the first line OR add space between paragraphs, never both. For screens, space-between is the easier read; indents belong to print.

9. **Check the result in context.** Read a real chunk of the actual content at the actual sizes, on a real screen, at arm's length. Squint test: the page should show a clear hierarchy of dark blocks (headlines), gray blocks (body), and light labels before you can read a word. If everything looks the same weight, your scale is too compressed.

### Helper: generate a type scale

Save this as `type_scale.py` and run it with `python3 type_scale.py` (no dependencies). It prints a scale and a CSS block you can paste into a stylesheet.

```python
#!/usr/bin/env python3
"""Generate a modular type scale and CSS custom properties."""

BASE = 16.0      # body size in px
RATIO = 1.25     # 1.25 quiet, 1.333 editorial, 1.5 expressive
STEPS_UP = 5     # headline steps above base
STEPS_DOWN = 2   # small/caption steps below base

def main():
    sizes = {}
    sizes["base"] = BASE
    for i in range(1, STEPS_UP + 1):
        sizes[f"h{STEPS_UP - i + 1}"] = round(BASE * (RATIO ** i))
    for i in range(1, STEPS_DOWN + 1):
        sizes[f"small-{i}"] = round(BASE / (RATIO ** i))
    print("Scale (px):")
    for name in sorted(sizes, key=lambda n: sizes[n], reverse=True):
        print(f"  {name:8s} {sizes[name]}")
    print("\nCSS:")
    print(":root {")
    for name in sorted(sizes, key=lambda n: sizes[n], reverse=True):
        css_name = name.replace("_", "-")
        print(f"  --text-{css_name}: {sizes[name]}px;")
    print("}")

if __name__ == "__main__":
    main()
```

## Output Contract

When this skill runs, deliver:

- **Font choices:** body family, display family, and optional mono, each with a one-line reason (job it does, why this one).
- **Type scale:** the ratio used plus the concrete sizes (from the helper script or equivalent).
- **Spacing spec:** body line-height, headline line-height range, measure target (chars/line), letter-spacing rules, paragraph and section gaps.
- **Pairing check note:** one sentence on how the two faces contrast and what they share, so the choice is reviewable.

## Operating Rules

1. Defaults first, exceptions named: 16px body, 1.6 line-height, 45-75 char measure, two families, space-between paragraphs. State which default you changed and why.
2. Free and system fonts only in recommendations. Do not pitch paid fonts or foundries; if the user already owns one, work with it.
3. No snob rules. If you say avoid something (a font, a pairing), name the specific situation where it fails, not a blanket ban.
4. Test with real words, real sizes, on screen. Alphabet specimens and 48px previews lie about body text.
5. Hierarchy is doing its job when a skimmed page communicates structure. If the user can only see structure by reading, the type failed, no matter how nice the fonts are.
