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.
- package/README.md +60 -0
- package/bin/cli.js +177 -0
- package/package.json +31 -0
- package/templates/REFERENCE.md +376 -0
- package/templates/SHOWCASE.html +254 -0
- package/templates/assets/zark-icon.png +0 -0
- package/templates/assets/zark-logo.png +0 -0
- package/templates/brand.jsx +89 -0
- package/templates/components.jsx +385 -0
- package/templates/design-canvas.jsx +789 -0
- package/templates/foundations.jsx +363 -0
- package/templates/icons.jsx +65 -0
- package/templates/layouts.jsx +232 -0
- package/templates/patterns.jsx +268 -0
- package/templates/primitives.jsx +306 -0
- package/templates/tokens.css +306 -0
- package/templates/visual-references/icon-zark.png +0 -0
- package/templates/visual-references/logo-zark-principal.png +0 -0
- package/templates/visual-references/pasted-1777605750385-0.png +0 -0
- package/templates/visual-references/pasted-1777605766298-0.png +0 -0
- package/templates/visual-references/pasted-1777605775820-0.png +0 -0
- package/templates/visual-references/pasted-1777605789833-0.png +0 -0
- package/templates/visual-references/pasted-1777605802420-0.png +0 -0
- package/templates/visual-references/pasted-1777605812470-0.png +0 -0
- package/templates/visual-references/pasted-1777605817688-0.png +0 -0
- package/templates/visual-references/pasted-1777605828485-0.png +0 -0
- package/templates/visual-references/pasted-1777605837137-0.png +0 -0
- package/templates/visual-references/pasted-1777605849789-0.png +0 -0
- package/templates/visual-references/pasted-1777605864942-0.png +0 -0
- package/templates/visual-references/pasted-1777605877920-0.png +0 -0
- package/templates/visual-references/pasted-1777605897353-0.png +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Zark — Layouts: full dashboard mock, hero/marketing, playground
|
|
2
|
+
|
|
3
|
+
const HeaderBar = () => (
|
|
4
|
+
<div style={{
|
|
5
|
+
height: 56, padding:'0 24px',
|
|
6
|
+
display:'flex', alignItems:'center', justifyContent:'space-between',
|
|
7
|
+
borderBottom:'1px solid var(--line-200)', background:'var(--paper)',
|
|
8
|
+
}}>
|
|
9
|
+
<div style={{
|
|
10
|
+
display:'inline-flex', alignItems:'center', gap: 8,
|
|
11
|
+
padding:'6px 12px', background:'var(--ember-50)',
|
|
12
|
+
border:'1px solid var(--ember-200)', borderRadius:'var(--r-md)',
|
|
13
|
+
}}>
|
|
14
|
+
<Avatar name="P" size={18} square color="var(--ember-500)"/>
|
|
15
|
+
<span style={{ fontSize: 13, color:'var(--ember-700)', fontWeight: 500 }}>Personal Team</span>
|
|
16
|
+
<Icons.ChevDown size={12} style={{ color:'var(--ember-700)' }}/>
|
|
17
|
+
</div>
|
|
18
|
+
<div style={{ display:'flex', gap: 6, alignItems:'center' }}>
|
|
19
|
+
<Button variant="ghost" size="sm" icon={<Icons.Bell size={14}/>}/>
|
|
20
|
+
<Button variant="ghost" size="sm" icon={<Icons.Help size={14}/>}>Help</Button>
|
|
21
|
+
<Button variant="secondary" size="sm" icon={<Icons.Docs size={14}/>}>Docs</Button>
|
|
22
|
+
<Button variant="primary" size="sm" icon={<Icons.Upgrade size={14}/>}>Upgrade</Button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const SidebarItem = ({ icon, label, active, sub }) => (
|
|
28
|
+
<div style={{
|
|
29
|
+
display:'flex', alignItems:'center', gap: 10,
|
|
30
|
+
padding:'7px 10px', fontSize: 13,
|
|
31
|
+
color: active ? 'var(--ember-700)' : 'var(--ink-500)',
|
|
32
|
+
background: active ? 'var(--ember-50)' : 'transparent',
|
|
33
|
+
borderRadius:'var(--r-md)', cursor:'pointer',
|
|
34
|
+
fontWeight: active ? 500 : 400,
|
|
35
|
+
}}>
|
|
36
|
+
<span style={{ color: active ? 'var(--ember-600)' : 'var(--ink-400)' }}>{icon}</span>
|
|
37
|
+
<span style={{ flex: 1 }}>{label}</span>
|
|
38
|
+
{sub && <Icons.ChevDown size={12}/>}
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const Sidebar = () => (
|
|
43
|
+
<div style={{
|
|
44
|
+
width: 240, background:'var(--canvas)',
|
|
45
|
+
borderRight:'1px solid var(--line-200)',
|
|
46
|
+
padding: 12, display:'flex', flexDirection:'column', gap: 4,
|
|
47
|
+
}}>
|
|
48
|
+
<div style={{ padding:'8px 10px 16px' }}><ZarkLogo/></div>
|
|
49
|
+
<div style={{ padding:'0 4px 8px' }}>
|
|
50
|
+
<Input size="sm" icon={<Icons.Search size={12}/>} placeholder="Search" suffix={<Kbd>⌘K</Kbd>}/>
|
|
51
|
+
</div>
|
|
52
|
+
<SidebarItem icon={<Icons.Home size={16}/>} label="Overview" active/>
|
|
53
|
+
<SidebarItem icon={<Icons.Play size={16}/>} label="Playground"/>
|
|
54
|
+
<SidebarItem icon={<Icons.Extract size={16}/>} label="Extract" sub/>
|
|
55
|
+
<SidebarItem icon={<Icons.Activity size={16}/>} label="Activity Logs"/>
|
|
56
|
+
<SidebarItem icon={<Icons.Usage size={16}/>} label="Usage"/>
|
|
57
|
+
<SidebarItem icon={<Icons.Key size={16}/>} label="API Keys"/>
|
|
58
|
+
<SidebarItem icon={<Icons.Settings size={16}/>} label="Settings"/>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const DashboardLayout = () => (
|
|
63
|
+
<Panel title="Dashboard — overview" padded={false}>
|
|
64
|
+
<div style={{ display:'flex', minHeight: 540 }}>
|
|
65
|
+
<Sidebar/>
|
|
66
|
+
<div style={{ flex: 1, display:'flex', flexDirection:'column', background:'var(--paper)' }}>
|
|
67
|
+
<HeaderBar/>
|
|
68
|
+
<div style={{ padding: 28, display:'flex', flexDirection:'column', gap: 24, flex: 1 }}>
|
|
69
|
+
<div>
|
|
70
|
+
<h2 style={{ margin:0, fontSize: 22, fontWeight: 600, color:'var(--ink-700)', fontFamily:'var(--font-display)', letterSpacing:'-0.012em' }}>Explore our endpoints</h2>
|
|
71
|
+
<p style={{ margin:'4px 0 0', fontSize: 13, color:'var(--ink-400)' }}>Power your applications with our comprehensive scraping API</p>
|
|
72
|
+
</div>
|
|
73
|
+
<div style={{ display:'flex', border:'1px solid var(--line-200)' }}>
|
|
74
|
+
<EndpointCard icon={<Icons.Drag size={14}/>} label="Scrape" desc="Get llm-ready data from websites."/>
|
|
75
|
+
<EndpointCard icon={<Icons.Search size={14}/>} label="Search" tag="NEW" desc="Search the web and get full content."/>
|
|
76
|
+
<EndpointCard icon={<Icons.Globe size={14}/>} label="Crawl" desc="Crawl all the pages on a website."/>
|
|
77
|
+
<EndpointCard icon={<Icons.Sparkles size={14}/>} label="Extract" desc="Get structured data with AI."/>
|
|
78
|
+
</div>
|
|
79
|
+
<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
|
|
80
|
+
<div style={{ background:'var(--surface)', border:'1px solid var(--line-200)', borderRadius:'var(--r-xl)', padding: 18 }}>
|
|
81
|
+
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline' }}>
|
|
82
|
+
<div>
|
|
83
|
+
<div style={{ fontSize: 14, fontWeight: 600, color:'var(--ink-700)' }}>Scraped pages — Last 7 days</div>
|
|
84
|
+
<div style={{ fontSize: 11, color:'var(--ink-400)', marginTop: 2 }}>Credit usage differs</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div style={{ fontSize: 26, fontWeight: 600, fontFamily:'var(--font-display)' }}>2</div>
|
|
87
|
+
</div>
|
|
88
|
+
<div style={{ marginTop: 12, display:'flex', justifyContent:'center' }}>
|
|
89
|
+
<AsciiCurve width={66} height={9}/>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div style={{ background:'var(--surface)', border:'1px solid var(--line-200)', borderRadius:'var(--r-xl)', padding: 18 }}>
|
|
93
|
+
<div style={{ fontSize: 14, fontWeight: 600, color:'var(--ink-700)' }}>API Key</div>
|
|
94
|
+
<div style={{ fontSize: 11, color:'var(--ink-400)', marginTop: 2, marginBottom: 12 }}>Start scraping right away</div>
|
|
95
|
+
<Input mono value="fc-9••••••••••••••••••••••aebf" readOnly suffix={<span style={{ display:'inline-flex', gap: 6, color:'var(--ink-400)' }}><Icons.Eye size={14}/><Icons.Copy size={14}/></span>}/>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</Panel>
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const HeroLayout = () => (
|
|
105
|
+
<Panel title="Marketing — hero" padded={false}>
|
|
106
|
+
<div style={{
|
|
107
|
+
position:'relative', minHeight: 480, padding: '40px 32px',
|
|
108
|
+
background: 'var(--paper)', overflow:'hidden',
|
|
109
|
+
}}>
|
|
110
|
+
<div style={{ position:'absolute', inset:0, opacity: 0.5, pointerEvents:'none' }}>
|
|
111
|
+
<AsciiBackdrop width={140} height={48} density={0.18} seed={3}/>
|
|
112
|
+
</div>
|
|
113
|
+
<div style={{ position:'relative', maxWidth: 720, margin:'0 auto', textAlign:'center', display:'flex', flexDirection:'column', alignItems:'center', gap: 24 }}>
|
|
114
|
+
<div style={{
|
|
115
|
+
display:'inline-flex', alignItems:'center', gap: 8,
|
|
116
|
+
padding:'5px 12px', background:'var(--surface)',
|
|
117
|
+
border:'1px solid var(--line-200)', borderRadius:'var(--r-pill)',
|
|
118
|
+
fontSize: 12, color:'var(--ink-600)', boxShadow:'var(--shadow-xs)',
|
|
119
|
+
}}>
|
|
120
|
+
2 Months Free — Annually <Icons.ChevRight size={12}/>
|
|
121
|
+
</div>
|
|
122
|
+
<h1 style={{
|
|
123
|
+
margin: 0,
|
|
124
|
+
fontFamily:'var(--font-display)', fontSize: 64, fontWeight: 700,
|
|
125
|
+
letterSpacing:'-0.025em', lineHeight: 1.05,
|
|
126
|
+
color:'var(--ink-700)',
|
|
127
|
+
}}>
|
|
128
|
+
Turn websites into<br/>
|
|
129
|
+
<span style={{ color:'var(--ember-500)' }}>LLM-ready</span> data
|
|
130
|
+
</h1>
|
|
131
|
+
<p style={{ margin: 0, fontSize: 16, color:'var(--ink-400)', maxWidth: 460, lineHeight: 1.55 }}>
|
|
132
|
+
Power your AI apps with clean data crawled from any website. It's also open source.
|
|
133
|
+
</p>
|
|
134
|
+
<div style={{
|
|
135
|
+
display:'flex', alignItems:'center', width: 480, height: 52,
|
|
136
|
+
background:'var(--surface)',
|
|
137
|
+
border:'1px solid var(--line-300)',
|
|
138
|
+
borderRadius:'var(--r-pill)',
|
|
139
|
+
boxShadow:'var(--shadow-md)', overflow:'hidden', padding: 4,
|
|
140
|
+
}}>
|
|
141
|
+
<span style={{ display:'inline-flex', alignItems:'center', gap: 6, padding:'0 16px', color:'var(--ink-400)' }}>
|
|
142
|
+
<Icons.Globe size={16}/>
|
|
143
|
+
</span>
|
|
144
|
+
<input placeholder="https://example.com" style={{
|
|
145
|
+
flex: 1, border:'none', outline:'none', background:'transparent',
|
|
146
|
+
fontSize: 14, color:'var(--ink-700)', fontFamily:'var(--font-mono)',
|
|
147
|
+
}}/>
|
|
148
|
+
<Button variant="primary" size="md" style={{ borderRadius: 999, width: 44, padding: 0 }}>
|
|
149
|
+
<Icons.ChevRight size={16}/>
|
|
150
|
+
</Button>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</Panel>
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const PlaygroundLayout = () => (
|
|
158
|
+
<Panel title="Playground state" padded={false}>
|
|
159
|
+
<div style={{ position:'relative', minHeight: 380, padding:'48px 32px', background:'var(--paper)', overflow:'hidden' }}>
|
|
160
|
+
<div style={{ position:'absolute', top: 32, left: 32, opacity: 0.45, pointerEvents:'none' }}><AsciiBackdrop width={36} height={20} density={0.28} seed={11}/></div>
|
|
161
|
+
<div style={{ position:'absolute', top: 32, right: 32, opacity: 0.45, pointerEvents:'none' }}><AsciiBackdrop width={36} height={20} density={0.28} seed={22}/></div>
|
|
162
|
+
|
|
163
|
+
<div style={{ position:'relative', maxWidth: 640, margin:'0 auto', textAlign:'center', display:'flex', flexDirection:'column', alignItems:'center', gap: 24 }}>
|
|
164
|
+
<div>
|
|
165
|
+
<h1 style={{ margin: 0, fontFamily:'var(--font-display)', fontSize: 38, fontWeight: 600, letterSpacing:'-0.018em', color:'var(--ink-700)' }}>Playground</h1>
|
|
166
|
+
<p style={{ margin:'8px 0 0', fontSize: 14, color:'var(--ink-400)' }}>API, Docs and Playground - all in one place</p>
|
|
167
|
+
</div>
|
|
168
|
+
<Segmented value="scrape" onChange={()=>{}} items={[
|
|
169
|
+
{ value:'scrape', label:'Scrape', icon:<Icons.Drag size={14}/> },
|
|
170
|
+
{ value:'search', label:'Search', icon:<Icons.Search size={14}/>, tag:'New' },
|
|
171
|
+
{ value:'map', label:'Map', icon:<Icons.Filter size={14}/> },
|
|
172
|
+
{ value:'crawl', label:'Crawl', icon:<Icons.Close size={14}/> },
|
|
173
|
+
]}/>
|
|
174
|
+
<div style={{
|
|
175
|
+
width: '100%', maxWidth: 540,
|
|
176
|
+
background:'var(--surface)',
|
|
177
|
+
border:'1px solid var(--line-200)',
|
|
178
|
+
borderRadius:'var(--r-xl)',
|
|
179
|
+
boxShadow:'var(--shadow-md)', padding: 14,
|
|
180
|
+
display:'flex', flexDirection:'column', gap: 12,
|
|
181
|
+
}}>
|
|
182
|
+
<div style={{ display:'flex', alignItems:'center', gap: 0, height: 36, border:'1px solid var(--line-200)', borderRadius:'var(--r-md)', overflow:'hidden' }}>
|
|
183
|
+
<span style={{ padding:'0 12px', fontFamily:'var(--font-mono)', fontSize: 12, color:'var(--ink-400)', borderRight:'1px solid var(--line-200)', height:'100%', display:'flex', alignItems:'center' }}>https://</span>
|
|
184
|
+
<input defaultValue="www.nngroup.com/articles/usability-101-introduction-to-usability/" style={{ flex: 1, border:'none', outline:'none', padding:'0 12px', fontFamily:'var(--font-mono)', fontSize: 12, color:'var(--ink-700)' }}/>
|
|
185
|
+
</div>
|
|
186
|
+
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
|
|
187
|
+
<div style={{ display:'flex', gap: 8 }}>
|
|
188
|
+
<Button variant="ghost" size="sm" icon={<Icons.Settings size={14}/>}/>
|
|
189
|
+
<Button variant="secondary" size="sm" icon={<Icons.Docs size={14}/>} iconRight={<Icons.ChevDown size={12}/>}>Format: Markdown</Button>
|
|
190
|
+
</div>
|
|
191
|
+
<div style={{ display:'flex', gap: 8 }}>
|
|
192
|
+
<Button variant="secondary" size="sm" icon={<Icons.Code size={14}/>}>Get code</Button>
|
|
193
|
+
<Button variant="primary" size="sm">Start scraping</Button>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
</Panel>
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const FooterShowcase = () => (
|
|
203
|
+
<Panel title="Footer / brand bar" padded={false}>
|
|
204
|
+
<div style={{
|
|
205
|
+
background:'var(--ink-800)', color:'#fff',
|
|
206
|
+
padding:'18px 24px',
|
|
207
|
+
display:'flex', alignItems:'center', justifyContent:'space-between',
|
|
208
|
+
}}>
|
|
209
|
+
<div style={{ display:'flex', alignItems:'center', gap: 12 }}>
|
|
210
|
+
<Icons.Flame size={28} style={{ color:'var(--ember-500)' }}/>
|
|
211
|
+
<span style={{ fontFamily:'var(--font-display)', fontSize: 20, fontWeight: 600 }}>Zark</span>
|
|
212
|
+
</div>
|
|
213
|
+
<span style={{ fontSize: 12, color:'rgba(255,255,255,0.55)', fontFamily:'var(--font-mono)' }}>v2.0.0 · est. 2026</span>
|
|
214
|
+
</div>
|
|
215
|
+
</Panel>
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const LayoutsSection = () => (
|
|
219
|
+
<Section
|
|
220
|
+
id="layouts"
|
|
221
|
+
eyebrow="07 — Layouts"
|
|
222
|
+
title="The system, fully composed"
|
|
223
|
+
description="Three canonical screens show every primitive in its native habitat. Hairlines stay warm, ascii fields appear behind hero moments, the URL pill is the connective tissue across product surfaces."
|
|
224
|
+
>
|
|
225
|
+
<DashboardLayout/>
|
|
226
|
+
<PlaygroundLayout/>
|
|
227
|
+
<HeroLayout/>
|
|
228
|
+
<FooterShowcase/>
|
|
229
|
+
</Section>
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
window.LayoutsSection = LayoutsSection;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// Zark — Patterns: modal, onboarding, code-block, data table, date picker, banner
|
|
2
|
+
|
|
3
|
+
const ModalShowcase = () => (
|
|
4
|
+
<Panel title="Modal — onboarding step" padded={false}>
|
|
5
|
+
<div style={{
|
|
6
|
+
padding: 32, background: `
|
|
7
|
+
radial-gradient(ellipse at top, var(--paper) 0%, var(--canvas) 80%)
|
|
8
|
+
`, position:'relative', minHeight: 380,
|
|
9
|
+
}}>
|
|
10
|
+
<div style={{
|
|
11
|
+
position:'absolute', inset:0,
|
|
12
|
+
background:'rgba(20, 17, 12, 0.04)',
|
|
13
|
+
backdropFilter:'blur(2px)',
|
|
14
|
+
}}/>
|
|
15
|
+
<div style={{
|
|
16
|
+
position:'relative', maxWidth: 460, margin:'24px auto',
|
|
17
|
+
background:'var(--surface)',
|
|
18
|
+
border:'1px solid var(--line-200)',
|
|
19
|
+
borderRadius:'var(--r-2xl)',
|
|
20
|
+
boxShadow:'var(--shadow-modal)',
|
|
21
|
+
overflow:'hidden',
|
|
22
|
+
}}>
|
|
23
|
+
<div style={{ padding:'24px 24px 0' }}>
|
|
24
|
+
<div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom: 6 }}>
|
|
25
|
+
<h3 style={{ margin: 0, fontSize: 20, fontWeight: 600, fontFamily:'var(--font-display)', letterSpacing:'-0.012em', color:'var(--ink-700)' }}>Let's get you started</h3>
|
|
26
|
+
<Tag tone="default" size="xs" square>Optional</Tag>
|
|
27
|
+
</div>
|
|
28
|
+
<p style={{ margin:'0 0 16px', fontSize: 12, color:'var(--ink-400)' }}>Complete these quick actions to earn bonus credits for your account.</p>
|
|
29
|
+
<div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom: 8 }}>
|
|
30
|
+
<div style={{ display:'flex', gap: 4 }}>
|
|
31
|
+
<span style={{ width: 28, height: 4, borderRadius: 2, background:'var(--ember-500)' }}/>
|
|
32
|
+
<span style={{ width: 12, height: 4, borderRadius: 2, background:'var(--ink-100)' }}/>
|
|
33
|
+
<span style={{ width: 12, height: 4, borderRadius: 2, background:'var(--ink-100)' }}/>
|
|
34
|
+
<span style={{ width: 12, height: 4, borderRadius: 2, background:'var(--ink-100)' }}/>
|
|
35
|
+
</div>
|
|
36
|
+
<Tag tone="default" size="xs" square>Step 1 of 4</Tag>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div style={{ padding: 4 }}>
|
|
40
|
+
{[
|
|
41
|
+
{t:'Email Verified', d:'Your email has been verified', claimed: true, c: ''},
|
|
42
|
+
{t:'Star our GitHub repo', d:'Check out our open source code and contribute', c:'+100 credits'},
|
|
43
|
+
{t:'Join our Discord', d:'Connect with us and get community help', c:'+50 credits'},
|
|
44
|
+
{t:'Follow us on X', d:'Stay updated on new features and launches', c:'+50 credits'},
|
|
45
|
+
].map(item => (
|
|
46
|
+
<div key={item.t} style={{ padding:'12px 20px', borderRadius:'var(--r-md)', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
|
|
47
|
+
<div>
|
|
48
|
+
<div style={{ fontSize: 13, fontWeight: 500, color: item.claimed ? 'var(--success-700)' : 'var(--ember-700)' }}>{item.t}</div>
|
|
49
|
+
<div style={{ fontSize: 11, color:'var(--ink-400)', marginTop: 2 }}>{item.d}</div>
|
|
50
|
+
</div>
|
|
51
|
+
{item.claimed ? <Tag tone="success" size="xs">Claimed</Tag> : <span style={{ fontSize: 12, color:'var(--ink-500)', fontFamily:'var(--font-mono)' }}>{item.c}</span>}
|
|
52
|
+
</div>
|
|
53
|
+
))}
|
|
54
|
+
</div>
|
|
55
|
+
<div style={{ padding:'16px 20px', borderTop:'1px solid var(--line-100)', display:'flex', justifyContent:'flex-end' }}>
|
|
56
|
+
<Button variant="secondary">Continue</Button>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</Panel>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const CodeBlock = () => (
|
|
64
|
+
<Panel title="Code block — MCP integration">
|
|
65
|
+
<div style={{
|
|
66
|
+
background:'var(--surface)',
|
|
67
|
+
border:'1px solid var(--line-200)',
|
|
68
|
+
borderRadius:'var(--r-lg)',
|
|
69
|
+
padding: 16,
|
|
70
|
+
fontFamily:'var(--font-mono)', fontSize: 12, lineHeight: 1.7,
|
|
71
|
+
color:'var(--ink-600)', position:'relative',
|
|
72
|
+
}}>
|
|
73
|
+
<div style={{ position:'absolute', top: 10, right: 10, display:'flex', gap: 4 }}>
|
|
74
|
+
<Button variant="ghost" size="xs" icon={<Icons.Eye size={12}/>}/>
|
|
75
|
+
<Button variant="ghost" size="xs" icon={<Icons.Copy size={12}/>}/>
|
|
76
|
+
</div>
|
|
77
|
+
<div>{'{'}</div>
|
|
78
|
+
<div style={{ paddingLeft: 16 }}><span style={{ color:'var(--code-fg)' }}>"mcpServers"</span>: {'{'}</div>
|
|
79
|
+
<div style={{ paddingLeft: 32 }}><span style={{ color:'var(--code-fg)' }}>"zark-mcp"</span>: {'{'}</div>
|
|
80
|
+
<div style={{ paddingLeft: 48 }}><span style={{ color:'var(--code-fg)' }}>"command"</span>: <span style={{ color:'var(--success-700)' }}>"npx"</span>,</div>
|
|
81
|
+
<div style={{ paddingLeft: 48 }}><span style={{ color:'var(--code-fg)' }}>"args"</span>: [<span style={{ color:'var(--success-700)' }}>"-y"</span>, <span style={{ color:'var(--success-700)' }}>"zark-mcp"</span>],</div>
|
|
82
|
+
<div style={{ paddingLeft: 48 }}><span style={{ color:'var(--code-fg)' }}>"env"</span>: {'{'}</div>
|
|
83
|
+
<div style={{ paddingLeft: 64 }}><span style={{ color:'var(--code-fg)' }}>"ZARK_API_KEY"</span>: <span style={{ color:'var(--success-700)' }}>"$API_KEY"</span></div>
|
|
84
|
+
<div style={{ paddingLeft: 48 }}>{'}'}</div>
|
|
85
|
+
<div style={{ paddingLeft: 32 }}>{'}'}</div>
|
|
86
|
+
<div style={{ paddingLeft: 16 }}>{'}'}</div>
|
|
87
|
+
<div>{'}'}</div>
|
|
88
|
+
</div>
|
|
89
|
+
</Panel>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const DataTableShowcase = () => (
|
|
93
|
+
<Panel title="Data table" padded={false}>
|
|
94
|
+
<div style={{
|
|
95
|
+
padding:'14px 18px',
|
|
96
|
+
borderBottom:'1px solid var(--line-100)',
|
|
97
|
+
display:'flex', alignItems:'center', justifyContent:'space-between',
|
|
98
|
+
}}>
|
|
99
|
+
<div style={{ display:'flex', gap: 8, alignItems:'center' }}>
|
|
100
|
+
<div style={{ width: 240 }}><Input size="sm" icon={<Icons.Search size={12}/>} placeholder="Search..."/></div>
|
|
101
|
+
<Button variant="secondary" size="sm" icon={<Icons.Filter size={12}/>}>/scrape</Button>
|
|
102
|
+
</div>
|
|
103
|
+
<Button variant="secondary" size="sm" icon={<Icons.Calendar size={12}/>} iconRight={<Icons.ChevDown size={12}/>}>Custom range</Button>
|
|
104
|
+
</div>
|
|
105
|
+
<div>
|
|
106
|
+
<div style={{
|
|
107
|
+
display:'grid', gridTemplateColumns:'120px 1fr 100px 60px 140px 40px',
|
|
108
|
+
padding:'10px 18px',
|
|
109
|
+
fontFamily:'var(--font-mono)', fontSize: 10,
|
|
110
|
+
letterSpacing:'var(--ls-wider)', textTransform:'uppercase',
|
|
111
|
+
color:'var(--ink-300)',
|
|
112
|
+
borderBottom:'1px solid var(--line-100)',
|
|
113
|
+
}}>
|
|
114
|
+
<span>Endpoint</span><span>URL</span><span>Status</span><span>Cr</span><span>Date</span><span></span>
|
|
115
|
+
</div>
|
|
116
|
+
{[
|
|
117
|
+
['/SCRAPE','https://www.zark.dev/careers','Completed','1','Sep 08, 25 09:57 AM'],
|
|
118
|
+
['/SCRAPE','https://www.zark.dev/playground/extract','Completed','2','Sep 08, 25 09:57 AM'],
|
|
119
|
+
['/SCRAPE','https://www.zark.dev/extract','Failed','0','Sep 08, 25 09:55 AM'],
|
|
120
|
+
['/SCRAPE','https://www.zark.dev/templates','Completed','1','Sep 08, 25 09:54 AM'],
|
|
121
|
+
['/SCRAPE','https://www.zark.dev/signin/signup','Pending','—','Sep 08, 25 09:50 AM'],
|
|
122
|
+
].map((row, i) => (
|
|
123
|
+
<div key={i} style={{
|
|
124
|
+
display:'grid', gridTemplateColumns:'120px 1fr 100px 60px 140px 40px',
|
|
125
|
+
padding:'14px 18px', alignItems:'center',
|
|
126
|
+
borderBottom: i < 4 ? '1px solid var(--line-100)' : 'none',
|
|
127
|
+
fontSize: 12,
|
|
128
|
+
}}>
|
|
129
|
+
<Tag tone="mono" size="xs" square>{row[0]}</Tag>
|
|
130
|
+
<span style={{ color:'var(--ink-600)', fontFamily:'var(--font-mono)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{row[1]}</span>
|
|
131
|
+
<Tag tone={row[2]==='Completed'?'success': row[2]==='Failed'?'danger':'warning'} size="xs">{row[2]}</Tag>
|
|
132
|
+
<span style={{ color:'var(--ink-500)', fontFamily:'var(--font-mono)' }}>{row[3]}</span>
|
|
133
|
+
<span style={{ color:'var(--ink-400)', fontFamily:'var(--font-mono)', fontSize: 11 }}>{row[4]}</span>
|
|
134
|
+
<Icons.Download size={14} style={{ color:'var(--ink-300)', cursor:'pointer' }}/>
|
|
135
|
+
</div>
|
|
136
|
+
))}
|
|
137
|
+
</div>
|
|
138
|
+
</Panel>
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const DatePickerShowcase = () => {
|
|
142
|
+
const month = (label, sel = []) => (
|
|
143
|
+
<div>
|
|
144
|
+
<div style={{ fontSize: 13, fontWeight: 600, color:'var(--ink-700)', textAlign:'center', marginBottom: 8 }}>{label}</div>
|
|
145
|
+
<div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap: 2, fontFamily:'var(--font-mono)', fontSize: 10, color:'var(--ink-300)' }}>
|
|
146
|
+
{['Mo','Tu','We','Th','Fr','Sa','Su'].map(d=><div key={d} style={{ textAlign:'center', padding:'4px 0' }}>{d}</div>)}
|
|
147
|
+
</div>
|
|
148
|
+
<div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap: 2, fontSize: 11 }}>
|
|
149
|
+
{Array.from({length: 30}, (_, i) => i + 1).map(d => {
|
|
150
|
+
const isSel = sel.includes(d);
|
|
151
|
+
return (
|
|
152
|
+
<div key={d} style={{
|
|
153
|
+
aspectRatio:'1/1', display:'flex', alignItems:'center', justifyContent:'center',
|
|
154
|
+
borderRadius:'var(--r-sm)',
|
|
155
|
+
background: isSel ? 'var(--ember-500)' : 'transparent',
|
|
156
|
+
color: isSel ? '#fff' : 'var(--ink-600)',
|
|
157
|
+
fontWeight: isSel ? 600 : 400,
|
|
158
|
+
cursor:'pointer',
|
|
159
|
+
}}>{d}</div>
|
|
160
|
+
);
|
|
161
|
+
})}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
return (
|
|
166
|
+
<Panel title="Date range picker">
|
|
167
|
+
<div style={{
|
|
168
|
+
background:'var(--surface)', border:'1px solid var(--line-200)',
|
|
169
|
+
borderRadius:'var(--r-xl)', boxShadow:'var(--shadow-lg)',
|
|
170
|
+
maxWidth: 560, padding: 16,
|
|
171
|
+
}}>
|
|
172
|
+
<div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom: 12 }}>
|
|
173
|
+
<div style={{ fontSize: 13, fontWeight: 600, color:'var(--ink-600)' }}>Date Range</div>
|
|
174
|
+
<Icons.Close size={14} style={{ color:'var(--ink-400)', cursor:'pointer' }}/>
|
|
175
|
+
</div>
|
|
176
|
+
<div style={{ display:'flex', justifyContent:'space-between', marginBottom: 8, padding:'0 8px' }}>
|
|
177
|
+
<Icons.ChevLeft size={14} style={{ color:'var(--ink-400)', cursor:'pointer' }}/>
|
|
178
|
+
<Icons.ChevRight size={14} style={{ color:'var(--ink-400)', cursor:'pointer' }}/>
|
|
179
|
+
</div>
|
|
180
|
+
<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
|
|
181
|
+
{month('September 2025', [1, 8])}
|
|
182
|
+
{month('October 2025')}
|
|
183
|
+
</div>
|
|
184
|
+
<div style={{ display:'flex', justifyContent:'flex-end', gap: 8, marginTop: 16 }}>
|
|
185
|
+
<Button variant="secondary" size="sm">Cancel</Button>
|
|
186
|
+
<Button variant="primary" size="sm">Apply</Button>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</Panel>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const BannerShowcase = () => (
|
|
194
|
+
<Panel title="Banners & toasts">
|
|
195
|
+
<ComponentRow label="Top announcement bar">
|
|
196
|
+
<div style={{
|
|
197
|
+
width:'100%',
|
|
198
|
+
background:'var(--paper)',
|
|
199
|
+
border:'1px solid var(--line-200)',
|
|
200
|
+
borderRadius:'var(--r-md)',
|
|
201
|
+
padding:'10px 16px',
|
|
202
|
+
textAlign:'center',
|
|
203
|
+
fontSize: 13, color:'var(--ink-600)',
|
|
204
|
+
}}>
|
|
205
|
+
We just raised our Series A and shipped Zark v2 🎉 <a style={{ color:'var(--ember-700)', textDecoration:'underline' }}>Read the blog.</a>
|
|
206
|
+
</div>
|
|
207
|
+
</ComponentRow>
|
|
208
|
+
<ComponentRow label="In-page tip card">
|
|
209
|
+
<div style={{
|
|
210
|
+
display:'flex', gap: 12, padding: 14,
|
|
211
|
+
background:'var(--surface)',
|
|
212
|
+
border:'1px solid var(--line-200)',
|
|
213
|
+
borderRadius:'var(--r-lg)',
|
|
214
|
+
maxWidth: 320,
|
|
215
|
+
boxShadow:'var(--shadow-md)',
|
|
216
|
+
}}>
|
|
217
|
+
<Icons.Sparkles size={16} style={{ color:'var(--ember-500)', marginTop: 2 }}/>
|
|
218
|
+
<div style={{ flex: 1 }}>
|
|
219
|
+
<div style={{ fontSize: 12, fontFamily:'var(--font-mono)', letterSpacing:'var(--ls-wider)', color:'var(--ink-300)', textTransform:'uppercase', marginBottom: 4 }}>What's New</div>
|
|
220
|
+
<div style={{ fontSize: 13, fontWeight: 600, color:'var(--ink-700)', marginBottom: 4 }}>Introducing Zark v2</div>
|
|
221
|
+
<div style={{ fontSize: 12, color:'var(--ink-400)', lineHeight: 1.45 }}>10x faster scraping, news and image search, smart crawling and more.</div>
|
|
222
|
+
</div>
|
|
223
|
+
<Icons.Close size={12} style={{ color:'var(--ink-300)', cursor:'pointer' }}/>
|
|
224
|
+
</div>
|
|
225
|
+
</ComponentRow>
|
|
226
|
+
<ComponentRow label="Toast / pill">
|
|
227
|
+
<div style={{
|
|
228
|
+
display:'inline-flex', alignItems:'center', gap: 8,
|
|
229
|
+
padding:'8px 14px',
|
|
230
|
+
background:'var(--ink-700)',
|
|
231
|
+
color:'#fff',
|
|
232
|
+
borderRadius:'var(--r-pill)',
|
|
233
|
+
fontSize: 12, boxShadow:'var(--shadow-lg)',
|
|
234
|
+
}}>
|
|
235
|
+
Welcome to Zark! <Icons.Flame size={14} style={{ color:'var(--ember-400)' }}/>
|
|
236
|
+
</div>
|
|
237
|
+
<div style={{
|
|
238
|
+
display:'inline-flex', alignItems:'center', gap: 8,
|
|
239
|
+
padding:'8px 14px',
|
|
240
|
+
background:'var(--success-500)', color:'#fff',
|
|
241
|
+
borderRadius:'var(--r-pill)', fontSize: 12,
|
|
242
|
+
}}>
|
|
243
|
+
<Icons.Check size={14}/> Copied as Markdown
|
|
244
|
+
</div>
|
|
245
|
+
</ComponentRow>
|
|
246
|
+
</Panel>
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const PatternsSection = () => (
|
|
250
|
+
<Section
|
|
251
|
+
id="patterns"
|
|
252
|
+
eyebrow="06 — Patterns"
|
|
253
|
+
title="Composed patterns, not isolated parts"
|
|
254
|
+
description="These templates encode opinion: the URL pill always sits inside an ascii field, code blocks always include eye+copy affordances, modals always announce a step counter, tables lead with a mono endpoint tag. Reach for these before improvising."
|
|
255
|
+
>
|
|
256
|
+
<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
|
|
257
|
+
<ModalShowcase/>
|
|
258
|
+
<CodeBlock/>
|
|
259
|
+
</div>
|
|
260
|
+
<DataTableShowcase/>
|
|
261
|
+
<div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 24 }}>
|
|
262
|
+
<DatePickerShowcase/>
|
|
263
|
+
<BannerShowcase/>
|
|
264
|
+
</div>
|
|
265
|
+
</Section>
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
window.PatternsSection = PatternsSection;
|