zark-design 1.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.
Files changed (31) hide show
  1. package/README.md +60 -0
  2. package/bin/cli.js +177 -0
  3. package/package.json +31 -0
  4. package/templates/REFERENCE.md +376 -0
  5. package/templates/SHOWCASE.html +254 -0
  6. package/templates/assets/zark-icon.png +0 -0
  7. package/templates/assets/zark-logo.png +0 -0
  8. package/templates/brand.jsx +89 -0
  9. package/templates/components.jsx +385 -0
  10. package/templates/design-canvas.jsx +789 -0
  11. package/templates/foundations.jsx +363 -0
  12. package/templates/icons.jsx +65 -0
  13. package/templates/layouts.jsx +232 -0
  14. package/templates/patterns.jsx +268 -0
  15. package/templates/primitives.jsx +306 -0
  16. package/templates/tokens.css +306 -0
  17. package/templates/visual-references/icon-zark.png +0 -0
  18. package/templates/visual-references/logo-zark-principal.png +0 -0
  19. package/templates/visual-references/pasted-1777605750385-0.png +0 -0
  20. package/templates/visual-references/pasted-1777605766298-0.png +0 -0
  21. package/templates/visual-references/pasted-1777605775820-0.png +0 -0
  22. package/templates/visual-references/pasted-1777605789833-0.png +0 -0
  23. package/templates/visual-references/pasted-1777605802420-0.png +0 -0
  24. package/templates/visual-references/pasted-1777605812470-0.png +0 -0
  25. package/templates/visual-references/pasted-1777605817688-0.png +0 -0
  26. package/templates/visual-references/pasted-1777605828485-0.png +0 -0
  27. package/templates/visual-references/pasted-1777605837137-0.png +0 -0
  28. package/templates/visual-references/pasted-1777605849789-0.png +0 -0
  29. package/templates/visual-references/pasted-1777605864942-0.png +0 -0
  30. package/templates/visual-references/pasted-1777605877920-0.png +0 -0
  31. package/templates/visual-references/pasted-1777605897353-0.png +0 -0
@@ -0,0 +1,363 @@
1
+ // Zark — Foundation sections (colors, type, spacing, radii, shadows, motion, icons)
2
+
3
+ const Swatch = ({ name, value, tone='dark' }) => (
4
+ <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
5
+ <div style={{
6
+ height: 80, borderRadius:'var(--r-lg)',
7
+ background: value,
8
+ border: tone==='light' ? '1px solid var(--line-200)' : 'none',
9
+ boxShadow: 'var(--shadow-xs)',
10
+ position:'relative', overflow:'hidden',
11
+ }}>
12
+ <span style={{
13
+ position:'absolute', bottom:8, left:10,
14
+ fontFamily:'var(--font-mono)', fontSize: 10,
15
+ color: tone==='light' ? 'var(--ink-500)' : 'rgba(255,255,255,0.85)',
16
+ }}>{value}</span>
17
+ </div>
18
+ <div style={{ display:'flex', justifyContent:'space-between', fontSize:11 }}>
19
+ <span style={{ color:'var(--ink-600)', fontWeight: 500 }}>{name}</span>
20
+ </div>
21
+ </div>
22
+ );
23
+
24
+ const ColorRamp = ({ title, prefix, steps, tones }) => (
25
+ <Panel title={title} kicker={`${steps.length} stops`}>
26
+ <div style={{ display:'grid', gridTemplateColumns:`repeat(${steps.length}, 1fr)`, gap: 8 }}>
27
+ {steps.map((step, i) => (
28
+ <Swatch key={step}
29
+ name={step}
30
+ value={`var(--${prefix}-${step})`}
31
+ tone={tones[i] || 'dark'}
32
+ />
33
+ ))}
34
+ </div>
35
+ </Panel>
36
+ );
37
+
38
+ const ColorsSection = () => (
39
+ <Section
40
+ id="colors"
41
+ eyebrow="01 — Colors"
42
+ title="A warm, ember-driven palette"
43
+ description="Tones lean warm to evoke a paper-and-ink feel. The orange ember scale carries brand and primary action; neutrals are subtly toned and never pure-cool gray. Semantic colors are reserved exclusively for system feedback."
44
+ >
45
+ <ColorRamp
46
+ title="Ember — Brand & primary action"
47
+ prefix="ember"
48
+ steps={[50,100,200,300,400,500,600,700,800,900]}
49
+ tones={['light','light','light','dark','dark','dark','dark','dark','dark','dark']}
50
+ />
51
+ <ColorRamp
52
+ title="Ink — Text & UI neutrals"
53
+ prefix="ink"
54
+ steps={[50,100,200,300,400,500,600,700,800,900]}
55
+ tones={['light','light','light','light','dark','dark','dark','dark','dark','dark']}
56
+ />
57
+
58
+ <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
59
+ <Panel title="Surface & lines" kicker="paper, canvas, hairlines">
60
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap: 8 }}>
61
+ <Swatch name="paper" value="var(--paper)" tone="light"/>
62
+ <Swatch name="canvas" value="var(--canvas)" tone="light"/>
63
+ <Swatch name="surface" value="var(--surface)" tone="light"/>
64
+ <Swatch name="line-100" value="var(--line-100)" tone="light"/>
65
+ <Swatch name="line-200" value="var(--line-200)" tone="light"/>
66
+ <Swatch name="line-300" value="var(--line-300)" tone="light"/>
67
+ </div>
68
+ <div style={{ marginTop: 16, fontSize: 12, color:'var(--ink-400)', lineHeight: 1.5 }}>
69
+ App background uses <strong style={{color:'var(--ink-600)'}}>paper</strong>. Sidebar shifts to <strong style={{color:'var(--ink-600)'}}>canvas</strong>. Cards always sit on pure <strong style={{color:'var(--ink-600)'}}>surface</strong>. Hairlines are all warm-toned.
70
+ </div>
71
+ </Panel>
72
+
73
+ <Panel title="Semantic" kicker="status only">
74
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 8 }}>
75
+ <Swatch name="success" value="var(--success-500)"/>
76
+ <Swatch name="warning" value="var(--warning-500)"/>
77
+ <Swatch name="danger" value="var(--danger-500)"/>
78
+ <Swatch name="info" value="var(--info-500)"/>
79
+ </div>
80
+ <div style={{ marginTop:16, display:'flex', flexWrap:'wrap', gap:8 }}>
81
+ <Tag tone="success">Completed</Tag>
82
+ <Tag tone="warning">Pending</Tag>
83
+ <Tag tone="danger">Failed</Tag>
84
+ <Tag tone="info">Live</Tag>
85
+ <Tag tone="ember">New</Tag>
86
+ <Tag tone="default">Optional</Tag>
87
+ </div>
88
+ </Panel>
89
+ </div>
90
+
91
+ <Panel title="Usage rules" kicker="when to reach for what">
92
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap: 24 }}>
93
+ <div>
94
+ <div style={{ fontSize:12, fontWeight:600, color:'var(--ember-700)', marginBottom: 8 }}>Ember</div>
95
+ <ul style={{ margin: 0, padding: '0 0 0 16px', fontSize: 12, color:'var(--ink-500)', lineHeight: 1.7 }}>
96
+ <li>Primary CTAs (Upgrade, Start)</li>
97
+ <li>Selected nav state (soft tint)</li>
98
+ <li>Live data accents on charts</li>
99
+ <li>Keyword highlights in copy</li>
100
+ </ul>
101
+ </div>
102
+ <div>
103
+ <div style={{ fontSize:12, fontWeight:600, color:'var(--ink-700)', marginBottom: 8 }}>Ink</div>
104
+ <ul style={{ margin: 0, padding: '0 0 0 16px', fontSize: 12, color:'var(--ink-500)', lineHeight: 1.7 }}>
105
+ <li>Body copy: ink-700</li>
106
+ <li>Secondary copy: ink-400</li>
107
+ <li>Disabled / placeholder: ink-300</li>
108
+ <li>Footer chrome: ink-800</li>
109
+ </ul>
110
+ </div>
111
+ <div>
112
+ <div style={{ fontSize:12, fontWeight:600, color:'var(--info-700)', marginBottom: 8 }}>Semantic</div>
113
+ <ul style={{ margin: 0, padding: '0 0 0 16px', fontSize: 12, color:'var(--ink-500)', lineHeight: 1.7 }}>
114
+ <li>Use only for status / feedback</li>
115
+ <li>Always pair with an icon</li>
116
+ <li>Avoid using as decoration</li>
117
+ <li>50-tints for subtle backgrounds</li>
118
+ </ul>
119
+ </div>
120
+ </div>
121
+ </Panel>
122
+ </Section>
123
+ );
124
+
125
+ // ---------- TYPOGRAPHY ----------
126
+ const TypeRow = ({ size, name, sample, weight, ls, lh, mono }) => (
127
+ <div style={{
128
+ display:'grid', gridTemplateColumns:'140px 1fr 220px',
129
+ gap:24, padding:'20px 0',
130
+ borderTop:'1px solid var(--line-100)',
131
+ alignItems:'baseline',
132
+ }}>
133
+ <div>
134
+ <div style={{ fontSize:12, color:'var(--ink-600)', fontWeight: 500 }}>{name}</div>
135
+ <div style={{ fontSize:10, color:'var(--ink-300)', fontFamily:'var(--font-mono)', marginTop: 2 }}>{size}px / {weight}</div>
136
+ </div>
137
+ <div style={{
138
+ fontFamily: mono ? 'var(--font-mono)' : 'var(--font-display)',
139
+ fontSize: size, fontWeight: weight,
140
+ letterSpacing: ls, lineHeight: lh,
141
+ color:'var(--ink-700)',
142
+ }}>{sample}</div>
143
+ <div style={{ fontSize:11, color:'var(--ink-400)', fontFamily:'var(--font-mono)' }}>
144
+ ls: {ls} · lh: {lh}
145
+ </div>
146
+ </div>
147
+ );
148
+
149
+ const TypographySection = () => (
150
+ <Section
151
+ id="type"
152
+ eyebrow="02 — Typography"
153
+ title="Inter Tight for display, Inter for UI, JetBrains Mono for technical"
154
+ description="The display face is tight and confident — used at large sizes for hero moments and section titles. UI text uses Inter at standard tracking. Mono is reserved for code, keys, IDs, and the small uppercase eyebrows that mark categories."
155
+ >
156
+ <Panel title="Type scale" kicker="display & UI" padded={false}>
157
+ <div style={{ padding:'8px 24px 24px' }}>
158
+ <TypeRow size={88} name="Display" sample="Turn data into signal" weight={600} ls="-0.025em" lh={1.05}/>
159
+ <TypeRow size={48} name="H1" sample="Activity Logs" weight={600} ls="-0.02em" lh={1.1}/>
160
+ <TypeRow size={36} name="H2" sample="Explore our endpoints" weight={600} ls="-0.018em" lh={1.15}/>
161
+ <TypeRow size={28} name="H3" sample="Where did you hear about us?" weight={600} ls="-0.015em" lh={1.2}/>
162
+ <TypeRow size={22} name="H4" sample="Concurrent Browsers" weight={600} ls="-0.012em" lh={1.25}/>
163
+ <TypeRow size={18} name="Lead" sample="API, docs and playground — all in one place" weight={500} ls="-0.005em" lh={1.4}/>
164
+ <TypeRow size={14} name="Body" sample="Power your applications with our comprehensive scraping API." weight={400} ls="0" lh={1.55}/>
165
+ <TypeRow size={13} name="Body sm" sample="Take a look at your requests activity" weight={400} ls="0" lh={1.5}/>
166
+ <TypeRow size={12} name="Caption" sample="Credit usage differs" weight={400} ls="0" lh={1.45}/>
167
+ <TypeRow size={11} name="Eyebrow" sample="STEP 2 OF 4" weight={500} ls="0.14em" lh={1.4} mono/>
168
+ <TypeRow size={12} name="Mono" sample="fc-9••••••••••••aebf" weight={400} ls="0" lh={1.5} mono/>
169
+ </div>
170
+ </Panel>
171
+
172
+ <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:24 }}>
173
+ <Panel title="Font families" kicker="3 faces, no exceptions">
174
+ <div style={{ display:'flex', flexDirection:'column', gap: 16 }}>
175
+ <div>
176
+ <div style={{ fontFamily:'var(--font-display)', fontSize: 32, fontWeight: 600, letterSpacing:'-0.018em', color:'var(--ink-700)', lineHeight: 1.1 }}>Inter Tight</div>
177
+ <div style={{ fontFamily:'var(--font-mono)', fontSize: 10, color:'var(--ink-400)', marginTop: 4 }}>display · 500 / 600 / 700</div>
178
+ </div>
179
+ <div>
180
+ <div style={{ fontFamily:'var(--font-sans)', fontSize: 24, fontWeight: 500, color:'var(--ink-700)' }}>Inter</div>
181
+ <div style={{ fontFamily:'var(--font-mono)', fontSize: 10, color:'var(--ink-400)', marginTop: 4 }}>UI · 400 / 500 / 600</div>
182
+ </div>
183
+ <div>
184
+ <div style={{ fontFamily:'var(--font-mono)', fontSize: 22, color:'var(--ink-700)' }}>JetBrains Mono</div>
185
+ <div style={{ fontFamily:'var(--font-mono)', fontSize: 10, color:'var(--ink-400)', marginTop: 4 }}>code, keys, eyebrows · 400 / 500</div>
186
+ </div>
187
+ </div>
188
+ </Panel>
189
+
190
+ <Panel title="Pairings in context" kicker="rhythm">
191
+ <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
192
+ <div>
193
+ <div style={{ fontFamily:'var(--font-mono)', fontSize: 11, letterSpacing:'var(--ls-widest)', textTransform:'uppercase', color:'var(--ember-600)', marginBottom: 6 }}>02 — TYPOGRAPHY</div>
194
+ <div style={{ fontFamily:'var(--font-display)', fontSize: 28, fontWeight: 600, letterSpacing:'-0.015em', color:'var(--ink-700)', lineHeight: 1.15 }}>The mono carries the meta</div>
195
+ <div style={{ fontSize: 14, color:'var(--ink-400)', marginTop: 8, lineHeight: 1.55 }}>Inter handles supporting copy at body sizes — comfortable to read in long blocks, comfortable to compress in tables.</div>
196
+ </div>
197
+ <div style={{ height: 1, background:'var(--line-100)' }}/>
198
+ <div>
199
+ <div style={{ fontFamily:'var(--font-display)', fontSize: 36, fontWeight: 600, letterSpacing:'-0.02em', color:'var(--ink-700)', lineHeight: 1.05 }}>
200
+ Turn websites into <span style={{ color:'var(--ember-500)' }}>LLM-ready</span> data
201
+ </div>
202
+ </div>
203
+ </div>
204
+ </Panel>
205
+ </div>
206
+ </Section>
207
+ );
208
+
209
+ // ---------- SPACING / RADII / SHADOWS / MOTION ----------
210
+ const SpacingSection = () => {
211
+ const steps = [
212
+ {n:1, v:2}, {n:2, v:4}, {n:3, v:6}, {n:4, v:8}, {n:5, v:10},
213
+ {n:6, v:12}, {n:7, v:14}, {n:8, v:16}, {n:10, v:20}, {n:12, v:24},
214
+ {n:14, v:28}, {n:16, v:32}, {n:20, v:40}, {n:24, v:48}, {n:32, v:64}, {n:40, v:80}, {n:48, v:96},
215
+ ];
216
+ const radii = [
217
+ {n:'xs', v:'3px'}, {n:'sm', v:'4px'}, {n:'md', v:'6px'},
218
+ {n:'lg', v:'8px'}, {n:'xl', v:'12px'}, {n:'2xl', v:'16px'}, {n:'3xl', v:'20px'}, {n:'pill', v:'999px'},
219
+ ];
220
+ const shadows = [
221
+ {n:'xs', v:'var(--shadow-xs)'},
222
+ {n:'sm', v:'var(--shadow-sm)'},
223
+ {n:'md', v:'var(--shadow-md)'},
224
+ {n:'lg', v:'var(--shadow-lg)'},
225
+ {n:'xl', v:'var(--shadow-xl)'},
226
+ {n:'modal', v:'var(--shadow-modal)'},
227
+ ];
228
+ return (
229
+ <Section
230
+ id="space"
231
+ eyebrow="03 — Spacing, radii, shadows"
232
+ title="A 4-pixel base, never broken"
233
+ description="Density is high but never cramped. The spacing scale uses 4px as its atom; smaller increments exist (2px, 6px) for fine adjustment. Radii grow with surface size — chips are pill-shaped, inputs use 8px, cards 12px, modals 16px."
234
+ >
235
+ <Panel title="Spacing scale" kicker="4px atom">
236
+ <div style={{ display:'flex', flexDirection:'column', gap: 4 }}>
237
+ {steps.map(s => (
238
+ <div key={s.n} style={{ display:'grid', gridTemplateColumns:'80px 60px 1fr', gap:12, alignItems:'center', fontSize: 11, fontFamily:'var(--font-mono)', color:'var(--ink-500)', padding:'4px 0' }}>
239
+ <span style={{ color:'var(--ink-700)' }}>--sp-{s.n}</span>
240
+ <span style={{ color:'var(--ink-300)' }}>{s.v}px</span>
241
+ <span style={{ height: 14, width: s.v, background:'var(--ember-300)', borderRadius:2 }}/>
242
+ </div>
243
+ ))}
244
+ </div>
245
+ </Panel>
246
+
247
+ <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
248
+ <Panel title="Radii" kicker="surface size → corner size">
249
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 16 }}>
250
+ {radii.map(r => (
251
+ <div key={r.n} style={{ textAlign:'center' }}>
252
+ <div style={{
253
+ width:'100%', aspectRatio:'1/1',
254
+ background:'var(--ember-50)',
255
+ border:'1px solid var(--ember-200)',
256
+ borderRadius: r.v, marginBottom: 8,
257
+ }}/>
258
+ <div style={{ fontSize:11, color:'var(--ink-600)', fontWeight: 500 }}>r-{r.n}</div>
259
+ <div style={{ fontSize:10, color:'var(--ink-300)', fontFamily:'var(--font-mono)' }}>{r.v}</div>
260
+ </div>
261
+ ))}
262
+ </div>
263
+ </Panel>
264
+
265
+ <Panel title="Shadows" kicker="elevation steps">
266
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap: 20 }}>
267
+ {shadows.map(s => (
268
+ <div key={s.n}>
269
+ <div style={{
270
+ height: 70, background:'var(--surface)',
271
+ borderRadius:'var(--r-lg)', boxShadow: s.v,
272
+ marginBottom: 8,
273
+ }}/>
274
+ <div style={{ fontSize:11, color:'var(--ink-600)' }}>shadow-{s.n}</div>
275
+ </div>
276
+ ))}
277
+ </div>
278
+ </Panel>
279
+ </div>
280
+
281
+ <Panel title="Motion" kicker="curves & timings">
282
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 24, fontSize: 12 }}>
283
+ <div>
284
+ <div style={{ color:'var(--ink-600)', fontWeight: 600, marginBottom: 8 }}>Easings</div>
285
+ <Spec mono label="ease-out" value="(0.22, 1, 0.36, 1)"/>
286
+ <Spec mono label="in-out" value="(0.65, 0, 0.35, 1)"/>
287
+ <Spec mono label="spring" value="(0.34, 1.56, 0.64, 1)"/>
288
+ </div>
289
+ <div>
290
+ <div style={{ color:'var(--ink-600)', fontWeight: 600, marginBottom: 8 }}>Durations</div>
291
+ <Spec mono label="t-fast" value="120ms"/>
292
+ <Spec mono label="t-base" value="180ms"/>
293
+ <Spec mono label="t-slow" value="280ms"/>
294
+ <Spec mono label="t-slower" value="420ms"/>
295
+ </div>
296
+ <div style={{ gridColumn:'span 2' }}>
297
+ <div style={{ color:'var(--ink-600)', fontWeight: 600, marginBottom: 8 }}>Rules</div>
298
+ <ul style={{ margin: 0, padding:'0 0 0 16px', color:'var(--ink-500)', lineHeight: 1.7 }}>
299
+ <li>Hover/press: <strong style={{color:'var(--ink-700)'}}>t-fast / ease-out</strong></li>
300
+ <li>Toggle, tab, dropdown: <strong style={{color:'var(--ink-700)'}}>t-base / ease-out</strong></li>
301
+ <li>Modal entrance: <strong style={{color:'var(--ink-700)'}}>t-slow / spring</strong> for scale, <strong style={{color:'var(--ink-700)'}}>t-base</strong> for fade</li>
302
+ <li>Page transitions: avoid; let content swap instantly with subtle fade only</li>
303
+ </ul>
304
+ </div>
305
+ </div>
306
+ </Panel>
307
+ </Section>
308
+ );
309
+ };
310
+
311
+ // ---------- ICONS ----------
312
+ const IconsSection = () => {
313
+ const list = [
314
+ 'Search','Home','Play','Extract','Activity','Usage','Key','Settings',
315
+ 'Bell','Help','Docs','Upgrade','ChevDown','ChevUp','ChevLeft','ChevRight',
316
+ 'Plus','Close','Check','Eye','Copy','Download','Upload','External',
317
+ 'Filter','Calendar','Cmd','Sparkles','Globe','Code','Spinner','Stop','Share','Warning','Drag','Flame'
318
+ ];
319
+ return (
320
+ <Section
321
+ id="icons"
322
+ eyebrow="04 — Iconography"
323
+ title="One stroke weight, one personality"
324
+ description="Outline icons drawn on an 18px grid with a 1.5px stroke and round caps. They sit at 16px in dense UI (nav, inputs) and 18–20px in section headers. Filled flames and shapes are the only exception, used for the brand mark."
325
+ >
326
+ <Panel title="The set" kicker={`${list.length} symbols`}>
327
+ <div style={{ display:'grid', gridTemplateColumns:'repeat(8, 1fr)', gap: 4 }}>
328
+ {list.map(name => {
329
+ const I = Icons[name];
330
+ return (
331
+ <div key={name} style={{
332
+ display:'flex', flexDirection:'column', alignItems:'center', gap: 6,
333
+ padding:'14px 6px', borderRadius:'var(--r-md)',
334
+ color:'var(--ink-600)',
335
+ transition:'background var(--t-fast)', cursor:'default',
336
+ }} onMouseEnter={e=>e.currentTarget.style.background='var(--paper)'}
337
+ onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
338
+ <I size={20}/>
339
+ <span style={{ fontSize:10, color:'var(--ink-400)', fontFamily:'var(--font-mono)' }}>{name}</span>
340
+ </div>
341
+ );
342
+ })}
343
+ </div>
344
+ </Panel>
345
+
346
+ <Panel title="Sizes & contexts">
347
+ <div style={{ display:'flex', alignItems:'center', gap: 32, color:'var(--ink-600)' }}>
348
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={12}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>12 · inline</span></div>
349
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={14}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>14 · button</span></div>
350
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={16}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>16 · nav / input</span></div>
351
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={20}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>20 · section</span></div>
352
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={24}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>24 · feature</span></div>
353
+ <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}><Icons.Search size={32}/><span style={{ fontSize:10, fontFamily:'var(--font-mono)', color:'var(--ink-400)' }}>32 · empty state</span></div>
354
+ </div>
355
+ </Panel>
356
+ </Section>
357
+ );
358
+ };
359
+
360
+ window.ColorsSection = ColorsSection;
361
+ window.TypographySection = TypographySection;
362
+ window.SpacingSection = SpacingSection;
363
+ window.IconsSection = IconsSection;
@@ -0,0 +1,65 @@
1
+ // Zark Icon Set — outline, 1.5px stroke, 18px viewBox, currentColor
2
+ // Modeled after the simple line iconography of the source.
3
+
4
+ const Ico = ({ d, size = 16, stroke = 1.5, fill = 'none', children, vb = 18, ...rest }) => (
5
+ <svg
6
+ width={size}
7
+ height={size}
8
+ viewBox={`0 0 ${vb} ${vb}`}
9
+ fill={fill}
10
+ stroke="currentColor"
11
+ strokeWidth={stroke}
12
+ strokeLinecap="round"
13
+ strokeLinejoin="round"
14
+ aria-hidden="true"
15
+ {...rest}
16
+ >
17
+ {d ? <path d={d} /> : children}
18
+ </svg>
19
+ );
20
+
21
+ const Icons = {
22
+ Search: (p) => <Ico {...p}><circle cx="8" cy="8" r="5"/><path d="M15 15l-3-3"/></Ico>,
23
+ Home: (p) => <Ico {...p}><path d="M3 9l6-5 6 5v6a1 1 0 0 1-1 1h-3v-4H7v4H4a1 1 0 0 1-1-1V9z"/></Ico>,
24
+ Play: (p) => <Ico {...p}><circle cx="9" cy="9" r="6.5"/><path d="M7.5 6.5l4 2.5-4 2.5z" fill="currentColor"/></Ico>,
25
+ Extract: (p) => <Ico {...p}><path d="M3 4h12M3 9h8M3 14h12"/><path d="M14 6l2 2-2 2"/></Ico>,
26
+ Activity: (p) => <Ico {...p}><path d="M2 9h3l2-5 4 10 2-5h3"/></Ico>,
27
+ Usage: (p) => <Ico {...p}><path d="M3 14h12"/><rect x="4" y="9" width="2" height="5"/><rect x="8" y="6" width="2" height="8"/><rect x="12" y="3" width="2" height="11"/></Ico>,
28
+ Key: (p) => <Ico {...p}><circle cx="6" cy="9" r="3"/><path d="M9 9h7l-2 2 2 2"/></Ico>,
29
+ Settings: (p) => <Ico {...p}><circle cx="9" cy="9" r="2.5"/><path d="M9 1.5v2M9 14.5v2M16.5 9h-2M3.5 9h-2M14.3 3.7l-1.4 1.4M5.1 12.9l-1.4 1.4M14.3 14.3l-1.4-1.4M5.1 5.1L3.7 3.7"/></Ico>,
30
+ Bell: (p) => <Ico {...p}><path d="M4 12V8a5 5 0 0 1 10 0v4l1 1H3l1-1z"/><path d="M7.5 15a1.5 1.5 0 0 0 3 0"/></Ico>,
31
+ Help: (p) => <Ico {...p}><circle cx="9" cy="9" r="6.5"/><path d="M7 7a2 2 0 0 1 4 0c0 1-2 1.5-2 3"/><circle cx="9" cy="13" r="0.7" fill="currentColor"/></Ico>,
32
+ Docs: (p) => <Ico {...p}><path d="M4 2h7l3 3v11H4z"/><path d="M11 2v3h3M6 8h6M6 11h6M6 14h4"/></Ico>,
33
+ Upgrade: (p) => <Ico {...p}><path d="M9 3l5 5h-3v6H7V8H4l5-5z"/></Ico>,
34
+ ChevDown: (p) => <Ico {...p}><path d="M4 7l5 4 5-4"/></Ico>,
35
+ ChevUp: (p) => <Ico {...p}><path d="M4 11l5-4 5 4"/></Ico>,
36
+ ChevLeft: (p) => <Ico {...p}><path d="M11 4L7 9l4 5"/></Ico>,
37
+ ChevRight: (p) => <Ico {...p}><path d="M7 4l4 5-4 5"/></Ico>,
38
+ Plus: (p) => <Ico {...p}><path d="M9 3v12M3 9h12"/></Ico>,
39
+ Close: (p) => <Ico {...p}><path d="M4 4l10 10M14 4L4 14"/></Ico>,
40
+ Check: (p) => <Ico {...p}><path d="M3 9l4 4 8-9"/></Ico>,
41
+ Eye: (p) => <Ico {...p}><path d="M1.5 9S4 4 9 4s7.5 5 7.5 5-2.5 5-7.5 5-7.5-5-7.5-5z"/><circle cx="9" cy="9" r="2.2"/></Ico>,
42
+ Copy: (p) => <Ico {...p}><rect x="5" y="5" width="9" height="10" rx="1.5"/><path d="M11 5V4a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h1"/></Ico>,
43
+ Download: (p) => <Ico {...p}><path d="M9 3v9M5 9l4 4 4-4M3 15h12"/></Ico>,
44
+ Upload: (p) => <Ico {...p}><path d="M9 13V4M5 7l4-4 4 4M3 15h12"/></Ico>,
45
+ External: (p) => <Ico {...p}><path d="M7 3H4v11h11v-3"/><path d="M10 3h5v5M15 3l-7 7"/></Ico>,
46
+ Filter: (p) => <Ico {...p}><path d="M3 4h12l-4.5 6V15l-3-2v-3z"/></Ico>,
47
+ Calendar: (p) => <Ico {...p}><rect x="3" y="4" width="12" height="11" rx="1.5"/><path d="M3 7h12M6 2v3M12 2v3"/></Ico>,
48
+ Cmd: (p) => <Ico {...p}><path d="M5 5h8v8H5z"/><path d="M5 5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM13 5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM5 13a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM13 13a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3z"/></Ico>,
49
+ Sparkles: (p) => <Ico {...p}><path d="M9 2l1.5 4.5L15 8l-4.5 1.5L9 14l-1.5-4.5L3 8l4.5-1.5L9 2z"/></Ico>,
50
+ Globe: (p) => <Ico {...p}><circle cx="9" cy="9" r="6.5"/><path d="M3 9h12M9 2.5c2 2 3 4 3 6.5s-1 4.5-3 6.5c-2-2-3-4-3-6.5s1-4.5 3-6.5z"/></Ico>,
51
+ Code: (p) => <Ico {...p}><path d="M6 5l-4 4 4 4M12 5l4 4-4 4M11 3l-4 12"/></Ico>,
52
+ Spinner: (p) => <Ico {...p}><path d="M9 2.5a6.5 6.5 0 1 1-6.5 6.5"/></Ico>,
53
+ Stop: (p) => <Ico {...p}><rect x="4" y="4" width="10" height="10" rx="1.5"/></Ico>,
54
+ Share: (p) => <Ico {...p}><path d="M9 2v9M5 6l4-4 4 4M3 11v3a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-3"/></Ico>,
55
+ Warning: (p) => <Ico {...p}><path d="M9 2l7 13H2L9 2z"/><path d="M9 7v3"/><circle cx="9" cy="13" r="0.6" fill="currentColor"/></Ico>,
56
+ Drag: (p) => <Ico {...p} stroke={0}><circle cx="6" cy="5" r="1" fill="currentColor"/><circle cx="6" cy="9" r="1" fill="currentColor"/><circle cx="6" cy="13" r="1" fill="currentColor"/><circle cx="12" cy="5" r="1" fill="currentColor"/><circle cx="12" cy="9" r="1" fill="currentColor"/><circle cx="12" cy="13" r="1" fill="currentColor"/></Ico>,
57
+ Flame: (p) => (
58
+ <Ico {...p} fill="currentColor" stroke="none">
59
+ <path d="M9 1.5c0 2.5-2 3.5-3.5 5.5C4 9 4 11.5 5.5 13.5 6.5 14.8 8 15.5 9 15.5s2.5-.7 3.5-2c1.5-2 1.5-4.5 0-6.5C11 5 9 4 9 1.5z M9 9c.5 1 1.5 1.2 1.5 2.5S9.8 13.5 9 13.5s-1.5-.7-1.5-2S8.5 10 9 9z" fillRule="evenodd"/>
60
+ </Ico>
61
+ ),
62
+ };
63
+
64
+ window.Icons = Icons;
65
+ window.Ico = Ico;