Scan complete · 253ms · 1,709 code files

Design System Diagnosis

adobe/spectrum-web-components · scanned 2026-09-01
Health score
66/100
web components (Lit)TypeScriptplain CSScustom design system (--spectrum-*)monorepoalso present: --swc-*, --mod-*, --system-*AGENTS.md.cursor/rules
Summary
20 typefaces, brands use 2 or 3. 56 hardcoded colours outside the token set, your agent will happily copy them at random. 40 !important declarations, the cascade admitting defeat.

Where to start

Three tweaks · 66 → 94

01
Unwind the 40 !important declarations
+11
Each one is a selector losing an argument with another selector; typography.css alone carries 8. Fix the specificity at the source and they stop being necessary.
paste it into your agent ·
02
Collapse the 5 near-identical colours
+11
#f5f5f5 and #f8f8f8 are the same colour to any eye, and they are used 11 times between them. Nobody chose to have both. Pick the one that is already a token, point the other at it, and the pair stops multiplying.
paste it into your agent ·
03
Tokenise the 56 stray colours
+6
They are hardcoded where no token names them; 2nd-gen/packages/core/controllers/focusgroup-navigation-controller/stories/demo-hosts.ts alone carries 45. Every one is a value your agent will happily copy.
paste it into your agent ·

You sat through the roast

so you get a present.

Agent trap. 8px appears 43 times. An agent looking for how this repo does spacing reads repetition as intent, so it will write occurrence 44. The most copied pattern here is the one you least want copied.
Agent trap. 40 !important declarations, and each one is a shouting match a previous developer decided to win by force. An agent whose style will not apply does what the repo taught it and shouts louder. The volume in this codebase only goes up.
1,358
distinct colours
Ideal Design System~24
Avg Design System130 · messier than 97%
Reputable systems24
45
shades of grey
Ideal Design System~13
Avg Design System17
Reputable systems5
26
off-scale spacing values
Ideal Design System~12
Avg Design System34
Reputable systems6
0
duplicated components
Ideal Design System0 =
Avg Design System20 · cleaner than 85%
Reputable systems12
0
inline style blocks
Ideal Design System0 =
Avg Design System49 · cleaner than 85%
Reputable systems12
5
near-identical colour pairs
Ideal Design System0
Avg Design System13
Reputable systems1
40
!important declarations
Ideal Design System0
Avg Design System7 · messier than 74%
Reputable systems3
0
components never imported
Ideal Design System0 =
Avg Design System14
Reputable systems0 =
library: internal use only, downstream consumers invisible
0
arbitrary bracket values
Ideal Design System~20
Avg Design System70 · cleaner than 71%
Reputable systems0 =

Package by package

2 packages with enough UI to judge · the repo score above is the whole thing blended, and 90 packages were too small or too backend to score

packagescoreworst findingsize
2nd-gen/packages/swc 90 27 !important declarations 176 files
1st-gen/tools/styles 95 1 !important declarations 7 files

A repo scores below its own packages by arithmetic, not by accident: distinct values add up across packages, so the whole always carries more than any part. Read the package scores for where each team stands, and the repo score for what your agent sees when it looks at everything at once.

What your AI agent sees today

Your agent reads AGENTS.md, .cursor/rules. But none of it points at a single source of truth for components and tokens, because there isn't one yet. The numbers below are what your agent actually works from.

AGENTS.md · generic (AGENTS.md standard).cursor/rules · Cursor
4 rule references gone stale · a rule your agent obeys is worse than no rule when the repo has moved on
@spectrum-web-components/COMPONENT/sp-COMPONENT.js named in .cursor/rules/component-readme.mdc, but the path no longer exists
2nd-gen/packages/swc/components/component-name/Component.ts named in .cursor/rules/stories-documentation.mdc, but the path no longer exists
2nd-gen/packages/core/components/component-name/Component.base.ts named in .cursor/rules/stories-documentation.mdc, but the path no longer exists
../../stylelint.config.js named in .cursor/rules/styles.mdc, but the path no longer exists

Rules rot quietly: nobody edits them when a component is renamed or a file moves. Regenerate them from a fresh scan, or fix the lines by hand.

Palette
1,358colours

A healthy product palette is up to ~24 colours: one brand hue with a few tints, one accent, up to 13 greys, and status colours.

1,302 tokens56 strays
Colour usage
Sized by how often each is used
token stray
+1298
Grey ramp · sorted dark → light · how many can you tell apart?
5 nearly identical pairs · copy-paste, not decisions
#f5f5f5 ×10 #f8f8f8 ×1#ffffff ×7 #f8f8f8 ×1#6d6d6d ×4 #666666 ×1#faf0ff ×3 #f8f8f8 ×1#c0c0c0 ×2 #bbbbbb ×2

26 off-scale spacing values

a disciplined repo keeps these around a dozen · on-scale Tailwind steps (·) shown for context · off-scale in coral

8px
43
12px
21
-1px
13
4px
11
2px
7
6px
6
20px
5
10px
5
3px
4
16px
4
24px
3
14px
3
1em
2
0px
1
-999em
1
30px
1
29px
1
-44px
1

Typography & shape

20
typefaces
Ideal Design System~3
Avg Design System3 · messier than 100%
Reputable systems1
231
font sizes
Ideal Design System~10
Avg Design System20 · messier than 100%
Reputable systems6
165
border radii
Ideal Design System~10
Avg Design System13 · messier than 100%
Reputable systems2
37
shadow styles
Ideal Design System~6
Avg Design System2 · messier than 97%
Reputable systems1
the type scale, at its real sizes · how many of these are the same decision?
1.125rem ×1 Almost but not quite
0.875rem ×2 Almost but not quite
14px ×1 Almost but not quite
0.75rem ×1 Almost but not quite
the corners, drawn · 165 radii in one interface
4px ×28
5px ×14
100% ×11
8px ×11
12px ×9
16px ×8
20px ×7
9px ×7
50% ×6
6px ×5
15px ×4
10px ×4
2px ×3
1px ×1

20 typefaces, declared 67 different ways

every distinct declaration is a chance for the next one to be wrong

token("sans-serif-font")×17
var(--mod-button-font-family, var(--mod-sans-font-family-stack, var(--×6
var(--mod-body-sans-serif-font-family, var(--spectrum-body-sans-serif-×4
var(--mod-heading-cjk-font-family, var(--spectrum-heading-cjk-font-fam×4
var(--mod-body-cjk-font-family, var(--spectrum-body-cjk-font-family))×4
var(--mod-detail-cjk-font-family, var(--spectrum-detail-cjk-font-famil×4
var(--mod-code-cjk-font-family, var(--spectrum-code-cjk-font-family))×4
token("serif-font")×4

Where it hurts most

the 5 files carrying the most off-system styling

40 !important declarations

styling no system can see

40 !important declarations · the cascade admitting defeat
typography.css ×8card-template.css ×6illustrated-message.css ×4tooltip.css ×4overlay.css ×3tooltip.css ×3

The composition map

68 components defined · tile area is internal use: how the system builds from itself, downstream consumers invisible from here · the real system, drawn to scale

6 components are imported exactly once: <Breadcrumbs>, <ColorField>, <ContextualHelp>, <CssTable>, <OnionSkinner>, <StoryDecorator>. Quiet corners, not yet a system.

componentuseddefined inprops
<BreadcrumbItem> 1st-gen/packages/breadcrumbs/sp-breadcrumb-item.ts none
<InfieldButton> 1st-gen/packages/infield-button/sp-infield-button.ts none
<Theme> 1st-gen/tools/theme/sp-theme.ts none
<Combobox> 1st-gen/packages/combobox/sp-combobox.ts none
<Breadcrumbs> 1st-gen/packages/breadcrumbs/sp-breadcrumbs.ts none
<ColorField> 1st-gen/packages/color-field/sp-color-field.ts none
<ContextualHelp> 1st-gen/packages/contextual-help/sp-contextual-help.ts none
<CssTable> 1st-gen/projects/css-custom-vars-viewer/src/sp-css-table.ts none
<OnionSkinner> 1st-gen/projects/vrt-compare/onion-skinner.ts none
<StoryDecorator> 1st-gen/projects/story-decorator/sp-story-decorator.ts none