@andrewxhill/graphics-press-css 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1739 @@
1
+ /**
2
+ * Graphics Press CSS — Tailwind CSS Plugin v4.0.0
3
+ * ─────────────────────────────────────────────────────────────────────────────
4
+ * A Tailwind CSS v3+ plugin that mirrors the Graphics Press CSS library.
5
+ *
6
+ * Usage in tailwind.config.js:
7
+ * const graphicsPress = require('@andrewxhill/graphics-press-css/tailwind');
8
+ * module.exports = { plugins: [graphicsPress] };
9
+ *
10
+ * MIT License. See LICENSE for details.
11
+ * ─────────────────────────────────────────────────────────────────────────────
12
+ */
13
+
14
+ const plugin = require('tailwindcss/plugin');
15
+
16
+ module.exports = plugin(
17
+ function ({ addBase, addComponents, addUtilities, theme }) {
18
+
19
+ /* ═══════════════════════════════════════════════════════════════════════
20
+ BASE — @font-face, CSS reset, custom properties (tokens)
21
+ ═══════════════════════════════════════════════════════════════════════ */
22
+
23
+ addBase({
24
+ /* ── ET Book font-face declarations ─────────────────────────────── */
25
+ '@font-face': [
26
+ {
27
+ fontFamily: '"ET Book"',
28
+ src: 'url("https://edwardtufte.github.io/et-book/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff") format("woff"), url("https://edwardtufte.github.io/et-book/et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf") format("truetype")',
29
+ fontWeight: 'normal',
30
+ fontStyle: 'normal',
31
+ fontDisplay: 'swap',
32
+ },
33
+ {
34
+ fontFamily: '"ET Book"',
35
+ src: 'url("https://edwardtufte.github.io/et-book/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff") format("woff"), url("https://edwardtufte.github.io/et-book/et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf") format("truetype")',
36
+ fontWeight: 'normal',
37
+ fontStyle: 'italic',
38
+ fontDisplay: 'swap',
39
+ },
40
+ {
41
+ fontFamily: '"ET Book"',
42
+ src: 'url("https://edwardtufte.github.io/et-book/et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff") format("woff"), url("https://edwardtufte.github.io/et-book/et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf") format("truetype")',
43
+ fontWeight: 'bold',
44
+ fontStyle: 'normal',
45
+ fontDisplay: 'swap',
46
+ },
47
+ ],
48
+
49
+ /* ── Light-mode tokens (default) ────────────────────────────────── */
50
+ ':root': {
51
+ colorScheme: 'light',
52
+
53
+ /* Layout */
54
+ '--gp-text-width': '640px',
55
+ '--gp-margin-width': '260px',
56
+ '--gp-gutter': '48px',
57
+ '--gp-outer-margin': 'clamp(3rem, 8vw, 6rem)',
58
+ '--gp-page-width': 'calc(var(--gp-text-width) + var(--gp-gutter) + var(--gp-margin-width))',
59
+
60
+ /* Typefaces */
61
+ '--gp-serif': '"ET Book", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif',
62
+ '--gp-sans': '"Gill Sans", "Gill Sans MT", Calibri, Optima, "Trebuchet MS", sans-serif',
63
+ '--gp-mono': '"Lucida Console", "Andale Mono", Monaco, Consolas, monospace',
64
+
65
+ /* Fluid type scale */
66
+ '--gp-font-size': 'clamp(14px, 1vw + 10px, 16px)',
67
+ '--gp-line-height': 'clamp(1.58, 1.5 + 0.4vw, 1.68)',
68
+ '--gp-small': '0.8em',
69
+ '--gp-caption': '0.77em',
70
+ '--gp-micro': '0.69em',
71
+
72
+ /* Spacing */
73
+ '--gp-space-xs': '0.25rem',
74
+ '--gp-space-sm': '0.5rem',
75
+ '--gp-space-md': '1rem',
76
+ '--gp-space-lg': '2rem',
77
+ '--gp-space-xl': '4rem',
78
+
79
+ /* Surface */
80
+ '--gp-paper': 'oklch(99.4% 0.008 98)',
81
+ '--gp-ink': 'oklch(17% 0.004 60)',
82
+ '--gp-margin-ink': 'oklch(43% 0.003 60)',
83
+ '--gp-ghost-ink': 'oklch(69% 0.003 60)',
84
+ '--gp-rule': 'oklch(62% 0.002 60)',
85
+ '--gp-light-rule': 'oklch(84% 0.005 95)',
86
+ '--gp-code-bg': 'oklch(95% 0.006 95)',
87
+
88
+ /* Categorical palette */
89
+ '--gp-red': 'oklch(44% 0.14 27)',
90
+ '--gp-red-light': 'oklch(64% 0.10 27)',
91
+ '--gp-blue': 'oklch(44% 0.09 251)',
92
+ '--gp-blue-light': 'oklch(64% 0.07 251)',
93
+ '--gp-green': 'oklch(50% 0.08 149)',
94
+ '--gp-green-light': 'oklch(67% 0.06 149)',
95
+ '--gp-ochre': 'oklch(49% 0.10 72)',
96
+ '--gp-ochre-light': 'oklch(67% 0.08 72)',
97
+ '--gp-brown': 'oklch(42% 0.09 52)',
98
+ '--gp-gray-data': 'oklch(51% 0.002 60)',
99
+
100
+ /* Sequential ramp */
101
+ '--gp-seq-1': 'oklch(95% 0.04 80)',
102
+ '--gp-seq-2': 'oklch(82% 0.07 76)',
103
+ '--gp-seq-3': 'oklch(68% 0.09 72)',
104
+ '--gp-seq-4': 'oklch(55% 0.10 68)',
105
+ '--gp-seq-5': 'oklch(42% 0.10 65)',
106
+
107
+ /* Diverging ramp */
108
+ '--gp-div-lo-2': 'oklch(44% 0.09 251)',
109
+ '--gp-div-lo-1': 'oklch(64% 0.07 251)',
110
+ '--gp-div-mid': 'oklch(92% 0.004 95)',
111
+ '--gp-div-hi-1': 'oklch(64% 0.10 27)',
112
+ '--gp-div-hi-2': 'oklch(44% 0.14 27)',
113
+
114
+ /* Animation */
115
+ '--gp-ease': 'cubic-bezier(0.4, 0, 0.2, 1)',
116
+ '--gp-ease-out': 'cubic-bezier(0, 0, 0.2, 1)',
117
+
118
+ /* SVG color tokens */
119
+ '--svg-ink': '#111111',
120
+ '--svg-margin': '#555555',
121
+ '--svg-mid': '#777777',
122
+ '--svg-rule-mid': '#999999',
123
+ '--svg-ghost': '#aaaaaa',
124
+ '--svg-rule': '#cccccc',
125
+ '--svg-light-rule': '#d4d4c8',
126
+ '--svg-soft': '#dddddd',
127
+ '--svg-faint': '#eeeeee',
128
+ '--svg-dim': '#888888',
129
+ '--svg-dark-rule': '#333333',
130
+ '--svg-red': '#b5322a',
131
+ '--svg-blue': '#3a5a8c',
132
+ '--svg-green': '#4a7a50',
133
+ '--svg-ochre': '#8b6914',
134
+ '--svg-blue-light': '#90a8c8',
135
+ },
136
+
137
+ /* ── Dark mode via prefers-color-scheme ────────────────────────── */
138
+ '@media (prefers-color-scheme: dark)': {
139
+ ':root:not(.light)': {
140
+ colorScheme: 'dark',
141
+ '--gp-paper': 'oklch(17% 0.008 80)',
142
+ '--gp-ink': 'oklch(90% 0.005 85)',
143
+ '--gp-margin-ink': 'oklch(63% 0.005 85)',
144
+ '--gp-ghost-ink': 'oklch(40% 0.004 85)',
145
+ '--gp-rule': 'oklch(35% 0.003 85)',
146
+ '--gp-light-rule': 'oklch(27% 0.005 85)',
147
+ '--gp-code-bg': 'oklch(22% 0.007 80)',
148
+ '--gp-red': 'oklch(66% 0.13 27)',
149
+ '--gp-red-light': 'oklch(76% 0.09 27)',
150
+ '--gp-blue': 'oklch(66% 0.09 251)',
151
+ '--gp-blue-light': 'oklch(76% 0.06 251)',
152
+ '--gp-green': 'oklch(66% 0.08 149)',
153
+ '--gp-green-light': 'oklch(76% 0.06 149)',
154
+ '--gp-ochre': 'oklch(66% 0.09 72)',
155
+ '--gp-ochre-light': 'oklch(76% 0.07 72)',
156
+ '--gp-gray-data': 'oklch(58% 0.002 60)',
157
+ '--gp-seq-1': 'oklch(35% 0.06 72)',
158
+ '--gp-seq-2': 'oklch(47% 0.08 72)',
159
+ '--gp-seq-3': 'oklch(59% 0.09 72)',
160
+ '--gp-seq-4': 'oklch(71% 0.09 72)',
161
+ '--gp-seq-5': 'oklch(83% 0.07 72)',
162
+ '--gp-div-lo-2': 'oklch(66% 0.09 251)',
163
+ '--gp-div-lo-1': 'oklch(76% 0.06 251)',
164
+ '--gp-div-mid': 'oklch(25% 0.004 85)',
165
+ '--gp-div-hi-1': 'oklch(76% 0.09 27)',
166
+ '--gp-div-hi-2': 'oklch(66% 0.13 27)',
167
+ },
168
+ },
169
+
170
+ /* ── Dark mode via .dark class ──────────────────────────────────── */
171
+ '.dark': {
172
+ colorScheme: 'dark',
173
+ '--gp-paper': 'oklch(17% 0.008 80)',
174
+ '--gp-ink': 'oklch(90% 0.005 85)',
175
+ '--gp-margin-ink': 'oklch(63% 0.005 85)',
176
+ '--gp-ghost-ink': 'oklch(40% 0.004 85)',
177
+ '--gp-rule': 'oklch(35% 0.003 85)',
178
+ '--gp-light-rule': 'oklch(27% 0.005 85)',
179
+ '--gp-code-bg': 'oklch(22% 0.007 80)',
180
+ '--gp-red': 'oklch(66% 0.13 27)',
181
+ '--gp-red-light': 'oklch(76% 0.09 27)',
182
+ '--gp-blue': 'oklch(66% 0.09 251)',
183
+ '--gp-blue-light': 'oklch(76% 0.06 251)',
184
+ '--gp-green': 'oklch(66% 0.08 149)',
185
+ '--gp-green-light': 'oklch(76% 0.06 149)',
186
+ '--gp-ochre': 'oklch(66% 0.09 72)',
187
+ '--gp-ochre-light': 'oklch(76% 0.07 72)',
188
+ '--gp-gray-data': 'oklch(58% 0.002 60)',
189
+ '--gp-seq-1': 'oklch(35% 0.06 72)',
190
+ '--gp-seq-2': 'oklch(47% 0.08 72)',
191
+ '--gp-seq-3': 'oklch(59% 0.09 72)',
192
+ '--gp-seq-4': 'oklch(71% 0.09 72)',
193
+ '--gp-seq-5': 'oklch(83% 0.07 72)',
194
+ '--gp-div-lo-2': 'oklch(66% 0.09 251)',
195
+ '--gp-div-lo-1': 'oklch(76% 0.06 251)',
196
+ '--gp-div-mid': 'oklch(25% 0.004 85)',
197
+ '--gp-div-hi-1': 'oklch(76% 0.09 27)',
198
+ '--gp-div-hi-2': 'oklch(66% 0.13 27)',
199
+
200
+ /* SVG dark overrides */
201
+ '--svg-ink': '#e6e0d8',
202
+ '--svg-margin': '#a09898',
203
+ '--svg-mid': '#8a8480',
204
+ '--svg-rule-mid': '#606060',
205
+ '--svg-ghost': '#505050',
206
+ '--svg-rule': '#404040',
207
+ '--svg-light-rule': '#383430',
208
+ '--svg-soft': '#353030',
209
+ '--svg-faint': '#2e2a26',
210
+ '--svg-dim': '#585450',
211
+ '--svg-dark-rule': '#888480',
212
+ '--svg-red': '#e07070',
213
+ '--svg-blue': '#7090c8',
214
+ '--svg-green': '#70b078',
215
+ '--svg-ochre': '#c8a040',
216
+ '--svg-blue-light': '#7090c8',
217
+ },
218
+
219
+ /* ── CSS Reset ──────────────────────────────────────────────────── */
220
+ '*, *::before, *::after': {
221
+ boxSizing: 'border-box',
222
+ },
223
+ 'html': {
224
+ fontSize: 'var(--gp-font-size)',
225
+ background: 'var(--gp-paper)',
226
+ color: 'var(--gp-ink)',
227
+ transition: 'background-color 0.25s var(--gp-ease), color 0.25s var(--gp-ease)',
228
+ },
229
+
230
+ /* ── Base typography ────────────────────────────────────────────── */
231
+ 'body': {
232
+ fontFamily: 'var(--gp-serif)',
233
+ fontWeight: 'normal',
234
+ lineHeight: 'var(--gp-line-height)',
235
+ background: 'var(--gp-paper)',
236
+ color: 'var(--gp-ink)',
237
+ margin: '0',
238
+ padding: '0',
239
+ counterReset: 'sidenote-counter',
240
+ textAlign: 'left',
241
+ hyphens: 'none',
242
+ '-webkit-hyphens': 'none',
243
+ fontVariantNumeric: 'oldstyle-nums proportional-nums',
244
+ fontOpticalSizing: 'auto',
245
+ minHeight: '100dvh',
246
+ paddingLeft: 'env(safe-area-inset-left)',
247
+ paddingRight: 'env(safe-area-inset-right)',
248
+ },
249
+
250
+ 'h1': {
251
+ fontSize: 'clamp(1.7rem, 3vw + 0.8rem, 2.4rem)',
252
+ fontStyle: 'italic',
253
+ fontWeight: 'normal',
254
+ lineHeight: '1.18',
255
+ fontOpticalSizing: 'auto',
256
+ margin: '0 0 var(--gp-space-sm)',
257
+ maxWidth: 'var(--gp-text-width)',
258
+ },
259
+ 'h2': {
260
+ fontSize: 'clamp(1rem, 0.8vw + 0.75rem, 1.1rem)',
261
+ fontStyle: 'italic',
262
+ fontWeight: 'normal',
263
+ margin: 'var(--gp-space-lg) 0 var(--gp-space-sm)',
264
+ maxWidth: 'var(--gp-text-width)',
265
+ },
266
+ 'h3': {
267
+ fontSize: '1rem',
268
+ fontStyle: 'italic',
269
+ fontWeight: 'normal',
270
+ margin: 'var(--gp-space-md) 0 var(--gp-space-xs)',
271
+ maxWidth: 'var(--gp-text-width)',
272
+ },
273
+ 'h4, h5, h6': {
274
+ fontSize: '0.94rem',
275
+ fontWeight: 'normal',
276
+ fontVariant: 'small-caps',
277
+ letterSpacing: '0.06em',
278
+ margin: 'var(--gp-space-md) 0 var(--gp-space-xs)',
279
+ maxWidth: 'var(--gp-text-width)',
280
+ },
281
+
282
+ 'p': {
283
+ margin: '0 0 var(--gp-space-md)',
284
+ maxWidth: 'var(--gp-text-width)',
285
+ },
286
+ 'p + p': {
287
+ marginTop: 'calc(-1 * var(--gp-space-sm))',
288
+ textIndent: '1.5em',
289
+ },
290
+ 'h1 + p, h2 + p, h3 + p, h4 + p, blockquote + p, figure + p, hr + p': {
291
+ textIndent: '0',
292
+ },
293
+
294
+ 'abbr, .small-caps': {
295
+ fontVariant: 'small-caps',
296
+ letterSpacing: '0.06em',
297
+ fontSize: '0.9em',
298
+ },
299
+ 'em': { fontStyle: 'italic' },
300
+ 'strong': { fontWeight: 'bold' },
301
+ 'sup, sub': {
302
+ fontSize: '0.7em',
303
+ lineHeight: '0',
304
+ position: 'relative',
305
+ verticalAlign: 'baseline',
306
+ fontVariantNumeric: 'lining-nums',
307
+ },
308
+ 'sup': { top: '-0.5em' },
309
+ 'sub': { bottom: '-0.25em' },
310
+
311
+ 'a': {
312
+ color: 'var(--gp-ink)',
313
+ textDecoration: 'underline',
314
+ textDecorationColor: 'var(--gp-light-rule)',
315
+ textUnderlineOffset: '2px',
316
+ transition: 'text-decoration-color 0.15s',
317
+ },
318
+ 'a:hover': { textDecorationColor: 'var(--gp-ink)' },
319
+
320
+ 'hr': {
321
+ border: 'none',
322
+ margin: 'var(--gp-space-xl) 0',
323
+ maxWidth: 'var(--gp-text-width)',
324
+ },
325
+ 'hr::after': {
326
+ content: '"\\00B7 \\00B7 \\00B7"',
327
+ display: 'block',
328
+ textAlign: 'center',
329
+ color: 'var(--gp-light-rule)',
330
+ letterSpacing: '0.5em',
331
+ },
332
+
333
+ 'table': {
334
+ fontVariantNumeric: 'lining-nums tabular-nums',
335
+ },
336
+ 'ul, ol': {
337
+ paddingLeft: '1.5em',
338
+ margin: '0 0 var(--gp-space-md)',
339
+ maxWidth: 'var(--gp-text-width)',
340
+ },
341
+ 'li': {
342
+ marginBottom: 'var(--gp-space-xs)',
343
+ lineHeight: 'var(--gp-line-height)',
344
+ },
345
+ 'li > ul, li > ol': {
346
+ margin: 'var(--gp-space-xs) 0',
347
+ },
348
+ 'dl': {
349
+ margin: '0 0 var(--gp-space-md)',
350
+ maxWidth: 'var(--gp-text-width)',
351
+ },
352
+ 'dt': {
353
+ fontVariant: 'small-caps',
354
+ letterSpacing: '0.05em',
355
+ marginTop: 'var(--gp-space-sm)',
356
+ },
357
+ 'dd': {
358
+ marginLeft: '1.5em',
359
+ marginBottom: 'var(--gp-space-xs)',
360
+ color: 'var(--gp-margin-ink)',
361
+ fontSize: 'var(--gp-small)',
362
+ },
363
+
364
+ 'blockquote': {
365
+ fontStyle: 'italic',
366
+ margin: 'var(--gp-space-md) 0 var(--gp-space-md) 2em',
367
+ padding: '0',
368
+ border: 'none',
369
+ maxWidth: 'calc(var(--gp-text-width) - 2em)',
370
+ },
371
+ 'blockquote footer, blockquote cite': {
372
+ fontStyle: 'normal',
373
+ fontSize: 'var(--gp-small)',
374
+ color: 'var(--gp-margin-ink)',
375
+ display: 'block',
376
+ marginTop: 'var(--gp-space-xs)',
377
+ },
378
+ 'blockquote footer::before': { content: '"\\2014 "' },
379
+
380
+ 'code, kbd, samp': {
381
+ fontFamily: 'var(--gp-mono)',
382
+ fontSize: '0.84em',
383
+ background: 'var(--gp-code-bg)',
384
+ padding: '0.06em 0.28em',
385
+ borderRadius: '2px',
386
+ fontVariantNumeric: 'lining-nums',
387
+ transition: 'background-color 0.25s',
388
+ },
389
+ 'pre': {
390
+ background: 'var(--gp-code-bg)',
391
+ padding: 'var(--gp-space-md)',
392
+ overflowX: 'auto',
393
+ margin: 'var(--gp-space-md) 0',
394
+ borderLeft: '2px solid var(--gp-light-rule)',
395
+ maxWidth: 'var(--gp-text-width)',
396
+ transition: 'background-color 0.25s, border-color 0.25s',
397
+ },
398
+ 'pre code': {
399
+ background: 'none',
400
+ padding: '0',
401
+ fontSize: 'var(--gp-small)',
402
+ lineHeight: '1.5',
403
+ },
404
+
405
+ /* ── Sparkline draw animation ───────────────────────────────────── */
406
+ '@keyframes gp-draw': {
407
+ to: { strokeDashoffset: '0' },
408
+ },
409
+ });
410
+
411
+
412
+ /* ═══════════════════════════════════════════════════════════════════════
413
+ COMPONENTS
414
+ ═══════════════════════════════════════════════════════════════════════ */
415
+
416
+ addComponents({
417
+
418
+ /* ── Typography components ──────────────────────────────────────── */
419
+ '.subtitle': {
420
+ fontSize: '1.04rem',
421
+ fontStyle: 'italic',
422
+ margin: 'calc(-1 * var(--gp-space-xs)) 0 var(--gp-space-lg)',
423
+ color: 'var(--gp-margin-ink)',
424
+ maxWidth: 'var(--gp-text-width)',
425
+ },
426
+ '.author': {
427
+ fontFamily: 'var(--gp-sans)',
428
+ fontSize: 'var(--gp-small)',
429
+ letterSpacing: '0.04em',
430
+ color: 'var(--gp-margin-ink)',
431
+ margin: 'calc(-1 * var(--gp-space-md)) 0 var(--gp-space-xl)',
432
+ fontVariantNumeric: 'lining-nums',
433
+ maxWidth: 'var(--gp-text-width)',
434
+ },
435
+ 'p.lead': {
436
+ fontSize: '1.06rem',
437
+ textIndent: '0',
438
+ },
439
+ 'p.drop-cap::first-letter': {
440
+ fontSize: '3.6em',
441
+ lineHeight: '0.72',
442
+ float: 'left',
443
+ paddingRight: '0.06em',
444
+ marginTop: '0.06em',
445
+ fontStyle: 'normal',
446
+ },
447
+ '.new-thought': {
448
+ fontVariant: 'small-caps',
449
+ letterSpacing: '0.08em',
450
+ },
451
+ '.callout': {
452
+ fontSize: 'var(--gp-small)',
453
+ color: 'var(--gp-margin-ink)',
454
+ fontStyle: 'italic',
455
+ paddingLeft: '1em',
456
+ borderLeft: '1px solid var(--gp-light-rule)',
457
+ margin: 'var(--gp-space-sm) 0',
458
+ maxWidth: 'var(--gp-text-width)',
459
+ },
460
+ '.rule-thin': {
461
+ border: 'none',
462
+ borderTop: '0.5px solid var(--gp-light-rule)',
463
+ margin: 'var(--gp-space-md) 0',
464
+ maxWidth: 'var(--gp-text-width)',
465
+ },
466
+ '.lnf': { fontVariantNumeric: 'lining-nums tabular-nums' },
467
+ '.unit': {
468
+ fontSize: '0.82em',
469
+ color: 'var(--gp-margin-ink)',
470
+ fontVariantNumeric: 'lining-nums',
471
+ },
472
+ '.datum': {
473
+ fontVariantNumeric: 'lining-nums tabular-nums',
474
+ fontFamily: 'var(--gp-sans)',
475
+ fontSize: '0.9em',
476
+ letterSpacing: '-0.01em',
477
+ },
478
+ '.data-label': {
479
+ fontFamily: 'var(--gp-sans)',
480
+ fontSize: 'var(--gp-micro)',
481
+ color: 'var(--gp-margin-ink)',
482
+ },
483
+ '.source-line': {
484
+ fontFamily: 'var(--gp-sans)',
485
+ fontSize: 'var(--gp-micro)',
486
+ color: 'var(--gp-ghost-ink)',
487
+ marginTop: 'var(--gp-space-xs)',
488
+ maxWidth: 'var(--gp-text-width)',
489
+ },
490
+ '.source-line::before': { content: '"Source: "' },
491
+
492
+ /* ── Data notes ─────────────────────────────────────────────────── */
493
+ 'details.data-note': {
494
+ fontSize: 'var(--gp-small)',
495
+ color: 'var(--gp-margin-ink)',
496
+ margin: 'var(--gp-space-sm) 0',
497
+ borderLeft: '1px solid var(--gp-light-rule)',
498
+ paddingLeft: 'var(--gp-space-sm)',
499
+ maxWidth: 'var(--gp-text-width)',
500
+ },
501
+ 'details.data-note summary': {
502
+ cursor: 'pointer',
503
+ fontFamily: 'var(--gp-sans)',
504
+ fontSize: 'var(--gp-micro)',
505
+ letterSpacing: '0.08em',
506
+ textTransform: 'uppercase',
507
+ color: 'var(--gp-ghost-ink)',
508
+ listStyle: 'none',
509
+ padding: 'var(--gp-space-xs) 0',
510
+ transition: 'color 0.15s',
511
+ userSelect: 'none',
512
+ },
513
+ 'details.data-note summary::-webkit-details-marker': { display: 'none' },
514
+ 'details.data-note summary::before': { content: '"\\25B8 "', fontSize: '0.8em' },
515
+ 'details.data-note[open] summary::before': { content: '"\\25BE "' },
516
+ 'details.data-note summary:hover': { color: 'var(--gp-margin-ink)' },
517
+
518
+ /* ── Epigraph ───────────────────────────────────────────────────── */
519
+ '.epigraph': {
520
+ margin: 'var(--gp-space-xl) 0 var(--gp-space-xl) 5%',
521
+ maxWidth: 'var(--gp-text-width)',
522
+ },
523
+ '.epigraph > blockquote': {
524
+ fontStyle: 'italic',
525
+ fontSize: '1.04rem',
526
+ margin: '0',
527
+ padding: '0',
528
+ border: 'none',
529
+ },
530
+ '.epigraph > blockquote footer': {
531
+ fontStyle: 'normal',
532
+ fontSize: 'var(--gp-small)',
533
+ color: 'var(--gp-margin-ink)',
534
+ display: 'block',
535
+ marginTop: 'var(--gp-space-sm)',
536
+ },
537
+
538
+ /* ── Bibliography ───────────────────────────────────────────────── */
539
+ '.bibliography': {
540
+ margin: 'var(--gp-space-lg) 0',
541
+ maxWidth: 'var(--gp-text-width)',
542
+ },
543
+ '.bibliography ol, .bibliography ul': {
544
+ paddingLeft: '0',
545
+ listStyle: 'none',
546
+ },
547
+ '.bibliography li': {
548
+ fontSize: 'var(--gp-small)',
549
+ paddingLeft: '2em',
550
+ textIndent: '-2em',
551
+ marginBottom: 'var(--gp-space-sm)',
552
+ color: 'var(--gp-margin-ink)',
553
+ lineHeight: '1.5',
554
+ },
555
+ '.bibliography .title': { fontStyle: 'italic' },
556
+
557
+ /* ── Pull quote ─────────────────────────────────────────────────── */
558
+ '.pull-quote': {
559
+ fontSize: 'clamp(1.2rem, 2vw + 0.6rem, 1.45rem)',
560
+ fontStyle: 'italic',
561
+ lineHeight: '1.35',
562
+ margin: 'var(--gp-space-lg) 0',
563
+ maxWidth: 'var(--gp-text-width)',
564
+ },
565
+
566
+ /* ═══════════════════════════════════════════════════════════════════
567
+ LAYOUT
568
+ ═══════════════════════════════════════════════════════════════════ */
569
+
570
+ 'article': {
571
+ position: 'relative',
572
+ maxWidth: 'var(--gp-page-width)',
573
+ margin: '0 auto',
574
+ padding: 'var(--gp-space-xl) var(--gp-outer-margin)',
575
+ },
576
+ 'section': { paddingTop: 'var(--gp-space-lg)' },
577
+
578
+ '.running-header': {
579
+ fontFamily: 'var(--gp-sans)',
580
+ fontSize: 'var(--gp-micro)',
581
+ letterSpacing: '0.12em',
582
+ textTransform: 'uppercase',
583
+ color: 'var(--gp-ghost-ink)',
584
+ maxWidth: 'var(--gp-page-width)',
585
+ display: 'flex',
586
+ justifyContent: 'space-between',
587
+ borderBottom: '0.5px solid var(--gp-light-rule)',
588
+ paddingBottom: 'var(--gp-space-sm)',
589
+ marginBottom: 'var(--gp-space-xl)',
590
+ transition: 'border-color 0.25s, color 0.25s',
591
+ },
592
+
593
+ /* ── Figure compare ─────────────────────────────────────────────── */
594
+ '.figure-compare': {
595
+ display: 'grid',
596
+ gridTemplateColumns: '1fr 1fr',
597
+ gap: 'var(--gp-space-md)',
598
+ maxWidth: 'var(--gp-text-width)',
599
+ margin: 'var(--gp-space-lg) 0',
600
+ alignItems: 'start',
601
+ },
602
+ '.figure-compare.figure-compare-full': { maxWidth: 'var(--gp-page-width)' },
603
+ '.figure-compare figure': { margin: '0', maxWidth: 'none' },
604
+ '.figure-compare figcaption': {
605
+ float: 'none !important',
606
+ width: 'auto !important',
607
+ marginRight: '0 !important',
608
+ marginTop: 'var(--gp-space-xs)',
609
+ },
610
+
611
+ /* ── Compare wrap ───────────────────────────────────────────────── */
612
+ '.compare-wrap': {
613
+ display: 'grid',
614
+ gridTemplateColumns: '1fr 1fr',
615
+ gap: 'var(--gp-space-lg)',
616
+ maxWidth: 'var(--gp-text-width)',
617
+ margin: 'var(--gp-space-lg) 0',
618
+ borderTop: '0.75px solid var(--gp-rule)',
619
+ paddingTop: 'var(--gp-space-md)',
620
+ },
621
+ '.compare-wrap.compare-wrap-full': { maxWidth: 'var(--gp-page-width)' },
622
+ '.compare-col': { fontSize: 'var(--gp-small)' },
623
+ '.compare-col__header': {
624
+ fontFamily: 'var(--gp-sans)',
625
+ fontSize: 'var(--gp-micro)',
626
+ letterSpacing: '0.1em',
627
+ textTransform: 'uppercase',
628
+ color: 'var(--gp-margin-ink)',
629
+ marginBottom: 'var(--gp-space-sm)',
630
+ paddingBottom: '2px',
631
+ borderBottom: '0.5px solid var(--gp-light-rule)',
632
+ },
633
+ '.compare-col.before': { color: 'var(--gp-margin-ink)' },
634
+
635
+ /* ── Stat grid ──────────────────────────────────────────────────── */
636
+ '.stat-grid': {
637
+ display: 'grid',
638
+ gridTemplateColumns: 'repeat(auto-fit, minmax(130px, 1fr))',
639
+ gap: 'var(--gp-space-md) var(--gp-space-lg)',
640
+ borderTop: '1.5px solid var(--gp-ink)',
641
+ paddingTop: 'var(--gp-space-md)',
642
+ margin: 'var(--gp-space-lg) 0',
643
+ maxWidth: 'var(--gp-text-width)',
644
+ transition: 'border-color 0.25s',
645
+ },
646
+
647
+ /* ── Evidence layout ────────────────────────────────────────────── */
648
+ '.evidence': {
649
+ display: 'grid',
650
+ gridTemplateColumns: 'minmax(0, 1.4fr) minmax(0, 1fr)',
651
+ gap: 'var(--gp-space-lg)',
652
+ maxWidth: 'var(--gp-page-width)',
653
+ margin: 'var(--gp-space-lg) 0',
654
+ alignItems: 'start',
655
+ },
656
+ '.evidence__image': { margin: '0', maxWidth: 'none' },
657
+ '.evidence__image img, .evidence__image svg': {
658
+ maxWidth: '100%',
659
+ height: 'auto',
660
+ display: 'block',
661
+ },
662
+ '.evidence__image figcaption': {
663
+ float: 'none',
664
+ width: 'auto',
665
+ marginRight: '0',
666
+ marginTop: 'var(--gp-space-xs)',
667
+ fontSize: 'var(--gp-caption)',
668
+ fontFamily: 'var(--gp-sans)',
669
+ color: 'var(--gp-margin-ink)',
670
+ },
671
+ '.evidence__analysis': {
672
+ fontSize: 'var(--gp-small)',
673
+ lineHeight: '1.6',
674
+ color: 'var(--gp-ink)',
675
+ paddingTop: '0.1rem',
676
+ },
677
+ '.evidence__analysis p': { maxWidth: 'none' },
678
+ '.evidence__analysis p + p': { textIndent: '1.2em' },
679
+ '.evidence__caption': {
680
+ gridColumn: '1 / -1',
681
+ fontFamily: 'var(--gp-sans)',
682
+ fontSize: 'var(--gp-caption)',
683
+ color: 'var(--gp-margin-ink)',
684
+ borderTop: '0.5px solid var(--gp-light-rule)',
685
+ paddingTop: 'var(--gp-space-xs)',
686
+ marginTop: 'var(--gp-space-xs)',
687
+ },
688
+
689
+ /* ═══════════════════════════════════════════════════════════════════
690
+ SIDENOTES & MARGIN NOTES
691
+ ═══════════════════════════════════════════════════════════════════ */
692
+
693
+ '.sidenote-number': { counterIncrement: 'sidenote-counter' },
694
+ '.sidenote-number::after, .sidenote::before': {
695
+ content: 'counter(sidenote-counter)',
696
+ fontSize: '0.68rem',
697
+ verticalAlign: 'super',
698
+ lineHeight: '0',
699
+ fontVariantNumeric: 'lining-nums',
700
+ },
701
+ '.sidenote-number::after': { color: 'var(--gp-margin-ink)', paddingLeft: '1px' },
702
+ '.sidenote::before': { color: 'var(--gp-margin-ink)', paddingRight: '4px' },
703
+ 'input.sidenote-toggle': { display: 'none' },
704
+
705
+ '.sidenote, .marginnote': {
706
+ float: 'right',
707
+ clear: 'right',
708
+ marginRight: 'calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)))',
709
+ width: 'var(--gp-margin-width)',
710
+ fontSize: 'var(--gp-small)',
711
+ lineHeight: '1.5',
712
+ color: 'var(--gp-margin-ink)',
713
+ fontStyle: 'normal',
714
+ verticalAlign: 'baseline',
715
+ position: 'sticky',
716
+ top: '2rem',
717
+ paddingTop: '0.08rem',
718
+ transition: 'color 0.25s',
719
+ },
720
+ '.marginnote img, .marginnote svg': {
721
+ maxWidth: '100%',
722
+ height: 'auto',
723
+ display: 'block',
724
+ marginBottom: 'var(--gp-space-xs)',
725
+ },
726
+ '.marginnote-label': {
727
+ fontFamily: 'var(--gp-sans)',
728
+ fontSize: 'var(--gp-micro)',
729
+ letterSpacing: '0.1em',
730
+ textTransform: 'uppercase',
731
+ color: 'var(--gp-ghost-ink)',
732
+ display: 'block',
733
+ marginBottom: '2px',
734
+ },
735
+ 'label.sidenote-toggle': { display: 'none', cursor: 'pointer' },
736
+ 'label.sidenote-number': { display: 'inline' },
737
+ '.sidenote a, .marginnote a, figcaption a': { color: 'var(--gp-margin-ink)' },
738
+
739
+ '.section-marker': {
740
+ float: 'right',
741
+ clear: 'right',
742
+ marginRight: 'calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)))',
743
+ width: 'var(--gp-margin-width)',
744
+ fontFamily: 'var(--gp-sans)',
745
+ fontSize: 'var(--gp-micro)',
746
+ letterSpacing: '0.1em',
747
+ textTransform: 'uppercase',
748
+ color: 'var(--gp-ghost-ink)',
749
+ paddingTop: '0.2rem',
750
+ position: 'sticky',
751
+ top: '2rem',
752
+ },
753
+
754
+ /* ═══════════════════════════════════════════════════════════════════
755
+ FIGURES
756
+ ═══════════════════════════════════════════════════════════════════ */
757
+
758
+ 'figure': {
759
+ maxWidth: 'var(--gp-text-width)',
760
+ margin: 'var(--gp-space-lg) 0',
761
+ padding: '0',
762
+ },
763
+ 'figure img, figure svg, figure canvas': {
764
+ maxWidth: '100%',
765
+ height: 'auto',
766
+ display: 'block',
767
+ },
768
+ 'figure.figure-full': { maxWidth: 'var(--gp-page-width)' },
769
+ 'figure.figure-margin': {
770
+ float: 'right',
771
+ clear: 'right',
772
+ marginRight: 'calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)))',
773
+ width: 'var(--gp-margin-width)',
774
+ marginTop: '0',
775
+ marginBottom: 'var(--gp-space-md)',
776
+ },
777
+
778
+ 'figcaption': {
779
+ fontSize: 'var(--gp-caption)',
780
+ fontFamily: 'var(--gp-sans)',
781
+ fontOpticalSizing: 'auto',
782
+ lineHeight: '1.45',
783
+ color: 'var(--gp-margin-ink)',
784
+ marginTop: 'var(--gp-space-xs)',
785
+ transition: 'color 0.25s',
786
+ },
787
+ 'figure:not(.figure-margin):not(.figure-full):not(.evidence__image) figcaption': {
788
+ float: 'right',
789
+ clear: 'right',
790
+ marginRight: 'calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)))',
791
+ width: 'var(--gp-margin-width)',
792
+ marginTop: '0',
793
+ },
794
+ 'figure.figure-full figcaption': {
795
+ float: 'right',
796
+ width: 'var(--gp-margin-width)',
797
+ marginTop: 'var(--gp-space-xs)',
798
+ },
799
+ 'figure.figure-margin figcaption': {
800
+ float: 'none',
801
+ width: 'auto',
802
+ fontSize: '0.71em',
803
+ },
804
+
805
+ /* ═══════════════════════════════════════════════════════════════════
806
+ TABLES — Booktabs
807
+ ═══════════════════════════════════════════════════════════════════ */
808
+
809
+ 'table': {
810
+ maxWidth: 'var(--gp-text-width)',
811
+ width: '100%',
812
+ borderCollapse: 'collapse',
813
+ fontFamily: 'var(--gp-sans)',
814
+ fontSize: 'var(--gp-small)',
815
+ fontVariantNumeric: 'lining-nums tabular-nums',
816
+ margin: 'var(--gp-space-lg) 0',
817
+ lineHeight: '1.4',
818
+ transition: 'color 0.25s',
819
+ },
820
+ 'thead': {
821
+ borderTop: '1.5px solid var(--gp-ink)',
822
+ borderBottom: '0.75px solid var(--gp-ink)',
823
+ },
824
+ 'tbody tr:last-child td': {
825
+ borderBottom: '1.5px solid var(--gp-ink)',
826
+ paddingBottom: 'var(--gp-space-sm)',
827
+ },
828
+ 'tbody tr.midrule td': {
829
+ borderTop: '0.75px solid var(--gp-rule)',
830
+ paddingTop: 'var(--gp-space-sm)',
831
+ },
832
+ 'tbody tr.midrule-above td': { paddingBottom: 'var(--gp-space-sm)' },
833
+ 'th': {
834
+ fontWeight: 'normal',
835
+ fontVariant: 'small-caps',
836
+ letterSpacing: '0.06em',
837
+ textAlign: 'left',
838
+ padding: 'var(--gp-space-xs) var(--gp-space-sm)',
839
+ verticalAlign: 'bottom',
840
+ },
841
+ 'td': {
842
+ padding: 'var(--gp-space-xs) var(--gp-space-sm)',
843
+ verticalAlign: 'top',
844
+ },
845
+ 'td.num, th.num': { textAlign: 'right' },
846
+ 'td.neg': { color: 'var(--gp-red)' },
847
+ 'td.pos': { color: 'var(--gp-green)' },
848
+ 'tr.highlight td': {
849
+ background: 'var(--gp-code-bg)',
850
+ fontStyle: 'italic',
851
+ },
852
+ '.table-dense th, .table-dense td': {
853
+ padding: '2px var(--gp-space-xs)',
854
+ fontSize: 'var(--gp-micro)',
855
+ },
856
+ 'table.table-full': { maxWidth: 'var(--gp-page-width)' },
857
+ 'table.table-striped tbody tr:nth-child(even) td': {
858
+ background: 'oklch(from var(--gp-paper) calc(l - 0.02) c h)',
859
+ },
860
+ 'caption': {
861
+ fontSize: 'var(--gp-caption)',
862
+ fontFamily: 'var(--gp-sans)',
863
+ color: 'var(--gp-margin-ink)',
864
+ textAlign: 'left',
865
+ captionSide: 'top',
866
+ paddingBottom: 'var(--gp-space-xs)',
867
+ },
868
+
869
+ /* ═══════════════════════════════════════════════════════════════════
870
+ SPARKLINES
871
+ ═══════════════════════════════════════════════════════════════════ */
872
+
873
+ '.sparkline': {
874
+ display: 'inline-block',
875
+ verticalAlign: 'middle',
876
+ lineHeight: '1',
877
+ position: 'relative',
878
+ top: '-1px',
879
+ },
880
+ '.sparkline svg': { overflow: 'visible' },
881
+ '@media (prefers-reduced-motion: no-preference)': {
882
+ '.sp-draw': {
883
+ strokeDasharray: '300',
884
+ strokeDashoffset: '300',
885
+ animation: 'gp-draw 0.9s var(--gp-ease-out) forwards',
886
+ },
887
+ },
888
+ 'table.sparkline-table': {
889
+ fontFamily: 'var(--gp-sans)',
890
+ fontSize: 'var(--gp-small)',
891
+ },
892
+ 'table.sparkline-table .sp-cell': {
893
+ paddingTop: '2px',
894
+ paddingBottom: '2px',
895
+ },
896
+ 'table.sparkline-table .sp-cell svg': {
897
+ display: 'block',
898
+ overflow: 'visible',
899
+ },
900
+
901
+ /* ═══════════════════════════════════════════════════════════════════
902
+ SMALL MULTIPLES
903
+ ═══════════════════════════════════════════════════════════════════ */
904
+
905
+ '.small-multiples': {
906
+ maxWidth: 'var(--gp-page-width)',
907
+ display: 'grid',
908
+ gridTemplateColumns: 'repeat(auto-fill, minmax(130px, 1fr))',
909
+ gap: 'var(--gp-space-md)',
910
+ margin: 'var(--gp-space-lg) 0',
911
+ },
912
+ '.small-multiples-3': { gridTemplateColumns: 'repeat(3, 1fr)' },
913
+ '.small-multiples-4': { gridTemplateColumns: 'repeat(4, 1fr)' },
914
+ '.small-multiples-6': { gridTemplateColumns: 'repeat(6, 1fr)' },
915
+ '.small-multiples figure': { margin: '0', maxWidth: 'none' },
916
+ '.small-multiples figure figcaption': {
917
+ float: 'none',
918
+ width: 'auto',
919
+ marginRight: '0',
920
+ marginTop: 'var(--gp-space-xs)',
921
+ fontSize: '0.7em',
922
+ },
923
+ '.small-multiples-xlabel': {
924
+ gridColumn: '1 / -1',
925
+ fontFamily: 'var(--gp-sans)',
926
+ fontSize: 'var(--gp-micro)',
927
+ color: 'var(--gp-margin-ink)',
928
+ textAlign: 'center',
929
+ marginTop: 'calc(-1 * var(--gp-space-sm))',
930
+ },
931
+
932
+ /* ═══════════════════════════════════════════════════════════════════
933
+ PULL STATISTICS
934
+ ═══════════════════════════════════════════════════════════════════ */
935
+
936
+ '.pull-stat': {
937
+ margin: 'var(--gp-space-lg) 0',
938
+ maxWidth: 'var(--gp-text-width)',
939
+ },
940
+ '.pull-stat__number': {
941
+ fontSize: 'clamp(2.4rem, 4vw + 1rem, 3.5rem)',
942
+ lineHeight: '1',
943
+ fontStyle: 'italic',
944
+ fontWeight: 'normal',
945
+ display: 'block',
946
+ fontVariantNumeric: 'lining-nums',
947
+ },
948
+ '.pull-stat__label': {
949
+ fontFamily: 'var(--gp-sans)',
950
+ fontSize: 'var(--gp-small)',
951
+ color: 'var(--gp-margin-ink)',
952
+ letterSpacing: '0.04em',
953
+ display: 'block',
954
+ marginTop: '0.2em',
955
+ },
956
+ '.pull-stat__context': {
957
+ fontSize: 'var(--gp-small)',
958
+ color: 'var(--gp-ghost-ink)',
959
+ fontStyle: 'italic',
960
+ display: 'block',
961
+ },
962
+
963
+ /* ═══════════════════════════════════════════════════════════════════
964
+ BAR CHART
965
+ ═══════════════════════════════════════════════════════════════════ */
966
+
967
+ '.bar-chart': {
968
+ listStyle: 'none',
969
+ padding: '0',
970
+ margin: 'var(--gp-space-lg) 0',
971
+ maxWidth: 'var(--gp-text-width)',
972
+ },
973
+ '.bar-chart li': {
974
+ display: 'grid',
975
+ gridTemplateColumns: '160px 1fr auto',
976
+ alignItems: 'center',
977
+ gap: 'var(--gp-space-sm)',
978
+ marginBottom: 'var(--gp-space-xs)',
979
+ fontFamily: 'var(--gp-sans)',
980
+ fontSize: 'var(--gp-small)',
981
+ },
982
+ '.bar-label': {
983
+ textAlign: 'right',
984
+ color: 'var(--gp-ink)',
985
+ whiteSpace: 'nowrap',
986
+ overflow: 'hidden',
987
+ textOverflow: 'ellipsis',
988
+ },
989
+ '.bar': {
990
+ position: 'relative',
991
+ height: '1px',
992
+ background: 'var(--gp-ghost-ink)',
993
+ },
994
+ '.bar::after': {
995
+ content: '""',
996
+ position: 'absolute',
997
+ left: 'var(--bar-value, 50%)',
998
+ top: '-3px',
999
+ width: '1px',
1000
+ height: '7px',
1001
+ background: 'var(--gp-ink)',
1002
+ },
1003
+ '.bar-chart.filled .bar': {
1004
+ height: '8px',
1005
+ background: 'none',
1006
+ },
1007
+ '.bar-chart.filled .bar::before': {
1008
+ content: '""',
1009
+ position: 'absolute',
1010
+ left: '0',
1011
+ top: '0',
1012
+ height: '100%',
1013
+ width: 'var(--bar-value, 0%)',
1014
+ background: 'var(--gp-gray-data)',
1015
+ },
1016
+ '.bar-chart.filled .bar::after': { display: 'none' },
1017
+ '.bar-value': {
1018
+ color: 'var(--gp-margin-ink)',
1019
+ whiteSpace: 'nowrap',
1020
+ fontVariantNumeric: 'tabular-nums lining-nums',
1021
+ },
1022
+ '.bar.red::after, .bar-chart.filled .bar.red::before': { background: 'var(--gp-red)' },
1023
+ '.bar.blue::after, .bar-chart.filled .bar.blue::before': { background: 'var(--gp-blue)' },
1024
+ '.bar.green::after, .bar-chart.filled .bar.green::before': { background: 'var(--gp-green)' },
1025
+ '.bar.ochre::after, .bar-chart.filled .bar.ochre::before': { background: 'var(--gp-ochre)' },
1026
+
1027
+ /* ── Ghosting / emphasis ────────────────────────────────────────── */
1028
+ '.ghost': { opacity: '0.22' },
1029
+ '.near-ghost': { opacity: '0.40' },
1030
+ '.focal': { opacity: '1' },
1031
+
1032
+ /* ═══════════════════════════════════════════════════════════════════
1033
+ DOT CHART
1034
+ ═══════════════════════════════════════════════════════════════════ */
1035
+
1036
+ '.dot-chart': {
1037
+ listStyle: 'none',
1038
+ padding: '0',
1039
+ margin: 'var(--gp-space-lg) 0',
1040
+ maxWidth: 'var(--gp-text-width)',
1041
+ },
1042
+ '.dot-chart li': {
1043
+ display: 'grid',
1044
+ gridTemplateColumns: '160px 1fr auto',
1045
+ alignItems: 'center',
1046
+ gap: 'var(--gp-space-sm)',
1047
+ marginBottom: 'var(--gp-space-xs)',
1048
+ fontFamily: 'var(--gp-sans)',
1049
+ fontSize: 'var(--gp-small)',
1050
+ },
1051
+ '.dc-label': {
1052
+ textAlign: 'right',
1053
+ color: 'var(--gp-ink)',
1054
+ whiteSpace: 'nowrap',
1055
+ overflow: 'hidden',
1056
+ textOverflow: 'ellipsis',
1057
+ },
1058
+ '.dc-track': {
1059
+ position: 'relative',
1060
+ height: '1px',
1061
+ background: 'var(--gp-light-rule)',
1062
+ },
1063
+ '.dc-dot': {
1064
+ position: 'absolute',
1065
+ left: 'var(--dc-pos, 50%)',
1066
+ top: '50%',
1067
+ transform: 'translate(-50%, -50%)',
1068
+ width: '6px',
1069
+ height: '6px',
1070
+ borderRadius: '50%',
1071
+ background: 'var(--gp-ink)',
1072
+ transition: 'background 0.25s',
1073
+ },
1074
+ '.dc-dot.red': { background: 'var(--gp-red)' },
1075
+ '.dc-dot.blue': { background: 'var(--gp-blue)' },
1076
+ '.dc-dot.green': { background: 'var(--gp-green)' },
1077
+ '.dc-dot.open': {
1078
+ background: 'var(--gp-paper)',
1079
+ border: '1.5px solid var(--gp-ink)',
1080
+ },
1081
+ '.dc-value': {
1082
+ color: 'var(--gp-margin-ink)',
1083
+ fontVariantNumeric: 'tabular-nums lining-nums',
1084
+ },
1085
+
1086
+ /* ═══════════════════════════════════════════════════════════════════
1087
+ DUMBBELL CHART
1088
+ ═══════════════════════════════════════════════════════════════════ */
1089
+
1090
+ '.dumbbell': {
1091
+ listStyle: 'none',
1092
+ padding: '0',
1093
+ margin: 'var(--gp-space-lg) 0',
1094
+ maxWidth: 'var(--gp-text-width)',
1095
+ },
1096
+ '.dumbbell li': {
1097
+ display: 'grid',
1098
+ gridTemplateColumns: '160px 1fr auto',
1099
+ alignItems: 'center',
1100
+ gap: 'var(--gp-space-sm)',
1101
+ marginBottom: 'var(--gp-space-sm)',
1102
+ fontFamily: 'var(--gp-sans)',
1103
+ fontSize: 'var(--gp-small)',
1104
+ },
1105
+ '.db-label': {
1106
+ textAlign: 'right',
1107
+ color: 'var(--gp-ink)',
1108
+ whiteSpace: 'nowrap',
1109
+ overflow: 'hidden',
1110
+ textOverflow: 'ellipsis',
1111
+ },
1112
+ '.db-track': {
1113
+ position: 'relative',
1114
+ height: '1px',
1115
+ },
1116
+ '.db-track::before': {
1117
+ content: '""',
1118
+ position: 'absolute',
1119
+ top: '0',
1120
+ left: 'var(--db-l, 30%)',
1121
+ right: 'calc(100% - var(--db-r, 70%))',
1122
+ height: '1px',
1123
+ background: 'var(--gp-ghost-ink)',
1124
+ },
1125
+ '.db-dot': {
1126
+ position: 'absolute',
1127
+ top: '50%',
1128
+ width: '8px',
1129
+ height: '8px',
1130
+ borderRadius: '50%',
1131
+ },
1132
+ '.db-dot--left': {
1133
+ left: 'var(--db-l, 30%)',
1134
+ transform: 'translate(-50%, -50%)',
1135
+ background: 'var(--gp-blue)',
1136
+ },
1137
+ '.db-dot--right': {
1138
+ left: 'var(--db-r, 70%)',
1139
+ transform: 'translate(-50%, -50%)',
1140
+ background: 'var(--gp-red)',
1141
+ },
1142
+ '.db-value': {
1143
+ color: 'var(--gp-margin-ink)',
1144
+ fontSize: 'var(--gp-micro)',
1145
+ whiteSpace: 'nowrap',
1146
+ fontVariantNumeric: 'lining-nums',
1147
+ },
1148
+
1149
+ /* ═══════════════════════════════════════════════════════════════════
1150
+ STRIP PLOT
1151
+ ═══════════════════════════════════════════════════════════════════ */
1152
+
1153
+ '.strip-plot': {
1154
+ listStyle: 'none',
1155
+ padding: '0',
1156
+ margin: 'var(--gp-space-lg) 0',
1157
+ maxWidth: 'var(--gp-text-width)',
1158
+ },
1159
+ '.strip-plot li': {
1160
+ display: 'grid',
1161
+ gridTemplateColumns: '160px 1fr',
1162
+ alignItems: 'center',
1163
+ gap: 'var(--gp-space-sm)',
1164
+ marginBottom: '10px',
1165
+ fontFamily: 'var(--gp-sans)',
1166
+ fontSize: 'var(--gp-small)',
1167
+ },
1168
+ '.sp-label': {
1169
+ textAlign: 'right',
1170
+ color: 'var(--gp-ink)',
1171
+ whiteSpace: 'nowrap',
1172
+ },
1173
+ '.sp-track': {
1174
+ position: 'relative',
1175
+ height: '1px',
1176
+ background: 'var(--gp-light-rule)',
1177
+ },
1178
+ '.sp-dot': {
1179
+ position: 'absolute',
1180
+ left: 'var(--sp-pos, 50%)',
1181
+ top: '50%',
1182
+ transform: 'translate(-50%, -50%)',
1183
+ width: '5px',
1184
+ height: '5px',
1185
+ borderRadius: '50%',
1186
+ background: 'var(--gp-ink)',
1187
+ opacity: '0.65',
1188
+ },
1189
+ '.sp-dot.red': { background: 'var(--gp-red)' },
1190
+ '.sp-dot.blue': { background: 'var(--gp-blue)' },
1191
+ '.sp-dot.green': { background: 'var(--gp-green)' },
1192
+ '.sp-axis-labels': {
1193
+ display: 'flex',
1194
+ justifyContent: 'space-between',
1195
+ marginLeft: 'calc(160px + var(--gp-space-sm))',
1196
+ fontFamily: 'var(--gp-sans)',
1197
+ fontSize: 'var(--gp-micro)',
1198
+ color: 'var(--gp-margin-ink)',
1199
+ marginTop: '4px',
1200
+ fontVariantNumeric: 'lining-nums',
1201
+ },
1202
+
1203
+ /* ═══════════════════════════════════════════════════════════════════
1204
+ STEM-AND-LEAF
1205
+ ═══════════════════════════════════════════════════════════════════ */
1206
+
1207
+ 'table.stem-leaf': {
1208
+ fontFamily: 'var(--gp-mono)',
1209
+ fontSize: 'var(--gp-small)',
1210
+ fontVariantNumeric: 'lining-nums tabular-nums',
1211
+ maxWidth: 'var(--gp-text-width)',
1212
+ margin: 'var(--gp-space-lg) 0',
1213
+ lineHeight: '1.9',
1214
+ borderCollapse: 'collapse',
1215
+ width: '100%',
1216
+ border: 'none',
1217
+ },
1218
+ 'table.stem-leaf thead': { borderBottom: '0.75px solid var(--gp-rule)' },
1219
+ 'table.stem-leaf thead th': {
1220
+ fontFamily: 'var(--gp-sans)',
1221
+ fontSize: 'var(--gp-micro)',
1222
+ letterSpacing: '0.06em',
1223
+ textTransform: 'uppercase',
1224
+ color: 'var(--gp-ghost-ink)',
1225
+ fontWeight: 'normal',
1226
+ paddingBottom: '3px',
1227
+ },
1228
+ 'table.stem-leaf .sl-col-left': {
1229
+ width: '43%',
1230
+ textAlign: 'right',
1231
+ paddingRight: '8px',
1232
+ color: 'var(--gp-blue)',
1233
+ },
1234
+ 'table.stem-leaf .sl-col-stem': {
1235
+ width: '14%',
1236
+ textAlign: 'center',
1237
+ color: 'var(--gp-margin-ink)',
1238
+ borderLeft: '0.5px solid var(--gp-rule)',
1239
+ borderRight: '0.5px solid var(--gp-rule)',
1240
+ padding: '0 4px',
1241
+ },
1242
+ 'table.stem-leaf thead .sl-col-stem': { color: 'var(--gp-margin-ink)' },
1243
+ 'table.stem-leaf .sl-col-right': {
1244
+ width: '43%',
1245
+ textAlign: 'left',
1246
+ paddingLeft: '8px',
1247
+ },
1248
+ '.sl-unit': {
1249
+ fontFamily: 'var(--gp-sans)',
1250
+ fontSize: 'var(--gp-micro)',
1251
+ color: 'var(--gp-ghost-ink)',
1252
+ marginTop: 'var(--gp-space-xs)',
1253
+ },
1254
+
1255
+ /* ═══════════════════════════════════════════════════════════════════
1256
+ BULLET GRAPH
1257
+ ═══════════════════════════════════════════════════════════════════ */
1258
+
1259
+ '.bullet-graphs': {
1260
+ maxWidth: 'var(--gp-text-width)',
1261
+ margin: 'var(--gp-space-lg) 0',
1262
+ display: 'flex',
1263
+ flexDirection: 'column',
1264
+ gap: 'var(--gp-space-md)',
1265
+ },
1266
+ '.bullet-graph': {
1267
+ display: 'grid',
1268
+ gridTemplateColumns: '140px 1fr auto',
1269
+ alignItems: 'center',
1270
+ gap: 'var(--gp-space-sm)',
1271
+ fontFamily: 'var(--gp-sans)',
1272
+ fontSize: 'var(--gp-small)',
1273
+ },
1274
+ '.bg-label': { textAlign: 'right', color: 'var(--gp-ink)' },
1275
+ '.bg-track': { position: 'relative', height: '16px', background: 'transparent' },
1276
+ '.bg-range': { position: 'absolute', top: '0', height: '100%', display: 'inline-block' },
1277
+ '.bg-range-1': { left: '0', background: 'var(--gp-ghost-ink)', opacity: '0.35' },
1278
+ '.bg-range-2': { left: '33%', background: 'var(--gp-ghost-ink)', opacity: '0.22' },
1279
+ '.bg-range-3': { left: '66%', background: 'var(--gp-ghost-ink)', opacity: '0.12' },
1280
+ '.bg-bar': {
1281
+ position: 'absolute',
1282
+ left: '0',
1283
+ top: '25%',
1284
+ height: '50%',
1285
+ background: 'var(--gp-ink)',
1286
+ zIndex: '2',
1287
+ transition: 'background 0.25s',
1288
+ },
1289
+ '.bg-bar.red': { background: 'var(--gp-red)' },
1290
+ '.bg-bar.blue': { background: 'var(--gp-blue)' },
1291
+ '.bg-bar.green': { background: 'var(--gp-green)' },
1292
+ '.bg-target': {
1293
+ position: 'absolute',
1294
+ top: '10%',
1295
+ height: '80%',
1296
+ width: '2px',
1297
+ background: 'var(--gp-ink)',
1298
+ zIndex: '3',
1299
+ transform: 'translateX(-50%)',
1300
+ },
1301
+ '.bg-value': {
1302
+ color: 'var(--gp-margin-ink)',
1303
+ fontVariantNumeric: 'tabular-nums lining-nums',
1304
+ },
1305
+ '.bg-axis': {
1306
+ marginLeft: 'calc(140px + var(--gp-space-sm))',
1307
+ display: 'flex',
1308
+ justifyContent: 'space-between',
1309
+ fontFamily: 'var(--gp-sans)',
1310
+ fontSize: 'var(--gp-micro)',
1311
+ color: 'var(--gp-ghost-ink)',
1312
+ borderTop: '0.5px solid var(--gp-light-rule)',
1313
+ paddingTop: '2px',
1314
+ },
1315
+
1316
+ /* ═══════════════════════════════════════════════════════════════════
1317
+ HEAT TABLE
1318
+ ═══════════════════════════════════════════════════════════════════ */
1319
+
1320
+ '.heat-table td.heat': {
1321
+ color: 'var(--gp-ink)',
1322
+ transition: 'background 0.2s',
1323
+ textAlign: 'right',
1324
+ },
1325
+ '.heat-table td.heat[data-dark]': { color: 'oklch(93% 0.005 85)' },
1326
+ '.heat-table td.heat-div': {
1327
+ textAlign: 'right',
1328
+ transition: 'background 0.2s',
1329
+ },
1330
+
1331
+ /* ═══════════════════════════════════════════════════════════════════
1332
+ RANKED TABLE
1333
+ ═══════════════════════════════════════════════════════════════════ */
1334
+
1335
+ 'table.ranked-table td.rank': {
1336
+ color: 'var(--gp-ghost-ink)',
1337
+ textAlign: 'right',
1338
+ paddingRight: 'var(--gp-space-sm)',
1339
+ fontVariantNumeric: 'lining-nums tabular-nums',
1340
+ width: '2em',
1341
+ },
1342
+ 'table.ranked-table td.rank-label': {
1343
+ backgroundImage: 'radial-gradient(circle, var(--gp-light-rule) 1px, transparent 1px)',
1344
+ backgroundSize: '6px 1px',
1345
+ backgroundPosition: '0 0.9em',
1346
+ backgroundRepeat: 'repeat-x',
1347
+ paddingRight: 'var(--gp-space-sm)',
1348
+ },
1349
+ 'table.ranked-table td.rank-label span': {
1350
+ background: 'var(--gp-paper)',
1351
+ paddingRight: '4px',
1352
+ transition: 'background 0.25s',
1353
+ },
1354
+ 'table.ranked-table td.rank-value': {
1355
+ fontVariantNumeric: 'tabular-nums lining-nums',
1356
+ textAlign: 'right',
1357
+ },
1358
+ 'table.ranked-table tr.rank-highlight td.rank-label span, table.ranked-table tr.rank-highlight td.rank-label': {
1359
+ fontStyle: 'italic',
1360
+ },
1361
+
1362
+ /* ═══════════════════════════════════════════════════════════════════
1363
+ TIMELINE
1364
+ ═══════════════════════════════════════════════════════════════════ */
1365
+
1366
+ '.timeline': {
1367
+ maxWidth: 'var(--gp-text-width)',
1368
+ margin: 'var(--gp-space-lg) 0',
1369
+ fontFamily: 'var(--gp-sans)',
1370
+ fontSize: 'var(--gp-small)',
1371
+ },
1372
+ '.tl-track': {
1373
+ position: 'relative',
1374
+ height: '48px',
1375
+ borderBottom: '1px solid var(--gp-ink)',
1376
+ },
1377
+ '.tl-event': {
1378
+ position: 'absolute',
1379
+ left: 'var(--tl-pos, 50%)',
1380
+ bottom: '0',
1381
+ transform: 'translateX(-50%)',
1382
+ display: 'flex',
1383
+ flexDirection: 'column-reverse',
1384
+ alignItems: 'center',
1385
+ },
1386
+ '.tl-event::after': {
1387
+ content: '""',
1388
+ display: 'block',
1389
+ width: '6px',
1390
+ height: '6px',
1391
+ borderRadius: '50%',
1392
+ background: 'var(--gp-ink)',
1393
+ },
1394
+ '.tl-event-label': {
1395
+ fontSize: 'var(--gp-micro)',
1396
+ color: 'var(--gp-ink)',
1397
+ whiteSpace: 'nowrap',
1398
+ marginBottom: '4px',
1399
+ textAlign: 'center',
1400
+ },
1401
+ '.tl-period': {
1402
+ position: 'absolute',
1403
+ bottom: '4px',
1404
+ left: 'var(--tl-start, 0%)',
1405
+ right: 'calc(100% - var(--tl-end, 50%))',
1406
+ height: '8px',
1407
+ background: 'var(--gp-ghost-ink)',
1408
+ opacity: '0.4',
1409
+ },
1410
+ '.tl-period-label': {
1411
+ position: 'absolute',
1412
+ top: '-18px',
1413
+ left: '0',
1414
+ fontSize: 'var(--gp-micro)',
1415
+ color: 'var(--gp-margin-ink)',
1416
+ whiteSpace: 'nowrap',
1417
+ },
1418
+ '.tl-period.red': { background: 'var(--gp-red)', opacity: '0.5' },
1419
+ '.tl-period.blue': { background: 'var(--gp-blue)', opacity: '0.5' },
1420
+ '.tl-period.green': { background: 'var(--gp-green)', opacity: '0.5' },
1421
+ '.tl-period.ochre': { background: 'var(--gp-ochre)', opacity: '0.5' },
1422
+ '.tl-axis': {
1423
+ display: 'flex',
1424
+ justifyContent: 'space-between',
1425
+ marginTop: '4px',
1426
+ fontSize: 'var(--gp-micro)',
1427
+ color: 'var(--gp-margin-ink)',
1428
+ fontVariantNumeric: 'lining-nums',
1429
+ },
1430
+ '.tl-axis span::before': {
1431
+ content: '""',
1432
+ display: 'block',
1433
+ width: '1px',
1434
+ height: '4px',
1435
+ background: 'var(--gp-rule)',
1436
+ margin: '0 auto 2px',
1437
+ },
1438
+
1439
+ /* ═══════════════════════════════════════════════════════════════════
1440
+ SLOPEGRAPH
1441
+ ═══════════════════════════════════════════════════════════════════ */
1442
+
1443
+ '.slopegraph-wrap': {
1444
+ maxWidth: 'var(--gp-text-width)',
1445
+ margin: 'var(--gp-space-lg) 0',
1446
+ },
1447
+
1448
+ /* ═══════════════════════════════════════════════════════════════════
1449
+ PARALLEL COORDINATES
1450
+ ═══════════════════════════════════════════════════════════════════ */
1451
+
1452
+ '.parallel-coords': {
1453
+ maxWidth: 'var(--gp-page-width)',
1454
+ margin: 'var(--gp-space-lg) 0',
1455
+ overflowX: 'auto',
1456
+ },
1457
+ '.parallel-coords svg': { display: 'block', overflow: 'visible' },
1458
+ '.pc-line': {
1459
+ fill: 'none',
1460
+ stroke: 'var(--gp-ghost-ink)',
1461
+ strokeWidth: '0.75',
1462
+ opacity: '0.5',
1463
+ },
1464
+ '.pc-line.highlight': {
1465
+ stroke: 'var(--gp-red)',
1466
+ strokeWidth: '1.5',
1467
+ opacity: '1',
1468
+ },
1469
+ '.pc-line.blue-hl': {
1470
+ stroke: 'var(--gp-blue)',
1471
+ strokeWidth: '1.5',
1472
+ opacity: '1',
1473
+ },
1474
+ '.pc-axis': { stroke: 'var(--gp-rule)', strokeWidth: '0.75' },
1475
+
1476
+ /* ═══════════════════════════════════════════════════════════════════
1477
+ SVG ANNOTATION CONVENTIONS
1478
+ ═══════════════════════════════════════════════════════════════════ */
1479
+
1480
+ '.ann-line': { stroke: 'var(--gp-ghost-ink)', strokeWidth: '0.6', fill: 'none' },
1481
+ '.ann-text': {
1482
+ fontFamily: 'var(--gp-sans)',
1483
+ fontSize: '8px',
1484
+ fill: 'var(--gp-margin-ink)',
1485
+ fontStyle: 'italic',
1486
+ },
1487
+ '.ref-band': { fill: 'var(--gp-ghost-ink)', fillOpacity: '0.10', stroke: 'none' },
1488
+ '.ref-line': {
1489
+ stroke: 'var(--gp-rule)',
1490
+ strokeWidth: '0.75',
1491
+ strokeDasharray: '2 4',
1492
+ fill: 'none',
1493
+ },
1494
+ '.zero-line': {
1495
+ stroke: 'var(--gp-rule)',
1496
+ strokeWidth: '0.75',
1497
+ strokeDasharray: '2 4',
1498
+ fill: 'none',
1499
+ },
1500
+
1501
+ /* ═══════════════════════════════════════════════════════════════════
1502
+ RESPONSIVE — 960px breakpoint
1503
+ ═══════════════════════════════════════════════════════════════════ */
1504
+
1505
+ '@media (max-width: 960px)': {
1506
+ 'article': {
1507
+ paddingTop: 'var(--gp-space-lg)',
1508
+ paddingBottom: 'var(--gp-space-lg)',
1509
+ },
1510
+ 'label.sidenote-toggle:not(.sidenote-number)': {
1511
+ display: 'inline',
1512
+ cursor: 'pointer',
1513
+ color: 'var(--gp-red)',
1514
+ fontSize: '0.85em',
1515
+ },
1516
+ '.sidenote, .marginnote': {
1517
+ display: 'none',
1518
+ float: 'none',
1519
+ position: 'static',
1520
+ margin: 'var(--gp-space-sm) 0',
1521
+ width: '100%',
1522
+ background: 'var(--gp-code-bg)',
1523
+ padding: 'var(--gp-space-sm) var(--gp-space-md)',
1524
+ borderLeft: '2px solid var(--gp-light-rule)',
1525
+ fontSize: 'var(--gp-small)',
1526
+ color: 'var(--gp-margin-ink)',
1527
+ },
1528
+ '.sidenote-toggle:checked + .sidenote, .sidenote-toggle:checked + .marginnote': {
1529
+ display: 'block',
1530
+ },
1531
+ 'figure.figure-margin': {
1532
+ float: 'none',
1533
+ marginRight: '0',
1534
+ width: '100%',
1535
+ },
1536
+ 'figure:not(.figure-margin):not(.figure-full):not(.evidence__image) figcaption': {
1537
+ float: 'none',
1538
+ marginRight: '0',
1539
+ width: '100%',
1540
+ marginTop: 'var(--gp-space-xs)',
1541
+ },
1542
+ 'figure.figure-full, figure.figure-full figcaption': {
1543
+ maxWidth: '100%',
1544
+ float: 'none',
1545
+ width: '100%',
1546
+ },
1547
+ '.figure-compare, .compare-wrap, .evidence': {
1548
+ gridTemplateColumns: '1fr',
1549
+ },
1550
+ '.evidence__caption': { gridColumn: '1' },
1551
+ '.small-multiples-3, .small-multiples-4': {
1552
+ gridTemplateColumns: 'repeat(2, 1fr)',
1553
+ },
1554
+ '.small-multiples-6': { gridTemplateColumns: 'repeat(3, 1fr)' },
1555
+ '.running-header': { flexDirection: 'column' },
1556
+ '.dot-chart li, .dumbbell li, .bar-chart li': {
1557
+ gridTemplateColumns: '100px 1fr auto',
1558
+ },
1559
+ '.strip-plot li': { gridTemplateColumns: '100px 1fr' },
1560
+ '.sp-axis-labels': { marginLeft: 'calc(100px + var(--gp-space-sm))' },
1561
+ '.bullet-graph': { gridTemplateColumns: '100px 1fr auto' },
1562
+ '.bg-axis': { marginLeft: 'calc(100px + var(--gp-space-sm))' },
1563
+ },
1564
+
1565
+ /* ═══════════════════════════════════════════════════════════════════
1566
+ RESPONSIVE — 560px breakpoint
1567
+ ═══════════════════════════════════════════════════════════════════ */
1568
+
1569
+ '@media (max-width: 560px)': {
1570
+ 'article': {
1571
+ paddingTop: 'var(--gp-space-md)',
1572
+ paddingBottom: 'var(--gp-space-md)',
1573
+ },
1574
+ '.stat-grid': { gridTemplateColumns: 'repeat(2, 1fr)' },
1575
+ '.dot-chart li, .dumbbell li, .bar-chart li': {
1576
+ gridTemplateColumns: '70px 1fr auto',
1577
+ },
1578
+ '.strip-plot li': { gridTemplateColumns: '70px 1fr' },
1579
+ '.sp-axis-labels': { marginLeft: 'calc(70px + var(--gp-space-sm))' },
1580
+ '.bullet-graph': { gridTemplateColumns: '70px 1fr auto' },
1581
+ '.bg-axis': { marginLeft: 'calc(70px + var(--gp-space-sm))' },
1582
+ '.small-multiples-3, .small-multiples-4, .small-multiples-6': {
1583
+ gridTemplateColumns: 'repeat(2, 1fr)',
1584
+ },
1585
+ },
1586
+
1587
+ /* ═══════════════════════════════════════════════════════════════════
1588
+ PRINT
1589
+ ═══════════════════════════════════════════════════════════════════ */
1590
+
1591
+ '@media print': {
1592
+ ':root': {
1593
+ '--gp-font-size': '11pt',
1594
+ '--gp-text-width': '120mm',
1595
+ '--gp-margin-width': '50mm',
1596
+ '--gp-gutter': '10mm',
1597
+ '--gp-outer-margin': '0mm',
1598
+ },
1599
+ 'html': { colorScheme: 'light' },
1600
+ 'body': { background: 'white', color: 'black' },
1601
+ 'article': { maxWidth: 'none', padding: '0' },
1602
+ 'a': { textDecoration: 'none', color: 'black' },
1603
+ '.sidenote, .marginnote': {
1604
+ display: 'block !important',
1605
+ float: 'right',
1606
+ position: 'static',
1607
+ marginRight: 'calc(-1 * (var(--gp-margin-width) + var(--gp-gutter)))',
1608
+ width: 'var(--gp-margin-width)',
1609
+ fontSize: '8pt',
1610
+ background: 'none',
1611
+ border: 'none',
1612
+ padding: '0',
1613
+ },
1614
+ 'input.sidenote-toggle, label.sidenote-toggle:not(.sidenote-number)': {
1615
+ display: 'none',
1616
+ },
1617
+ 'figure, table': { breakInside: 'avoid' },
1618
+ 'h1, h2, h3': { breakAfter: 'avoid' },
1619
+ },
1620
+ });
1621
+
1622
+
1623
+ /* ═══════════════════════════════════════════════════════════════════════
1624
+ UTILITIES
1625
+ ═══════════════════════════════════════════════════════════════════════ */
1626
+
1627
+ addUtilities({
1628
+ /* ── Color utilities ────────────────────────────────────────────── */
1629
+ '.gp-red': { color: 'var(--gp-red)' },
1630
+ '.gp-blue': { color: 'var(--gp-blue)' },
1631
+ '.gp-green': { color: 'var(--gp-green)' },
1632
+ '.gp-ochre': { color: 'var(--gp-ochre)' },
1633
+
1634
+ /* ── Layout utilities ───────────────────────────────────────────── */
1635
+ '.full-bleed': { maxWidth: 'var(--gp-page-width) !important' },
1636
+ '.align-right': { textAlign: 'right' },
1637
+ '.align-center': { textAlign: 'center' },
1638
+
1639
+ /* ── Typography utilities ───────────────────────────────────────── */
1640
+ '.sans': { fontFamily: 'var(--gp-sans)' },
1641
+ '.mono': { fontFamily: 'var(--gp-mono)' },
1642
+ '.italic': { fontStyle: 'italic' },
1643
+ '.muted': { color: 'var(--gp-margin-ink)' },
1644
+ '.very-muted': { color: 'var(--gp-ghost-ink)' },
1645
+ '.small': { fontSize: 'var(--gp-small)' },
1646
+ '.micro': { fontSize: 'var(--gp-micro)' },
1647
+
1648
+ /* ── Clearfix ───────────────────────────────────────────────────── */
1649
+ '.cf::after': { content: '""', display: 'table', clear: 'both' },
1650
+
1651
+ /* ── Margin utilities ───────────────────────────────────────────── */
1652
+ '.mt-sm': { marginTop: 'var(--gp-space-sm)' },
1653
+ '.mt-md': { marginTop: 'var(--gp-space-md)' },
1654
+ '.mt-lg': { marginTop: 'var(--gp-space-lg)' },
1655
+ '.mt-xl': { marginTop: 'var(--gp-space-xl)' },
1656
+ '.mb-sm': { marginBottom: 'var(--gp-space-sm)' },
1657
+ '.mb-md': { marginBottom: 'var(--gp-space-md)' },
1658
+ '.mb-lg': { marginBottom: 'var(--gp-space-lg)' },
1659
+ '.mb-xl': { marginBottom: 'var(--gp-space-xl)' },
1660
+
1661
+ /* ── Sequential color utilities ─────────────────────────────────── */
1662
+ '.seq-1': { color: 'var(--gp-seq-1)' },
1663
+ '.seq-2': { color: 'var(--gp-seq-2)' },
1664
+ '.seq-3': { color: 'var(--gp-seq-3)' },
1665
+ '.seq-4': { color: 'var(--gp-seq-4)' },
1666
+ '.seq-5': { color: 'var(--gp-seq-5)' },
1667
+
1668
+ /* ── Ghost / emphasis utilities ─────────────────────────────────── */
1669
+ '.ghost': { opacity: '0.22' },
1670
+ '.near-ghost': { opacity: '0.40' },
1671
+ '.focal': { opacity: '1' },
1672
+ });
1673
+ },
1674
+
1675
+ /* ═══════════════════════════════════════════════════════════════════════
1676
+ THEME EXTENSIONS — enables Tailwind utility classes like:
1677
+ text-gp-red, bg-gp-paper, font-serif, etc.
1678
+ ═══════════════════════════════════════════════════════════════════════ */
1679
+ {
1680
+ theme: {
1681
+ extend: {
1682
+ colors: {
1683
+ 'gp-paper': 'var(--gp-paper)',
1684
+ 'gp-ink': 'var(--gp-ink)',
1685
+ 'gp-margin-ink': 'var(--gp-margin-ink)',
1686
+ 'gp-ghost-ink': 'var(--gp-ghost-ink)',
1687
+ 'gp-rule': 'var(--gp-rule)',
1688
+ 'gp-light-rule': 'var(--gp-light-rule)',
1689
+ 'gp-code-bg': 'var(--gp-code-bg)',
1690
+
1691
+ 'gp-red': 'var(--gp-red)',
1692
+ 'gp-red-light': 'var(--gp-red-light)',
1693
+ 'gp-blue': 'var(--gp-blue)',
1694
+ 'gp-blue-light': 'var(--gp-blue-light)',
1695
+ 'gp-green': 'var(--gp-green)',
1696
+ 'gp-green-light': 'var(--gp-green-light)',
1697
+ 'gp-ochre': 'var(--gp-ochre)',
1698
+ 'gp-ochre-light': 'var(--gp-ochre-light)',
1699
+ 'gp-brown': 'var(--gp-brown)',
1700
+ 'gp-gray-data': 'var(--gp-gray-data)',
1701
+
1702
+ 'gp-seq-1': 'var(--gp-seq-1)',
1703
+ 'gp-seq-2': 'var(--gp-seq-2)',
1704
+ 'gp-seq-3': 'var(--gp-seq-3)',
1705
+ 'gp-seq-4': 'var(--gp-seq-4)',
1706
+ 'gp-seq-5': 'var(--gp-seq-5)',
1707
+
1708
+ 'gp-div-lo-2': 'var(--gp-div-lo-2)',
1709
+ 'gp-div-lo-1': 'var(--gp-div-lo-1)',
1710
+ 'gp-div-mid': 'var(--gp-div-mid)',
1711
+ 'gp-div-hi-1': 'var(--gp-div-hi-1)',
1712
+ 'gp-div-hi-2': 'var(--gp-div-hi-2)',
1713
+ },
1714
+ fontFamily: {
1715
+ 'serif': ['var(--gp-serif)'],
1716
+ 'sans': ['var(--gp-sans)'],
1717
+ 'mono': ['var(--gp-mono)'],
1718
+ },
1719
+ spacing: {
1720
+ 'gp-xs': 'var(--gp-space-xs)',
1721
+ 'gp-sm': 'var(--gp-space-sm)',
1722
+ 'gp-md': 'var(--gp-space-md)',
1723
+ 'gp-lg': 'var(--gp-space-lg)',
1724
+ 'gp-xl': 'var(--gp-space-xl)',
1725
+ },
1726
+ maxWidth: {
1727
+ 'gp-text': 'var(--gp-text-width)',
1728
+ 'gp-margin': 'var(--gp-margin-width)',
1729
+ 'gp-page': 'var(--gp-page-width)',
1730
+ },
1731
+ width: {
1732
+ 'gp-text': 'var(--gp-text-width)',
1733
+ 'gp-margin': 'var(--gp-margin-width)',
1734
+ 'gp-page': 'var(--gp-page-width)',
1735
+ },
1736
+ },
1737
+ },
1738
+ }
1739
+ );