designlang 7.0.0 → 7.1.0

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.
Files changed (64) hide show
  1. package/.vercel/README.txt +11 -0
  2. package/.vercel/project.json +1 -0
  3. package/CHANGELOG.md +15 -0
  4. package/CONTRIBUTING.md +25 -0
  5. package/README.md +9 -7
  6. package/bin/design-extract.js +18 -1
  7. package/chrome-extension/README.md +41 -0
  8. package/chrome-extension/icons/favicon.svg +7 -0
  9. package/chrome-extension/icons/icon-128.png +0 -0
  10. package/chrome-extension/icons/icon-16.png +0 -0
  11. package/chrome-extension/icons/icon-32.png +0 -0
  12. package/chrome-extension/icons/icon-48.png +0 -0
  13. package/chrome-extension/manifest.json +26 -0
  14. package/chrome-extension/popup.html +167 -0
  15. package/chrome-extension/popup.js +59 -0
  16. package/docs/superpowers/specs/2026-04-18-website-redesign-design.md +120 -0
  17. package/docs/superpowers/specs/2026-04-19-designlang-v7-1-design.md +111 -0
  18. package/package.json +1 -1
  19. package/src/config.js +3 -0
  20. package/src/crawler.js +20 -2
  21. package/src/utils-cookies.js +73 -0
  22. package/tests/cookies.test.js +98 -0
  23. package/website/app/api/extract/route.js +216 -56
  24. package/website/app/components/A11ySlider.js +369 -0
  25. package/website/app/components/Comparison.js +286 -0
  26. package/website/app/components/CssHealth.js +243 -0
  27. package/website/app/components/HeroExtractor.js +455 -0
  28. package/website/app/components/Marginalia.js +3 -0
  29. package/website/app/components/McpSection.js +223 -0
  30. package/website/app/components/PlatformTabs.js +250 -0
  31. package/website/app/components/RegionsComponents.js +429 -0
  32. package/website/app/components/Rule.js +13 -0
  33. package/website/app/components/Specimens.js +237 -0
  34. package/website/app/components/StructuredData.js +144 -0
  35. package/website/app/components/TokenBrowser.js +344 -0
  36. package/website/app/components/token-browser-sample.js +65 -0
  37. package/website/app/globals.css +415 -633
  38. package/website/app/icon.svg +7 -0
  39. package/website/app/layout.js +113 -6
  40. package/website/app/opengraph-image.js +170 -0
  41. package/website/app/page.js +325 -148
  42. package/website/app/robots.js +15 -0
  43. package/website/app/seo-config.js +82 -0
  44. package/website/app/sitemap.js +18 -0
  45. package/website/lib/cache.js +73 -0
  46. package/website/lib/rate-limit.js +30 -0
  47. package/website/lib/rate-limit.test.js +55 -0
  48. package/website/lib/specimens.json +86 -0
  49. package/website/lib/token-helpers.js +70 -0
  50. package/website/lib/url-safety.js +103 -0
  51. package/website/lib/url-safety.test.js +116 -0
  52. package/website/lib/zip-files.js +15 -0
  53. package/website/package-lock.json +85 -0
  54. package/website/package.json +1 -0
  55. package/website/public/favicon.svg +7 -0
  56. package/website/public/logo-specimen.svg +76 -0
  57. package/website/public/mark.svg +12 -0
  58. package/website/public/site.webmanifest +13 -0
  59. package/website/app/favicon.ico +0 -0
  60. package/website/public/file.svg +0 -1
  61. package/website/public/globe.svg +0 -1
  62. package/website/public/next.svg +0 -1
  63. package/website/public/vercel.svg +0 -1
  64. package/website/public/window.svg +0 -1
@@ -1,723 +1,505 @@
1
+ /* ─────────────────────────────────────────────────────────────
2
+ designlang website — foundation
3
+ Direction: Live Design DNA. Paper-first, one accent.
4
+ ───────────────────────────────────────────────────────────── */
5
+
1
6
  :root {
2
- --red: #ffffff;
3
- --black: #0a0a0a;
4
- --white: #ffffff;
5
- --cream: #ffffff;
6
- --yellow: #ffffff;
7
- --gray: #333;
7
+ /* Palette */
8
+ --paper: #f3f1ea;
9
+ --paper-2: #ece8dd;
10
+ --paper-3: #d8d3c5;
11
+ --ink: #0a0908;
12
+ --ink-2: #403c34;
13
+ --ink-3: #8b8778;
14
+ --accent: #ff4800;
15
+
16
+ /* Type */
17
+ --font-body: var(--font-body), -apple-system, 'Segoe UI', system-ui, sans-serif;
18
+ --font-mono: var(--font-mono), 'SF Mono', ui-monospace, Menlo, monospace;
19
+ --font-display: var(--font-display), Georgia, serif;
20
+
21
+ /* Rhythm */
22
+ --r1: 4px;
23
+ --r2: 8px;
24
+ --r3: 12px;
25
+ --r4: 16px;
26
+ --r5: 24px;
27
+ --r6: 32px;
28
+ --r7: 48px;
29
+ --r8: 64px;
30
+ --r9: 96px;
31
+ --r10: 144px;
32
+
33
+ /* Grid */
34
+ --page-max: 1440px;
35
+ --page-pad-x: clamp(20px, 4vw, 56px);
36
+ --col-count: 12;
37
+ --col-gap: 24px;
38
+
39
+ /* Hairline */
40
+ --hair: 1px solid var(--ink);
41
+ --hair-soft: 1px solid var(--ink-3);
42
+ }
43
+
44
+ * {
45
+ margin: 0;
46
+ padding: 0;
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ html {
51
+ background: var(--paper);
52
+ color: var(--ink);
53
+ color-scheme: light;
54
+ font-family: var(--font-body);
55
+ font-size: 16px;
56
+ line-height: 1.45;
57
+ -webkit-font-smoothing: antialiased;
58
+ text-rendering: optimizeLegibility;
59
+ scroll-behavior: smooth;
8
60
  }
9
61
 
10
- * { margin: 0; padding: 0; box-sizing: border-box; }
11
-
12
- html { scroll-behavior: smooth; }
13
-
14
62
  body {
15
- background: var(--black);
16
- color: var(--white);
17
- font-family: 'Inter', sans-serif;
63
+ background: var(--paper);
64
+ min-height: 100dvh;
18
65
  overflow-x: hidden;
19
- cursor: crosshair;
20
- }
21
-
22
- ::selection {
23
- background: var(--red);
24
- color: var(--black);
25
- }
26
-
27
- a { color: inherit; }
28
-
29
- /* ── HERO ── */
30
- .hero {
31
- min-height: 100vh;
32
- display: flex;
33
- flex-direction: column;
34
- justify-content: center;
35
- align-items: center;
36
- position: relative;
37
- border-bottom: 4px solid var(--red);
38
- overflow: hidden;
39
- }
40
-
41
- .hero::before {
42
- content: 'DESIGNLANG DESIGNLANG DESIGNLANG DESIGNLANG DESIGNLANG ';
43
- position: absolute;
44
- top: 0;
45
- left: 0;
46
- width: 300%;
47
- font-family: 'Unbounded', sans-serif;
48
- font-size: 14vw;
49
- font-weight: 900;
50
- color: rgba(255, 255, 255, 0.03);
51
- white-space: nowrap;
52
- pointer-events: none;
53
- animation: scroll-text 20s linear infinite;
54
- line-height: 1;
55
- }
56
-
57
- @keyframes scroll-text {
58
- 0% { transform: translateX(0); }
59
- 100% { transform: translateX(-33.33%); }
60
66
  }
61
67
 
62
- .hero-title {
63
- font-family: 'Unbounded', sans-serif;
64
- font-size: clamp(4rem, 12vw, 10rem);
65
- font-weight: 900;
66
- text-transform: uppercase;
67
- letter-spacing: -0.04em;
68
- line-height: 0.9;
69
- text-align: center;
70
- position: relative;
71
- z-index: 1;
72
- }
73
-
74
- .hero-title span {
75
- display: block;
76
- color: var(--red);
77
- font-size: 0.4em;
78
- letter-spacing: 0.2em;
79
- margin-top: 16px;
80
- }
81
-
82
- .hero-sub {
83
- font-family: 'JetBrains Mono', monospace;
84
- font-size: clamp(14px, 1.5vw, 18px);
85
- color: #888;
86
- margin-top: 32px;
87
- text-align: center;
88
- max-width: 600px;
89
- line-height: 1.6;
90
- z-index: 1;
91
- }
92
-
93
- .hero-cmd {
94
- margin-top: 48px;
95
- background: #111;
96
- border: 2px solid var(--red);
97
- padding: 20px 40px;
98
- font-family: 'JetBrains Mono', monospace;
99
- font-size: clamp(16px, 2vw, 22px);
100
- color: var(--yellow);
101
- position: relative;
102
- z-index: 1;
103
- transition: all 0.2s;
68
+ a {
69
+ color: inherit;
104
70
  text-decoration: none;
105
- display: inline-block;
106
- }
107
-
108
- .hero-cmd:hover {
109
- background: var(--red);
110
- color: var(--black);
111
- transform: translate(-4px, -4px);
112
- box-shadow: 4px 4px 0 var(--yellow);
113
- }
114
-
115
- .hero-cmd::before {
116
- content: '$ ';
117
- color: var(--red);
118
- }
119
-
120
- .hero-cmd:hover::before {
121
- color: var(--black);
122
- }
123
-
124
- .scroll-hint {
125
- position: absolute;
126
- bottom: 40px;
127
- font-family: 'JetBrains Mono', monospace;
128
- font-size: 12px;
129
- color: #444;
130
- letter-spacing: 0.3em;
131
- text-transform: uppercase;
132
- animation: pulse 2s ease-in-out infinite;
133
- }
134
-
135
- @keyframes pulse {
136
- 0%, 100% { opacity: 0.3; }
137
- 50% { opacity: 1; }
138
- }
139
-
140
- /* ── SECTION LAYOUT ── */
141
- section {
142
- padding: 100px 24px;
143
- max-width: 1400px;
144
- margin: 0 auto;
145
- }
146
-
147
- .section-red {
148
- background: var(--red);
149
- color: var(--black);
150
- max-width: 100%;
151
- padding: 80px 24px;
152
- }
153
-
154
- .section-cream {
155
- background: var(--cream);
156
- color: var(--black);
157
- max-width: 100%;
158
- padding: 80px 24px;
159
- }
160
-
161
- .section-inner {
162
- max-width: 1400px;
163
- margin: 0 auto;
164
- }
165
-
166
- .section-title {
167
- font-family: 'Unbounded', sans-serif;
168
- font-size: clamp(2rem, 5vw, 4rem);
169
- font-weight: 900;
170
- text-transform: uppercase;
171
- letter-spacing: -0.02em;
172
- margin-bottom: 48px;
173
- line-height: 1;
71
+ border-bottom: 1px solid currentColor;
72
+ transition: color 120ms ease, border-color 120ms ease;
174
73
  }
175
74
 
176
- .section-title::after {
177
- content: ' ///';
178
- color: var(--red);
75
+ a:hover {
76
+ color: var(--accent);
179
77
  }
180
78
 
181
- .section-red .section-title::after {
182
- color: var(--black);
183
- }
184
-
185
- .section-cream .section-title::after {
186
- color: var(--red);
187
- }
188
-
189
- /* ── OUTPUT FILES ── */
190
- .files-grid {
191
- display: grid;
192
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
193
- gap: 2px;
194
- }
195
-
196
- .file-card {
197
- background: #111;
198
- border: 2px solid #222;
199
- padding: 28px;
200
- transition: all 0.15s;
201
- position: relative;
202
- overflow: hidden;
203
- }
204
-
205
- .file-card:hover {
206
- border-color: var(--red);
207
- transform: translate(-2px, -2px);
208
- box-shadow: 2px 2px 0 var(--red);
209
- }
210
-
211
- .file-card::before {
212
- content: attr(data-num);
213
- position: absolute;
214
- top: -10px;
215
- right: 10px;
216
- font-family: 'Unbounded', sans-serif;
217
- font-size: 80px;
218
- font-weight: 900;
219
- color: rgba(255, 255, 255, 0.06);
220
- line-height: 1;
221
- }
222
-
223
- .file-name {
224
- font-family: 'JetBrains Mono', monospace;
225
- font-size: 15px;
226
- color: var(--yellow);
227
- margin-bottom: 8px;
228
- }
229
-
230
- .file-desc {
231
- font-size: 14px;
232
- color: #888;
233
- line-height: 1.5;
234
- }
235
-
236
- /* ── FEATURES ── */
237
- .features-list {
238
- display: grid;
239
- grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
240
- gap: 0;
241
- }
242
-
243
- .feature {
244
- padding: 32px;
245
- border: 1px solid #222;
246
- transition: all 0.15s;
247
- }
248
-
249
- .feature:hover {
250
- background: #111;
251
- border-color: var(--red);
252
- }
253
-
254
- .feature-name {
255
- font-family: 'Unbounded', sans-serif;
256
- font-size: 18px;
257
- font-weight: 700;
258
- text-transform: uppercase;
259
- margin-bottom: 8px;
260
- }
261
-
262
- .feature-cmd {
263
- font-family: 'JetBrains Mono', monospace;
264
- font-size: 13px;
265
- color: var(--yellow);
266
- margin-bottom: 12px;
267
- }
268
-
269
- .feature-desc {
270
- font-size: 14px;
271
- color: #888;
272
- line-height: 1.5;
273
- }
274
-
275
- /* ── SCORE DEMO ── */
276
- .score-demo {
277
- background: #111;
278
- border: 2px solid var(--red);
279
- padding: 40px;
280
- font-family: 'JetBrains Mono', monospace;
281
- font-size: 14px;
282
- line-height: 2;
283
- overflow-x: auto;
284
- color: #ccc;
285
- }
286
-
287
- .score-grade {
288
- font-family: 'Unbounded', sans-serif;
289
- font-size: 64px;
290
- font-weight: 900;
291
- color: var(--red);
292
- display: inline;
293
- }
294
-
295
- /* ── COMMANDS ── */
296
- .commands-grid {
297
- display: grid;
298
- grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
299
- gap: 2px;
300
- }
301
-
302
- .command-card {
303
- background: var(--black);
304
- padding: 32px;
305
- border: 2px solid rgba(255,255,255,0.3);
306
- transition: all 0.15s;
79
+ button {
80
+ font: inherit;
81
+ color: inherit;
82
+ background: none;
83
+ border: 0;
84
+ cursor: pointer;
307
85
  }
308
86
 
309
- .command-card:hover {
310
- border-color: var(--red);
311
- background: rgba(255, 255, 255, 0.05);
87
+ input, textarea, select {
88
+ font: inherit;
89
+ color: inherit;
90
+ background: transparent;
91
+ border: 0;
92
+ outline: 0;
312
93
  }
313
94
 
314
- .command-name {
315
- font-family: 'JetBrains Mono', monospace;
316
- font-size: 18px;
317
- font-weight: 700;
318
- color: var(--yellow);
319
- margin-bottom: 12px;
95
+ ::selection {
96
+ background: var(--ink);
97
+ color: var(--paper);
320
98
  }
321
99
 
322
- .command-desc {
323
- font-size: 14px;
324
- color: #ccc;
325
- line-height: 1.5;
326
- }
100
+ img, svg { display: block; max-width: 100%; }
327
101
 
328
- /* ── STATS STRIP ── */
329
- .stats-strip {
330
- display: flex;
331
- flex-wrap: wrap;
332
- border-top: 2px solid var(--red);
333
- border-bottom: 2px solid var(--red);
334
- }
102
+ /* ── Typography ─────────────────────────────────────────────── */
335
103
 
336
- .stat {
337
- flex: 1;
338
- min-width: 150px;
339
- padding: 32px 24px;
340
- text-align: center;
341
- border-right: 1px solid #222;
104
+ .display {
105
+ font-family: var(--font-display);
106
+ font-weight: 400;
107
+ letter-spacing: -0.03em;
108
+ line-height: 0.92;
109
+ font-variation-settings: 'opsz' 144, 'SOFT' 30;
342
110
  }
343
111
 
344
- .stat:last-child { border-right: none; }
345
-
346
- .stat-value {
347
- font-family: 'Unbounded', sans-serif;
348
- font-size: 48px;
349
- font-weight: 900;
350
- color: var(--red);
351
- line-height: 1;
112
+ .mono {
113
+ font-family: var(--font-mono);
114
+ font-feature-settings: 'zero' 1, 'ss01' 1;
352
115
  }
353
116
 
354
- .stat-label {
355
- font-family: 'JetBrains Mono', monospace;
117
+ .eyebrow {
118
+ font-family: var(--font-mono);
356
119
  font-size: 11px;
357
- color: #666;
120
+ letter-spacing: 0.14em;
358
121
  text-transform: uppercase;
359
- letter-spacing: 0.15em;
360
- margin-top: 8px;
361
- }
362
-
363
- /* ── FOOTER ── */
364
- footer {
365
- padding: 60px 24px;
366
- text-align: center;
367
- border-top: 4px solid var(--red);
122
+ color: var(--ink-2);
368
123
  }
369
124
 
370
- footer a {
371
- text-decoration: underline;
372
- text-underline-offset: 4px;
373
- }
374
-
375
- footer a:hover {
376
- color: var(--red);
377
- }
378
-
379
- .footer-title {
380
- font-family: 'Unbounded', sans-serif;
381
- font-size: 24px;
382
- font-weight: 900;
125
+ .section-label {
126
+ font-family: var(--font-mono);
127
+ font-size: 12px;
128
+ letter-spacing: 0.14em;
383
129
  text-transform: uppercase;
384
- margin-bottom: 16px;
130
+ color: var(--ink-2);
131
+ display: inline-flex;
132
+ align-items: baseline;
133
+ gap: 10px;
385
134
  }
386
135
 
387
- .footer-links {
388
- display: flex;
389
- gap: 32px;
390
- justify-content: center;
391
- margin-top: 24px;
392
- font-family: 'JetBrains Mono', monospace;
393
- font-size: 14px;
136
+ .section-label::before {
137
+ content: '';
138
+ width: 24px;
139
+ height: 1px;
140
+ background: var(--ink);
141
+ display: inline-block;
142
+ transform: translateY(-4px);
394
143
  }
395
144
 
396
- .footer-copy {
397
- margin-top: 48px;
398
- font-size: 12px;
399
- color: #444;
400
- }
145
+ .prose p { max-width: 62ch; }
146
+ .prose p + p { margin-top: 1em; }
401
147
 
402
- /* ── MARQUEE ── */
403
- .marquee {
404
- overflow: hidden;
405
- white-space: nowrap;
406
- border-top: 2px solid #222;
407
- border-bottom: 2px solid #222;
408
- padding: 12px 0;
409
- font-family: 'JetBrains Mono', monospace;
410
- font-size: 13px;
411
- color: #444;
412
- }
148
+ /* ── Layout primitives ──────────────────────────────────────── */
413
149
 
414
- .marquee-inner {
415
- display: inline-block;
416
- animation: marquee 30s linear infinite;
150
+ .page {
151
+ max-width: var(--page-max);
152
+ margin: 0 auto;
153
+ padding-inline: var(--page-pad-x);
417
154
  }
418
155
 
419
- @keyframes marquee {
420
- 0% { transform: translateX(0); }
421
- 100% { transform: translateX(-50%); }
422
- }
156
+ .stack-lg > * + * { margin-top: var(--r8); }
157
+ .stack-md > * + * { margin-top: var(--r5); }
158
+ .stack-sm > * + * { margin-top: var(--r3); }
423
159
 
424
- /* ── EXTRACTOR ── */
425
- .extractor {
426
- max-width: 800px;
160
+ .grid-12 {
161
+ display: grid;
162
+ grid-template-columns: repeat(var(--col-count), minmax(0, 1fr));
163
+ gap: var(--col-gap);
427
164
  }
428
165
 
429
- .extractor-form {
166
+ /* Rule — a hairline with optional section label inline at left edge. */
167
+ .rule {
168
+ position: relative;
430
169
  display: flex;
431
- gap: 0;
170
+ align-items: baseline;
171
+ gap: var(--r4);
172
+ padding-block: var(--r4);
432
173
  }
433
174
 
434
- .extractor-input {
435
- flex: 1;
436
- background: var(--black);
437
- border: 2px solid var(--black);
438
- border-right: none;
439
- padding: 16px 20px;
440
- font-family: 'JetBrains Mono', monospace;
441
- font-size: 16px;
442
- color: var(--yellow);
443
- outline: none;
444
- }
445
-
446
- .extractor-input::placeholder {
447
- color: #555;
175
+ .rule-line {
176
+ flex: 1 1 auto;
177
+ height: 1px;
178
+ background: var(--ink);
448
179
  }
449
180
 
450
- .extractor-input:focus {
451
- border-color: var(--yellow);
452
- }
453
-
454
- .extractor-btn {
455
- background: var(--black);
456
- border: 2px solid var(--black);
457
- padding: 16px 32px;
458
- font-family: 'Unbounded', sans-serif;
459
- font-size: 14px;
460
- font-weight: 700;
181
+ .rule-label {
182
+ font-family: var(--font-mono);
183
+ font-size: 11px;
184
+ letter-spacing: 0.14em;
461
185
  text-transform: uppercase;
462
- color: var(--red);
463
- cursor: pointer;
464
- transition: all 0.15s;
186
+ color: var(--ink);
465
187
  white-space: nowrap;
466
188
  }
467
189
 
468
- .extractor-btn:hover:not(:disabled) {
469
- background: var(--yellow);
470
- color: var(--black);
471
- border-color: var(--yellow);
472
- }
473
-
474
- .extractor-btn:disabled {
475
- opacity: 0.5;
476
- cursor: not-allowed;
190
+ .rule-number {
191
+ color: var(--ink-3);
192
+ margin-right: var(--r2);
477
193
  }
478
194
 
479
- .extractor-loading {
480
- margin-top: 32px;
481
- font-family: 'JetBrains Mono', monospace;
482
- font-size: 14px;
483
- }
484
-
485
- .extractor-loading p {
486
- color: var(--black);
195
+ /* Marginalia — side-column notes; collapse to block on small screens. */
196
+ .with-margin {
197
+ display: grid;
198
+ grid-template-columns: minmax(0, 1fr) minmax(180px, 240px);
199
+ gap: var(--col-gap);
200
+ align-items: start;
487
201
  }
488
202
 
489
- .extractor-loading-sub {
490
- color: #333 !important;
203
+ .marginalia {
204
+ font-family: var(--font-mono);
491
205
  font-size: 12px;
492
- margin-top: 4px;
493
- }
494
-
495
- .extractor-spinner {
496
- width: 24px;
497
- height: 24px;
498
- border: 3px solid var(--black);
499
- border-top-color: transparent;
500
- border-radius: 50%;
501
- animation: spin 0.8s linear infinite;
502
- margin-bottom: 12px;
206
+ line-height: 1.5;
207
+ color: var(--ink-2);
208
+ border-left: var(--hair);
209
+ padding-left: var(--r4);
503
210
  }
504
211
 
505
- @keyframes spin {
506
- to { transform: rotate(360deg); }
507
- }
212
+ .marginalia .foot { color: var(--ink-3); }
213
+ .marginalia code { color: var(--ink); }
508
214
 
509
- .extractor-error {
510
- margin-top: 24px;
511
- background: var(--black);
512
- border: 2px solid var(--yellow);
513
- padding: 16px 20px;
514
- font-family: 'JetBrains Mono', monospace;
515
- font-size: 14px;
516
- color: var(--yellow);
215
+ @media (max-width: 860px) {
216
+ .with-margin {
217
+ grid-template-columns: 1fr;
218
+ }
219
+ .marginalia {
220
+ border-left: 0;
221
+ border-top: var(--hair);
222
+ padding-left: 0;
223
+ padding-top: var(--r3);
224
+ }
517
225
  }
518
226
 
519
- .extractor-error-hint {
520
- margin-top: 12px;
521
- font-size: 12px;
522
- color: #888;
523
- line-height: 1.8;
524
- }
525
-
526
- .extractor-error-hint code {
527
- display: inline-block;
528
- margin-top: 4px;
529
- background: #1a1a1a;
530
- padding: 6px 12px;
531
- color: var(--yellow);
532
- font-size: 13px;
533
- }
227
+ /* ── Controls ───────────────────────────────────────────────── */
534
228
 
535
- .extractor-results {
536
- margin-top: 32px;
537
- background: var(--black);
538
- border: 2px solid var(--black);
539
- }
540
-
541
- .extractor-results-header {
542
- display: flex;
543
- justify-content: space-between;
229
+ .cta {
230
+ display: inline-flex;
544
231
  align-items: center;
545
- padding: 20px 24px;
546
- border-bottom: 1px solid #222;
547
- flex-wrap: wrap;
548
- gap: 12px;
549
- }
550
-
551
- .extractor-results-header h3 {
552
- font-family: 'Unbounded', sans-serif;
553
- font-size: 16px;
554
- font-weight: 700;
555
- color: var(--white);
556
- text-transform: uppercase;
557
- }
558
-
559
- .extractor-download {
560
- background: var(--red);
561
- border: none;
562
- padding: 10px 20px;
563
- font-family: 'JetBrains Mono', monospace;
232
+ gap: 10px;
233
+ padding: 14px 22px 15px;
234
+ background: var(--ink);
235
+ color: var(--paper);
236
+ border: var(--hair);
237
+ box-shadow: 6px 6px 0 var(--accent);
238
+ font-family: var(--font-mono);
564
239
  font-size: 13px;
565
- font-weight: 700;
566
- color: var(--black);
567
- cursor: pointer;
568
- text-transform: uppercase;
569
- transition: all 0.15s;
240
+ letter-spacing: 0.04em;
241
+ transition: transform 120ms ease, box-shadow 120ms ease;
570
242
  }
571
243
 
572
- .extractor-download:hover {
573
- background: var(--yellow);
244
+ .cta:hover {
574
245
  transform: translate(-2px, -2px);
575
- box-shadow: 2px 2px 0 var(--red);
246
+ box-shadow: 8px 8px 0 var(--accent);
247
+ color: var(--paper);
576
248
  }
577
249
 
578
- .extractor-stats-grid {
579
- display: grid;
580
- grid-template-columns: repeat(3, 1fr);
581
- border-bottom: 1px solid #222;
250
+ .cta:active {
251
+ transform: translate(4px, 4px);
252
+ box-shadow: 2px 2px 0 var(--accent);
582
253
  }
583
254
 
584
- .extractor-stat {
585
- padding: 20px 24px;
586
- border-right: 1px solid #222;
587
- border-bottom: 1px solid #222;
588
- }
589
-
590
- .extractor-stat:nth-child(3n) {
591
- border-right: none;
592
- }
593
-
594
- .extractor-stat-value {
595
- font-family: 'Unbounded', sans-serif;
596
- font-size: 28px;
597
- font-weight: 900;
598
- color: var(--red);
599
- line-height: 1;
600
- }
601
-
602
- .extractor-stat-label {
603
- font-family: 'JetBrains Mono', monospace;
255
+ /* Chip — used for small tag/label pieces. */
256
+ .chip {
257
+ display: inline-flex;
258
+ align-items: center;
259
+ gap: 6px;
260
+ padding: 3px 8px 4px;
261
+ border: var(--hair);
262
+ font-family: var(--font-mono);
604
263
  font-size: 11px;
605
- color: #666;
606
- text-transform: uppercase;
607
- letter-spacing: 0.1em;
608
- margin-top: 6px;
609
- }
610
-
611
- .extractor-section {
612
- padding: 20px 24px;
613
- border-bottom: 1px solid #222;
614
- }
615
-
616
- .extractor-section:last-child {
617
- border-bottom: none;
618
- }
619
-
620
- .extractor-section-title {
621
- font-family: 'Unbounded', sans-serif;
622
- font-size: 12px;
623
- font-weight: 700;
624
- text-transform: uppercase;
625
- letter-spacing: 0.1em;
626
- color: var(--red);
627
- margin-bottom: 12px;
628
- }
629
-
630
- .extractor-colors {
631
- display: flex;
632
- flex-wrap: wrap;
633
- gap: 8px;
264
+ letter-spacing: 0.04em;
265
+ background: var(--paper);
266
+ color: var(--ink);
634
267
  }
635
268
 
636
- .extractor-swatch {
637
- text-align: center;
638
- }
269
+ /* ── Accessibility ──────────────────────────────────────────── */
639
270
 
640
- .extractor-swatch-color {
641
- width: 40px;
642
- height: 40px;
643
- border: 1px solid #333;
271
+ :focus-visible {
272
+ outline: 2px solid var(--accent);
273
+ outline-offset: 3px;
644
274
  }
645
275
 
646
- .extractor-swatch-hex {
647
- font-family: 'JetBrains Mono', monospace;
648
- font-size: 9px;
649
- color: #666;
650
- margin-top: 4px;
276
+ @media (prefers-reduced-motion: reduce) {
277
+ *,
278
+ *::before,
279
+ *::after {
280
+ animation-duration: 0s !important;
281
+ animation-iteration-count: 1 !important;
282
+ transition-duration: 0s !important;
283
+ scroll-behavior: auto !important;
284
+ }
651
285
  }
652
286
 
653
- .extractor-fonts {
654
- font-family: 'JetBrains Mono', monospace;
655
- font-size: 14px;
656
- color: #ccc;
657
- }
287
+ /* ── Section scaffold ───────────────────────────────────────── */
658
288
 
659
- .extractor-a11y {
660
- display: flex;
661
- align-items: center;
662
- gap: 16px;
289
+ section {
290
+ padding-block: var(--r9);
663
291
  }
664
292
 
665
- .extractor-a11y-score {
666
- font-family: 'Unbounded', sans-serif;
667
- font-size: 18px;
668
- font-weight: 700;
293
+ section + section {
294
+ border-top: var(--hair);
669
295
  }
670
296
 
671
- .extractor-a11y-score.good { color: #ffffff; }
672
- .extractor-a11y-score.ok { color: #aaaaaa; }
673
- .extractor-a11y-score.bad { color: #666666; }
674
-
675
- .extractor-a11y-fails {
676
- font-family: 'JetBrains Mono', monospace;
677
- font-size: 12px;
678
- color: #888;
297
+ section[id] {
298
+ scroll-margin-top: var(--r6);
679
299
  }
680
300
 
681
- .extractor-files {
682
- display: flex;
683
- flex-direction: column;
684
- gap: 4px;
685
- }
301
+ h1, h2, h3, h4, h5, h6 { font-weight: 400; }
686
302
 
687
- .extractor-file {
688
- display: flex;
689
- justify-content: space-between;
690
- padding: 6px 0;
691
- border-bottom: 1px solid #1a1a1a;
303
+ h2.display {
304
+ font-size: clamp(36px, 6vw, 88px);
692
305
  }
693
306
 
694
- .extractor-file:last-child {
695
- border-bottom: none;
307
+ h3.display {
308
+ font-size: clamp(26px, 3.5vw, 48px);
696
309
  }
697
310
 
698
- .extractor-file-name {
699
- font-family: 'JetBrains Mono', monospace;
700
- font-size: 13px;
701
- color: var(--yellow);
702
- }
703
-
704
- .extractor-file-size {
705
- font-family: 'JetBrains Mono', monospace;
706
- font-size: 12px;
707
- color: #555;
708
- }
709
-
710
- /* ── RESPONSIVE ── */
711
- @media (max-width: 768px) {
712
- .features-list { grid-template-columns: 1fr; }
713
- .commands-grid { grid-template-columns: 1fr; }
714
- .files-grid { grid-template-columns: 1fr; }
715
- .stats-strip { flex-direction: column; }
716
- .stat { border-right: none; border-bottom: 1px solid #222; }
717
- .hero-cmd { font-size: 14px; padding: 16px 24px; }
718
- .extractor-form { flex-direction: column; }
719
- .extractor-input { border-right: 2px solid var(--black); border-bottom: none; }
720
- .extractor-stats-grid { grid-template-columns: repeat(2, 1fr); }
721
- .extractor-stat:nth-child(3n) { border-right: 1px solid #222; }
722
- .extractor-stat:nth-child(2n) { border-right: none; }
311
+ .hero-title {
312
+ font-size: clamp(48px, 11vw, 200px);
313
+ }
314
+
315
+ /* ── Mobile & tablet pass ───────────────────────────────────── */
316
+
317
+ @media (max-width: 860px) {
318
+ :root {
319
+ --page-pad-x: 18px;
320
+ --col-gap: 14px;
321
+ }
322
+
323
+ section {
324
+ padding-block: var(--r7);
325
+ }
326
+
327
+ .display,
328
+ .hero-title,
329
+ h1,
330
+ h2,
331
+ h3 {
332
+ overflow-wrap: anywhere;
333
+ word-break: break-word;
334
+ hyphens: auto;
335
+ letter-spacing: -0.02em;
336
+ }
337
+
338
+ .hero-title {
339
+ font-size: clamp(44px, 13vw, 96px);
340
+ line-height: 0.95;
341
+ }
342
+
343
+ h2.display {
344
+ font-size: clamp(32px, 8vw, 56px);
345
+ }
346
+
347
+ h3.display {
348
+ font-size: clamp(22px, 6vw, 36px);
349
+ }
350
+
351
+ .prose p,
352
+ .prose {
353
+ font-size: 16px !important;
354
+ }
355
+
356
+ /* Header nav: horizontal scroll instead of overflow. */
357
+ header nav {
358
+ overflow-x: auto;
359
+ overflow-y: hidden;
360
+ scrollbar-width: none;
361
+ white-space: nowrap;
362
+ gap: var(--r4) !important;
363
+ font-size: 11px !important;
364
+ max-width: 60%;
365
+ }
366
+
367
+ header nav::-webkit-scrollbar {
368
+ display: none;
369
+ }
370
+
371
+ /* Hero form: stack input over button, no border on button side. */
372
+ #extract form {
373
+ flex-direction: column;
374
+ max-width: 100% !important;
375
+ }
376
+
377
+ #extract form input {
378
+ border-right: 0 !important;
379
+ border-bottom: var(--hair);
380
+ padding: 14px 16px !important;
381
+ font-size: 15px !important;
382
+ }
383
+
384
+ #extract form button {
385
+ width: 100%;
386
+ justify-content: space-between;
387
+ }
388
+
389
+ /* Tables, code blocks, long scroll strips: constrain inside page, scroll on x. */
390
+ pre,
391
+ table,
392
+ .scroll-x {
393
+ max-width: 100%;
394
+ overflow-x: auto;
395
+ -webkit-overflow-scrolling: touch;
396
+ }
397
+
398
+ pre {
399
+ font-size: 12px !important;
400
+ padding: var(--r3) var(--r4) !important;
401
+ }
402
+
403
+ /* Grid-12 defaults: drop to single column on mobile unless overridden. */
404
+ .grid-12 {
405
+ grid-template-columns: minmax(0, 1fr) !important;
406
+ gap: var(--r4) !important;
407
+ }
408
+
409
+ /* Min-width: 0 on every grid child so content (like a 640-unit SVG) can't
410
+ push a 1fr track wider than the viewport. */
411
+ .grid-12 > *,
412
+ .with-margin > *,
413
+ [style*='grid-template-columns'] > * {
414
+ min-width: 0;
415
+ }
416
+
417
+ /* Everything absolutely should not push the page sideways. */
418
+ body,
419
+ main.page {
420
+ max-width: 100vw;
421
+ overflow-x: clip;
422
+ }
423
+
424
+ /* Constrain every SVG, image, and video so fixed-width art can't spill. */
425
+ section svg,
426
+ section img,
427
+ section video,
428
+ section canvas {
429
+ max-width: 100%;
430
+ height: auto;
431
+ }
432
+
433
+ /* Any element that opts into `.scroll-x` or `.tabstrip` scrolls horizontally
434
+ inside its section on narrow viewports. */
435
+ .scroll-x,
436
+ .tabstrip,
437
+ [role='tablist'] {
438
+ overflow-x: auto;
439
+ -webkit-overflow-scrolling: touch;
440
+ scrollbar-width: thin;
441
+ }
442
+
443
+ /* Token browser: let it scroll-x on tiny viewports. */
444
+ section [data-token-browser],
445
+ section [data-regions-schematic],
446
+ section [data-platform-code],
447
+ section [data-specimens-strip] {
448
+ overflow-x: auto;
449
+ -webkit-overflow-scrolling: touch;
450
+ }
451
+
452
+ /* Specimen cards / wide cards: the strip itself scrolls; cards keep their
453
+ design width. */
454
+ [data-specimens-strip] > * {
455
+ flex: 0 0 auto;
456
+ }
457
+
458
+ /* Any container with a fixed min-width: safe max-width safety net. */
459
+ main.page > * {
460
+ max-width: 100%;
461
+ }
462
+
463
+ /* Inline-style grid overrides — components use style={{gridTemplateColumns:…}}
464
+ so we match the resulting attribute and force single-column on mobile. */
465
+ [style*="grid-template-columns: repeat(4"],
466
+ [style*="grid-template-columns: repeat(3"],
467
+ [style*="grid-template-columns:5fr"],
468
+ [style*="grid-template-columns: 5fr"],
469
+ [style*="grid-template-columns:100px"],
470
+ [style*="grid-template-columns: 100px"] {
471
+ grid-template-columns: 1fr !important;
472
+ }
473
+
474
+ /* Specimens strip: horizontal scroll with snap. Cards stay at their
475
+ design-time width; the parent scrolls. */
476
+ [style*="scroll-snap-type"] {
477
+ padding-inline: 0 !important;
478
+ }
479
+
480
+ [style*="scroll-snap-type"] > * {
481
+ min-width: 80vw;
482
+ max-width: 92vw;
483
+ }
484
+ }
485
+
486
+ @media (max-width: 480px) {
487
+ .hero-title {
488
+ font-size: clamp(40px, 12vw, 72px);
489
+ }
490
+
491
+ header nav {
492
+ max-width: 55%;
493
+ gap: 14px !important;
494
+ font-size: 10px !important;
495
+ letter-spacing: 0.08em !important;
496
+ }
497
+
498
+ .section-label {
499
+ font-size: 11px !important;
500
+ }
501
+
502
+ pre {
503
+ font-size: 11px !important;
504
+ }
723
505
  }