返回 AiToEarn
typeset.md
1 Typography carries most of the information on the page. Replace generic defaults (Inter, Roboto, system fallback at flat scale) with type that reflects the brand and scales with intentional contrast.
2
3 ---
4
5 ## Register
6
7 Brand: run the font selection procedure in [brand.md](brand.md). Fluid `clamp()` scale, ≥1.25 ratio between steps.
8
9 Product: system fonts and familiar sans stacks are legitimate here. One well-tuned family typically carries the whole UI. Fixed `rem` scale, 1.125–1.2 ratio between more closely-spaced steps.
10
11 ---
12
13 ## Assess Current Typography
14
15 Analyze what's weak or generic about the current type:
16
17 1. **Font choices**:
18 - Are we using invisible defaults? (Inter, Roboto, Arial, Open Sans, system defaults)
19 - Does the font match the brand personality? (A playful brand shouldn't use a corporate typeface)
20 - Are there too many font families? (More than 2-3 is almost always a mess)
21
22 2. **Hierarchy**:
23 - Can you tell headings from body from captions at a glance?
24 - Are font sizes too close together? (14px, 15px, 16px = muddy hierarchy)
25 - Are weight contrasts strong enough? (Medium vs Regular is barely visible)
26
27 3. **Sizing & scale**:
28 - Is there a consistent type scale, or are sizes arbitrary?
29 - Does body text meet minimum readability? (16px+)
30 - Is the sizing strategy appropriate for the context? (Fixed `rem` scales for app UIs; fluid `clamp()` for marketing/content page headings)
31
32 4. **Readability**:
33 - Are line lengths comfortable? (45-75 characters ideal)
34 - Is line-height appropriate for the font and context?
35 - Is there enough contrast between text and background?
36
37 5. **Consistency**:
38 - Are the same elements styled the same way throughout?
39 - Are font weights used consistently? (Not bold in one section, semibold in another for the same role)
40 - Is letter-spacing intentional or default everywhere?
41
42 **CRITICAL**: The goal isn't to make text "fancier." It's to make it clearer, more readable, and more intentional. Good typography is invisible; bad typography is distracting.
43
44 ## Plan Typography Improvements
45
46 Consult the [Reference Material](#reference-material) section below for detailed guidance on scales, pairing, and loading strategies.
47
48 Create a systematic plan:
49
50 - **Font selection**: Do fonts need replacing? What fits the brand/context?
51 - **Type scale**: Establish a modular scale (e.g., 1.25 ratio) with clear hierarchy
52 - **Weight strategy**: Which weights serve which roles? (Regular for body, Semibold for labels, Bold for headings, or whatever fits)
53 - **Spacing**: Line-heights, letter-spacing, and margins between typographic elements
54
55 ## Improve Typography Systematically
56
57 ### Font Selection
58
59 If fonts need replacing:
60 - Choose fonts that reflect the brand personality
61 - Pair with genuine contrast (serif + sans, geometric + humanist), or use a single family in multiple weights
62 - Ensure web font loading doesn't cause layout shift (`font-display: swap`, metric-matched fallbacks)
63
64 ### Establish Hierarchy
65
66 Build a clear type scale:
67 - **5 sizes cover most needs**: caption, secondary, body, subheading, heading
68 - **Use a consistent ratio** between levels (1.25, 1.333, or 1.5)
69 - **Combine dimensions**: Size + weight + color + space for strong hierarchy. Don't rely on size alone
70 - **App UIs**: Use a fixed `rem`-based type scale, optionally adjusted at 1-2 breakpoints. Fluid sizing undermines the spatial predictability that dense, container-based layouts need
71 - **Marketing / content pages**: Use fluid sizing via `clamp(min, preferred, max)` for headings and display text. Keep body text fixed
72
73 ### Fix Readability
74
75 - Set `max-width` on text containers using `ch` units (`max-width: 65ch`)
76 - Adjust line-height per context: tighter for headings (1.1-1.2), looser for body (1.5-1.7)
77 - Increase line-height slightly for light-on-dark text
78 - Ensure body text is at least 16px / 1rem
79
80 ### Refine Details
81
82 - Use `tabular-nums` for data tables and numbers that should align
83 - Apply proper `letter-spacing`: slightly open for small caps and uppercase, default or tight for large display text
84 - Use semantic token names (`--text-body`, `--text-heading`), not value names (`--font-16`)
85 - Set `font-kerning: normal` and consider OpenType features where appropriate
86
87 ### Weight Consistency
88
89 - Define clear roles for each weight and stick to them
90 - Don't use more than 3-4 weights (Regular, Medium, Semibold, Bold is plenty)
91 - Load only the weights you actually use (each weight adds to page load)
92
93 **NEVER**:
94 - Use more than 2-3 font families
95 - Pick sizes arbitrarily; commit to a scale
96 - Set body text below 16px
97 - Use decorative/display fonts for body text
98 - Disable browser zoom (`user-scalable=no`)
99 - Use `px` for font sizes; use `rem` to respect user settings
100 - Default to Inter/Roboto/Open Sans when personality matters
101 - Pair fonts that are similar but not identical (two geometric sans-serifs)
102
103 ## Verify Typography Improvements
104
105 - **Hierarchy**: Can you identify heading vs body vs caption instantly?
106 - **Readability**: Is body text comfortable to read in long passages?
107 - **Consistency**: Are same-role elements styled identically throughout?
108 - **Personality**: Does the typography reflect the brand?
109 - **Performance**: Are web fonts loading efficiently without layout shift?
110 - **Accessibility**: Does text meet WCAG contrast ratios? Is it zoomable to 200%?
111
112 When the type carries the hierarchy on its own, hand off to `$impeccable polish` for the final pass.
113
114 ## Live-mode signature params
115
116 Each variant MUST declare a `scale` param controlling the hierarchy ratio. Express all font sizes in the variant's scoped CSS through `calc(var(--p-scale, 1) * <base>)` or, better, scale the type ramp via `clamp(min, calc(var(--p-scale, 1) * Npx), max)`. Users slide from subdued to commanding.
117
118 ```json
119 {"id":"scale","kind":"range","min":0.85,"max":1.3,"step":0.05,"default":1,"label":"Scale"}
120 ```
121
122 Where the variant riffs on a specific pairing, expose the pairing choice as a `steps` param (e.g. "serif display + sans body" vs. "mono display + sans body" vs. "all-sans"). Each branch routes through `:scope[data-p-pairing="X"]` selectors in scoped CSS.
123
124 See `reference/live.md` for the full params contract.
125
126 ---
127
128 ## Reference Material
129
130 The sections below were previously `typography.md` and live inline now so the typeset flow has its deep typography reference in one place. `bolder.md` also references this section.
131
132 ### Typography
133
134 #### Classic Typography Principles
135
136 ##### Vertical Rhythm
137
138 Your line-height should be the base unit for ALL vertical spacing. If body text has `line-height: 1.5` on `16px` type (= 24px), spacing values should be multiples of 24px. This creates subconscious harmony; text and space share a mathematical foundation.
139
140 ##### Modular Scale & Hierarchy
141
142 The common mistake: too many font sizes that are too close together (14px, 15px, 16px, 18px...). This creates muddy hierarchy.
143
144 **Use fewer sizes with more contrast.** A 5-size system covers most needs:
145
146 | Role | Typical Ratio | Use Case |
147 |------|---------------|----------|
148 | xs | 0.75rem | Captions, legal |
149 | sm | 0.875rem | Secondary UI, metadata |
150 | base | 1rem | Body text |
151 | lg | 1.25-1.5rem | Subheadings, lead text |
152 | xl+ | 2-4rem | Headlines, hero text |
153
154 Popular ratios: 1.25 (major third), 1.333 (perfect fourth), 1.5 (perfect fifth). Pick one and commit.
155
156 ##### Readability & Measure
157
158 Use `ch` units for character-based measure (`max-width: 65ch`). Line-height scales inversely with line length: narrow columns need tighter leading, wide columns need more.
159
160 **Non-obvious**: Light text on dark backgrounds needs compensation on three axes, not just one. Bump line-height by 0.05–0.1, add a touch of letter-spacing (0.01–0.02em), and optionally step the body weight up one notch (regular → medium). The perceived weight drops across all three; fix all three.
161
162 **Paragraph rhythm**: Pick either space between paragraphs OR first-line indentation. Never both. Digital usually wants space; editorial/long-form can justify indent-only.
163
164 #### Font Selection & Pairing
165
166 The tactical selection procedure and the reflex-reject list live in [reference/brand.md](brand.md) under **Font selection procedure** and **Reflex-reject list** (loaded for brand-register tasks). The rest of this section covers the adjacent knowledge: anti-reflex corrections, system font use, and pairing rules.
167
168 ##### Anti-reflexes worth defending against
169
170 - A technical/utilitarian brief does NOT need a serif "for warmth." Most tech tools should look like tech tools.
171 - An editorial/premium brief does NOT need the same expressive serif everyone is using right now. Premium can be Swiss-modern, can be neo-grotesque, can be a literal monospace, can be a quiet humanist sans.
172 - A children's product does NOT need a rounded display font. Kids' books use real type.
173 - A "modern" brief does NOT need a geometric sans. The most modern thing you can do is not use the font everyone else is using.
174
175 **System fonts are underrated**: `-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui` looks native, loads instantly, and is highly readable. Consider this for apps where performance > personality.
176
177 ##### Pairing Principles
178
179 **The non-obvious truth**: You often don't need a second font. One well-chosen font family in multiple weights creates cleaner hierarchy than two competing typefaces. Only add a second font when you need genuine contrast (e.g., display headlines + body serif).
180
181 When pairing, contrast on multiple axes:
182 - Serif + Sans (structure contrast)
183 - Geometric + Humanist (personality contrast)
184 - Condensed display + Wide body (proportion contrast)
185
186 ##### Web Font Loading
187
188 The layout shift problem: fonts load late, text reflows, and users see content jump. Here's the fix:
189
190 ```css
191 /* 1. Use font-display: swap for visibility */
192 @font-face {
193 font-family: 'CustomFont';
194 src: url('font.woff2') format('woff2');
195 font-display: swap;
196 }
197
198 /* 2. Match fallback metrics to minimize shift */
199 @font-face {
200 font-family: 'CustomFont-Fallback';
201 src: local('Arial');
202 size-adjust: 105%; /* Scale to match x-height */
203 ascent-override: 90%; /* Match ascender height */
204 descent-override: 20%; /* Match descender depth */
205 line-gap-override: 10%; /* Match line spacing */
206 }
207
208 body {
209 font-family: 'CustomFont', 'CustomFont-Fallback', sans-serif;
210 }
211 ```
212
213 Tools like [Fontaine](https://github.com/unjs/fontaine) calculate these overrides automatically.
214
215 **`swap` vs `optional`**: `swap` shows fallback text immediately and FOUT-swaps when the web font arrives. `optional` uses the fallback if the web font misses a small load budget (~100ms) and avoids the shift entirely. Pick `optional` when zero layout shift matters more than seeing the branded font on slow networks.
216
217 **Preload the critical weight only**: typically the regular-weight body font used above the fold. Preloading every weight costs more bandwidth than it saves.
218
219 **Variable fonts for 3+ weights or styles**: a single variable font file is usually smaller than three static weight files, gives fractional weight control, and pairs well with `font-optical-sizing: auto`. For 1–2 weights, static is fine.
220
221 #### Modern Web Typography
222
223 ##### Fluid Type
224
225 Fluid typography via `clamp(min, preferred, max)` scales text smoothly with the viewport. The middle value (e.g., `5vw + 1rem`) controls scaling rate (higher vw = faster scaling). Add a rem offset so it doesn't collapse to 0 on small screens.
226
227 **Use fluid type for**: Headings and display text on marketing/content pages where text dominates the layout and needs to breathe across viewport sizes.
228
229 **Use fixed `rem` scales for**: App UIs, dashboards, and data-dense interfaces. No major app design system (Material, Polaris, Primer, Carbon) uses fluid type in product UI; fixed scales with optional breakpoint adjustments give the spatial predictability that container-based layouts need. Body text should also be fixed even on marketing pages, since the size difference across viewports is too small to warrant it.
230
231 **Bound your clamp()**: keep `max-size ≤ ~2.5 × min-size`. Wider ratios break the browser's zoom and reflow behaviour and make large viewports feel like the page is shouting.
232
233 **Scale container width and font-size together** so effective character measure stays in the 45–75ch band at every viewport. A heading that widens faster than its container drifts out of the comfortable measure at the top end.
234
235 ##### OpenType Features
236
237 Most developers don't know these exist. Use them for polish:
238
239 ```css
240 /* Proper fractions */
241 .recipe-amount { font-variant-numeric: diagonal-fractions; }
242
243 /* Small caps for abbreviations */
244 abbr { font-variant-caps: all-small-caps; }
245
246 /* Disable ligatures in code */
247 code { font-variant-ligatures: none; }
248
249 /* Enable kerning (usually on by default, but be explicit) */
250 body { font-kerning: normal; }
251 ```
252
253 Check what features your font supports at [Wakamai Fondue](https://wakamaifondue.com/).
254
255 ##### Rendering polish
256
257 ```css
258 /* Variable fonts: pick the right optical-size master automatically */
259 body { font-optical-sizing: auto; }
260 ```
261
262 **ALL-CAPS tracking**: capitals sit too close at default spacing. Add 5–12% letter-spacing (`letter-spacing: 0.05em` to `0.12em`) to short all-caps labels, eyebrows, and small headings. Real small caps (via `font-variant-caps`) need the same treatment, slightly gentler.
263
264 #### Typography System Architecture
265
266 Name tokens semantically (`--text-body`, `--text-heading`), not by value (`--font-size-16`). Include font stacks, size scale, weights, line-heights, and letter-spacing in your token system.
267
268 #### Accessibility Considerations
269
270 Beyond contrast ratios (which are well-documented), consider:
271
272 - **Never disable zoom**: `user-scalable=no` breaks accessibility. If your layout breaks at 200% zoom, fix the layout.
273 - **Use rem/em for font sizes**: This respects user browser settings. Never `px` for body text.
274 - **Minimum 16px body text**: Smaller than this strains eyes and fails WCAG on mobile.
275 - **Adequate touch targets**: Text links need padding or line-height that creates 44px+ tap targets.
276
277 ---
278
279 **Avoid**: More than 2-3 font families per project. Skipping fallback font definitions. Ignoring font loading performance (FOUT/FOIT). Using decorative fonts for body text.
280
280 lines MARKDOWN