designlang 7.2.0 → 9.0.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/CHANGELOG.md +69 -0
- package/README.md +154 -13
- package/bin/design-extract.js +94 -1
- package/package.json +9 -3
- package/src/config.js +2 -0
- package/src/crawler.js +55 -6
- package/src/drift.js +137 -0
- package/src/extractors/accessibility.js +44 -1
- package/src/extractors/colors.js +50 -12
- package/src/extractors/component-anatomy.js +123 -0
- package/src/extractors/motion.js +184 -0
- package/src/extractors/scoring.js +49 -30
- package/src/extractors/voice.js +96 -0
- package/src/formatters/markdown.js +88 -0
- package/src/formatters/motion-tokens.js +22 -0
- package/src/index.js +14 -0
- package/src/lint.js +198 -0
- package/src/visual-diff.js +116 -0
- package/.github/FUNDING.yml +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -62
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -28
- package/.github/og-preview.png +0 -0
- package/.github/workflows/manavarya-bot.yml +0 -17
- package/chrome-extension/README.md +0 -41
- package/chrome-extension/icons/favicon.svg +0 -7
- package/chrome-extension/icons/icon-128.png +0 -0
- package/chrome-extension/icons/icon-16.png +0 -0
- package/chrome-extension/icons/icon-32.png +0 -0
- package/chrome-extension/icons/icon-48.png +0 -0
- package/chrome-extension/manifest.json +0 -26
- package/chrome-extension/popup.html +0 -167
- package/chrome-extension/popup.js +0 -59
- package/docs/superpowers/plans/2026-04-18-designlang-v7.md +0 -1121
- package/docs/superpowers/specs/2026-04-18-designlang-v7-design.md +0 -150
- package/docs/superpowers/specs/2026-04-18-website-redesign-design.md +0 -120
- package/docs/superpowers/specs/2026-04-19-designlang-v7-1-design.md +0 -111
- package/tests/cli.test.js +0 -84
- package/tests/cookies.test.js +0 -98
- package/tests/extractors.test.js +0 -792
- package/tests/formatters.test.js +0 -709
- package/tests/interaction-states.test.js +0 -62
- package/tests/mcp.test.js +0 -68
- package/tests/modern-css.test.js +0 -104
- package/tests/routes-reconciliation.test.js +0 -120
- package/tests/utils.test.js +0 -413
- package/tests/wide-gamut.test.js +0 -90
- package/website/.claude/launch.json +0 -11
- package/website/AGENTS.md +0 -5
- package/website/CLAUDE.md +0 -1
- package/website/README.md +0 -36
- package/website/app/api/extract/route.js +0 -245
- package/website/app/components/A11ySlider.js +0 -369
- package/website/app/components/Comparison.js +0 -286
- package/website/app/components/CssHealth.js +0 -243
- package/website/app/components/Extractor.js +0 -184
- package/website/app/components/HeroExtractor.js +0 -455
- package/website/app/components/Marginalia.js +0 -3
- package/website/app/components/McpSection.js +0 -223
- package/website/app/components/PlatformTabs.js +0 -250
- package/website/app/components/RegionsComponents.js +0 -429
- package/website/app/components/Rule.js +0 -13
- package/website/app/components/Specimens.js +0 -237
- package/website/app/components/StructuredData.js +0 -144
- package/website/app/components/TokenBrowser.js +0 -344
- package/website/app/components/token-browser-sample.js +0 -65
- package/website/app/globals.css +0 -505
- package/website/app/icon.svg +0 -7
- package/website/app/layout.js +0 -126
- package/website/app/opengraph-image.js +0 -170
- package/website/app/page.js +0 -399
- package/website/app/robots.js +0 -15
- package/website/app/seo-config.js +0 -82
- package/website/app/sitemap.js +0 -18
- package/website/jsconfig.json +0 -7
- package/website/lib/cache.js +0 -73
- package/website/lib/rate-limit.js +0 -30
- package/website/lib/rate-limit.test.js +0 -55
- package/website/lib/specimens.json +0 -86
- package/website/lib/token-helpers.js +0 -70
- package/website/lib/url-safety.js +0 -103
- package/website/lib/url-safety.test.js +0 -116
- package/website/lib/zip-files.js +0 -15
- package/website/next.config.mjs +0 -15
- package/website/package-lock.json +0 -1353
- package/website/package.json +0 -19
- package/website/public/favicon.svg +0 -7
- package/website/public/logo-specimen.svg +0 -76
- package/website/public/mark.svg +0 -12
- package/website/public/site.webmanifest +0 -13
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { ImageResponse } from 'next/og';
|
|
2
|
-
|
|
3
|
-
export const runtime = 'nodejs';
|
|
4
|
-
export const alt =
|
|
5
|
-
'designlang specimen card. A lowercase d built from a ring, a stem, and one extracted orange token, next to the wordmark designlang in Fraunces with a molten-orange period, and a five-swatch palette strip.';
|
|
6
|
-
export const size = { width: 1200, height: 630 };
|
|
7
|
-
export const contentType = 'image/png';
|
|
8
|
-
|
|
9
|
-
const PAPER = '#F3F1EA';
|
|
10
|
-
const INK = '#0A0908';
|
|
11
|
-
const INK_2 = '#403C34';
|
|
12
|
-
const INK_3 = '#8B8778';
|
|
13
|
-
const ACCENT = '#FF4800';
|
|
14
|
-
|
|
15
|
-
export default async function OpengraphImage() {
|
|
16
|
-
return new ImageResponse(
|
|
17
|
-
(
|
|
18
|
-
<div
|
|
19
|
-
style={{
|
|
20
|
-
width: '100%',
|
|
21
|
-
height: '100%',
|
|
22
|
-
background: PAPER,
|
|
23
|
-
color: INK,
|
|
24
|
-
display: 'flex',
|
|
25
|
-
flexDirection: 'column',
|
|
26
|
-
justifyContent: 'space-between',
|
|
27
|
-
padding: 56,
|
|
28
|
-
fontFamily: 'Georgia, serif',
|
|
29
|
-
border: `2px solid ${INK}`,
|
|
30
|
-
}}
|
|
31
|
-
>
|
|
32
|
-
{/* top caption strip */}
|
|
33
|
-
<div
|
|
34
|
-
style={{
|
|
35
|
-
display: 'flex',
|
|
36
|
-
justifyContent: 'space-between',
|
|
37
|
-
fontFamily: 'ui-monospace, Menlo, monospace',
|
|
38
|
-
fontSize: 16,
|
|
39
|
-
color: INK_2,
|
|
40
|
-
letterSpacing: 2,
|
|
41
|
-
textTransform: 'uppercase',
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
45
|
-
<span>SPECIMEN / 01</span>
|
|
46
|
-
<span>EXTRACTED 2026</span>
|
|
47
|
-
</div>
|
|
48
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 4, textAlign: 'right' }}>
|
|
49
|
-
<span>v7.0</span>
|
|
50
|
-
<span>W3C DTCG</span>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
|
|
54
|
-
{/* wordmark row */}
|
|
55
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: 48 }}>
|
|
56
|
-
{/* mark */}
|
|
57
|
-
<div
|
|
58
|
-
style={{
|
|
59
|
-
position: 'relative',
|
|
60
|
-
width: 150,
|
|
61
|
-
height: 180,
|
|
62
|
-
display: 'flex',
|
|
63
|
-
}}
|
|
64
|
-
>
|
|
65
|
-
{/* counter ring */}
|
|
66
|
-
<div
|
|
67
|
-
style={{
|
|
68
|
-
position: 'absolute',
|
|
69
|
-
left: 0,
|
|
70
|
-
bottom: 0,
|
|
71
|
-
width: 116,
|
|
72
|
-
height: 116,
|
|
73
|
-
border: `24px solid ${INK}`,
|
|
74
|
-
borderRadius: '50%',
|
|
75
|
-
}}
|
|
76
|
-
/>
|
|
77
|
-
{/* stem */}
|
|
78
|
-
<div
|
|
79
|
-
style={{
|
|
80
|
-
position: 'absolute',
|
|
81
|
-
left: 92,
|
|
82
|
-
top: 0,
|
|
83
|
-
width: 26,
|
|
84
|
-
height: 180,
|
|
85
|
-
background: INK,
|
|
86
|
-
}}
|
|
87
|
-
/>
|
|
88
|
-
{/* extracted token */}
|
|
89
|
-
<div
|
|
90
|
-
style={{
|
|
91
|
-
position: 'absolute',
|
|
92
|
-
left: 122,
|
|
93
|
-
top: 150,
|
|
94
|
-
width: 30,
|
|
95
|
-
height: 30,
|
|
96
|
-
background: ACCENT,
|
|
97
|
-
}}
|
|
98
|
-
/>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
{/* word + tagline */}
|
|
102
|
-
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
103
|
-
<div
|
|
104
|
-
style={{
|
|
105
|
-
fontSize: 128,
|
|
106
|
-
lineHeight: 1,
|
|
107
|
-
letterSpacing: -4,
|
|
108
|
-
display: 'flex',
|
|
109
|
-
alignItems: 'baseline',
|
|
110
|
-
}}
|
|
111
|
-
>
|
|
112
|
-
<span style={{ color: INK }}>designlang</span>
|
|
113
|
-
<span style={{ color: ACCENT }}>.</span>
|
|
114
|
-
</div>
|
|
115
|
-
<div
|
|
116
|
-
style={{
|
|
117
|
-
marginTop: 14,
|
|
118
|
-
fontSize: 22,
|
|
119
|
-
fontStyle: 'italic',
|
|
120
|
-
color: INK_2,
|
|
121
|
-
fontFamily: 'Helvetica, Arial, sans-serif',
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
reads a website the way a developer reads a stylesheet.
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
|
|
129
|
-
{/* bottom: palette + command */}
|
|
130
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
|
|
131
|
-
<div style={{ display: 'flex', gap: 14 }}>
|
|
132
|
-
{[INK, INK_2, INK_3, '#D8D3C5', ACCENT].map((c) => (
|
|
133
|
-
<div key={c} style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
134
|
-
<div style={{ width: 56, height: 56, background: c }} />
|
|
135
|
-
<span
|
|
136
|
-
style={{
|
|
137
|
-
fontFamily: 'ui-monospace, Menlo, monospace',
|
|
138
|
-
fontSize: 12,
|
|
139
|
-
color: INK_2,
|
|
140
|
-
letterSpacing: 1,
|
|
141
|
-
}}
|
|
142
|
-
>
|
|
143
|
-
{c}
|
|
144
|
-
</span>
|
|
145
|
-
</div>
|
|
146
|
-
))}
|
|
147
|
-
</div>
|
|
148
|
-
<div
|
|
149
|
-
style={{
|
|
150
|
-
display: 'flex',
|
|
151
|
-
flexDirection: 'column',
|
|
152
|
-
gap: 6,
|
|
153
|
-
textAlign: 'right',
|
|
154
|
-
fontFamily: 'ui-monospace, Menlo, monospace',
|
|
155
|
-
fontSize: 16,
|
|
156
|
-
letterSpacing: 1.2,
|
|
157
|
-
color: INK_2,
|
|
158
|
-
}}
|
|
159
|
-
>
|
|
160
|
-
<span>$ npx designlang <url></span>
|
|
161
|
-
<span style={{ color: INK_3 }}>MIT · Node ≥ 20 · Playwright</span>
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
),
|
|
166
|
-
{
|
|
167
|
-
...size,
|
|
168
|
-
}
|
|
169
|
-
);
|
|
170
|
-
}
|
package/website/app/page.js
DELETED
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
import Rule from './components/Rule';
|
|
2
|
-
import Marginalia from './components/Marginalia';
|
|
3
|
-
import HeroExtractor from './components/HeroExtractor';
|
|
4
|
-
import TokenBrowser from './components/TokenBrowser';
|
|
5
|
-
import McpSection from './components/McpSection';
|
|
6
|
-
import PlatformTabs from './components/PlatformTabs';
|
|
7
|
-
import CssHealth from './components/CssHealth';
|
|
8
|
-
import A11ySlider from './components/A11ySlider';
|
|
9
|
-
import RegionsComponents from './components/RegionsComponents';
|
|
10
|
-
import Specimens from './components/Specimens';
|
|
11
|
-
import Comparison from './components/Comparison';
|
|
12
|
-
|
|
13
|
-
export default function Home() {
|
|
14
|
-
return (
|
|
15
|
-
<main className="page">
|
|
16
|
-
{/* ── HEAD SLUG ─────────────────────────────────────── */}
|
|
17
|
-
<header style={{ paddingTop: 'var(--r4)', paddingBottom: 'var(--r5)' }}>
|
|
18
|
-
<div
|
|
19
|
-
style={{
|
|
20
|
-
display: 'flex',
|
|
21
|
-
justifyContent: 'space-between',
|
|
22
|
-
alignItems: 'baseline',
|
|
23
|
-
gap: 'var(--r5)',
|
|
24
|
-
borderBottom: 'var(--hair)',
|
|
25
|
-
paddingBottom: 'var(--r3)',
|
|
26
|
-
}}
|
|
27
|
-
>
|
|
28
|
-
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
|
|
29
|
-
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
30
|
-
<img src="/mark.svg" alt="" width={22} height={22} style={{ display: 'block' }} />
|
|
31
|
-
<span className="mono" style={{ fontSize: 13, letterSpacing: '0.02em' }}>
|
|
32
|
-
designlang
|
|
33
|
-
<span style={{ color: 'var(--ink-3)', marginLeft: 12 }}>v7.0</span>
|
|
34
|
-
</span>
|
|
35
|
-
</span>
|
|
36
|
-
<nav
|
|
37
|
-
className="mono"
|
|
38
|
-
style={{ display: 'flex', gap: 'var(--r5)', fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.1em' }}
|
|
39
|
-
>
|
|
40
|
-
<a href="#extract" style={{ borderBottom: 0 }}>Extract</a>
|
|
41
|
-
<a href="#features" style={{ borderBottom: 0 }}>Features</a>
|
|
42
|
-
<a href="#specimens" style={{ borderBottom: 0 }}>Specimens</a>
|
|
43
|
-
<a href="#install" style={{ borderBottom: 0 }}>Install</a>
|
|
44
|
-
<a href="https://github.com/Manavarya09/design-extract" style={{ borderBottom: 0 }}>GitHub</a>
|
|
45
|
-
<a href="https://www.npmjs.com/package/designlang" style={{ borderBottom: 0 }}>npm</a>
|
|
46
|
-
</nav>
|
|
47
|
-
</div>
|
|
48
|
-
</header>
|
|
49
|
-
|
|
50
|
-
{/* ── §00 HERO ──────────────────────────────────────── */}
|
|
51
|
-
<section id="extract" style={{ paddingBlock: 'var(--r7) var(--r8)', borderTop: 0 }}>
|
|
52
|
-
<div className="with-margin">
|
|
53
|
-
<div>
|
|
54
|
-
<div className="section-label" style={{ marginBottom: 'var(--r6)' }}>
|
|
55
|
-
<span>§00 — Entry</span>
|
|
56
|
-
</div>
|
|
57
|
-
<h1
|
|
58
|
-
className="display hero-title"
|
|
59
|
-
style={{ marginBottom: 'var(--r7)' }}
|
|
60
|
-
>
|
|
61
|
-
A website<br />
|
|
62
|
-
reads as a<br />
|
|
63
|
-
<em style={{ fontStyle: 'italic', color: 'var(--accent)' }}>design system</em>.
|
|
64
|
-
</h1>
|
|
65
|
-
<p className="prose" style={{ fontSize: 20, lineHeight: 1.4, maxWidth: '46ch' }}>
|
|
66
|
-
designlang crawls any URL and returns its complete design language —
|
|
67
|
-
tokens, typography, spacing, shadows, components, regions, health,
|
|
68
|
-
remediations — in W3C DTCG format, with native emitters for iOS,
|
|
69
|
-
Android, Flutter and WordPress, and a live MCP server your editor can read.
|
|
70
|
-
</p>
|
|
71
|
-
</div>
|
|
72
|
-
<Marginalia>
|
|
73
|
-
<div>extraction runtime</div>
|
|
74
|
-
<div>
|
|
75
|
-
<code>Playwright 1.59</code>
|
|
76
|
-
<br />
|
|
77
|
-
<code>@sparticuz/chromium</code>
|
|
78
|
-
</div>
|
|
79
|
-
<hr style={{ margin: '12px 0', border: 0, borderTop: '1px solid var(--ink-3)' }} />
|
|
80
|
-
<div>default invocation</div>
|
|
81
|
-
<div><code>$ npx designlang <url></code></div>
|
|
82
|
-
<p className="foot" style={{ marginTop: 12 }}>
|
|
83
|
-
Works without install. Playwright fetches Chromium on first run;
|
|
84
|
-
≈ 3–6 seconds per page on a modern laptop.
|
|
85
|
-
</p>
|
|
86
|
-
</Marginalia>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<HeroExtractor />
|
|
90
|
-
</section>
|
|
91
|
-
|
|
92
|
-
{/* ── §01 DTCG BROWSER ──────────────────────────────── */}
|
|
93
|
-
<section id="features">
|
|
94
|
-
<Rule number="01" label="DTCG token browser" />
|
|
95
|
-
<div style={{ padding: 'var(--r6) 0' }}>
|
|
96
|
-
<TokenBrowser />
|
|
97
|
-
</div>
|
|
98
|
-
</section>
|
|
99
|
-
|
|
100
|
-
{/* ── §02 MCP ───────────────────────────────────────── */}
|
|
101
|
-
<section>
|
|
102
|
-
<Rule number="02" label="MCP server" />
|
|
103
|
-
<McpSection />
|
|
104
|
-
</section>
|
|
105
|
-
|
|
106
|
-
{/* ── §03 MULTI-PLATFORM ────────────────────────────── */}
|
|
107
|
-
<section>
|
|
108
|
-
<Rule number="03" label="Multi-platform emitters" />
|
|
109
|
-
<PlatformTabs />
|
|
110
|
-
</section>
|
|
111
|
-
|
|
112
|
-
{/* ── §04 HEALTH ────────────────────────────────────── */}
|
|
113
|
-
<section>
|
|
114
|
-
<CssHealth />
|
|
115
|
-
</section>
|
|
116
|
-
|
|
117
|
-
{/* ── §05 REMEDIATION ───────────────────────────────── */}
|
|
118
|
-
<section>
|
|
119
|
-
<A11ySlider />
|
|
120
|
-
</section>
|
|
121
|
-
|
|
122
|
-
{/* ── §06 REGIONS + COMPONENTS ──────────────────────── */}
|
|
123
|
-
<section>
|
|
124
|
-
<RegionsComponents />
|
|
125
|
-
</section>
|
|
126
|
-
|
|
127
|
-
{/* ── §07 SPECIMENS ─────────────────────────────────── */}
|
|
128
|
-
<section id="specimens">
|
|
129
|
-
<Rule number="07" label="Specimens" />
|
|
130
|
-
<Specimens />
|
|
131
|
-
</section>
|
|
132
|
-
|
|
133
|
-
{/* ── §08 COMPARISON ────────────────────────────────── */}
|
|
134
|
-
<section>
|
|
135
|
-
<Rule number="08" label="Compared" />
|
|
136
|
-
<Comparison />
|
|
137
|
-
</section>
|
|
138
|
-
|
|
139
|
-
{/* ── §09 INSTALL ───────────────────────────────────── */}
|
|
140
|
-
<section id="install" style={{ paddingBottom: 'var(--r9)' }}>
|
|
141
|
-
<Rule number="09" label="Install" />
|
|
142
|
-
<InstallTracks />
|
|
143
|
-
</section>
|
|
144
|
-
|
|
145
|
-
{/* ── FOOTER ───────────────────────────────────────── */}
|
|
146
|
-
<SiteFooter />
|
|
147
|
-
</main>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function InstallTracks() {
|
|
152
|
-
const preStyle = {
|
|
153
|
-
padding: 'var(--r4) var(--r5)',
|
|
154
|
-
background: 'var(--ink)',
|
|
155
|
-
color: 'var(--paper)',
|
|
156
|
-
fontSize: 13,
|
|
157
|
-
lineHeight: 1.7,
|
|
158
|
-
overflowX: 'auto',
|
|
159
|
-
whiteSpace: 'pre',
|
|
160
|
-
};
|
|
161
|
-
const colHead = {
|
|
162
|
-
fontFamily: 'var(--font-mono)',
|
|
163
|
-
fontSize: 11,
|
|
164
|
-
letterSpacing: '0.14em',
|
|
165
|
-
textTransform: 'uppercase',
|
|
166
|
-
color: 'var(--ink-2)',
|
|
167
|
-
marginBottom: 'var(--r3)',
|
|
168
|
-
};
|
|
169
|
-
const colTitle = {
|
|
170
|
-
fontSize: 36,
|
|
171
|
-
lineHeight: 1,
|
|
172
|
-
letterSpacing: '-0.02em',
|
|
173
|
-
marginBottom: 'var(--r4)',
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
return (
|
|
177
|
-
<div style={{ marginTop: 'var(--r5)' }}>
|
|
178
|
-
<div className="install-grid">
|
|
179
|
-
{/* CLI */}
|
|
180
|
-
<div className="install-col">
|
|
181
|
-
<div style={colHead}>track 01</div>
|
|
182
|
-
<h3 className="display" style={colTitle}>CLI</h3>
|
|
183
|
-
<p style={{ fontSize: 14, color: 'var(--ink-2)', marginBottom: 'var(--r3)', maxWidth: '34ch' }}>
|
|
184
|
-
Zero install via npx. Node ≥ 20.
|
|
185
|
-
</p>
|
|
186
|
-
<pre className="mono" style={preStyle}>
|
|
187
|
-
{`1 $ npx designlang <url>
|
|
188
|
-
2 $ npx designlang <url> --platforms all
|
|
189
|
-
3 $ npx designlang <url> --emit-agent-rules
|
|
190
|
-
4 $ npx designlang <url> --cookie-file ./cookies.txt
|
|
191
|
-
5 $ npx designlang <url> --insecure
|
|
192
|
-
6 $ npx designlang <url> --user-agent "custom-ua"
|
|
193
|
-
7 $ npx designlang <url> --tokens-legacy`}
|
|
194
|
-
</pre>
|
|
195
|
-
</div>
|
|
196
|
-
|
|
197
|
-
{/* MCP */}
|
|
198
|
-
<div className="install-col">
|
|
199
|
-
<div style={colHead}>track 02</div>
|
|
200
|
-
<h3 className="display" style={colTitle}>MCP server</h3>
|
|
201
|
-
<p className="mono" style={{ fontSize: 11, color: 'var(--ink-3)', marginBottom: 'var(--r3)' }}>
|
|
202
|
-
claude_desktop_config.json / ~/.cursor/mcp.json
|
|
203
|
-
</p>
|
|
204
|
-
<pre className="mono" style={preStyle}>
|
|
205
|
-
{`{
|
|
206
|
-
"mcpServers": {
|
|
207
|
-
"designlang": {
|
|
208
|
-
"command": "npx",
|
|
209
|
-
"args": [
|
|
210
|
-
"designlang",
|
|
211
|
-
"mcp",
|
|
212
|
-
"--output-dir",
|
|
213
|
-
"./design-extract-output"
|
|
214
|
-
]
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}`}
|
|
218
|
-
</pre>
|
|
219
|
-
<p style={{ fontSize: 13, color: 'var(--ink-2)', marginTop: 'var(--r3)', fontStyle: 'italic', fontFamily: 'var(--font-display)' }}>
|
|
220
|
-
Once connected, every MCP-aware agent can query your last extraction.
|
|
221
|
-
</p>
|
|
222
|
-
</div>
|
|
223
|
-
|
|
224
|
-
{/* Agent rules */}
|
|
225
|
-
<div className="install-col">
|
|
226
|
-
<div style={colHead}>track 03</div>
|
|
227
|
-
<h3 className="display" style={colTitle}>Agent rules</h3>
|
|
228
|
-
<p style={{ fontSize: 14, color: 'var(--ink-2)', marginBottom: 'var(--r3)', maxWidth: '34ch' }}>
|
|
229
|
-
One flag emits ready-to-commit rules for every popular agent.
|
|
230
|
-
</p>
|
|
231
|
-
<pre className="mono" style={preStyle}>
|
|
232
|
-
{`$ npx designlang <url> --emit-agent-rules`}
|
|
233
|
-
</pre>
|
|
234
|
-
<ul
|
|
235
|
-
className="mono"
|
|
236
|
-
style={{
|
|
237
|
-
listStyle: 'none',
|
|
238
|
-
padding: 0,
|
|
239
|
-
marginTop: 'var(--r3)',
|
|
240
|
-
fontSize: 12,
|
|
241
|
-
lineHeight: 1.9,
|
|
242
|
-
color: 'var(--ink-2)',
|
|
243
|
-
}}
|
|
244
|
-
>
|
|
245
|
-
<li>.cursor/rules/designlang.mdc</li>
|
|
246
|
-
<li>.claude/skills/designlang/SKILL.md</li>
|
|
247
|
-
<li>CLAUDE.md.fragment</li>
|
|
248
|
-
<li>agents.md</li>
|
|
249
|
-
</ul>
|
|
250
|
-
</div>
|
|
251
|
-
|
|
252
|
-
{/* Chrome extension */}
|
|
253
|
-
<div className="install-col">
|
|
254
|
-
<div style={colHead}>track 04 · new in v7.1</div>
|
|
255
|
-
<h3 className="display" style={colTitle}>Chrome extension</h3>
|
|
256
|
-
<p style={{ fontSize: 14, color: 'var(--ink-2)', marginBottom: 'var(--r3)', maxWidth: '34ch' }}>
|
|
257
|
-
One click from any tab. Opens this page with the URL prefilled.
|
|
258
|
-
</p>
|
|
259
|
-
<ol
|
|
260
|
-
className="mono"
|
|
261
|
-
style={{
|
|
262
|
-
padding: 0,
|
|
263
|
-
margin: 0,
|
|
264
|
-
listStylePosition: 'inside',
|
|
265
|
-
fontSize: 12,
|
|
266
|
-
lineHeight: 1.9,
|
|
267
|
-
color: 'var(--ink-2)',
|
|
268
|
-
}}
|
|
269
|
-
>
|
|
270
|
-
<li>clone the repo</li>
|
|
271
|
-
<li>open <code style={{ color: 'var(--ink)' }}>chrome://extensions</code></li>
|
|
272
|
-
<li>toggle developer mode</li>
|
|
273
|
-
<li>load unpacked → <code style={{ color: 'var(--ink)' }}>chrome-extension/</code></li>
|
|
274
|
-
</ol>
|
|
275
|
-
<p style={{ fontSize: 13, color: 'var(--ink-2)', marginTop: 'var(--r4)', fontStyle: 'italic', fontFamily: 'var(--font-display)' }}>
|
|
276
|
-
Manifest v3. Only permission: <code className="mono" style={{ fontStyle: 'normal' }}>activeTab</code>.
|
|
277
|
-
</p>
|
|
278
|
-
<a
|
|
279
|
-
href="https://github.com/Manavarya09/design-extract/tree/main/chrome-extension"
|
|
280
|
-
target="_blank"
|
|
281
|
-
rel="noopener"
|
|
282
|
-
className="mono"
|
|
283
|
-
style={{ display: 'inline-block', marginTop: 'var(--r3)', fontSize: 12, letterSpacing: '0.06em', textTransform: 'uppercase' }}
|
|
284
|
-
>
|
|
285
|
-
source →
|
|
286
|
-
</a>
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
|
|
290
|
-
<style>{`
|
|
291
|
-
.install-grid {
|
|
292
|
-
display: grid;
|
|
293
|
-
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
294
|
-
gap: 0;
|
|
295
|
-
}
|
|
296
|
-
.install-col {
|
|
297
|
-
padding: 0 var(--r4);
|
|
298
|
-
}
|
|
299
|
-
.install-col:first-child { padding-left: 0; }
|
|
300
|
-
.install-col:last-child { padding-right: 0; }
|
|
301
|
-
.install-col + .install-col {
|
|
302
|
-
border-left: 1px solid var(--ink);
|
|
303
|
-
}
|
|
304
|
-
@media (max-width: 1100px) {
|
|
305
|
-
.install-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
|
|
306
|
-
.install-col { padding: var(--r4) var(--r4); }
|
|
307
|
-
.install-col:nth-child(2n+1) { padding-left: 0; }
|
|
308
|
-
.install-col:nth-child(2n) { padding-right: 0; }
|
|
309
|
-
.install-col:nth-child(n+3) { border-top: 1px solid var(--ink); }
|
|
310
|
-
.install-col:nth-child(2n+1) { border-left: 0; }
|
|
311
|
-
}
|
|
312
|
-
@media (max-width: 640px) {
|
|
313
|
-
.install-grid { grid-template-columns: 1fr; gap: 0; }
|
|
314
|
-
.install-col { padding: var(--r5) 0; border-left: 0 !important; }
|
|
315
|
-
.install-col + .install-col { border-top: 1px solid var(--ink); }
|
|
316
|
-
}
|
|
317
|
-
`}</style>
|
|
318
|
-
</div>
|
|
319
|
-
);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
function SiteFooter() {
|
|
323
|
-
const colHead = {
|
|
324
|
-
fontFamily: 'var(--font-mono)',
|
|
325
|
-
fontSize: 11,
|
|
326
|
-
letterSpacing: '0.14em',
|
|
327
|
-
textTransform: 'uppercase',
|
|
328
|
-
color: 'var(--ink-2)',
|
|
329
|
-
marginBottom: 'var(--r3)',
|
|
330
|
-
};
|
|
331
|
-
const linkStyle = {
|
|
332
|
-
display: 'block',
|
|
333
|
-
fontFamily: 'var(--font-mono)',
|
|
334
|
-
fontSize: 12,
|
|
335
|
-
padding: '6px 0',
|
|
336
|
-
borderBottom: '1px solid var(--paper-3)',
|
|
337
|
-
color: 'var(--ink)',
|
|
338
|
-
};
|
|
339
|
-
return (
|
|
340
|
-
<footer style={{ paddingBottom: 'var(--r7)' }}>
|
|
341
|
-
<div className="rule" role="separator" aria-label="end">
|
|
342
|
-
<div className="rule-line" />
|
|
343
|
-
<div className="chip mono" style={{ textTransform: 'uppercase', letterSpacing: '0.14em' }}>END</div>
|
|
344
|
-
</div>
|
|
345
|
-
|
|
346
|
-
<div
|
|
347
|
-
className="grid-12"
|
|
348
|
-
style={{ paddingTop: 'var(--r6)', paddingBottom: 'var(--r5)' }}
|
|
349
|
-
>
|
|
350
|
-
<div style={{ gridColumn: 'span 3' }}>
|
|
351
|
-
<div className="mono" style={{ fontSize: 14, letterSpacing: '0.02em' }}>designlang</div>
|
|
352
|
-
<p style={{ fontSize: 12, color: 'var(--ink-2)', marginTop: 8, fontFamily: 'var(--font-mono)' }}>
|
|
353
|
-
Built in Node, Playwright, and opinion.
|
|
354
|
-
</p>
|
|
355
|
-
</div>
|
|
356
|
-
|
|
357
|
-
<div style={{ gridColumn: 'span 3' }}>
|
|
358
|
-
<div style={colHead}>community</div>
|
|
359
|
-
<a href="https://github.com/Manavarya09/design-extract" style={linkStyle}>GitHub</a>
|
|
360
|
-
<a href="https://www.npmjs.com/package/designlang" style={linkStyle}>npm</a>
|
|
361
|
-
<a href="https://github.com/Manavarya09/design-extract/discussions" style={linkStyle}>Discussions</a>
|
|
362
|
-
<a href="https://github.com/Manavarya09/design-extract/issues" style={linkStyle}>Issues</a>
|
|
363
|
-
<a href="https://github.com/sponsors/Manavarya09" style={linkStyle}>Sponsor</a>
|
|
364
|
-
</div>
|
|
365
|
-
|
|
366
|
-
<div style={{ gridColumn: 'span 3' }}>
|
|
367
|
-
<div style={colHead}>reference</div>
|
|
368
|
-
<a href="https://github.com/Manavarya09/design-extract#cli" style={linkStyle}>CLI docs</a>
|
|
369
|
-
<a href="https://github.com/Manavarya09/design-extract#mcp" style={linkStyle}>MCP server</a>
|
|
370
|
-
<a href="https://github.com/Manavarya09/design-extract#agent-rules" style={linkStyle}>Cursor rules</a>
|
|
371
|
-
<a href="https://github.com/Manavarya09/design-extract/blob/main/CHANGELOG.md" style={linkStyle}>CHANGELOG</a>
|
|
372
|
-
</div>
|
|
373
|
-
|
|
374
|
-
<div style={{ gridColumn: 'span 3' }}>
|
|
375
|
-
<div style={colHead}>colophon</div>
|
|
376
|
-
<p style={{ fontSize: 12, color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', lineHeight: 1.6 }}>
|
|
377
|
-
v7.0 · MIT · Manav Arya Singh · 2026.
|
|
378
|
-
</p>
|
|
379
|
-
<p style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 10, fontFamily: 'var(--font-mono)', lineHeight: 1.6 }}>
|
|
380
|
-
Set in Fraunces (Undercase), Instrument Sans (Instrument), and JetBrains Mono (JetBrains).
|
|
381
|
-
</p>
|
|
382
|
-
</div>
|
|
383
|
-
</div>
|
|
384
|
-
|
|
385
|
-
<div
|
|
386
|
-
className="mono"
|
|
387
|
-
style={{
|
|
388
|
-
fontSize: 11,
|
|
389
|
-
color: 'var(--ink-3)',
|
|
390
|
-
borderTop: '1px solid var(--paper-3)',
|
|
391
|
-
paddingTop: 'var(--r3)',
|
|
392
|
-
letterSpacing: '0.04em',
|
|
393
|
-
}}
|
|
394
|
-
>
|
|
395
|
-
Extracted, not generated.
|
|
396
|
-
</div>
|
|
397
|
-
</footer>
|
|
398
|
-
);
|
|
399
|
-
}
|
package/website/app/robots.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
export const SITE_URL = 'https://designlang.manavaryasingh.com';
|
|
2
|
-
export const SITE_NAME = 'designlang';
|
|
3
|
-
|
|
4
|
-
export const SITE_TITLE =
|
|
5
|
-
"designlang \u2014 Extract any website's design system as DTCG tokens, MCP, iOS, Android, Flutter, WordPress";
|
|
6
|
-
|
|
7
|
-
export const SITE_DESCRIPTION =
|
|
8
|
-
'designlang is an open-source CLI that reverse-engineers any website into a complete design system \u2014 W3C DTCG tokens (primitive, semantic, composite), Tailwind, CSS variables, Figma variables, shadcn/ui theme, React / Vue / Svelte themes, iOS SwiftUI, Android Compose, Flutter, WordPress block theme, plus a stdio MCP server for Claude Code, Cursor, and Windsurf. CSS health audit, WCAG remediation, semantic region classifier, reusable component clustering, dark-mode diff, auth-gated crawling. One command, zero install.';
|
|
9
|
-
|
|
10
|
-
export const SITE_KEYWORDS = [
|
|
11
|
-
'design system extractor',
|
|
12
|
-
'extract design system from website',
|
|
13
|
-
'extract design tokens from url',
|
|
14
|
-
'website to design tokens',
|
|
15
|
-
'website to tailwind config',
|
|
16
|
-
'website to figma variables',
|
|
17
|
-
'W3C DTCG',
|
|
18
|
-
'W3C design tokens',
|
|
19
|
-
'DTCG tokens',
|
|
20
|
-
'design tokens format',
|
|
21
|
-
'design tokens generator',
|
|
22
|
-
'design token extractor',
|
|
23
|
-
'design tokens from website',
|
|
24
|
-
'semantic tokens',
|
|
25
|
-
'primitive tokens',
|
|
26
|
-
'alias tokens',
|
|
27
|
-
'composite tokens',
|
|
28
|
-
'style dictionary alternative',
|
|
29
|
-
'tokens studio alternative',
|
|
30
|
-
'subframe alternative',
|
|
31
|
-
'v0 alternative',
|
|
32
|
-
'builder.io alternative',
|
|
33
|
-
'project wallace alternative',
|
|
34
|
-
'supernova alternative',
|
|
35
|
-
'specify alternative',
|
|
36
|
-
'css extractor',
|
|
37
|
-
'extract css from website',
|
|
38
|
-
'website to css variables',
|
|
39
|
-
'website to shadcn theme',
|
|
40
|
-
'shadcn theme generator',
|
|
41
|
-
'shadcn/ui theme extractor',
|
|
42
|
-
'tailwind config generator',
|
|
43
|
-
'tailwind preset from website',
|
|
44
|
-
'react theme from website',
|
|
45
|
-
'figma variables generator',
|
|
46
|
-
'figma variables from website',
|
|
47
|
-
'figma tokens import',
|
|
48
|
-
'iOS SwiftUI tokens',
|
|
49
|
-
'Android Jetpack Compose tokens',
|
|
50
|
-
'Flutter theme from website',
|
|
51
|
-
'WordPress block theme generator',
|
|
52
|
-
'multi-platform design tokens',
|
|
53
|
-
'MCP server design tokens',
|
|
54
|
-
'MCP server Claude Code',
|
|
55
|
-
'MCP server Cursor',
|
|
56
|
-
'MCP server Windsurf',
|
|
57
|
-
'Claude Code design rules',
|
|
58
|
-
'Cursor project rules',
|
|
59
|
-
'Claude Code skills',
|
|
60
|
-
'AGENTS.md design system',
|
|
61
|
-
'design tokens MCP',
|
|
62
|
-
'agent rules emitter',
|
|
63
|
-
'CSS health audit',
|
|
64
|
-
'CSS specificity audit',
|
|
65
|
-
'unused CSS analyzer',
|
|
66
|
-
'WCAG contrast remediation',
|
|
67
|
-
'accessibility remediation',
|
|
68
|
-
'color contrast fixer',
|
|
69
|
-
'semantic regions classifier',
|
|
70
|
-
'component cluster detection',
|
|
71
|
-
'reusable component detection',
|
|
72
|
-
'dark mode diff',
|
|
73
|
-
'responsive breakpoint capture',
|
|
74
|
-
'interaction state capture',
|
|
75
|
-
'Playwright design extractor',
|
|
76
|
-
'headless browser design extraction',
|
|
77
|
-
'open source design system tool',
|
|
78
|
-
'CLI design system tool',
|
|
79
|
-
'npx designlang',
|
|
80
|
-
'designlang',
|
|
81
|
-
'Manav Arya Singh',
|
|
82
|
-
];
|
package/website/app/sitemap.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { SITE_URL } from './seo-config';
|
|
2
|
-
|
|
3
|
-
export default function sitemap() {
|
|
4
|
-
const now = new Date();
|
|
5
|
-
const anchors = [
|
|
6
|
-
'',
|
|
7
|
-
'#extract',
|
|
8
|
-
'#features',
|
|
9
|
-
'#specimens',
|
|
10
|
-
'#install',
|
|
11
|
-
];
|
|
12
|
-
return anchors.map((hash) => ({
|
|
13
|
-
url: `${SITE_URL}/${hash}`,
|
|
14
|
-
lastModified: now,
|
|
15
|
-
changeFrequency: 'weekly',
|
|
16
|
-
priority: hash === '' ? 1 : 0.8,
|
|
17
|
-
}));
|
|
18
|
-
}
|