roast-my-design-system 3.2.0 → 3.3.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.
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # roast-my-design-system
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/roast-my-design-system?color=2dd4bf&label=npm)](https://www.npmjs.com/package/roast-my-design-system) [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
4
+
3
5
  ## A Claude Code skill that roasts your repo's design system with real data.
4
6
 
5
- Run this skill on your codebase and get three things: a health score for your design system, the receipts behind it (every colour, spacing value, duplicated component and inline style, with real file paths), and the first fixes ranked by payoff. It benchmarks you against an Ideal Design System, 29 scanned public repos, and 10 reputable design systems (Primer, Polaris, Carbon, shadcn/ui…), and generates one shareable HTML report: **keep it as the audit, or hand it to Claude as the punch list for the fix.**
7
+ Run this skill on your codebase and get three things: a health score for your design system, the receipts behind it (every colour, spacing value, duplicated component and inline style, with real file paths), and the first fixes ranked by payoff. It benchmarks you against an Ideal Design System, 30 scanned public repos, and 10 reputable design systems (Primer, Polaris, Carbon, shadcn/ui…), and generates one shareable HTML report: **keep it as the audit, or hand it to Claude as the punch list for the fix.**
6
8
 
7
9
  ## Why this exists
8
10
 
@@ -12,7 +14,7 @@ Your AI agent (Claude, Cursor, Copilot) builds UI by imitating what's already in
12
14
 
13
15
  - **Pre-refactor audit.** Run `/roast-my-design-system` before a design-system cleanup to get the measured baseline: every colour, spacing value, duplicated component and inline style, with real file paths.
14
16
  - **Diagnosing almost-right AI output.** When Claude keeps generating UI that looks slightly off, the report shows which duplicated components and stray values it is imitating, and where the canonical ones live.
15
- - **Making the case without a meeting.** Drop the self-contained HTML report in Slack: a health score and three benchmarks (ideal norms, the 29-repo median, 10 reputable systems) argue for the design system for you.
17
+ - **Making the case without a meeting.** Drop the self-contained HTML report in Slack: a health score and three benchmarks (ideal norms, the 30-repo median, 10 reputable systems) argue for the design system for you.
16
18
  - **The fix loop.** Hand the report back to Claude as the punch list and work through the Where to start section, file by file.
17
19
 
18
20
  The full report for vercel/ai-chatbot, top to bottom:
@@ -30,7 +32,7 @@ The same report in light mode (one file, built-in toggle):
30
32
  - **No network, no telemetry.** Everything runs locally. Nothing about your code leaves your machine.
31
33
  - **Honest exclusions.** Test files, Storybook stories, docs sites, example apps, SVG artwork, and email templates (which *must* inline styles) are excluded, so you can't discredit the numbers on a technicality.
32
34
  - **Intent-aware counting (v3).** Runtime-computed inline styles, compound-component APIs and wrapper components are not crimes and are not counted as ones. Token-led repos are judged on their hardcoded strays, not their token architecture. Repeated arbitrary values are read as decisions without names, not drift.
33
- - **A real benchmark.** The "Avg Design System" yardstick comes from scanning 29 public React repos (cal.com, excalidraw, outline, twenty, dub, langfuse…). Median: 88 colours, 12 greys, 17 duplicated components, 42 inline style blocks.
35
+ - **A real benchmark.** The "Avg Design System" yardstick comes from scanning 30 public React repos (cal.com, excalidraw, outline, twenty, dub, langfuse…). Median: 96 colours, 14 greys, 14 duplicated components, 42 inline style blocks, 91 arbitrary Tailwind values.
34
36
  - **A second yardstick: reputable systems.** Curated, scoped scans of 10 well-known design systems (shadcn/ui, Primer, Polaris, Carbon, Material UI, Chakra, Ant Design, GOV.UK, Spectrum, Cloudscape) show what disciplined looks like at scale.
35
37
 
36
38
  ## Install
@@ -85,7 +87,7 @@ Open Claude Code in the repo you want roasted and type:
85
87
  You get the roast in chat plus `design-system-roast.html` at your repo root: a self-contained page (open it, Slack it, email it, no external requests) with:
86
88
 
87
89
  - a **health score** computed from how your numbers sit against the ideal
88
- - stat tiles comparing you to all three yardsticks: Ideal, the 29-repo average, and the reputable systems
90
+ - stat tiles comparing you to all three yardsticks: Ideal, the 30-repo average, and the reputable systems
89
91
  - a **light/dark theme toggle** in one file
90
92
  - the usage-weighted palette bar, the grey ramp, the off-scale spacing receipts, the duplicate-component receipts with clickable file paths, and the worst-offenders ledger
91
93
  - a **Where to start** close: up to three moves derived from your repo's own numbers, each with a file-path receipt
@@ -100,15 +102,16 @@ Three real roasts of public repos, hosted as-is (the same self-contained HTML th
100
102
 
101
103
  ## What it measures
102
104
 
103
- | Metric | Ideal Design System | Median of 29 scanned repos | Median of 10 reputable systems |
105
+ | Metric | Ideal Design System | Median of 30 scanned repos | Median of 10 reputable systems |
104
106
  |---|---|---|---|
105
- | Distinct colours | ~24 | 88 | 24 |
106
- | Shades of grey | up to 13 | 12 | 5 |
107
- | Off-scale spacing values | ~12 | 26 | 6 |
107
+ | Distinct colours | ~24 | 96 | 24 |
108
+ | Shades of grey | up to 13 | 14 | 5 |
109
+ | Off-scale spacing values | ~12 | 27 | 6 |
108
110
  | Typefaces | 2–3 | 2 | 1 |
109
111
  | Border radii | up to 10 | 12 | 2 |
110
- | Duplicated components | 0 | 17 | 10 |
111
- | Inline style blocks | 0 | 42 | 11 |
112
+ | Duplicated components | 0 | 14 | 10 |
113
+ | Inline style blocks | 0 | 42 | 12 |
114
+ | Arbitrary Tailwind values | ~20 | 91 | 0 |
112
115
 
113
116
  Yes, the median repo is already a mess. That's the point.
114
117
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "roast-my-design-system",
3
- "version": "3.2.0",
4
- "description": "Roast your design system with real data. A deterministic, zero-dependency scanner that counts every colour, grey, spacing value, typeface, duplicated component and inline style in your repo, scores it 0-100 against Ideal Design System norms and a 29-repo benchmark, and generates a shareable HTML diagnosis.",
3
+ "version": "3.3.0",
4
+ "description": "Roast your design system with real data. A deterministic, zero-dependency scanner that counts every colour, grey, spacing value, typeface, duplicated component, inline style and arbitrary Tailwind value in your repo, scores it 0-100 against Ideal Design System norms and a 30-repo benchmark, and generates a shareable HTML diagnosis.",
5
5
  "keywords": [
6
6
  "design-system",
7
7
  "design-tokens",
@@ -1,6 +1,6 @@
1
1
  {
2
- "builtAt": "2026-07-24T13:37:06.943Z",
3
- "repoCount": 29,
2
+ "builtAt": "2026-08-01T17:38:24.498Z",
3
+ "repoCount": 30,
4
4
  "ideal2026": {
5
5
  "colors": {
6
6
  "value": 24,
@@ -38,6 +38,10 @@
38
38
  "value": 0,
39
39
  "note": "styling belongs to the system"
40
40
  },
41
+ "arbitrary": {
42
+ "value": 20,
43
+ "note": "bracket escape hatches; a handful of deliberate exceptions"
44
+ },
41
45
  "zIndexes": {
42
46
  "value": 6,
43
47
  "note": "a fixed layer scale, ~6 layers"
@@ -77,37 +81,38 @@
77
81
  0,
78
82
  0,
79
83
  0,
80
- 0,
84
+ 2,
81
85
  3,
82
- 32,
83
- 35,
86
+ 26,
84
87
  36,
85
- 46,
86
- 47,
87
- 59,
88
+ 36,
89
+ 42,
90
+ 48,
91
+ 50,
92
+ 61,
88
93
  69,
89
94
  78,
90
- 88,
91
- 88,
92
- 108,
93
- 125,
94
- 134,
95
+ 89,
96
+ 102,
97
+ 112,
95
98
  137,
96
- 147,
97
- 155,
98
- 168,
99
- 172,
100
- 205,
101
- 245,
102
- 271,
103
- 384,
104
- 399,
105
- 1673
99
+ 142,
100
+ 154,
101
+ 169,
102
+ 169,
103
+ 170,
104
+ 174,
105
+ 206,
106
+ 246,
107
+ 302,
108
+ 385,
109
+ 403,
110
+ 1645
106
111
  ],
107
- "p25": 36,
108
- "median": 88,
109
- "p75": 168,
110
- "p90": 294
112
+ "p25": 38,
113
+ "median": 96,
114
+ "p75": 170,
115
+ "p90": 310
111
116
  },
112
117
  "greys": {
113
118
  "values": [
@@ -115,35 +120,36 @@
115
120
  0,
116
121
  0,
117
122
  0,
118
- 0,
123
+ 2,
119
124
  2,
120
125
  3,
121
- 3,
126
+ 4,
127
+ 4,
122
128
  5,
123
129
  8,
124
130
  8,
125
- 8,
126
131
  9,
127
- 12,
128
- 12,
132
+ 9,
133
+ 13,
134
+ 14,
129
135
  15,
130
136
  18,
131
137
  18,
132
- 23,
133
- 30,
138
+ 24,
134
139
  30,
135
140
  31,
141
+ 32,
136
142
  34,
137
- 34,
138
- 34,
139
- 43,
140
- 46,
143
+ 35,
144
+ 37,
145
+ 44,
146
+ 48,
141
147
  77,
142
- 105
148
+ 100
143
149
  ],
144
- "p25": 3,
145
- "median": 12,
146
- "p75": 31,
150
+ "p25": 4,
151
+ "median": 14,
152
+ "p75": 32,
147
153
  "p90": 44
148
154
  },
149
155
  "spacing": {
@@ -152,36 +158,37 @@
152
158
  0,
153
159
  2,
154
160
  3,
155
- 5,
156
161
  6,
157
- 9,
162
+ 6,
163
+ 6,
158
164
  9,
159
165
  10,
160
- 12,
166
+ 11,
167
+ 15,
161
168
  18,
162
- 20,
163
- 21,
164
- 23,
165
- 26,
169
+ 22,
170
+ 24,
171
+ 25,
166
172
  28,
167
- 30,
168
- 33,
169
- 35,
170
- 41,
171
- 43,
172
- 46,
173
- 52,
174
- 56,
175
- 63,
176
- 67,
177
- 72,
173
+ 31,
174
+ 34,
175
+ 37,
176
+ 50,
177
+ 51,
178
+ 54,
179
+ 55,
180
+ 59,
181
+ 61,
182
+ 64,
183
+ 78,
184
+ 82,
178
185
  84,
179
- 113
186
+ 121
180
187
  ],
181
188
  "p25": 9,
182
- "median": 26,
183
- "p75": 46,
184
- "p90": 68
189
+ "median": 27,
190
+ "p75": 55,
191
+ "p90": 78
185
192
  },
186
193
  "typefaces": {
187
194
  "values": [
@@ -200,6 +207,7 @@
200
207
  2,
201
208
  2,
202
209
  2,
210
+ 2,
203
211
  3,
204
212
  3,
205
213
  3,
@@ -212,7 +220,7 @@
212
220
  5,
213
221
  5,
214
222
  6,
215
- 8,
223
+ 7,
216
224
  9
217
225
  ],
218
226
  "p25": 1,
@@ -232,15 +240,16 @@
232
240
  7,
233
241
  9,
234
242
  10,
243
+ 11,
235
244
  12,
236
245
  12,
237
246
  13,
238
247
  14,
239
248
  18,
240
- 18,
241
- 21,
249
+ 20,
250
+ 20,
251
+ 22,
242
252
  22,
243
- 23,
244
253
  24,
245
254
  27,
246
255
  27,
@@ -252,8 +261,8 @@
252
261
  49,
253
262
  61
254
263
  ],
255
- "p25": 7,
256
- "median": 18,
264
+ "p25": 8,
265
+ "median": 16,
257
266
  "p75": 27,
258
267
  "p90": 37
259
268
  },
@@ -269,6 +278,7 @@
269
278
  8,
270
279
  8,
271
280
  9,
281
+ 9,
272
282
  10,
273
283
  11,
274
284
  11,
@@ -285,14 +295,14 @@
285
295
  24,
286
296
  25,
287
297
  26,
298
+ 26,
288
299
  30,
289
- 33,
290
300
  62
291
301
  ],
292
302
  "p25": 8,
293
303
  "median": 12,
294
304
  "p75": 21,
295
- "p90": 27
305
+ "p90": 26
296
306
  },
297
307
  "shadows": {
298
308
  "values": [
@@ -310,6 +320,7 @@
310
320
  0,
311
321
  0,
312
322
  0,
323
+ 0,
313
324
  1,
314
325
  1,
315
326
  2,
@@ -323,8 +334,8 @@
323
334
  10,
324
335
  10,
325
336
  16,
326
- 28,
327
- 28
337
+ 19,
338
+ 29
328
339
  ],
329
340
  "p25": 0,
330
341
  "median": 1,
@@ -347,26 +358,27 @@
347
358
  7,
348
359
  7,
349
360
  8,
361
+ 10,
350
362
  17,
351
363
  17,
352
364
  19,
365
+ 20,
353
366
  21,
354
- 21,
367
+ 22,
355
368
  23,
356
- 25,
357
369
  38,
358
370
  45,
359
- 73,
360
- 93,
361
- 98,
371
+ 59,
372
+ 92,
373
+ 95,
362
374
  103,
363
- 116,
375
+ 115,
364
376
  187
365
377
  ],
366
378
  "p25": 1,
367
- "median": 17,
368
- "p75": 38,
369
- "p90": 99
379
+ "median": 14,
380
+ "p75": 34,
381
+ "p90": 96
370
382
  },
371
383
  "inlineStyles": {
372
384
  "values": [
@@ -379,31 +391,32 @@
379
391
  5,
380
392
  7,
381
393
  11,
382
- 17,
394
+ 18,
383
395
  22,
384
396
  23,
385
- 36,
386
- 40,
397
+ 23,
398
+ 37,
399
+ 41,
387
400
  42,
388
- 44,
389
- 45,
401
+ 46,
390
402
  47,
403
+ 51,
391
404
  69,
392
- 70,
405
+ 71,
393
406
  76,
394
407
  79,
395
408
  82,
396
409
  117,
397
- 118,
398
410
  119,
411
+ 122,
399
412
  173,
400
413
  1178,
401
- 2885
414
+ 2914
402
415
  ],
403
- "p25": 7,
416
+ "p25": 8,
404
417
  "median": 42,
405
- "p75": 79,
406
- "p90": 130
418
+ "p75": 78,
419
+ "p90": 127
407
420
  },
408
421
  "arbitrary": {
409
422
  "values": [
@@ -419,65 +432,67 @@
419
432
  4,
420
433
  16,
421
434
  26,
435
+ 27,
422
436
  60,
423
- 85,
437
+ 78,
424
438
  103,
425
- 123,
439
+ 125,
426
440
  148,
427
- 154,
428
441
  164,
429
- 228,
442
+ 164,
430
443
  234,
444
+ 271,
431
445
  321,
432
- 339,
433
- 398,
434
- 467,
446
+ 374,
447
+ 407,
448
+ 468,
435
449
  470,
436
- 488,
450
+ 492,
437
451
  561,
438
452
  1751
439
453
  ],
440
454
  "p25": 0,
441
- "median": 103,
442
- "p75": 321,
443
- "p90": 474
455
+ "median": 91,
456
+ "p75": 309,
457
+ "p90": 472
444
458
  },
445
459
  "components": {
446
460
  "values": [
447
461
  9,
448
462
  25,
449
463
  36,
450
- 51,
451
- 62,
452
- 183,
453
- 184,
454
- 226,
455
- 276,
464
+ 50,
465
+ 60,
466
+ 182,
467
+ 190,
468
+ 220,
469
+ 272,
456
470
  315,
471
+ 342,
457
472
  350,
458
- 350,
459
- 418,
460
- 620,
461
- 779,
462
- 794,
463
- 826,
464
- 916,
465
- 965,
466
- 972,
467
- 1033,
468
- 1041,
469
- 1088,
470
- 1229,
471
- 1397,
472
- 1424,
473
- 1654,
474
- 2153,
475
- 2536
473
+ 417,
474
+ 546,
475
+ 629,
476
+ 777,
477
+ 790,
478
+ 834,
479
+ 936,
480
+ 940,
481
+ 961,
482
+ 970,
483
+ 1043,
484
+ 1081,
485
+ 1216,
486
+ 1379,
487
+ 1414,
488
+ 1619,
489
+ 2133,
490
+ 2549
476
491
  ],
477
- "p25": 226,
478
- "median": 779,
479
- "p75": 1041,
480
- "p90": 1470
492
+ "p25": 233,
493
+ "median": 703,
494
+ "p75": 1025,
495
+ "p90": 1435
481
496
  }
482
497
  },
483
498
  "repos": [
@@ -486,35 +501,35 @@
486
501
  "designSystem": "custom",
487
502
  "codeFiles": 4341,
488
503
  "metrics": {
489
- "colors": 384,
504
+ "colors": 385,
490
505
  "greys": 77,
491
- "spacing": 113,
506
+ "spacing": 121,
492
507
  "typefaces": 9,
493
508
  "fontSizes": 61,
494
509
  "radii": 62,
495
510
  "shadows": 10,
496
- "exactDuplicates": 116,
511
+ "exactDuplicates": 115,
497
512
  "inlineStyles": 79,
498
513
  "arbitrary": 321,
499
- "components": 1424
514
+ "components": 1414
500
515
  }
501
516
  },
502
517
  {
503
518
  "repo": "excalidraw/excalidraw",
504
519
  "designSystem": "custom",
505
- "codeFiles": 500,
520
+ "codeFiles": 502,
506
521
  "metrics": {
507
- "colors": 205,
508
- "greys": 43,
522
+ "colors": 206,
523
+ "greys": 44,
509
524
  "spacing": 84,
510
525
  "typefaces": 3,
511
526
  "fontSizes": 33,
512
527
  "radii": 30,
513
- "shadows": 28,
528
+ "shadows": 29,
514
529
  "exactDuplicates": 3,
515
530
  "inlineStyles": 82,
516
531
  "arbitrary": 0,
517
- "components": 350
532
+ "components": 342
518
533
  }
519
534
  },
520
535
  {
@@ -522,8 +537,8 @@
522
537
  "designSystem": "library",
523
538
  "codeFiles": 107,
524
539
  "metrics": {
525
- "colors": 108,
526
- "greys": 46,
540
+ "colors": 112,
541
+ "greys": 48,
527
542
  "spacing": 18,
528
543
  "typefaces": 4,
529
544
  "fontSizes": 7,
@@ -532,17 +547,17 @@
532
547
  "exactDuplicates": 4,
533
548
  "inlineStyles": 23,
534
549
  "arbitrary": 0,
535
- "components": 51
550
+ "components": 50
536
551
  }
537
552
  },
538
553
  {
539
554
  "repo": "outline/outline",
540
555
  "designSystem": "custom",
541
- "codeFiles": 2075,
556
+ "codeFiles": 2100,
542
557
  "metrics": {
543
- "colors": 88,
558
+ "colors": 89,
544
559
  "greys": 15,
545
- "spacing": 12,
560
+ "spacing": 15,
546
561
  "typefaces": 0,
547
562
  "fontSizes": 0,
548
563
  "radii": 0,
@@ -550,13 +565,13 @@
550
565
  "exactDuplicates": 23,
551
566
  "inlineStyles": 76,
552
567
  "arbitrary": 0,
553
- "components": 620
568
+ "components": 629
554
569
  }
555
570
  },
556
571
  {
557
572
  "repo": "nodejs/nodejs.org",
558
573
  "designSystem": "custom",
559
- "codeFiles": 370,
574
+ "codeFiles": 384,
560
575
  "metrics": {
561
576
  "colors": 69,
562
577
  "greys": 5,
@@ -568,7 +583,7 @@
568
583
  "exactDuplicates": 2,
569
584
  "inlineStyles": 0,
570
585
  "arbitrary": 4,
571
- "components": 226
586
+ "components": 220
572
587
  }
573
588
  },
574
589
  {
@@ -594,9 +609,9 @@
594
609
  "designSystem": "shadcn",
595
610
  "codeFiles": 129,
596
611
  "metrics": {
597
- "colors": 0,
598
- "greys": 0,
599
- "spacing": 5,
612
+ "colors": 2,
613
+ "greys": 2,
614
+ "spacing": 6,
600
615
  "typefaces": 2,
601
616
  "fontSizes": 13,
602
617
  "radii": 7,
@@ -604,7 +619,7 @@
604
619
  "exactDuplicates": 0,
605
620
  "inlineStyles": 0,
606
621
  "arbitrary": 60,
607
- "components": 183
622
+ "components": 182
608
623
  }
609
624
  },
610
625
  {
@@ -640,7 +655,7 @@
640
655
  "exactDuplicates": 1,
641
656
  "inlineStyles": 2,
642
657
  "arbitrary": 16,
643
- "components": 62
658
+ "components": 60
644
659
  }
645
660
  },
646
661
  {
@@ -648,7 +663,7 @@
648
663
  "designSystem": "shadcn",
649
664
  "codeFiles": 146,
650
665
  "metrics": {
651
- "colors": 59,
666
+ "colors": 61,
652
667
  "greys": 0,
653
668
  "spacing": 6,
654
669
  "typefaces": 3,
@@ -668,7 +683,7 @@
668
683
  "metrics": {
669
684
  "colors": 3,
670
685
  "greys": 3,
671
- "spacing": 23,
686
+ "spacing": 25,
672
687
  "typefaces": 1,
673
688
  "fontSizes": 9,
674
689
  "radii": 8,
@@ -676,17 +691,17 @@
676
691
  "exactDuplicates": 1,
677
692
  "inlineStyles": 11,
678
693
  "arbitrary": 148,
679
- "components": 276
694
+ "components": 272
680
695
  }
681
696
  },
682
697
  {
683
698
  "repo": "documenso/documenso",
684
699
  "designSystem": "custom",
685
- "codeFiles": 1905,
700
+ "codeFiles": 1906,
686
701
  "metrics": {
687
- "colors": 32,
688
- "greys": 12,
689
- "spacing": 26,
702
+ "colors": 36,
703
+ "greys": 13,
704
+ "spacing": 34,
690
705
  "typefaces": 6,
691
706
  "fontSizes": 22,
692
707
  "radii": 12,
@@ -694,17 +709,17 @@
694
709
  "exactDuplicates": 17,
695
710
  "inlineStyles": 69,
696
711
  "arbitrary": 234,
697
- "components": 794
712
+ "components": 790
698
713
  }
699
714
  },
700
715
  {
701
716
  "repo": "dubinc/dub",
702
717
  "designSystem": "custom",
703
- "codeFiles": 3510,
718
+ "codeFiles": 3523,
704
719
  "metrics": {
705
- "colors": 88,
706
- "greys": 12,
707
- "spacing": 41,
720
+ "colors": 102,
721
+ "greys": 14,
722
+ "spacing": 54,
708
723
  "typefaces": 3,
709
724
  "fontSizes": 37,
710
725
  "radii": 22,
@@ -712,31 +727,31 @@
712
727
  "exactDuplicates": 17,
713
728
  "inlineStyles": 47,
714
729
  "arbitrary": 470,
715
- "components": 1397
730
+ "components": 1379
716
731
  }
717
732
  },
718
733
  {
719
734
  "repo": "formbricks/formbricks",
720
735
  "designSystem": "custom",
721
- "codeFiles": 1857,
736
+ "codeFiles": 2051,
722
737
  "metrics": {
723
- "colors": 134,
738
+ "colors": 142,
724
739
  "greys": 18,
725
- "spacing": 35,
740
+ "spacing": 51,
726
741
  "typefaces": 2,
727
742
  "fontSizes": 28,
728
743
  "radii": 25,
729
744
  "shadows": 6,
730
- "exactDuplicates": 73,
731
- "inlineStyles": 17,
732
- "arbitrary": 154,
733
- "components": 1041
745
+ "exactDuplicates": 59,
746
+ "inlineStyles": 18,
747
+ "arbitrary": 164,
748
+ "components": 940
734
749
  }
735
750
  },
736
751
  {
737
752
  "repo": "openstatusHQ/openstatus",
738
753
  "designSystem": "custom",
739
- "codeFiles": 1885,
754
+ "codeFiles": 1916,
740
755
  "metrics": {
741
756
  "colors": 78,
742
757
  "greys": 2,
@@ -745,64 +760,82 @@
745
760
  "fontSizes": 14,
746
761
  "radii": 12,
747
762
  "shadows": 0,
748
- "exactDuplicates": 93,
763
+ "exactDuplicates": 92,
749
764
  "inlineStyles": 119,
750
765
  "arbitrary": 164,
751
- "components": 1088
766
+ "components": 1081
767
+ }
768
+ },
769
+ {
770
+ "repo": "lukevella/rallly",
771
+ "designSystem": "custom",
772
+ "codeFiles": 689,
773
+ "metrics": {
774
+ "colors": 26,
775
+ "greys": 4,
776
+ "spacing": 11,
777
+ "typefaces": 2,
778
+ "fontSizes": 12,
779
+ "radii": 9,
780
+ "shadows": 0,
781
+ "exactDuplicates": 10,
782
+ "inlineStyles": 23,
783
+ "arbitrary": 27,
784
+ "components": 546
752
785
  }
753
786
  },
754
787
  {
755
788
  "repo": "mfts/papermark",
756
789
  "designSystem": "shadcn",
757
- "codeFiles": 1335,
790
+ "codeFiles": 1354,
758
791
  "metrics": {
759
- "colors": 35,
792
+ "colors": 42,
760
793
  "greys": 9,
761
- "spacing": 43,
794
+ "spacing": 50,
762
795
  "typefaces": 1,
763
796
  "fontSizes": 27,
764
797
  "radii": 19,
765
798
  "shadows": 1,
766
- "exactDuplicates": 21,
767
- "inlineStyles": 45,
768
- "arbitrary": 398,
769
- "components": 779
799
+ "exactDuplicates": 20,
800
+ "inlineStyles": 46,
801
+ "arbitrary": 407,
802
+ "components": 777
770
803
  }
771
804
  },
772
805
  {
773
806
  "repo": "elie222/inbox-zero",
774
807
  "designSystem": "custom",
775
- "codeFiles": 1716,
808
+ "codeFiles": 1808,
776
809
  "metrics": {
777
- "colors": 147,
778
- "greys": 23,
779
- "spacing": 21,
810
+ "colors": 154,
811
+ "greys": 24,
812
+ "spacing": 22,
780
813
  "typefaces": 3,
781
814
  "fontSizes": 27,
782
815
  "radii": 20,
783
816
  "shadows": 0,
784
817
  "exactDuplicates": 21,
785
818
  "inlineStyles": 5,
786
- "arbitrary": 123,
787
- "components": 826
819
+ "arbitrary": 125,
820
+ "components": 834
788
821
  }
789
822
  },
790
823
  {
791
824
  "repo": "linkwarden/linkwarden",
792
825
  "designSystem": "custom",
793
- "codeFiles": 450,
826
+ "codeFiles": 462,
794
827
  "metrics": {
795
- "colors": 46,
796
- "greys": 8,
797
- "spacing": 9,
828
+ "colors": 50,
829
+ "greys": 9,
830
+ "spacing": 6,
798
831
  "typefaces": 2,
799
- "fontSizes": 12,
832
+ "fontSizes": 11,
800
833
  "radii": 9,
801
834
  "shadows": 0,
802
835
  "exactDuplicates": 7,
803
- "inlineStyles": 42,
804
- "arbitrary": 85,
805
- "components": 184
836
+ "inlineStyles": 41,
837
+ "arbitrary": 78,
838
+ "components": 190
806
839
  }
807
840
  },
808
841
  {
@@ -810,9 +843,9 @@
810
843
  "designSystem": "custom",
811
844
  "codeFiles": 892,
812
845
  "metrics": {
813
- "colors": 47,
846
+ "colors": 48,
814
847
  "greys": 8,
815
- "spacing": 33,
848
+ "spacing": 37,
816
849
  "typefaces": 1,
817
850
  "fontSizes": 4,
818
851
  "radii": 11,
@@ -820,61 +853,61 @@
820
853
  "exactDuplicates": 0,
821
854
  "inlineStyles": 173,
822
855
  "arbitrary": 1,
823
- "components": 418
856
+ "components": 417
824
857
  }
825
858
  },
826
859
  {
827
860
  "repo": "twentyhq/twenty",
828
861
  "designSystem": "library",
829
- "codeFiles": 14776,
862
+ "codeFiles": 15125,
830
863
  "metrics": {
831
- "colors": 1673,
832
- "greys": 105,
833
- "spacing": 30,
834
- "typefaces": 8,
835
- "fontSizes": 23,
836
- "radii": 33,
837
- "shadows": 28,
838
- "exactDuplicates": 25,
839
- "inlineStyles": 118,
864
+ "colors": 1645,
865
+ "greys": 100,
866
+ "spacing": 24,
867
+ "typefaces": 7,
868
+ "fontSizes": 20,
869
+ "radii": 26,
870
+ "shadows": 19,
871
+ "exactDuplicates": 22,
872
+ "inlineStyles": 122,
840
873
  "arbitrary": 0,
841
- "components": 2153
874
+ "components": 2133
842
875
  }
843
876
  },
844
877
  {
845
878
  "repo": "langfuse/langfuse",
846
879
  "designSystem": "custom",
847
- "codeFiles": 2694,
880
+ "codeFiles": 2758,
848
881
  "metrics": {
849
- "colors": 125,
850
- "greys": 3,
851
- "spacing": 20,
882
+ "colors": 170,
883
+ "greys": 4,
884
+ "spacing": 28,
852
885
  "typefaces": 0,
853
- "fontSizes": 18,
886
+ "fontSizes": 20,
854
887
  "radii": 10,
855
888
  "shadows": 0,
856
889
  "exactDuplicates": 7,
857
- "inlineStyles": 40,
858
- "arbitrary": 339,
859
- "components": 1033
890
+ "inlineStyles": 42,
891
+ "arbitrary": 374,
892
+ "components": 1043
860
893
  }
861
894
  },
862
895
  {
863
896
  "repo": "teableio/teable",
864
897
  "designSystem": "custom",
865
- "codeFiles": 4709,
898
+ "codeFiles": 4742,
866
899
  "metrics": {
867
- "colors": 245,
900
+ "colors": 246,
868
901
  "greys": 34,
869
- "spacing": 63,
902
+ "spacing": 64,
870
903
  "typefaces": 3,
871
904
  "fontSizes": 35,
872
905
  "radii": 24,
873
906
  "shadows": 10,
874
907
  "exactDuplicates": 45,
875
- "inlineStyles": 36,
876
- "arbitrary": 467,
877
- "components": 1229
908
+ "inlineStyles": 37,
909
+ "arbitrary": 468,
910
+ "components": 1216
878
911
  }
879
912
  },
880
913
  {
@@ -882,27 +915,27 @@
882
915
  "designSystem": "custom",
883
916
  "codeFiles": 3086,
884
917
  "metrics": {
885
- "colors": 399,
886
- "greys": 30,
887
- "spacing": 72,
918
+ "colors": 403,
919
+ "greys": 32,
920
+ "spacing": 78,
888
921
  "typefaces": 2,
889
922
  "fontSizes": 24,
890
923
  "radii": 21,
891
924
  "shadows": 4,
892
- "exactDuplicates": 98,
925
+ "exactDuplicates": 95,
893
926
  "inlineStyles": 22,
894
927
  "arbitrary": 561,
895
- "components": 1654
928
+ "components": 1619
896
929
  }
897
930
  },
898
931
  {
899
932
  "repo": "FlowiseAI/Flowise",
900
933
  "designSystem": "library",
901
- "codeFiles": 1650,
934
+ "codeFiles": 1651,
902
935
  "metrics": {
903
- "colors": 155,
904
- "greys": 34,
905
- "spacing": 46,
936
+ "colors": 169,
937
+ "greys": 35,
938
+ "spacing": 55,
906
939
  "typefaces": 3,
907
940
  "fontSizes": 18,
908
941
  "radii": 12,
@@ -916,37 +949,37 @@
916
949
  {
917
950
  "repo": "lobehub/lobe-chat",
918
951
  "designSystem": "library",
919
- "codeFiles": 8013,
952
+ "codeFiles": 8299,
920
953
  "metrics": {
921
- "colors": 271,
922
- "greys": 34,
923
- "spacing": 52,
954
+ "colors": 302,
955
+ "greys": 37,
956
+ "spacing": 61,
924
957
  "typefaces": 1,
925
958
  "fontSizes": 2,
926
959
  "radii": 1,
927
960
  "shadows": 0,
928
961
  "exactDuplicates": 187,
929
- "inlineStyles": 2885,
962
+ "inlineStyles": 2914,
930
963
  "arbitrary": 0,
931
- "components": 2536
964
+ "components": 2549
932
965
  }
933
966
  },
934
967
  {
935
968
  "repo": "danny-avila/LibreChat",
936
969
  "designSystem": "custom",
937
- "codeFiles": 2394,
970
+ "codeFiles": 2424,
938
971
  "metrics": {
939
- "colors": 172,
972
+ "colors": 174,
940
973
  "greys": 30,
941
- "spacing": 67,
974
+ "spacing": 82,
942
975
  "typefaces": 5,
943
976
  "fontSizes": 39,
944
977
  "radii": 26,
945
978
  "shadows": 16,
946
979
  "exactDuplicates": 38,
947
- "inlineStyles": 70,
948
- "arbitrary": 488,
949
- "components": 965
980
+ "inlineStyles": 71,
981
+ "arbitrary": 492,
982
+ "components": 961
950
983
  }
951
984
  },
952
985
  {
@@ -954,9 +987,9 @@
954
987
  "designSystem": "custom",
955
988
  "codeFiles": 1762,
956
989
  "metrics": {
957
- "colors": 168,
990
+ "colors": 169,
958
991
  "greys": 31,
959
- "spacing": 56,
992
+ "spacing": 59,
960
993
  "typefaces": 3,
961
994
  "fontSizes": 49,
962
995
  "radii": 20,
@@ -964,25 +997,25 @@
964
997
  "exactDuplicates": 103,
965
998
  "inlineStyles": 117,
966
999
  "arbitrary": 1751,
967
- "components": 972
1000
+ "components": 970
968
1001
  }
969
1002
  },
970
1003
  {
971
1004
  "repo": "triggerdotdev/trigger.dev",
972
1005
  "designSystem": "custom",
973
- "codeFiles": 2283,
1006
+ "codeFiles": 2354,
974
1007
  "metrics": {
975
1008
  "colors": 137,
976
1009
  "greys": 18,
977
- "spacing": 28,
1010
+ "spacing": 31,
978
1011
  "typefaces": 0,
979
- "fontSizes": 21,
1012
+ "fontSizes": 22,
980
1013
  "radii": 16,
981
1014
  "shadows": 0,
982
1015
  "exactDuplicates": 8,
983
- "inlineStyles": 44,
984
- "arbitrary": 228,
985
- "components": 916
1016
+ "inlineStyles": 51,
1017
+ "arbitrary": 271,
1018
+ "components": 936
986
1019
  }
987
1020
  },
988
1021
  {
@@ -1005,7 +1038,7 @@
1005
1038
  }
1006
1039
  ],
1007
1040
  "referenceSystems": {
1008
- "builtAt": "2026-07-24T13:37:09.100Z",
1041
+ "builtAt": "2026-08-01T17:38:26.401Z",
1009
1042
  "count": 10,
1010
1043
  "note": "Curated scoped scans of reputable public design systems. Not comparable head-to-head with product repos: see per-system notes.",
1011
1044
  "stats": {
@@ -1043,8 +1076,8 @@
1043
1076
  "values": [
1044
1077
  0,
1045
1078
  0,
1046
- 0,
1047
- 0,
1079
+ 1,
1080
+ 2,
1048
1081
  3,
1049
1082
  8,
1050
1083
  16,
@@ -1123,9 +1156,9 @@
1123
1156
  6,
1124
1157
  13,
1125
1158
  15,
1126
- 18,
1159
+ 17,
1127
1160
  28,
1128
- 168
1161
+ 170
1129
1162
  ],
1130
1163
  "median": 10
1131
1164
  },
@@ -1136,28 +1169,43 @@
1136
1169
  1,
1137
1170
  10,
1138
1171
  10,
1139
- 11,
1172
+ 14,
1140
1173
  14,
1141
1174
  17,
1142
1175
  22,
1143
1176
  24
1144
1177
  ],
1145
- "median": 11
1178
+ "median": 12
1179
+ },
1180
+ "arbitrary": {
1181
+ "values": [
1182
+ 0,
1183
+ 0,
1184
+ 0,
1185
+ 0,
1186
+ 0,
1187
+ 0,
1188
+ 0,
1189
+ 0,
1190
+ 0,
1191
+ 35
1192
+ ],
1193
+ "median": 0
1146
1194
  },
1147
1195
  "components": {
1148
1196
  "values": [
1149
1197
  0,
1150
1198
  170,
1151
- 234,
1152
- 247,
1153
- 258,
1154
- 326,
1199
+ 228,
1200
+ 243,
1201
+ 246,
1202
+ 314,
1155
1203
  331,
1156
- 510,
1204
+ 508,
1157
1205
  711,
1158
- 811
1206
+ 819
1159
1207
  ],
1160
- "median": 292
1208
+ "median": 280
1161
1209
  }
1162
1210
  },
1163
1211
  "systems": [
@@ -1177,6 +1225,7 @@
1177
1225
  "shadows": 0,
1178
1226
  "exactDuplicates": 0,
1179
1227
  "inlineStyles": 1,
1228
+ "arbitrary": 35,
1180
1229
  "components": 331
1181
1230
  }
1182
1231
  },
@@ -1196,7 +1245,8 @@
1196
1245
  "shadows": 35,
1197
1246
  "exactDuplicates": 13,
1198
1247
  "inlineStyles": 14,
1199
- "components": 234
1248
+ "arbitrary": 0,
1249
+ "components": 228
1200
1250
  }
1201
1251
  },
1202
1252
  {
@@ -1215,7 +1265,8 @@
1215
1265
  "shadows": 44,
1216
1266
  "exactDuplicates": 15,
1217
1267
  "inlineStyles": 10,
1218
- "components": 247
1268
+ "arbitrary": 0,
1269
+ "components": 243
1219
1270
  }
1220
1271
  },
1221
1272
  {
@@ -1223,7 +1274,7 @@
1223
1274
  "repo": "carbon-design-system/carbon",
1224
1275
  "scope": "packages/react/src",
1225
1276
  "note": "styling lives in separate Sass packages, so colour and radii counts are near zero",
1226
- "codeFiles": 515,
1277
+ "codeFiles": 518,
1227
1278
  "metrics": {
1228
1279
  "colors": 16,
1229
1280
  "greys": 0,
@@ -1234,7 +1285,8 @@
1234
1285
  "shadows": 1,
1235
1286
  "exactDuplicates": 6,
1236
1287
  "inlineStyles": 17,
1237
- "components": 326
1288
+ "arbitrary": 0,
1289
+ "components": 314
1238
1290
  }
1239
1291
  },
1240
1292
  {
@@ -1242,7 +1294,7 @@
1242
1294
  "repo": "mui/material-ui",
1243
1295
  "scope": "packages/mui-material/src",
1244
1296
  "note": "colour count is the reference palette shipped as JS; CSS-in-JS theme values are invisible",
1245
- "codeFiles": 978,
1297
+ "codeFiles": 979,
1246
1298
  "metrics": {
1247
1299
  "colors": 265,
1248
1300
  "greys": 19,
@@ -1253,6 +1305,7 @@
1253
1305
  "shadows": 0,
1254
1306
  "exactDuplicates": 2,
1255
1307
  "inlineStyles": 10,
1308
+ "arbitrary": 0,
1256
1309
  "components": 170
1257
1310
  }
1258
1311
  },
@@ -1272,6 +1325,7 @@
1272
1325
  "shadows": 0,
1273
1326
  "exactDuplicates": 0,
1274
1327
  "inlineStyles": 1,
1328
+ "arbitrary": 0,
1275
1329
  "components": 711
1276
1330
  }
1277
1331
  },
@@ -1289,9 +1343,10 @@
1289
1343
  "fontSizes": 5,
1290
1344
  "radii": 0,
1291
1345
  "shadows": 0,
1292
- "exactDuplicates": 18,
1346
+ "exactDuplicates": 17,
1293
1347
  "inlineStyles": 24,
1294
- "components": 258
1348
+ "arbitrary": 0,
1349
+ "components": 246
1295
1350
  }
1296
1351
  },
1297
1352
  {
@@ -1310,6 +1365,7 @@
1310
1365
  "shadows": 22,
1311
1366
  "exactDuplicates": 0,
1312
1367
  "inlineStyles": 0,
1368
+ "arbitrary": 0,
1313
1369
  "components": 0
1314
1370
  }
1315
1371
  },
@@ -1318,18 +1374,19 @@
1318
1374
  "repo": "adobe/react-spectrum",
1319
1375
  "scope": "packages/@react-spectrum",
1320
1376
  "note": "styling lives in separate spectrum-css packages; duplicate count is mostly re-export patterns",
1321
- "codeFiles": 827,
1377
+ "codeFiles": 832,
1322
1378
  "metrics": {
1323
1379
  "colors": 2,
1324
1380
  "greys": 1,
1325
- "spacing": 0,
1381
+ "spacing": 1,
1326
1382
  "typefaces": 5,
1327
1383
  "fontSizes": 0,
1328
1384
  "radii": 0,
1329
1385
  "shadows": 0,
1330
- "exactDuplicates": 168,
1331
- "inlineStyles": 11,
1332
- "components": 811
1386
+ "exactDuplicates": 170,
1387
+ "inlineStyles": 14,
1388
+ "arbitrary": 0,
1389
+ "components": 819
1333
1390
  }
1334
1391
  },
1335
1392
  {
@@ -1337,18 +1394,19 @@
1337
1394
  "repo": "cloudscape-design/components",
1338
1395
  "scope": "src",
1339
1396
  "note": "token-driven SCSS keeps colours low; shadow count comes from elevation and motion scss",
1340
- "codeFiles": 1219,
1397
+ "codeFiles": 1224,
1341
1398
  "metrics": {
1342
1399
  "colors": 12,
1343
1400
  "greys": 2,
1344
- "spacing": 0,
1401
+ "spacing": 2,
1345
1402
  "typefaces": 6,
1346
1403
  "fontSizes": 19,
1347
1404
  "radii": 4,
1348
1405
  "shadows": 54,
1349
1406
  "exactDuplicates": 28,
1350
1407
  "inlineStyles": 22,
1351
- "components": 510
1408
+ "arbitrary": 0,
1409
+ "components": 508
1352
1410
  }
1353
1411
  }
1354
1412
  ]
@@ -28,7 +28,7 @@ const outPath = resolve(arg('out', 'diagnosis.html'));
28
28
  const h = JSON.parse(readFileSync(inPath, 'utf8'));
29
29
 
30
30
  // Shown in the report footer; keep in step with plugin.json when releasing.
31
- const VERSION = '3.2.0';
31
+ const VERSION = '3.3.0';
32
32
 
33
33
  // Two shipped skins, same layout: 'dark' (navy glass, mint accent) and
34
34
  // 'light' (lilac wash, white glass, violet accent). --theme picks one.
@@ -231,7 +231,9 @@ if (bench && findings.length) {
231
231
  // is warn; beyond that bad.
232
232
  const ZERO_IDEAL = new Set(['exactDuplicates', 'inlineStyles']);
233
233
  const WARN_TOLERANCE = { exactDuplicates: 2, inlineStyles: 10 };
234
- const NO_ABSENCE_RULE = new Set(['colors', 'greys']);
234
+ // Absence rule also skipped for arbitrary values: zero brackets is discipline
235
+ // (nine of ten reputable systems sit at 0, including Tailwind-native shadcn/ui).
236
+ const NO_ABSENCE_RULE = new Set(['colors', 'greys', 'arbitrary']);
235
237
  function healthOf(metric, value) {
236
238
  const iv = ideal(metric);
237
239
  if (iv === null) return 'info';
@@ -272,7 +274,7 @@ function tile(value, label, metric, fallbackTarget, healthValue = value) {
272
274
  : clean !== null && clean >= 60 ? ` · cleaner than ${clean}%` : '';
273
275
  const av = displayAvg(metric);
274
276
  if (av !== null) rows.push(row('Avg Design System', `${n(av)}${avgNote}`, av, value));
275
- if (rm !== null && (rm > 0 || ZERO_IDEAL.has(metric))) rows.push(row('Reputable systems', n(rm), rm, value));
277
+ if (rm !== null && (rm > 0 || ZERO_IDEAL.has(metric) || metric === 'arbitrary')) rows.push(row('Reputable systems', n(rm), rm, value));
276
278
  return { num: n(value), label, health, rows };
277
279
  }
278
280
  const bigStats = [
@@ -281,10 +283,7 @@ const bigStats = [
281
283
  tile(spacingTotal, 'off-scale spacing values', 'spacing', 'a dozen deliberate exceptions'),
282
284
  tile(hardDupes.length, 'duplicated components', 'exactDuplicates', 'should be 0'),
283
285
  tile(inline.count, 'inline style blocks', 'inlineStyles', 'invisible to any system'),
284
- { num: String(reusable.length), label: 'components defined', health: 'info',
285
- rows: [ { label: 'the raw material', val: '', dir: '' },
286
- ...(median('components') ? [{ label: 'Avg Design System', val: n(median('components')), dir: '' }] : []),
287
- ...(refMedian('components') ? [{ label: 'Reputable systems', val: n(refMedian('components')), dir: '' }] : []) ] },
286
+ tile(arbitraryCount, 'arbitrary bracket values', 'arbitrary', 'a handful of deliberate exceptions'),
288
287
  ];
289
288
 
290
289
  // Health score for the hero: the scored tiles averaged (good 100 / warn 55 / bad 10).
@@ -472,7 +471,7 @@ function componentsSection() {
472
471
  <td class="path">${esc(c.file)}</td>
473
472
  <td>${c.propsHint?.named?.length ? c.propsHint.named.slice(0, 5).map((p) => `<span class="chip chip-xs">${esc(p)}</span>`).join(' ') : '<span class="dim">none</span>'}</td></tr>`).join('');
474
473
  return `<section class="glass pad">
475
- ${sectionHead('What you actually use', 'top components by adoption · the real system, buried in here')}
474
+ ${sectionHead('What you actually use', `${n(reusable.length)} components defined · top by adoption · the real system, buried in here`)}
476
475
  <div class="tbl-wrap"><table><thead><tr><th>component</th><th>used</th><th>defined in</th><th>props</th></tr></thead><tbody>${rows}</tbody></table></div></section>`;
477
476
  }
478
477