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,306 @@
1
+ // Zark — Primitives: Button, Input, Toggle, Tag, Badge, Tabs, Card, etc.
2
+
3
+ const Section = ({ id, eyebrow, title, description, children, columns }) => (
4
+ <section id={id} style={{
5
+ borderTop:'1px solid var(--line-200)',
6
+ padding:'72px 64px 80px',
7
+ }}>
8
+ <div style={{ maxWidth:1200, margin:'0 auto' }}>
9
+ <header style={{
10
+ display:'grid',
11
+ gridTemplateColumns:'minmax(220px, 280px) 1fr',
12
+ gap: 64,
13
+ marginBottom: 48,
14
+ alignItems:'start',
15
+ }}>
16
+ <div>
17
+ <div style={{
18
+ fontFamily:'var(--font-mono)', fontSize: 11,
19
+ letterSpacing:'var(--ls-widest)', textTransform:'uppercase',
20
+ color:'var(--ember-600)', marginBottom: 12,
21
+ }}>{eyebrow}</div>
22
+ <h2 style={{
23
+ fontFamily:'var(--font-display)',
24
+ fontSize: 'var(--fs-3xl)', lineHeight:'var(--lh-tight)',
25
+ letterSpacing:'var(--ls-tight)', margin: 0,
26
+ color:'var(--ink-700)',
27
+ }}>{title}</h2>
28
+ </div>
29
+ <p style={{
30
+ margin:0, color:'var(--ink-400)', fontSize:'var(--fs-lg)',
31
+ lineHeight: 1.55, maxWidth: 640,
32
+ }}>{description}</p>
33
+ </header>
34
+ <div style={{
35
+ display:'grid',
36
+ gridTemplateColumns: columns || '1fr',
37
+ gap: 24,
38
+ }}>
39
+ {children}
40
+ </div>
41
+ </div>
42
+ </section>
43
+ );
44
+
45
+ const Panel = ({ title, kicker, children, padded = true, style }) => (
46
+ <div style={{
47
+ background:'var(--surface)',
48
+ border:'1px solid var(--line-200)',
49
+ borderRadius:'var(--r-xl)',
50
+ overflow:'hidden',
51
+ ...style,
52
+ }}>
53
+ {(title || kicker) && (
54
+ <div style={{
55
+ padding:'14px 18px',
56
+ borderBottom:'1px solid var(--line-100)',
57
+ display:'flex', alignItems:'center', justifyContent:'space-between',
58
+ background:'var(--paper)',
59
+ }}>
60
+ <div style={{ fontSize: 13, fontWeight: 600, color:'var(--ink-600)' }}>{title}</div>
61
+ {kicker && <div style={{
62
+ fontFamily:'var(--font-mono)', fontSize: 10,
63
+ letterSpacing:'var(--ls-wider)', textTransform:'uppercase',
64
+ color:'var(--ink-300)',
65
+ }}>{kicker}</div>}
66
+ </div>
67
+ )}
68
+ <div style={{ padding: padded ? 24 : 0 }}>{children}</div>
69
+ </div>
70
+ );
71
+
72
+ const Spec = ({ label, value, mono }) => (
73
+ <div style={{ display:'flex', justifyContent:'space-between', gap:16, padding:'8px 0', borderBottom:'1px dashed var(--line-200)', fontSize: 12 }}>
74
+ <span style={{ color:'var(--ink-400)' }}>{label}</span>
75
+ <span style={{ color:'var(--ink-600)', fontFamily: mono ? 'var(--font-mono)' : 'inherit' }}>{value}</span>
76
+ </div>
77
+ );
78
+
79
+ // ---------- BUTTON ----------
80
+ const buttonVariants = {
81
+ primary: {
82
+ bg:'var(--ember-600)', fg:'#fff', border:'transparent',
83
+ bgHover:'var(--ember-700)',
84
+ },
85
+ secondary: {
86
+ bg:'var(--surface)', fg:'var(--ink-700)', border:'var(--line-300)',
87
+ bgHover:'var(--paper)',
88
+ },
89
+ ghost: {
90
+ bg:'transparent', fg:'var(--ink-600)', border:'transparent',
91
+ bgHover:'var(--ink-50)',
92
+ },
93
+ soft: {
94
+ bg:'var(--ember-50)', fg:'var(--ember-700)', border:'transparent',
95
+ bgHover:'var(--ember-100)',
96
+ },
97
+ danger: {
98
+ bg:'var(--surface)', fg:'var(--danger-700)', border:'var(--line-300)',
99
+ bgHover:'var(--danger-50)',
100
+ },
101
+ };
102
+ const buttonSizes = {
103
+ xs: { h: 22, px: 8, fs: 11, gap: 4, r: 'var(--r-sm)' },
104
+ sm: { h: 28, px: 10, fs: 12, gap: 6, r: 'var(--r-md)' },
105
+ md: { h: 32, px: 12, fs: 13, gap: 6, r: 'var(--r-md)' },
106
+ lg: { h: 40, px: 16, fs: 14, gap: 8, r: 'var(--r-lg)' },
107
+ };
108
+ const Button = ({ variant='secondary', size='md', icon, iconRight, children, full, ...rest }) => {
109
+ const v = buttonVariants[variant];
110
+ const s = buttonSizes[size];
111
+ const [hover, setHover] = React.useState(false);
112
+ return (
113
+ <button
114
+ onMouseEnter={()=>setHover(true)}
115
+ onMouseLeave={()=>setHover(false)}
116
+ style={{
117
+ display:'inline-flex', alignItems:'center', justifyContent:'center',
118
+ gap: s.gap,
119
+ height: s.h,
120
+ padding: `0 ${s.px}px`,
121
+ fontSize: s.fs, fontWeight: 500,
122
+ fontFamily:'var(--font-sans)',
123
+ color: v.fg,
124
+ background: hover ? v.bgHover : v.bg,
125
+ border: `1px solid ${v.border === 'transparent' ? 'transparent' : v.border}`,
126
+ borderRadius: s.r,
127
+ cursor:'pointer',
128
+ whiteSpace:'nowrap',
129
+ transition:'background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out)',
130
+ boxShadow: variant==='primary' ? 'inset 0 1px 0 rgba(255,255,255,0.18), 0 1px 2px rgba(168, 53, 8, 0.18)' :
131
+ variant==='secondary' ? 'var(--shadow-xs)' : 'none',
132
+ width: full ? '100%' : 'auto',
133
+ }}
134
+ {...rest}
135
+ >
136
+ {icon}
137
+ {children}
138
+ {iconRight}
139
+ </button>
140
+ );
141
+ };
142
+
143
+ // ---------- INPUT ----------
144
+ const Input = ({ icon, suffix, value, onChange, placeholder, mono, size='md', invalid, ...rest }) => {
145
+ const sizes = { sm:{h:28,fs:12,px:8}, md:{h:36,fs:13,px:12}, lg:{h:44,fs:14,px:14} };
146
+ const s = sizes[size];
147
+ return (
148
+ <label style={{
149
+ display:'inline-flex', alignItems:'center', gap: 6,
150
+ height: s.h,
151
+ padding: `0 ${s.px}px`,
152
+ background:'var(--surface)',
153
+ border:`1px solid ${invalid ? 'var(--danger-500)' : 'var(--line-300)'}`,
154
+ borderRadius:'var(--r-lg)',
155
+ width:'100%',
156
+ transition:'box-shadow var(--t-fast), border-color var(--t-fast)',
157
+ }}
158
+ onFocus={e=>e.currentTarget.style.boxShadow='var(--ring-focus)'}
159
+ onBlur={e=>e.currentTarget.style.boxShadow='none'}
160
+ >
161
+ {icon && <span style={{ color:'var(--ink-300)', display:'inline-flex' }}>{icon}</span>}
162
+ <input
163
+ value={value} onChange={onChange} placeholder={placeholder}
164
+ style={{
165
+ flex:1, border:'none', outline:'none', background:'transparent',
166
+ fontSize: s.fs, color:'var(--ink-700)',
167
+ fontFamily: mono ? 'var(--font-mono)' : 'var(--font-sans)',
168
+ minWidth: 0,
169
+ }}
170
+ {...rest}
171
+ />
172
+ {suffix && <span style={{ color:'var(--ink-300)' }}>{suffix}</span>}
173
+ </label>
174
+ );
175
+ };
176
+
177
+ // ---------- TAG / BADGE ----------
178
+ const Tag = ({ tone = 'default', size='sm', children, square }) => {
179
+ const tones = {
180
+ default:{ bg:'var(--ink-50)', fg:'var(--ink-500)' },
181
+ ember: { bg:'var(--ember-50)', fg:'var(--ember-700)' },
182
+ mono: { bg:'var(--tag-bg)', fg:'var(--tag-fg)' },
183
+ success:{ bg:'var(--success-50)', fg:'var(--success-700)' },
184
+ warning:{ bg:'var(--warning-50)', fg:'var(--warning-700)' },
185
+ danger: { bg:'var(--danger-50)', fg:'var(--danger-700)' },
186
+ info: { bg:'var(--info-50)', fg:'var(--info-700)' },
187
+ };
188
+ const sizes = { xs:{fs:10,h:18,px:6}, sm:{fs:11,h:22,px:8}, md:{fs:12,h:26,px:10} };
189
+ const t = tones[tone]; const s = sizes[size];
190
+ return (
191
+ <span style={{
192
+ display:'inline-flex', alignItems:'center', gap:4,
193
+ height: s.h, padding:`0 ${s.px}px`,
194
+ background:t.bg, color:t.fg,
195
+ fontSize:s.fs, fontWeight:500,
196
+ fontFamily:'var(--font-mono)',
197
+ letterSpacing:'var(--ls-wide)',
198
+ textTransform:'uppercase',
199
+ borderRadius: square ? 'var(--r-sm)' : 'var(--r-pill)',
200
+ }}>{children}</span>
201
+ );
202
+ };
203
+
204
+ const Badge = ({ count, tone='ember' }) => (
205
+ <span style={{
206
+ display:'inline-flex', alignItems:'center', justifyContent:'center',
207
+ minWidth:18, height:18, padding:'0 5px',
208
+ background: tone==='ember' ? 'var(--ember-500)' : 'var(--ink-600)',
209
+ color:'#fff', fontSize:10, fontWeight:600,
210
+ borderRadius:'var(--r-pill)',
211
+ }}>{count}</span>
212
+ );
213
+
214
+ // ---------- TOGGLE ----------
215
+ const Toggle = ({ on, onChange, size='md' }) => {
216
+ const sizes = { sm:{w:28,h:16,d:12}, md:{w:36,h:20,d:16}, lg:{w:44,h:24,d:20} };
217
+ const s = sizes[size];
218
+ return (
219
+ <button onClick={()=>onChange?.(!on)} style={{
220
+ width: s.w, height: s.h, padding: 2,
221
+ borderRadius:'var(--r-pill)',
222
+ background: on ? 'var(--ember-500)' : 'var(--ink-100)',
223
+ border:'none', cursor:'pointer', position:'relative',
224
+ transition:'background var(--t-base) var(--ease-out)',
225
+ }}>
226
+ <span style={{
227
+ position:'absolute', top:2,
228
+ left: on ? s.w - s.d - 2 : 2,
229
+ width: s.d, height: s.d, borderRadius:'50%',
230
+ background:'#fff',
231
+ boxShadow:'0 1px 2px rgba(0,0,0,0.18)',
232
+ transition:'left var(--t-base) var(--ease-out)',
233
+ }}/>
234
+ </button>
235
+ );
236
+ };
237
+
238
+ // ---------- TABS / SEGMENTED ----------
239
+ const Segmented = ({ items, value, onChange, size='md' }) => {
240
+ const sizes = { sm:{h:28,fs:12,px:10}, md:{h:34,fs:13,px:12} };
241
+ const s = sizes[size];
242
+ return (
243
+ <div style={{
244
+ display:'inline-flex', padding:3, gap:2,
245
+ background:'var(--ink-50)',
246
+ border:'1px solid var(--line-200)',
247
+ borderRadius:'var(--r-lg)',
248
+ }}>
249
+ {items.map(it => {
250
+ const active = it.value === value;
251
+ return (
252
+ <button key={it.value} onClick={()=>onChange?.(it.value)} style={{
253
+ display:'inline-flex', alignItems:'center', gap:6,
254
+ height: s.h, padding:`0 ${s.px}px`,
255
+ fontSize: s.fs, fontWeight: active ? 600 : 500,
256
+ color: active ? 'var(--ink-700)' : 'var(--ink-400)',
257
+ background: active ? 'var(--surface)' : 'transparent',
258
+ border:'none', cursor:'pointer',
259
+ borderRadius:'var(--r-md)',
260
+ boxShadow: active ? 'var(--shadow-xs), 0 0 0 1px var(--line-200)' : 'none',
261
+ transition:'all var(--t-fast)',
262
+ }}>{it.icon}{it.label}{it.tag && <Tag tone="mono" size="xs">{it.tag}</Tag>}</button>
263
+ );
264
+ })}
265
+ </div>
266
+ );
267
+ };
268
+
269
+ // ---------- AVATAR ----------
270
+ const Avatar = ({ name, size = 24, color = 'var(--ember-500)', square }) => (
271
+ <span style={{
272
+ width: size, height: size,
273
+ background: color, color:'#fff',
274
+ borderRadius: square ? 'var(--r-sm)' : '50%',
275
+ display:'inline-flex', alignItems:'center', justifyContent:'center',
276
+ fontSize: size * 0.42, fontWeight: 600,
277
+ fontFamily:'var(--font-display)',
278
+ flexShrink: 0,
279
+ }}>{(name || '?').charAt(0).toUpperCase()}</span>
280
+ );
281
+
282
+ // ---------- KBD ----------
283
+ const Kbd = ({ children }) => (
284
+ <span style={{
285
+ display:'inline-flex', alignItems:'center', justifyContent:'center',
286
+ minWidth: 18, height: 18, padding:'0 4px',
287
+ fontFamily:'var(--font-mono)', fontSize: 10,
288
+ color:'var(--ink-400)',
289
+ background:'var(--surface)',
290
+ border:'1px solid var(--line-200)',
291
+ borderBottomWidth: 2,
292
+ borderRadius:'var(--r-sm)',
293
+ }}>{children}</span>
294
+ );
295
+
296
+ window.Section = Section;
297
+ window.Panel = Panel;
298
+ window.Spec = Spec;
299
+ window.Button = Button;
300
+ window.Input = Input;
301
+ window.Tag = Tag;
302
+ window.Badge = Badge;
303
+ window.Toggle = Toggle;
304
+ window.Segmented = Segmented;
305
+ window.Avatar = Avatar;
306
+ window.Kbd = Kbd;
@@ -0,0 +1,306 @@
1
+ /* ============================================================
2
+ ZARK DESIGN SYSTEM — TOKENS
3
+ Light, warm, neutral system inspired by ember/orange-on-paper
4
+ ============================================================ */
5
+
6
+ :root {
7
+ /* ---------- BRAND / ACCENT (Zark Liquid Lava scale) ---------- */
8
+ /* Anchored on official Zark brand color #F56F10 (Liquid Lava) */
9
+ --ember-50: #fff3e9;
10
+ --ember-100: #ffe1c8;
11
+ --ember-200: #ffc28e;
12
+ --ember-300: #ffa056;
13
+ --ember-400: #ff8a3a; /* liquid-lava-light */
14
+ --ember-500: #f56f10; /* LIQUID LAVA — brand primary */
15
+ --ember-600: #d45e0d; /* liquid-lava-dark — primary action */
16
+ --ember-700: #ad4a09;
17
+ --ember-800: #843706;
18
+ --ember-900: #5e2704;
19
+ --liquid-lava: #f56f10;
20
+ --dark-void: #151419;
21
+ --glucon-grey: #1b1a1e;
22
+
23
+ /* ---------- NEUTRALS (warm paper → ink) ---------- */
24
+ --paper: #fafaf8; /* app bg */
25
+ --canvas: #f5f4f1; /* sidebar bg */
26
+ --surface: #ffffff; /* card bg */
27
+ --line-100: #f0eeea; /* hairlines on tinted bg */
28
+ --line-200: #e8e6e1; /* default borders */
29
+ --line-300: #d8d5cf; /* stronger dividers */
30
+
31
+ --ink-50: #f4f3f0;
32
+ --ink-100: #e8e6e1;
33
+ --ink-200: #c8c5bf;
34
+ --ink-300: #a09c95;
35
+ --ink-400: #6f6b64;
36
+ --ink-500: #4a4741;
37
+ --ink-600: #2e2c28;
38
+ --ink-700: #1a1916; /* near black */
39
+ --ink-800: #111110;
40
+ --ink-900: #0a0a09;
41
+
42
+ /* ---------- SEMANTIC ---------- */
43
+ --success-50: #ecfdf3;
44
+ --success-500: #10a960;
45
+ --success-700: #067a44;
46
+
47
+ --warning-50: #fff8e6;
48
+ --warning-500: #d99000;
49
+ --warning-700: #9a6500;
50
+
51
+ --danger-50: #fef1f1;
52
+ --danger-500: #dc3545;
53
+ --danger-700: #a52833;
54
+
55
+ --info-50: #eef5ff;
56
+ --info-500: #2f7adc;
57
+ --info-700: #1f5ba8;
58
+
59
+ /* tag/code accents */
60
+ --tag-bg: #fff0e0;
61
+ --tag-fg: #ad4a09;
62
+ --code-bg: #fff5ea;
63
+ --code-fg: #ad4a09;
64
+
65
+ /* ---------- TYPOGRAPHY ---------- */
66
+ --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
67
+ --font-mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
68
+ /* Darker Grotesque for the brand-flavored display moments (ZARK wordmark vibe).
69
+ Use it sparingly in SaaS — section heroes, hero numbers, marketing surfaces.
70
+ UI text stays on Inter. */
71
+ --font-display: "Darker Grotesque", "Inter Tight", "Inter", sans-serif;
72
+ --font-ui: "Inter", -apple-system, sans-serif;
73
+
74
+ /* type scale (px) */
75
+ --fs-2xs: 10px;
76
+ --fs-xs: 11px;
77
+ --fs-sm: 12px;
78
+ --fs-md: 13px;
79
+ --fs-base:14px;
80
+ --fs-lg: 16px;
81
+ --fs-xl: 18px;
82
+ --fs-2xl: 22px;
83
+ --fs-3xl: 28px;
84
+ --fs-4xl: 36px;
85
+ --fs-5xl: 48px;
86
+ --fs-6xl: 64px;
87
+ --fs-display: 88px;
88
+
89
+ /* line-heights */
90
+ --lh-tight: 1.1;
91
+ --lh-snug: 1.25;
92
+ --lh-base: 1.45;
93
+ --lh-loose: 1.6;
94
+
95
+ /* letter spacing */
96
+ --ls-tight: -0.02em;
97
+ --ls-snug: -0.01em;
98
+ --ls-normal: 0;
99
+ --ls-wide: 0.04em;
100
+ --ls-wider: 0.08em;
101
+ --ls-widest: 0.14em;
102
+
103
+ /* weights */
104
+ --fw-regular: 400;
105
+ --fw-medium: 500;
106
+ --fw-semibold:600;
107
+ --fw-bold: 700;
108
+
109
+ /* ---------- SPACING (4px base) ---------- */
110
+ --sp-0: 0;
111
+ --sp-1: 2px;
112
+ --sp-2: 4px;
113
+ --sp-3: 6px;
114
+ --sp-4: 8px;
115
+ --sp-5: 10px;
116
+ --sp-6: 12px;
117
+ --sp-7: 14px;
118
+ --sp-8: 16px;
119
+ --sp-10: 20px;
120
+ --sp-12: 24px;
121
+ --sp-14: 28px;
122
+ --sp-16: 32px;
123
+ --sp-20: 40px;
124
+ --sp-24: 48px;
125
+ --sp-32: 64px;
126
+ --sp-40: 80px;
127
+ --sp-48: 96px;
128
+
129
+ /* ---------- RADII ---------- */
130
+ --r-xs: 3px;
131
+ --r-sm: 4px;
132
+ --r-md: 6px;
133
+ --r-lg: 8px;
134
+ --r-xl: 12px;
135
+ --r-2xl: 16px;
136
+ --r-3xl: 20px;
137
+ --r-pill: 999px;
138
+
139
+ /* ---------- SHADOWS ---------- */
140
+ --shadow-xs: 0 1px 0 rgba(20, 17, 12, 0.04);
141
+ --shadow-sm: 0 1px 2px rgba(20, 17, 12, 0.05), 0 0 0 1px rgba(20, 17, 12, 0.04);
142
+ --shadow-md: 0 4px 12px rgba(20, 17, 12, 0.06), 0 1px 2px rgba(20, 17, 12, 0.05);
143
+ --shadow-lg: 0 12px 32px rgba(20, 17, 12, 0.08), 0 2px 6px rgba(20, 17, 12, 0.04);
144
+ --shadow-xl: 0 24px 64px rgba(20, 17, 12, 0.12), 0 4px 12px rgba(20, 17, 12, 0.05);
145
+ --shadow-modal: 0 32px 96px rgba(20, 17, 12, 0.18), 0 8px 24px rgba(20, 17, 12, 0.08);
146
+ --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.08);
147
+
148
+ --ring-focus: 0 0 0 3px rgba(255, 93, 31, 0.20);
149
+ --ring-focus-soft: 0 0 0 3px rgba(255, 93, 31, 0.12);
150
+
151
+ /* ---------- MOTION ---------- */
152
+ --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
153
+ --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
154
+ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
155
+ --t-fast: 120ms;
156
+ --t-base: 180ms;
157
+ --t-slow: 280ms;
158
+ --t-slower: 420ms;
159
+
160
+ /* ---------- LAYOUT ---------- */
161
+ --sidebar-w: 240px;
162
+ --topbar-h: 56px;
163
+ --container-max: 1280px;
164
+ }
165
+
166
+ /* ============================================================
167
+ BASE
168
+ ============================================================ */
169
+ * { box-sizing: border-box; }
170
+ html, body {
171
+ margin: 0;
172
+ padding: 0;
173
+ font-family: var(--font-sans);
174
+ font-size: var(--fs-base);
175
+ line-height: var(--lh-base);
176
+ color: var(--ink-700);
177
+ background: var(--paper);
178
+ -webkit-font-smoothing: antialiased;
179
+ text-rendering: optimizeLegibility;
180
+ }
181
+
182
+ ::selection { background: var(--ember-200); color: var(--ink-700); }
183
+
184
+ a { color: inherit; }
185
+ button { font-family: inherit; }
186
+
187
+ /* ============================================================
188
+ DARK THEME — opt-in via [data-theme="dark"] OR auto via prefers-color-scheme
189
+ ============================================================
190
+ Filosofia: o brand (liquid-lava/ember) MANTÉM os mesmos valores —
191
+ é a assinatura visual ZARK. O que muda são neutros, semânticos
192
+ suaves, sombras e ring-focus pra contraste correto.
193
+ ============================================================ */
194
+
195
+ [data-theme="dark"] {
196
+ /* Brand: liquid-lava preservado, mas os tons claros viram acentos */
197
+ --ember-50: #2a1810;
198
+ --ember-100: #3d2114;
199
+ --ember-200: #5e2704; /* invertido com 900 */
200
+ --ember-300: #843706;
201
+ --ember-400: #ad4a09;
202
+ --ember-500: #f56f10; /* LIQUID LAVA — inalterado, brand é brand */
203
+ --ember-600: #ff8a3a; /* mais claro = mais hover/active no dark */
204
+ --ember-700: #ffa056;
205
+ --ember-800: #ffc28e;
206
+ --ember-900: #ffe1c8;
207
+
208
+ /* Neutros: paper/canvas/surface vão pra escala dark-void */
209
+ --paper: #0e0d11; /* app bg — mais escuro que dark-void puro */
210
+ --canvas: #151419; /* dark-void — sidebar bg */
211
+ --surface: #1b1a1e; /* glucon-grey — card bg */
212
+ --line-100: #232227; /* hairlines */
213
+ --line-200: #2c2b32; /* default borders */
214
+ --line-300: #3a383f; /* stronger dividers */
215
+
216
+ /* Ink invertido: agora é warm-white sobre dark, não warm-black sobre paper */
217
+ --ink-50: #1a1916;
218
+ --ink-100: #2c2b27;
219
+ --ink-200: #4a4741;
220
+ --ink-300: #6f6b64;
221
+ --ink-400: #a09c95;
222
+ --ink-500: #c8c5bf;
223
+ --ink-600: #e0ddd6;
224
+ --ink-700: #f0ede5; /* near-white com warm tone */
225
+ --ink-800: #f7f5ef;
226
+ --ink-900: #fafaf8;
227
+
228
+ /* Semânticos suaves (50) ficam mais escuros pra fundo no dark */
229
+ --success-50: #0f2419;
230
+ --warning-50: #2a1f08;
231
+ --danger-50: #2a1010;
232
+ --info-50: #0e1a2c;
233
+
234
+ /* Tag/code mantêm legibilidade no dark */
235
+ --tag-bg: #3d2114;
236
+ --tag-fg: #ffc28e;
237
+ --code-bg: #2a1810;
238
+ --code-fg: #ffa056;
239
+
240
+ /* Sombras dark — invertidas: borda + glow leve em vez de drop-shadow grosso */
241
+ --shadow-xs: 0 1px 0 rgba(0, 0, 0, 0.5);
242
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
243
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
244
+ --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
245
+ --shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.3);
246
+ --shadow-modal: 0 32px 96px rgba(0, 0, 0, 0.7), 0 8px 24px rgba(0, 0, 0, 0.4);
247
+ --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);
248
+
249
+ --ring-focus: 0 0 0 3px rgba(255, 138, 58, 0.30);
250
+ --ring-focus-soft: 0 0 0 3px rgba(255, 138, 58, 0.16);
251
+ }
252
+
253
+ /* Dark mode automático via OS, opt-out: <html data-theme="light"> */
254
+ @media (prefers-color-scheme: dark) {
255
+ :root:not([data-theme="light"]) {
256
+ --ember-50: #2a1810;
257
+ --ember-100: #3d2114;
258
+ --ember-200: #5e2704;
259
+ --ember-300: #843706;
260
+ --ember-400: #ad4a09;
261
+ --ember-500: #f56f10;
262
+ --ember-600: #ff8a3a;
263
+ --ember-700: #ffa056;
264
+ --ember-800: #ffc28e;
265
+ --ember-900: #ffe1c8;
266
+
267
+ --paper: #0e0d11;
268
+ --canvas: #151419;
269
+ --surface: #1b1a1e;
270
+ --line-100: #232227;
271
+ --line-200: #2c2b32;
272
+ --line-300: #3a383f;
273
+
274
+ --ink-50: #1a1916;
275
+ --ink-100: #2c2b27;
276
+ --ink-200: #4a4741;
277
+ --ink-300: #6f6b64;
278
+ --ink-400: #a09c95;
279
+ --ink-500: #c8c5bf;
280
+ --ink-600: #e0ddd6;
281
+ --ink-700: #f0ede5;
282
+ --ink-800: #f7f5ef;
283
+ --ink-900: #fafaf8;
284
+
285
+ --success-50: #0f2419;
286
+ --warning-50: #2a1f08;
287
+ --danger-50: #2a1010;
288
+ --info-50: #0e1a2c;
289
+
290
+ --tag-bg: #3d2114;
291
+ --tag-fg: #ffc28e;
292
+ --code-bg: #2a1810;
293
+ --code-fg: #ffa056;
294
+
295
+ --shadow-xs: 0 1px 0 rgba(0, 0, 0, 0.5);
296
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.04);
297
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
298
+ --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
299
+ --shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.3);
300
+ --shadow-modal: 0 32px 96px rgba(0, 0, 0, 0.7), 0 8px 24px rgba(0, 0, 0, 0.4);
301
+ --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);
302
+
303
+ --ring-focus: 0 0 0 3px rgba(255, 138, 58, 0.30);
304
+ --ring-focus-soft: 0 0 0 3px rgba(255, 138, 58, 0.16);
305
+ }
306
+ }