Skip to main content

max / makenotwork

Move the wizard and media player onto the makeover gap scale First two files of the full geometry conversion decided 2026-08-02. Every spacing value now names the relationship it expresses rather than a size, so the touch density block in geometry.css finally has consumers and the generated layer stops being dead weight. This deliberately does not preserve current pixel values. Spacing tightens on a pointer and loosens on a coarse one, which is the trade the layer exists to make. Two exceptions kept literal with the reason in place: the checklist's 3.5rem label column, which is a fixed column width rather than a gap, and the media container's 5rem bottom runout, which sits above the scale top. The chapter row's hover bleed now reads one token on both sides, negated with calc for the margin, so the bleed and the inset cannot drift apart.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-02 20:06 UTC
Signed with PGP, not checked
Commit: 7959fe16f7fd641b1221ef28667962647203837b
Parent: 0ecab5d
2 files changed, +97 insertions, -91 deletions
@@ -4,15 +4,17 @@
4 4 .media-container {
5 5 max-width: 680px;
6 6 margin: 0 auto;
7 - padding: 3rem 1.5rem 5rem;
7 + /* Bottom is 5rem, above the scale top of 3rem: deliberate long-scroll
8 + runout under the footer, not a relationship. Kept literal. */
9 + padding: var(--gap-page) var(--gap-pane) 5rem;
8 10 }
9 11
10 12 /* Author header */
11 13 .author-header {
12 14 display: flex;
13 15 align-items: center;
14 - gap: 1rem;
15 - margin-bottom: 2rem;
16 + gap: var(--gap-section);
17 + margin-bottom: var(--gap-page);
16 18 }
17 19
18 20 .author-avatar {
@@ -59,7 +61,7 @@
59 61 font-size: 2.5rem;
60 62 font-weight: normal;
61 63 line-height: 1.2;
62 - margin-bottom: 1rem;
64 + margin-bottom: var(--gap-section);
63 65 color: var(--detail);
64 66 text-align: left;
65 67 }
@@ -69,7 +71,7 @@
69 71 font-family: var(--font-mono);
70 72 font-size: 0.9375rem;
71 73 color: var(--text-muted);
72 - margin-bottom: 2.5rem;
74 + margin-bottom: var(--gap-page);
73 75 }
74 76
75 77 .media-series a {
@@ -86,7 +88,7 @@
86 88 background: var(--surface-muted);
87 89 aspect-ratio: 1;
88 90 max-width: 400px;
89 - margin: 0 auto 2rem;
91 + margin: 0 auto var(--gap-page);
90 92 display: flex;
91 93 align-items: center;
92 94 justify-content: center;
@@ -103,7 +105,7 @@
103 105 /* Video display */
104 106 .video-display {
105 107 max-width: 100%;
106 - margin: 0 auto 2rem;
108 + margin: 0 auto var(--gap-page);
107 109 background: var(--detail);
108 110 }
109 111
@@ -121,15 +123,15 @@
121 123 /* Player controls */
122 124 .media-player {
123 125 background: var(--light-background);
124 - padding: 1.5rem;
125 - margin-bottom: 2.5rem;
126 + padding: var(--gap-pane);
127 + margin-bottom: var(--gap-page);
126 128 }
127 129
128 130 .player-controls {
129 131 display: flex;
130 132 align-items: center;
131 - gap: 1rem;
132 - margin-bottom: 1rem;
133 + gap: var(--gap-section);
134 + margin-bottom: var(--gap-section);
133 135 }
134 136
135 137 .play-button {
@@ -162,7 +164,7 @@
162 164 border-radius: 3px;
163 165 overflow: hidden;
164 166 cursor: pointer;
165 - margin-bottom: 0.5rem;
167 + margin-bottom: var(--gap-peer);
166 168 position: relative;
167 169 }
168 170
@@ -186,7 +188,7 @@
186 188 display: flex;
187 189 justify-content: space-between;
188 190 align-items: center;
189 - padding-top: 1rem;
191 + padding-top: var(--gap-section);
190 192 border-top: 1px solid var(--border);
191 193 }
192 194
@@ -195,13 +197,13 @@
195 197 font-size: 0.875rem;
196 198 display: flex;
197 199 align-items: center;
198 - gap: 0.5rem;
200 + gap: var(--gap-peer);
199 201 }
200 202
201 203 .speed-button {
202 204 background: var(--surface-muted);
203 205 border: none;
204 - padding: 0.375rem 0.75rem;
206 + padding: var(--gap-peer) var(--gap-section);
205 207 font-family: var(--font-mono);
206 208 font-size: 0.8125rem;
207 209 cursor: pointer;
@@ -220,7 +222,7 @@
220 222 .volume-control {
221 223 display: flex;
222 224 align-items: center;
223 - gap: 0.5rem;
225 + gap: var(--gap-peer);
224 226 }
225 227
226 228 .volume-icon {
@@ -259,25 +261,25 @@
259 261 font-family: var(--font-body);
260 262 font-size: 1.125rem;
261 263 line-height: 1.9;
262 - margin-bottom: 2rem;
264 + margin-bottom: var(--gap-page);
263 265 }
264 266
265 267 .media-description p {
266 - margin-bottom: 1.5rem;
268 + margin-bottom: var(--gap-pane);
267 269 }
268 270
269 271 /* Chapters */
270 272 .chapters {
271 273 background: var(--light-background);
272 - padding: 1.5rem;
273 - margin-bottom: 2rem;
274 + padding: var(--gap-pane);
275 + margin-bottom: var(--gap-page);
274 276 }
275 277
276 278 .chapters h3 {
277 279 font-family: var(--font-mono);
278 280 font-size: 1rem;
279 281 font-weight: normal;
280 - margin-bottom: 1rem;
282 + margin-bottom: var(--gap-section);
281 283 color: var(--detail);
282 284 }
283 285
@@ -288,7 +290,7 @@
288 290 .chapter-item {
289 291 display: flex;
290 292 justify-content: space-between;
291 - padding: 0.75rem 0;
293 + padding: var(--gap-section) 0;
292 294 border-bottom: 1px solid var(--border);
293 295 cursor: pointer;
294 296 transition: background 0.2s ease;
@@ -300,9 +302,11 @@
300 302
301 303 .chapter-item:hover {
302 304 background: var(--surface-muted);
303 - margin: 0 -1.5rem;
304 - padding-left: 1.5rem;
305 - padding-right: 1.5rem;
305 + /* The bleed and the inset must stay equal or the row shifts on hover,
306 + so both sides read the same token. */
307 + margin: 0 calc(var(--gap-pane) * -1);
308 + padding-left: var(--gap-pane);
309 + padding-right: var(--gap-pane);
306 310 }
307 311
308 312 .chapter-title {
@@ -319,10 +323,10 @@
319 323 /* Tags */
320 324 .media-tags {
321 325 display: flex;
322 - gap: 0.5rem;
326 + gap: var(--gap-peer);
323 327 flex-wrap: wrap;
324 - margin-top: 2rem;
325 - padding-top: 2rem;
328 + margin-top: var(--gap-page);
329 + padding-top: var(--gap-page);
326 330 border-top: 1px solid var(--border);
327 331 }
328 332
@@ -330,7 +334,7 @@
330 334 font-family: var(--font-mono);
331 335 background: var(--surface-muted);
332 336 color: var(--detail);
333 - padding: 0.375rem 0.75rem;
337 + padding: var(--gap-peer) var(--gap-section);
334 338 font-size: 0.8125rem;
335 339 }
336 340
@@ -338,7 +342,7 @@
338 342 .media-player-footer {
339 343 font-family: var(--font-mono);
340 344 text-align: center;
341 - padding: 2rem;
345 + padding: var(--gap-page);
342 346 font-size: 0.875rem;
343 347 color: var(--text-muted);
344 348 border-top: 1px solid var(--border);
@@ -364,11 +368,11 @@
364 368 font-size: 0.8125rem;
365 369 background: var(--surface-muted);
366 370 border: 1px solid var(--border);
367 - padding: 0.375rem 0.75rem;
371 + padding: var(--gap-peer) var(--gap-section);
368 372 cursor: pointer;
369 373 color: var(--detail);
370 374 display: none;
371 - margin-top: 0.5rem;
375 + margin-top: var(--gap-peer);
372 376 }
373 377
374 378 .skip-insertion:hover {
@@ -382,7 +386,7 @@
382 386 color: var(--text-muted);
383 387 font-style: italic;
384 388 display: none;
385 - margin-top: 0.25rem;
389 + margin-top: var(--gap-bound);
386 390 }
387 391
388 392 /* Responsive */
@@ -397,7 +401,7 @@
397 401
398 402 .player-secondary {
399 403 flex-direction: column;
400 - gap: 1rem;
404 + gap: var(--gap-section);
401 405 align-items: flex-start;
402 406 }
403 407 }
@@ -4,20 +4,20 @@
4 4 display: flex;
5 5 max-width: 1100px;
6 6 margin: 0 auto;
7 - gap: 2rem;
7 + gap: var(--gap-page);
8 8 min-height: 60vh;
9 9 }
10 10
11 11 .wizard-sidebar {
12 12 width: 220px;
13 13 flex-shrink: 0;
14 - padding-top: 0.5rem;
14 + padding-top: var(--gap-peer);
15 15 }
16 16
17 17 .wizard-sidebar h2 {
18 18 font-family: var(--font-heading); font-weight: bold;
19 19 font-size: 1.3rem;
20 - margin-bottom: 1.5rem;
20 + margin-bottom: var(--gap-pane);
21 21 }
22 22
23 23 .wizard-content {
@@ -36,8 +36,8 @@
36 36 .wizard-step-indicator {
37 37 display: flex;
38 38 align-items: center;
39 - gap: 0.6rem;
40 - padding: 0.5rem 0;
39 + gap: var(--gap-group);
40 + padding: var(--gap-peer) 0;
41 41 font-size: 0.9rem;
42 42 color: var(--text-muted);
43 43 position: relative;
@@ -96,20 +96,20 @@
96 96
97 97 .wizard-step {
98 98 background: var(--light-background);
99 - padding: 2rem;
99 + padding: var(--gap-page);
100 100 border-radius: 4px;
101 101 }
102 102
103 103 .wizard-step h2 {
104 104 font-family: var(--font-heading); font-weight: bold;
105 105 font-size: 1.6rem;
106 - margin-bottom: 0.25rem;
106 + margin-bottom: var(--gap-bound);
107 107 }
108 108
109 109 .step-description {
110 110 color: var(--text-muted);
111 111 font-size: 0.9rem;
112 - margin-bottom: 1.5rem;
112 + margin-bottom: var(--gap-pane);
113 113 }
114 114
115 115 /* Wizard Actions (button row) */
@@ -117,9 +117,9 @@
117 117 .wizard-actions {
118 118 display: flex;
119 119 align-items: center;
120 - gap: 0.75rem;
121 - margin-top: 2rem;
122 - padding-top: 1.5rem;
120 + gap: var(--gap-section);
121 + margin-top: var(--gap-page);
122 + padding-top: var(--gap-pane);
123 123 border-top: 1px solid var(--border);
124 124 flex-wrap: wrap;
125 125 }
@@ -133,8 +133,8 @@
133 133 .type-grid {
134 134 display: grid;
135 135 grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
136 - gap: 0.75rem;
137 - margin-top: 0.5rem;
136 + gap: var(--gap-section);
137 + margin-top: var(--gap-peer);
138 138 }
139 139
140 140 .type-grid-large {
@@ -171,7 +171,7 @@
171 171 }
172 172
173 173 .suggestion-item {
174 - padding: 0.5rem 0.75rem;
174 + padding: var(--gap-peer) var(--gap-section);
175 175 cursor: pointer;
176 176 font-size: 0.9rem;
177 177 }
@@ -193,7 +193,7 @@
193 193 .tier-row {
194 194 display: flex;
195 195 justify-content: space-between;
196 - padding: 0.4rem 0;
196 + padding: var(--gap-peer) 0;
197 197 font-size: 0.9rem;
198 198 border-bottom: 1px solid var(--border);
199 199 }
@@ -201,9 +201,9 @@
201 201 .tier-form-row {
202 202 display: grid;
203 203 grid-template-columns: 1fr 1fr 2fr;
204 - gap: 0.75rem;
205 - margin-top: 0.5rem;
206 - padding: 0.75rem;
204 + gap: var(--gap-section);
205 + margin-top: var(--gap-peer);
206 + padding: var(--gap-section);
207 207 background: var(--surface-alt);
208 208 border-radius: 4px;
209 209 }
@@ -213,38 +213,38 @@
213 213 .pricing-cards {
214 214 display: grid;
215 215 grid-template-columns: repeat(3, 1fr);
216 - gap: 1rem;
217 - margin-bottom: 1.5rem;
216 + gap: var(--gap-section);
217 + margin-bottom: var(--gap-pane);
218 218 }
219 219
220 220 /* (`.pricing-card`, `.content-choice-card`, and the `.is-disabled` modifier
221 221 all live in style.css under the canonical `.card--selectable` recipe.) */
222 222 .pricing-fields {
223 - margin-top: 1rem;
223 + margin-top: var(--gap-section);
224 224 }
225 225
226 226 .content-choice-cards {
227 227 display: grid;
228 228 grid-template-columns: 1fr 1fr;
229 - gap: 1rem;
230 - margin-bottom: 1.5rem;
229 + gap: var(--gap-section);
230 + margin-bottom: var(--gap-pane);
231 231 }
232 232
233 233 /* Preview Summary */
234 234
235 235 .preview-summary {
236 - margin-bottom: 1.5rem;
236 + margin-bottom: var(--gap-pane);
237 237 }
238 238
239 239 .preview-row {
240 240 display: flex;
241 - padding: 0.6rem 0;
241 + padding: var(--gap-group) 0;
242 242 border-bottom: 1px solid var(--border);
243 243 font-size: 0.9rem;
244 244 }
245 245
246 246 .preview-row.indent {
247 - padding-left: 1.5rem;
247 + padding-left: var(--gap-pane);
248 248 }
249 249
250 250 .preview-label {
@@ -261,13 +261,13 @@
261 261 /* Preview Checklist */
262 262
263 263 .preview-checklist {
264 - margin-bottom: 1.5rem;
264 + margin-bottom: var(--gap-pane);
265 265 }
266 266
267 267 .preview-checklist h3 {
268 268 font-family: var(--font-mono);
269 269 font-size: 0.95rem;
270 - margin-bottom: 0.5rem;
270 + margin-bottom: var(--gap-peer);
271 271 }
272 272
273 273 .preview-checklist ul {
@@ -277,7 +277,9 @@
277 277 }
278 278
279 279 .preview-checklist li {
280 - padding: 0.3rem 0;
280 + padding: var(--gap-bound) 0;
281 + /* Reserves the label column for the Done/Todo pseudo-element. A fixed
282 + column width, not a relationship, so it stays off the gap scale. */
281 283 padding-left: 3.5rem;
282 284 position: relative;
283 285 font-size: 0.9rem;
@@ -308,7 +310,7 @@
308 310 .upload-area {
309 311 border: 2px dashed var(--border);
310 312 border-radius: 4px;
311 - padding: 2rem;
313 + padding: var(--gap-page);
312 314 text-align: center;
313 315 cursor: pointer;
314 316 transition: border-color 0.15s;
@@ -325,7 +327,7 @@
325 327 .project-image-dropzone {
326 328 border: 2px dashed var(--border);
327 329 border-radius: 4px;
328 - padding: 2rem;
330 + padding: var(--gap-page);
329 331 text-align: center;
330 332 cursor: pointer;
331 333 transition: border-color 0.15s;
@@ -345,7 +347,7 @@
345 347 .project-image-upload {
346 348 display: flex;
347 349 flex-direction: column;
348 - gap: 0.75rem;
350 + gap: var(--gap-section);
349 351 max-width: 300px;
350 352 }
351 353
@@ -365,7 +367,7 @@
365 367 display: flex;
366 368 flex-wrap: wrap;
367 369 align-items: center;
368 - gap: 0.5rem;
370 + gap: var(--gap-peer);
369 371 }
370 372
371 373 .upload-progress-inline .progress-bar-container {
@@ -385,7 +387,7 @@
385 387 .upload-error-inline {
386 388 font-size: 0.85rem;
387 389 color: var(--danger, #c0392b);
388 - padding: 0.5rem 0.75rem;
390 + padding: var(--gap-peer) var(--gap-section);
389 391 background: rgba(192, 57, 43, 0.08);
390 392 border-radius: 4px;
391 393 }
@@ -394,9 +396,9 @@
394 396
395 397 .project-card-preview {
396 398 display: flex;
397 - gap: 1rem;
399 + gap: var(--gap-section);
398 400 align-items: center;
399 - padding: 1rem;
401 + padding: var(--gap-section);
400 402 background: var(--background);
401 403 border: 1px solid var(--border);
402 404 border-radius: 4px;
@@ -430,7 +432,7 @@
430 432
431 433 .distribution-section {
432 434 background: var(--background);
433 - padding: 1.25rem;
435 + padding: var(--gap-section);
434 436 border: 1px solid var(--border);
435 437 border-radius: 4px;
436 438 }
@@ -438,13 +440,13 @@
438 440 .distribution-section h3 {
439 441 font-family: var(--font-mono);
440 442 font-size: 0.95rem;
441 - margin-bottom: 0.5rem;
443 + margin-bottom: var(--gap-peer);
442 444 }
443 445
444 446 .checkbox-label {
445 447 display: flex;
446 448 align-items: center;
447 - gap: 0.5rem;
449 + gap: var(--gap-peer);
448 450 cursor: pointer;
449 451 font-size: 0.9rem;
450 452 }
@@ -468,7 +470,7 @@
468 470
469 471 .info-box {
470 472 background: var(--surface-alt);
471 - padding: 1rem;
473 + padding: var(--gap-section);
472 474 border-radius: 4px;
473 475 font-size: 0.9rem;
474 476 }
@@ -486,13 +488,13 @@
486 488
487 489 .wizard-steps {
488 490 display: flex;
489 - gap: 0.25rem;
491 + gap: var(--gap-bound);
490 492 overflow-x: auto;
491 493 }
492 494
493 495 .wizard-step-indicator {
494 496 flex-direction: column;
495 - gap: 0.2rem;
497 + gap: var(--gap-bound);
496 498 font-size: 0.75rem;
497 499 min-width: 0;
498 500 }
@@ -520,7 +522,7 @@
520 522
521 523 .preview-row {
522 524 flex-direction: column;
523 - gap: 0.25rem;
525 + gap: var(--gap-bound);
524 526 }
525 527
526 528 .preview-label {
@@ -541,7 +543,7 @@
541 543
542 544 /* Intro paragraph below .step-description that explains the concept. */
543 545 .wizard-step .form-hint {
544 - margin-bottom: 1.5rem;
546 + margin-bottom: var(--gap-pane);
545 547 }
546 548
547 549 /* "Checking..." style spinner shown next to async-validated inputs. */
@@ -550,20 +552,20 @@
550 552 }
551 553
552 554 /* Spacing helpers for hints that sit just above a control group. */
553 - .wizard-hint-gap-sm { margin-bottom: 0.5rem; }
554 - .wizard-hint-gap-md { margin-bottom: 0.75rem; }
555 + .wizard-hint-gap-sm { margin-bottom: var(--gap-peer); }
556 + .wizard-hint-gap-md { margin-bottom: var(--gap-section); }
555 557
556 558 /* Vertical radio group for AI disclosure and similar one-of-many pickers. */
557 559 .wizard-radio-group {
558 560 display: flex;
559 561 flex-direction: column;
560 - gap: 0.5rem;
562 + gap: var(--gap-peer);
561 563 }
562 564
563 565 .wizard-radio-option {
564 566 display: flex;
565 567 align-items: center;
566 - gap: 0.5rem;
568 + gap: var(--gap-peer);
567 569 cursor: pointer;
568 570 }
569 571
@@ -583,23 +585,23 @@
583 585 /* Stripe-step layout. */
584 586 .stripe-connect-box {
585 587 background: var(--surface-muted);
586 - padding: var(--space-4);
588 + padding: var(--gap-section);
587 589 text-align: center;
588 - margin: var(--space-3) 0;
590 + margin: var(--gap-section) 0;
589 591 }
590 592
591 593 .stripe-connect-box .stripe-intro {
592 - margin: var(--space-3) 0;
594 + margin: var(--gap-section) 0;
593 595 opacity: 0.8;
594 596 }
595 597
596 598 .stripe-connect-actions {
597 - margin-top: var(--space-4);
599 + margin-top: var(--gap-section);
598 600 }
599 601
600 602 .stripe-connect-cta {
601 603 display: inline-block;
602 - padding: 0.75rem 1.5rem;
604 + padding: var(--gap-section) var(--gap-pane);
603 605 text-decoration: none;
604 606 background: var(--stripe);
605 607 border: none;
@@ -613,22 +615,22 @@
613 615 .stripe-connect-note {
614 616 font-size: 0.8rem;
615 617 opacity: 0.5;
616 - margin-top: var(--space-3);
618 + margin-top: var(--gap-section);
617 619 }
618 620
619 621 .stripe-connect-note-secondary {
620 622 font-size: 0.8rem;
621 623 opacity: 0.7;
622 - margin-top: var(--space-2);
624 + margin-top: var(--gap-peer);
623 625 }
624 626
625 627 .stripe-benefits {
626 628 text-align: left;
627 - margin-top: var(--space-3);
629 + margin-top: var(--gap-section);
628 630 }
629 631
630 632 .benefit-item {
631 - padding: 0.4rem 0 0.4rem 1.5rem;
633 + padding: var(--gap-peer) 0 var(--gap-peer) var(--gap-pane);
632 634 position: relative;
633 635 font-size: 0.9rem;
634 636 }