/ templates / typography-system.css
typography-system.css
  1  /* ============================================
  2     TYPOGRAPHY DESIGN SYSTEM
  3  
  4     Theory: Modular scale (Major Third 1.25)
  5     Baseline: 8px grid for vertical rhythm
  6     Body size: 16px (accessibility minimum)
  7     Line length: 45-75 characters optimal
  8  
  9     References:
 10     - Bringhurst's "Elements of Typographic Style"
 11     - Material Design Typography
 12     - Apple Human Interface Guidelines
 13     ============================================ */
 14  
 15  :root {
 16    /* ===== Type Scale (Major Third 1.25) ===== */
 17    --text-xs: 10px;      /* Level -2: Micro text, legal */
 18    --text-sm: 13px;      /* Level -1: Small, captions */
 19    --text-base: 16px;    /* Level  0: Body text */
 20    --text-lg: 20px;      /* Level  1: Large body, intro */
 21    --text-xl: 25px;      /* Level  2: H3, card titles */
 22    --text-2xl: 31px;     /* Level  3: H2, section headers */
 23    --text-3xl: 39px;     /* Level  4: H1, page titles */
 24    --text-4xl: 49px;     /* Level  5: Display, hero */
 25    --text-5xl: 61px;     /* Level  6: Large display */
 26    --text-6xl: 76px;     /* Level  7: Massive hero */
 27  
 28    /* ===== Line Heights (matched to use case) ===== */
 29    --lh-none: 1.0;       /* Single line, logos */
 30    --lh-tight: 1.25;     /* Display, hero (48px+) */
 31    --lh-snug: 1.375;     /* Headings (24-48px) */
 32    --lh-normal: 1.5;     /* Body text (16-20px) */
 33    --lh-relaxed: 1.625;  /* Small text (12-14px) */
 34    --lh-loose: 1.75;     /* Dense content, CJK */
 35  
 36    /* ===== Font Weights (perceptual hierarchy) ===== */
 37    --weight-light: 300;     /* Rarely used, luxury brands */
 38    --weight-normal: 400;    /* Body text */
 39    --weight-medium: 500;    /* Subtle emphasis, UI */
 40    --weight-semibold: 600;  /* Strong emphasis, subheadings */
 41    --weight-bold: 700;      /* Headings, CTAs */
 42    --weight-black: 900;     /* Rarely used, extreme emphasis */
 43  
 44    /* ===== Letter Spacing (tracking) ===== */
 45    --tracking-tighter: -0.05em;  /* Display text (48px+) */
 46    --tracking-tight: -0.025em;   /* Headings (24-48px) */
 47    --tracking-normal: 0;         /* Body text */
 48    --tracking-wide: 0.025em;     /* Small text, all-caps */
 49    --tracking-wider: 0.05em;     /* Tiny text, labels */
 50  
 51    /* ===== Spacing Scale (8px baseline grid) ===== */
 52    --space-0: 0;
 53    --space-1: 4px;       /* 0.5 × 8 */
 54    --space-2: 8px;       /* 1 × 8 */
 55    --space-3: 12px;      /* 1.5 × 8 */
 56    --space-4: 16px;      /* 2 × 8 */
 57    --space-5: 20px;      /* 2.5 × 8 */
 58    --space-6: 24px;      /* 3 × 8 */
 59    --space-8: 32px;      /* 4 × 8 */
 60    --space-10: 40px;     /* 5 × 8 */
 61    --space-12: 48px;     /* 6 × 8 */
 62    --space-16: 64px;     /* 8 × 8 */
 63    --space-20: 80px;     /* 10 × 8 */
 64    --space-24: 96px;     /* 12 × 8 */
 65    --space-32: 128px;    /* 16 × 8 */
 66  
 67    /* ===== Semantic Spacing ===== */
 68    --space-heading-to-body: var(--space-3);    /* 12px */
 69    --space-paragraph: var(--space-4);          /* 16px */
 70    --space-paragraph-loose: var(--space-6);    /* 24px */
 71    --space-section-sm: var(--space-12);        /* 48px */
 72    --space-section-md: var(--space-16);        /* 64px */
 73    --space-section-lg: var(--space-24);        /* 96px */
 74  
 75    /* ===== Image Spacing ===== */
 76    --space-image-top: var(--space-8);          /* 32px - after text */
 77    --space-image-bottom: var(--space-4);       /* 16px - before caption */
 78    --space-caption-bottom: var(--space-12);    /* 48px - after caption */
 79  
 80    /* ===== Container Padding ===== */
 81    --padding-card: var(--space-8);             /* 32px */
 82    --padding-section-v: var(--space-16);       /* 64px vertical */
 83    --padding-section-h: var(--space-6);        /* 24px horizontal */
 84    --padding-button-v: var(--space-3);         /* 12px vertical */
 85    --padding-button-h: var(--space-6);         /* 24px horizontal */
 86  }
 87  
 88  /* ============================================
 89     BASE TYPOGRAPHY
 90     ============================================ */
 91  
 92  body {
 93    font-size: var(--text-base);
 94    line-height: var(--lh-normal);
 95    font-weight: var(--weight-normal);
 96    letter-spacing: var(--tracking-normal);
 97  
 98    /* Optical improvements */
 99    font-kerning: normal;
100    text-rendering: optimizeLegibility;
101    -webkit-font-smoothing: antialiased;
102    -moz-osx-font-smoothing: grayscale;
103  }
104  
105  /* ============================================
106     HEADINGS
107     ============================================ */
108  
109  h1 {
110    font-size: var(--text-3xl);
111    line-height: var(--lh-tight);
112    font-weight: var(--weight-bold);
113    letter-spacing: var(--tracking-tight);
114    margin-bottom: var(--space-heading-to-body);
115    text-wrap: balance;
116  }
117  
118  h2 {
119    font-size: var(--text-2xl);
120    line-height: var(--lh-snug);
121    font-weight: var(--weight-bold);
122    letter-spacing: var(--tracking-tight);
123    margin-top: var(--space-section-md);
124    margin-bottom: var(--space-heading-to-body);
125    text-wrap: balance;
126  }
127  
128  h3 {
129    font-size: var(--text-xl);
130    line-height: var(--lh-snug);
131    font-weight: var(--weight-semibold);
132    margin-top: var(--space-section-sm);
133    margin-bottom: var(--space-heading-to-body);
134    text-wrap: balance;
135  }
136  
137  h4 {
138    font-size: var(--text-lg);
139    line-height: var(--lh-snug);
140    font-weight: var(--weight-semibold);
141    margin-top: var(--space-8);
142    margin-bottom: var(--space-3);
143  }
144  
145  /* ============================================
146     BODY TEXT
147     ============================================ */
148  
149  p {
150    max-width: 65ch; /* Optimal line length */
151    margin-bottom: var(--space-paragraph);
152  
153    /* Advanced features */
154    orphans: 2;
155    widows: 2;
156    text-wrap: pretty;
157  }
158  
159  /* Intro paragraph */
160  .lead {
161    font-size: var(--text-lg);
162    line-height: var(--lh-normal);
163    margin-bottom: var(--space-paragraph-loose);
164  }
165  
166  /* Small text */
167  small, .text-small {
168    font-size: var(--text-sm);
169    line-height: var(--lh-relaxed);
170  }
171  
172  /* ============================================
173     LISTS
174     ============================================ */
175  
176  ul, ol {
177    margin-bottom: var(--space-paragraph);
178    padding-left: var(--space-6);
179  }
180  
181  li {
182    margin-bottom: var(--space-2);
183  }
184  
185  li:last-child {
186    margin-bottom: 0;
187  }
188  
189  /* ============================================
190     IMAGES & FIGURES
191     ============================================ */
192  
193  img {
194    max-width: 100%;
195    height: auto;
196    display: block;
197  }
198  
199  figure {
200    margin: var(--space-image-top) 0 var(--space-caption-bottom);
201  }
202  
203  figure img {
204    margin-bottom: var(--space-image-bottom);
205  }
206  
207  figcaption {
208    font-size: var(--text-sm);
209    line-height: var(--lh-relaxed);
210    color: #666;
211    text-align: center;
212  }
213  
214  /* ============================================
215     LINKS
216     ============================================ */
217  
218  a {
219    color: inherit;
220    text-decoration: underline;
221    text-decoration-thickness: 1px;
222    text-underline-offset: 2px;
223    transition: color 0.2s ease;
224  }
225  
226  a:hover {
227    text-decoration-thickness: 2px;
228  }
229  
230  /* ============================================
231     EMPHASIS
232     ============================================ */
233  
234  strong, b {
235    font-weight: var(--weight-semibold);
236  }
237  
238  em, i {
239    font-style: italic;
240  }
241  
242  /* ============================================
243     CODE
244     ============================================ */
245  
246  code {
247    font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
248    font-size: 0.9em;
249    padding: 2px 6px;
250    background: rgba(0, 0, 0, 0.05);
251    border-radius: 3px;
252  }
253  
254  pre {
255    font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
256    font-size: var(--text-sm);
257    line-height: var(--lh-relaxed);
258    padding: var(--space-4);
259    background: rgba(0, 0, 0, 0.05);
260    border-radius: 6px;
261    overflow-x: auto;
262    margin-bottom: var(--space-paragraph);
263  }
264  
265  pre code {
266    padding: 0;
267    background: none;
268  }
269  
270  /* ============================================
271     UTILITY CLASSES
272     ============================================ */
273  
274  /* Display text */
275  .text-display {
276    font-size: var(--text-4xl);
277    line-height: var(--lh-tight);
278    font-weight: var(--weight-bold);
279    letter-spacing: var(--tracking-tighter);
280  }
281  
282  .text-display-lg {
283    font-size: var(--text-5xl);
284    line-height: var(--lh-tight);
285    font-weight: var(--weight-bold);
286    letter-spacing: var(--tracking-tighter);
287  }
288  
289  .text-display-xl {
290    font-size: var(--text-6xl);
291    line-height: var(--lh-tight);
292    font-weight: var(--weight-bold);
293    letter-spacing: var(--tracking-tighter);
294  }
295  
296  /* Text wrapping */
297  .text-balance {
298    text-wrap: balance;
299  }
300  
301  .text-pretty {
302    text-wrap: pretty;
303  }
304  
305  .text-nowrap {
306    white-space: nowrap;
307  }
308  
309  /* Text alignment */
310  .text-left { text-align: left; }
311  .text-center { text-align: center; }
312  .text-right { text-align: right; }
313  
314  /* Font weights */
315  .font-normal { font-weight: var(--weight-normal); }
316  .font-medium { font-weight: var(--weight-medium); }
317  .font-semibold { font-weight: var(--weight-semibold); }
318  .font-bold { font-weight: var(--weight-bold); }
319  
320  /* ============================================
321     RESPONSIVE TYPOGRAPHY
322     ============================================ */
323  
324  /* Mobile adjustments */
325  @media (max-width: 640px) {
326    :root {
327      --text-3xl: 32px;  /* H1 smaller on mobile */
328      --text-2xl: 26px;  /* H2 smaller on mobile */
329      --text-xl: 22px;   /* H3 smaller on mobile */
330    }
331  
332    p {
333      max-width: 100%; /* Full width on mobile */
334    }
335  }
336  
337  /* Tablet adjustments */
338  @media (min-width: 641px) and (max-width: 1024px) {
339    :root {
340      --text-3xl: 36px;
341      --text-2xl: 28px;
342    }
343  }
344  
345  /* ============================================
346     DEBUG GRID (Development only)
347     Remove before production
348     ============================================ */
349  
350  body.debug-grid {
351    background-image:
352      repeating-linear-gradient(
353        to bottom,
354        transparent 0,
355        transparent 7px,
356        rgba(255, 0, 0, 0.1) 7px,
357        rgba(255, 0, 0, 0.1) 8px
358      );
359  }
360  
361  /* Usage: Add class="debug-grid" to body to verify 8px rhythm */