@hanzo/design 0.1.0 → 0.3.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.
@@ -0,0 +1,472 @@
1
+ // AUTO-GENERATED by scripts/gen-tokens.mjs from tokens/*.css — DO NOT EDIT.
2
+ // Edit the token in tokens/<group>.css and re-run `npm run gen`.
3
+ /* eslint-disable */
4
+ /** colors tokens (from tokens/colors.css). Values are raw CSS. */
5
+ export const colors = {
6
+ 'neutral-50': '#FAFAFA',
7
+ 'neutral-100': '#F5F5F5',
8
+ 'neutral-200': '#E5E5E5',
9
+ 'neutral-300': '#D4D4D4',
10
+ 'neutral-400': '#A3A3A3',
11
+ 'neutral-500': '#737373',
12
+ 'neutral-600': '#525252',
13
+ 'neutral-700': '#404040',
14
+ 'neutral-800': '#262626',
15
+ 'neutral-900': '#171717',
16
+ 'neutral-950': '#0A0A0A',
17
+ 'pure-black': '#000000',
18
+ 'pure-white': '#FFFFFF',
19
+ 'hanzo-black': '#0A0A0B',
20
+ 'hanzo-white': '#FFFFFF',
21
+ 'white-05': 'rgb(255 255 255 / .05)',
22
+ 'white-10': 'rgb(255 255 255 / .10)',
23
+ 'white-15': 'rgb(255 255 255 / .15)',
24
+ 'white-20': 'rgb(255 255 255 / .20)',
25
+ 'white-30': 'rgb(255 255 255 / .30)',
26
+ 'white-40': 'rgb(255 255 255 / .40)',
27
+ 'white-60': 'rgb(255 255 255 / .60)',
28
+ 'white-80': 'rgb(255 255 255 / .80)',
29
+ 'background': '#000000',
30
+ 'foreground': '#ededed',
31
+ 'card': '#0a0a0a',
32
+ 'card-foreground': '#f5f5f5',
33
+ 'popover': '#0a0a0a',
34
+ 'popover-foreground': '#f5f5f5',
35
+ 'primary': '#ffffff',
36
+ 'primary-foreground': '#000000',
37
+ 'secondary': '#1a1a1a',
38
+ 'secondary-foreground': '#f5f5f5',
39
+ 'muted': '#101010',
40
+ 'muted-foreground': '#888888',
41
+ 'accent': '#1a1a1a',
42
+ 'accent-foreground': '#f5f5f5',
43
+ 'destructive': '#666666',
44
+ 'destructive-foreground': '#f5f5f5',
45
+ 'border': '#1f1f1f',
46
+ 'input': '#1f1f1f',
47
+ 'ring': 'var(--neutral-500)',
48
+ 'brand': '#e4e4e7',
49
+ 'brand-foreground': '#09090b',
50
+ 'brand-muted': '#a3a3a3',
51
+ 'black': '#000000',
52
+ 'white': '#f5f5f5',
53
+ 'surface-page': 'var(--background)',
54
+ 'surface-card': 'rgb(23 23 23 / .5)',
55
+ 'surface-card-emphasis': 'rgb(23 23 23 / .8)',
56
+ 'surface-card-quiet': 'rgb(23 23 23 / .4)',
57
+ 'surface-overlay': 'rgb(10 10 10 / .95)',
58
+ 'surface-header': 'rgb(0 0 0 / .7)',
59
+ 'border-hairline': 'var(--neutral-800)',
60
+ 'border-card': 'var(--white-10)',
61
+ 'border-strong': 'var(--neutral-500)',
62
+ 'surface-0': 'var(--background)',
63
+ 'surface-1': 'var(--card)',
64
+ 'surface-2': 'var(--muted)',
65
+ 'surface-3': 'var(--secondary)',
66
+ 'text-primary': 'var(--pure-white)',
67
+ 'text-secondary': 'var(--white-80)',
68
+ 'text-tertiary': 'var(--white-60)',
69
+ 'text-helper': 'var(--muted-foreground)',
70
+ 'text-disabled': 'var(--white-30)',
71
+ 'state-error': '#ef4444',
72
+ 'state-error-text': '#fca5a5',
73
+ 'state-error-bg': 'rgb(239 68 68 / .1)',
74
+ 'state-online': '#4ade80',
75
+ 'state-success': '#22c55e',
76
+ 'chrome-dot-red': 'rgb(239 68 68 / .6)',
77
+ 'chrome-dot-yellow': 'rgb(234 179 8 / .6)',
78
+ 'chrome-dot-green': 'rgb(34 197 94 / .6)',
79
+ };
80
+ /** typography tokens (from tokens/typography.css). Values are raw CSS. */
81
+ export const typography = {
82
+ 'text-xs': '0.6875rem',
83
+ 'leading-xs': '1rem',
84
+ 'text-sm': '0.8125rem',
85
+ 'leading-sm': '1.15rem',
86
+ 'text-base': '0.875rem',
87
+ 'leading-base': '1.35rem',
88
+ 'text-lg': '0.9375rem',
89
+ 'leading-lg': '1.4rem',
90
+ 'text-xl': '1.0625rem',
91
+ 'leading-xl': '1.55rem',
92
+ 'text-2xl': '1.3125rem',
93
+ 'leading-2xl': '1.7rem',
94
+ 'text-3xl': '1.625rem',
95
+ 'leading-3xl': '1.95rem',
96
+ 'text-4xl': '2rem',
97
+ 'leading-4xl': '2.25rem',
98
+ 'text-5xl': '2.5rem',
99
+ 'leading-5xl': '1.05',
100
+ 'text-6xl': '3.25rem',
101
+ 'leading-6xl': '1',
102
+ 'text-7xl': '4rem',
103
+ 'leading-7xl': '1',
104
+ 'text-8xl': '5.25rem',
105
+ 'leading-8xl': '1',
106
+ 'text-9xl': '7rem',
107
+ 'leading-9xl': '1',
108
+ 'font-size-xs': 'var(--text-xs)',
109
+ 'font-size-sm': 'var(--text-sm)',
110
+ 'font-size-base': 'var(--text-base)',
111
+ 'font-size-lg': 'var(--text-lg)',
112
+ 'font-size-xl': 'var(--text-xl)',
113
+ 'font-size-2xl': 'var(--text-2xl)',
114
+ 'font-size-3xl': 'var(--text-3xl)',
115
+ 'font-size-4xl': 'var(--text-4xl)',
116
+ 'font-size-5xl': 'var(--text-5xl)',
117
+ 'font-size-6xl': 'var(--text-6xl)',
118
+ 'font-size-7xl': 'var(--text-7xl)',
119
+ 'font-size-8xl': 'var(--text-8xl)',
120
+ 'font-size-9xl': 'var(--text-9xl)',
121
+ 'weight-normal': '400',
122
+ 'weight-medium': '500',
123
+ 'weight-semibold': '600',
124
+ 'weight-bold': '700',
125
+ 'tracking-tight': '-0.025em',
126
+ 'tracking-normal': '0em',
127
+ 'tracking-wide': '0.025em',
128
+ 'tracking-widest': '0.1em',
129
+ 'leading-none': '1',
130
+ 'leading-tight': '1.25',
131
+ 'leading-snug': '1.375',
132
+ 'leading-normal': '1.5',
133
+ 'leading-relaxed': '1.625',
134
+ 'leading-golden': '1.618',
135
+ 'type-hero': '600 var(--text-5xl)/1.05 var(--font-display)',
136
+ 'type-h2': '700 var(--text-4xl)/var(--leading-4xl) var(--font-display)',
137
+ 'type-h3': '600 var(--text-xl)/var(--leading-xl) var(--font-display)',
138
+ 'type-lead': '400 var(--text-lg)/var(--leading-relaxed) var(--font-sans)',
139
+ 'type-body': '400 var(--text-sm)/var(--leading-sm) var(--font-sans)',
140
+ 'type-caption': '400 var(--text-xs)/var(--leading-xs) var(--font-sans)',
141
+ 'type-code': '400 var(--text-sm)/var(--leading-relaxed) var(--font-mono)',
142
+ 'type-eyebrow': '600 0.625rem/1 var(--font-sans)',
143
+ };
144
+ /** spacing tokens (from tokens/spacing.css). Values are raw CSS. */
145
+ export const spacing = {
146
+ 'space-0': '0',
147
+ 'space-1': '0.25rem',
148
+ 'space-2': '0.5rem',
149
+ 'space-3': '0.75rem',
150
+ 'space-4': '1rem',
151
+ 'space-5': '1.25rem',
152
+ 'space-6': '1.5rem',
153
+ 'space-8': '2rem',
154
+ 'space-10': '2.5rem',
155
+ 'space-12': '3rem',
156
+ 'space-14': '3.5rem',
157
+ 'space-16': '4rem',
158
+ 'space-20': '5rem',
159
+ 'space-24': '6rem',
160
+ 'space-32': '8rem',
161
+ 'golden-1': '0.25rem',
162
+ 'golden-2': '0.405rem',
163
+ 'golden-3': '0.654rem',
164
+ 'golden-4': '1.059rem',
165
+ 'golden-5': '1.713rem',
166
+ 'golden-6': '2.772rem',
167
+ 'golden-7': '4.487rem',
168
+ 'golden-8': '7.26rem',
169
+ 'golden-9': '11.749rem',
170
+ 'golden-split': '38.2% 61.8%',
171
+ 'container-max': '80rem',
172
+ 'container-prose': '48rem',
173
+ 'container-wide': '72rem',
174
+ 'gutter': '1rem',
175
+ 'gutter-sm': '1.5rem',
176
+ 'gutter-lg': '2rem',
177
+ 'section-y': '4rem',
178
+ 'section-y-lg': '6rem',
179
+ 'hero-y': '5rem',
180
+ 'hero-y-lg': '8rem',
181
+ 'header-height': '4rem',
182
+ };
183
+ /** radius tokens (from tokens/radius.css). Values are raw CSS. */
184
+ export const radius = {
185
+ 'radius': '0.5rem',
186
+ 'radius-sm': '0.375rem',
187
+ 'radius-md': '0.5rem',
188
+ 'radius-lg': '0.75rem',
189
+ 'radius-xl': '1rem',
190
+ 'radius-2xl': '1.5rem',
191
+ 'radius-composer': '28px',
192
+ 'radius-full': '9999px',
193
+ };
194
+ /** elevation tokens (from tokens/elevation.css). Values are raw CSS. */
195
+ export const elevation = {
196
+ 'shadow-none': 'none',
197
+ 'shadow-floating': '0 25px 50px -12px rgb(0 0 0 / .25)',
198
+ 'shadow-inset-hairline': 'inset 0 0 0 1px var(--white-10)',
199
+ 'ring-focus': '0 0 0 2px var(--ring)',
200
+ 'shadow-sm': '0 1px 2px 0 rgb(0 0 0 / .40)',
201
+ 'shadow': '0 1px 3px 0 rgb(0 0 0 / .45), 0 1px 2px -1px rgb(0 0 0 / .45)',
202
+ 'shadow-md': '0 4px 6px -1px rgb(0 0 0 / .50), 0 2px 4px -2px rgb(0 0 0 / .50)',
203
+ 'shadow-lg': '0 10px 15px -3px rgb(0 0 0 / .55), 0 4px 6px -4px rgb(0 0 0 / .55)',
204
+ 'shadow-xl': '0 20px 25px -5px rgb(0 0 0 / .60), 0 8px 10px -6px rgb(0 0 0 / .60)',
205
+ 'shadow-2xl': 'var(--shadow-floating)',
206
+ 'glow-hero': 'radial-gradient(circle,rgb(255 255 255 / .12) 0%,transparent 68%)',
207
+ 'glow-hero-blur': '120px',
208
+ 'sheen-card': 'radial-gradient(120% 120% at 80% 0%,rgb(255 255 255 / .08) 0%,transparent 55%)',
209
+ 'gradient-chrome': 'linear-gradient(to right,#ffffff,var(--white-80),var(--white-60))',
210
+ 'gradient-chrome-2': 'linear-gradient(to right,#ffffff,var(--neutral-500))',
211
+ 'gradient-protect': 'linear-gradient(to bottom,var(--white-10),transparent)',
212
+ };
213
+ /** motion tokens (from tokens/motion.css). Values are raw CSS. */
214
+ export const motion = {
215
+ 'duration-fast': '150ms',
216
+ 'duration-base': '300ms',
217
+ 'duration-slow': '400ms',
218
+ 'duration-slower': '500ms',
219
+ 'duration-glow': '9s',
220
+ 'ease-out': 'cubic-bezier(0,0,0.2,1)',
221
+ 'ease-in-out': 'cubic-bezier(0.4,0,0.2,1)',
222
+ 'stagger': '60ms',
223
+ 'entry-rise': '16px',
224
+ 'entry-rise-lg': '24px',
225
+ };
226
+ /** zIndex tokens (from tokens/z.css). Values are raw CSS. */
227
+ export const zIndex = {
228
+ 'z-base': '0',
229
+ 'z-raised': '10',
230
+ 'z-sticky': '200',
231
+ 'z-header': '300',
232
+ 'z-dropdown': '400',
233
+ 'z-overlay': '500',
234
+ 'z-modal': '600',
235
+ 'z-popover': '700',
236
+ 'z-toast': '800',
237
+ 'z-tooltip': 'var(--z-popover)',
238
+ 'z-notification': 'var(--z-toast)',
239
+ };
240
+ /** fonts tokens (from tokens/fonts.css). Values are raw CSS. */
241
+ export const fonts = {
242
+ 'font-sans': '"Geist","Geist Sans",ui-sans-serif,system-ui,sans-serif',
243
+ 'font-display': 'var(--font-sans)',
244
+ 'font-mono': '"Geist Mono",ui-monospace,SFMono-Regular,monospace',
245
+ 'font-serif': 'Georgia,serif',
246
+ 'font-feature-settings': '"ss01","ss02","cv01","cv02","cv03"',
247
+ };
248
+ /** base tokens (from tokens/base.css). Values are raw CSS. */
249
+ export const base = {};
250
+ /** Every token, keyed by its literal CSS custom-property name ('--background', …). */
251
+ export const cssVars = {
252
+ '--neutral-50': '#FAFAFA',
253
+ '--neutral-100': '#F5F5F5',
254
+ '--neutral-200': '#E5E5E5',
255
+ '--neutral-300': '#D4D4D4',
256
+ '--neutral-400': '#A3A3A3',
257
+ '--neutral-500': '#737373',
258
+ '--neutral-600': '#525252',
259
+ '--neutral-700': '#404040',
260
+ '--neutral-800': '#262626',
261
+ '--neutral-900': '#171717',
262
+ '--neutral-950': '#0A0A0A',
263
+ '--pure-black': '#000000',
264
+ '--pure-white': '#FFFFFF',
265
+ '--hanzo-black': '#0A0A0B',
266
+ '--hanzo-white': '#FFFFFF',
267
+ '--white-05': 'rgb(255 255 255 / .05)',
268
+ '--white-10': 'rgb(255 255 255 / .10)',
269
+ '--white-15': 'rgb(255 255 255 / .15)',
270
+ '--white-20': 'rgb(255 255 255 / .20)',
271
+ '--white-30': 'rgb(255 255 255 / .30)',
272
+ '--white-40': 'rgb(255 255 255 / .40)',
273
+ '--white-60': 'rgb(255 255 255 / .60)',
274
+ '--white-80': 'rgb(255 255 255 / .80)',
275
+ '--background': '#000000',
276
+ '--foreground': '#ededed',
277
+ '--card': '#0a0a0a',
278
+ '--card-foreground': '#f5f5f5',
279
+ '--popover': '#0a0a0a',
280
+ '--popover-foreground': '#f5f5f5',
281
+ '--primary': '#ffffff',
282
+ '--primary-foreground': '#000000',
283
+ '--secondary': '#1a1a1a',
284
+ '--secondary-foreground': '#f5f5f5',
285
+ '--muted': '#101010',
286
+ '--muted-foreground': '#888888',
287
+ '--accent': '#1a1a1a',
288
+ '--accent-foreground': '#f5f5f5',
289
+ '--destructive': '#666666',
290
+ '--destructive-foreground': '#f5f5f5',
291
+ '--border': '#1f1f1f',
292
+ '--input': '#1f1f1f',
293
+ '--ring': 'var(--neutral-500)',
294
+ '--brand': '#e4e4e7',
295
+ '--brand-foreground': '#09090b',
296
+ '--brand-muted': '#a3a3a3',
297
+ '--black': '#000000',
298
+ '--white': '#f5f5f5',
299
+ '--surface-page': 'var(--background)',
300
+ '--surface-card': 'rgb(23 23 23 / .5)',
301
+ '--surface-card-emphasis': 'rgb(23 23 23 / .8)',
302
+ '--surface-card-quiet': 'rgb(23 23 23 / .4)',
303
+ '--surface-overlay': 'rgb(10 10 10 / .95)',
304
+ '--surface-header': 'rgb(0 0 0 / .7)',
305
+ '--border-hairline': 'var(--neutral-800)',
306
+ '--border-card': 'var(--white-10)',
307
+ '--border-strong': 'var(--neutral-500)',
308
+ '--surface-0': 'var(--background)',
309
+ '--surface-1': 'var(--card)',
310
+ '--surface-2': 'var(--muted)',
311
+ '--surface-3': 'var(--secondary)',
312
+ '--text-primary': 'var(--pure-white)',
313
+ '--text-secondary': 'var(--white-80)',
314
+ '--text-tertiary': 'var(--white-60)',
315
+ '--text-helper': 'var(--muted-foreground)',
316
+ '--text-disabled': 'var(--white-30)',
317
+ '--state-error': '#ef4444',
318
+ '--state-error-text': '#fca5a5',
319
+ '--state-error-bg': 'rgb(239 68 68 / .1)',
320
+ '--state-online': '#4ade80',
321
+ '--state-success': '#22c55e',
322
+ '--chrome-dot-red': 'rgb(239 68 68 / .6)',
323
+ '--chrome-dot-yellow': 'rgb(234 179 8 / .6)',
324
+ '--chrome-dot-green': 'rgb(34 197 94 / .6)',
325
+ '--text-xs': '0.6875rem',
326
+ '--leading-xs': '1rem',
327
+ '--text-sm': '0.8125rem',
328
+ '--leading-sm': '1.15rem',
329
+ '--text-base': '0.875rem',
330
+ '--leading-base': '1.35rem',
331
+ '--text-lg': '0.9375rem',
332
+ '--leading-lg': '1.4rem',
333
+ '--text-xl': '1.0625rem',
334
+ '--leading-xl': '1.55rem',
335
+ '--text-2xl': '1.3125rem',
336
+ '--leading-2xl': '1.7rem',
337
+ '--text-3xl': '1.625rem',
338
+ '--leading-3xl': '1.95rem',
339
+ '--text-4xl': '2rem',
340
+ '--leading-4xl': '2.25rem',
341
+ '--text-5xl': '2.5rem',
342
+ '--leading-5xl': '1.05',
343
+ '--text-6xl': '3.25rem',
344
+ '--leading-6xl': '1',
345
+ '--text-7xl': '4rem',
346
+ '--leading-7xl': '1',
347
+ '--text-8xl': '5.25rem',
348
+ '--leading-8xl': '1',
349
+ '--text-9xl': '7rem',
350
+ '--leading-9xl': '1',
351
+ '--font-size-xs': 'var(--text-xs)',
352
+ '--font-size-sm': 'var(--text-sm)',
353
+ '--font-size-base': 'var(--text-base)',
354
+ '--font-size-lg': 'var(--text-lg)',
355
+ '--font-size-xl': 'var(--text-xl)',
356
+ '--font-size-2xl': 'var(--text-2xl)',
357
+ '--font-size-3xl': 'var(--text-3xl)',
358
+ '--font-size-4xl': 'var(--text-4xl)',
359
+ '--font-size-5xl': 'var(--text-5xl)',
360
+ '--font-size-6xl': 'var(--text-6xl)',
361
+ '--font-size-7xl': 'var(--text-7xl)',
362
+ '--font-size-8xl': 'var(--text-8xl)',
363
+ '--font-size-9xl': 'var(--text-9xl)',
364
+ '--weight-normal': '400',
365
+ '--weight-medium': '500',
366
+ '--weight-semibold': '600',
367
+ '--weight-bold': '700',
368
+ '--tracking-tight': '-0.025em',
369
+ '--tracking-normal': '0em',
370
+ '--tracking-wide': '0.025em',
371
+ '--tracking-widest': '0.1em',
372
+ '--leading-none': '1',
373
+ '--leading-tight': '1.25',
374
+ '--leading-snug': '1.375',
375
+ '--leading-normal': '1.5',
376
+ '--leading-relaxed': '1.625',
377
+ '--leading-golden': '1.618',
378
+ '--type-hero': '600 var(--text-5xl)/1.05 var(--font-display)',
379
+ '--type-h2': '700 var(--text-4xl)/var(--leading-4xl) var(--font-display)',
380
+ '--type-h3': '600 var(--text-xl)/var(--leading-xl) var(--font-display)',
381
+ '--type-lead': '400 var(--text-lg)/var(--leading-relaxed) var(--font-sans)',
382
+ '--type-body': '400 var(--text-sm)/var(--leading-sm) var(--font-sans)',
383
+ '--type-caption': '400 var(--text-xs)/var(--leading-xs) var(--font-sans)',
384
+ '--type-code': '400 var(--text-sm)/var(--leading-relaxed) var(--font-mono)',
385
+ '--type-eyebrow': '600 0.625rem/1 var(--font-sans)',
386
+ '--space-0': '0',
387
+ '--space-1': '0.25rem',
388
+ '--space-2': '0.5rem',
389
+ '--space-3': '0.75rem',
390
+ '--space-4': '1rem',
391
+ '--space-5': '1.25rem',
392
+ '--space-6': '1.5rem',
393
+ '--space-8': '2rem',
394
+ '--space-10': '2.5rem',
395
+ '--space-12': '3rem',
396
+ '--space-14': '3.5rem',
397
+ '--space-16': '4rem',
398
+ '--space-20': '5rem',
399
+ '--space-24': '6rem',
400
+ '--space-32': '8rem',
401
+ '--golden-1': '0.25rem',
402
+ '--golden-2': '0.405rem',
403
+ '--golden-3': '0.654rem',
404
+ '--golden-4': '1.059rem',
405
+ '--golden-5': '1.713rem',
406
+ '--golden-6': '2.772rem',
407
+ '--golden-7': '4.487rem',
408
+ '--golden-8': '7.26rem',
409
+ '--golden-9': '11.749rem',
410
+ '--golden-split': '38.2% 61.8%',
411
+ '--container-max': '80rem',
412
+ '--container-prose': '48rem',
413
+ '--container-wide': '72rem',
414
+ '--gutter': '1rem',
415
+ '--gutter-sm': '1.5rem',
416
+ '--gutter-lg': '2rem',
417
+ '--section-y': '4rem',
418
+ '--section-y-lg': '6rem',
419
+ '--hero-y': '5rem',
420
+ '--hero-y-lg': '8rem',
421
+ '--header-height': '4rem',
422
+ '--radius': '0.5rem',
423
+ '--radius-sm': '0.375rem',
424
+ '--radius-md': '0.5rem',
425
+ '--radius-lg': '0.75rem',
426
+ '--radius-xl': '1rem',
427
+ '--radius-2xl': '1.5rem',
428
+ '--radius-composer': '28px',
429
+ '--radius-full': '9999px',
430
+ '--shadow-none': 'none',
431
+ '--shadow-floating': '0 25px 50px -12px rgb(0 0 0 / .25)',
432
+ '--shadow-inset-hairline': 'inset 0 0 0 1px var(--white-10)',
433
+ '--ring-focus': '0 0 0 2px var(--ring)',
434
+ '--shadow-sm': '0 1px 2px 0 rgb(0 0 0 / .40)',
435
+ '--shadow': '0 1px 3px 0 rgb(0 0 0 / .45), 0 1px 2px -1px rgb(0 0 0 / .45)',
436
+ '--shadow-md': '0 4px 6px -1px rgb(0 0 0 / .50), 0 2px 4px -2px rgb(0 0 0 / .50)',
437
+ '--shadow-lg': '0 10px 15px -3px rgb(0 0 0 / .55), 0 4px 6px -4px rgb(0 0 0 / .55)',
438
+ '--shadow-xl': '0 20px 25px -5px rgb(0 0 0 / .60), 0 8px 10px -6px rgb(0 0 0 / .60)',
439
+ '--shadow-2xl': 'var(--shadow-floating)',
440
+ '--glow-hero': 'radial-gradient(circle,rgb(255 255 255 / .12) 0%,transparent 68%)',
441
+ '--glow-hero-blur': '120px',
442
+ '--sheen-card': 'radial-gradient(120% 120% at 80% 0%,rgb(255 255 255 / .08) 0%,transparent 55%)',
443
+ '--gradient-chrome': 'linear-gradient(to right,#ffffff,var(--white-80),var(--white-60))',
444
+ '--gradient-chrome-2': 'linear-gradient(to right,#ffffff,var(--neutral-500))',
445
+ '--gradient-protect': 'linear-gradient(to bottom,var(--white-10),transparent)',
446
+ '--duration-fast': '150ms',
447
+ '--duration-base': '300ms',
448
+ '--duration-slow': '400ms',
449
+ '--duration-slower': '500ms',
450
+ '--duration-glow': '9s',
451
+ '--ease-out': 'cubic-bezier(0,0,0.2,1)',
452
+ '--ease-in-out': 'cubic-bezier(0.4,0,0.2,1)',
453
+ '--stagger': '60ms',
454
+ '--entry-rise': '16px',
455
+ '--entry-rise-lg': '24px',
456
+ '--z-base': '0',
457
+ '--z-raised': '10',
458
+ '--z-sticky': '200',
459
+ '--z-header': '300',
460
+ '--z-dropdown': '400',
461
+ '--z-overlay': '500',
462
+ '--z-modal': '600',
463
+ '--z-popover': '700',
464
+ '--z-toast': '800',
465
+ '--z-tooltip': 'var(--z-popover)',
466
+ '--z-notification': 'var(--z-toast)',
467
+ '--font-sans': '"Geist","Geist Sans",ui-sans-serif,system-ui,sans-serif',
468
+ '--font-display': 'var(--font-sans)',
469
+ '--font-mono': '"Geist Mono",ui-monospace,SFMono-Regular,monospace',
470
+ '--font-serif': 'Georgia,serif',
471
+ '--font-feature-settings': '"ss01","ss02","cv01","cv02","cv03"',
472
+ };
@@ -0,0 +1,106 @@
1
+ # Hanzo Design System — Canonical Tokens
2
+
3
+ `@hanzo/ui` is the single source of truth for the shared Hanzo product look across
4
+ the **Tailwind** apps (hanzo.chat, hanzo.app, hanzo console, commerce, hanzo-desktop).
5
+ Change a value here; apps converge on it. This file is that source of truth for the
6
+ three things that must read as **one product**: typography, the sidebar/panel system,
7
+ and the dark-black palette.
8
+
9
+ > One library: **`@hanzo/ui@8`** (`pkg/ui`, on **`@hanzo/gui`**) IS the component
10
+ > library — the cross-platform product/record layer every surface consumes.
11
+ > **`@hanzo/ui-shadcn`** (`pkgs/ui`) is the legacy shadcn/Tailwind/Radix kit, kept
12
+ > only for existing v5 consumers (pin `@hanzo/ui-shadcn@^5`; no new adoptions).
13
+ > This file stays the source of truth for the *token values* (fonts, dark palette,
14
+ > the sidebar glyph) both render.
15
+
16
+ ---
17
+
18
+ ## 1. Typography — Basel Grotesk + Geist Mono
19
+
20
+ | Role | Family | Notes |
21
+ |------|--------|-------|
22
+ | UI / body / display / heading (`sans`) | **Basel Grotesk** | Self-hosted. Book = weight **400**, Medium = weight **500**. |
23
+ | code / data / mono (`mono`) | **Geist Mono** | `next/font/google` (`Geist_Mono`) or the geist CDN. |
24
+ | Arabic / Hebrew (`--font-ar` / `--font-he`) | unchanged | i18n only — keep. |
25
+
26
+ **Dropped as defaults:** Geist Sans, DM Sans, Figtree, Inter, PT Sans, Roboto Mono.
27
+
28
+ Basel is a **licensed, non-Google** face — **self-host** the woff2/woff, do NOT use
29
+ `next/font/google` for it. Canonical files (mirror lux.exchange):
30
+ `Basel-Grotesk-Book.woff2/.woff` (400), `Basel-Grotesk-Medium.woff2/.woff` (500).
31
+
32
+ `@font-face` (weights 400/500, `font-display: swap`, `font-style: normal`):
33
+
34
+ ```css
35
+ @font-face {
36
+ font-family: 'Basel';
37
+ font-style: normal;
38
+ font-weight: 400; /* Book; 500 = Medium */
39
+ font-display: swap;
40
+ src: url('.../Basel-Grotesk-Book.woff2') format('woff2'),
41
+ url('.../Basel-Grotesk-Book.woff') format('woff');
42
+ }
43
+ ```
44
+
45
+ Per-app adoption (converge the value, keep each app's own mechanism):
46
+ - **@hanzo/ui / Next apps** → `next/font/local` for Basel (`--font-basel-sans`) +
47
+ `next/font/google` `Geist_Mono` (`--font-geist-mono`). See `app/lib/fonts.ts`;
48
+ tailwind `sans → var(--font-basel-sans)`, `mono → var(--font-geist-mono)`.
49
+ - **Vite + Tailwind apps** (chat, launcher, desktop) → self-host Basel `@font-face`
50
+ + geist-mono CDN import; tailwind `fontFamily.sans = ['Basel', …]`,
51
+ `mono = ['Geist Mono', …]`.
52
+ - **Tamagui (console)** → Basel `@font-face` in globals + override the Tamagui
53
+ `body`/`heading` font `family` to Basel; Geist Mono for `code`/`pre`.
54
+
55
+ ---
56
+
57
+ ## 2. Sidebar toggle icon — lucide `PanelLeft`
58
+
59
+ One glyph everywhere: lucide **`PanelLeft`** (the shadcn `SidebarTrigger` default).
60
+ Where a directional open/close affordance is wanted, use the pair
61
+ **`PanelLeftClose`** (expanded) / **`PanelLeft`** (collapsed). Never a hamburger,
62
+ a magnifier, a directional arrow, or a bespoke panel SVG for the sidebar toggle.
63
+
64
+ - Icon: stroke-2, ~16–20px, `currentColor`.
65
+ - Button: ghost/outline, square (`size-7`/`h-6 w-6`), subtle hover.
66
+
67
+ ---
68
+
69
+ ## 3. Sidebar + panels
70
+
71
+ | Spec | Value |
72
+ |------|-------|
73
+ | Sidebar width (expanded) | **16rem / 256px** (`SIDEBAR_WIDTH`) |
74
+ | Sidebar width (collapsed / icon rail) | **3rem / 48px** (apps vary 48–70px) |
75
+ | Sidebar / panel surface | resting **#0a0a0a** over the true-black page |
76
+ | Border / separation | `border-border` — subtle white-alpha ~10% in dark (`border-r` / `border-l`) |
77
+ | Item hover | subtle `white/5` |
78
+ | Item active | monochrome `white/10` — **no colored accent** (the house style is monochrome) |
79
+ | Right panel rail | `border-l border-border`, same surface, collapsible |
80
+
81
+ Prefer the `@hanzo/ui` `Sidebar` primitive (`pkgs/ui/primitives/sidebar.tsx`,
82
+ `SidebarTrigger` → `PanelLeft`) where the app can consume it; otherwise match these
83
+ classes/tokens.
84
+
85
+ ---
86
+
87
+ ## 4. Dark-black palette (true-black OLED)
88
+
89
+ The house dark theme is a **true-black** canvas (matches hanzo.ai marketing +
90
+ hanzo.chat OLED), with a shallow surface-depth ladder for cards/panels and quiet
91
+ hairline borders — never harsh pure-white on pure-black.
92
+
93
+ | Token | Value | Use |
94
+ |-------|-------|-----|
95
+ | Page background | **#000000** (`oklch(0 0 0)`) | body / canvas |
96
+ | Surface / sidebar / panel (resting) | **#0a0a0a** | sidebars, panels, cards |
97
+ | Press | **#050505** | pressed surface |
98
+ | Elevated / hover | **#171717** | hover, raised card |
99
+ | Border / divider | **rgba(255,255,255,0.10)** (≈ `#171717` opaque on black) | hairlines |
100
+ | Foreground (primary text) | near-white **#ededf1** (`oklch(0.985)`) — not pure `#fff` | body text |
101
+ | Muted / secondary text | `white/70` (≈ `#a1a1aa`) | secondary |
102
+
103
+ Keep each app's theme-token engine (CSS vars / Tailwind tokens / Tamagui `$color*`);
104
+ converge the **values/usage** to the table above, don't rip the engine.
105
+
106
+ Reference: `pkgs/ui/style/hanzo-default-colors.css` (`.dark` / `.hanzo-ui-dark-theme`).
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@hanzo/design",
3
- "version": "0.1.0",
4
- "description": "Hanzo Design System \u2014 monochrome, dark-default tokens + components + brand assets, the single source of truth for every Hanzo surface.",
5
- "license": "MIT",
3
+ "version": "0.3.0",
4
+ "description": "Hanzo Design System \u2014 monochrome, dark-default tokens + components + brand assets, the single source of truth for every Hanzo surface. CSS + typed programmatic tokens.",
5
+ "license": "BSD-3-Clause",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/hanzoai/design.git"
@@ -12,7 +12,14 @@
12
12
  "sideEffects": [
13
13
  "*.css"
14
14
  ],
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
15
18
  "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
16
23
  "./styles.css": "./styles.css",
17
24
  "./tokens/*": "./tokens/*",
18
25
  "./components/*": "./components/*",
@@ -20,7 +27,18 @@
20
27
  "./content/*": "./content/*",
21
28
  "./assets/*": "./assets/*"
22
29
  },
30
+ "scripts": {
31
+ "gen": "node scripts/gen-tokens.mjs",
32
+ "test": "node scripts/check-tokens.mjs",
33
+ "build": "npm run gen && npm test && tsc -p tsconfig.json",
34
+ "prepublishOnly": "npm run build"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5.9.3"
38
+ },
23
39
  "files": [
40
+ "dist",
41
+ "src",
24
42
  "styles.css",
25
43
  "tokens",
26
44
  "components",
package/prompts/README.md CHANGED
@@ -24,3 +24,10 @@ Everything here assumes one import gives you the tokens:
24
24
  ```
25
25
 
26
26
  So every rule below can be obeyed with a CSS variable, never a hardcoded hex.
27
+
28
+ ## The two prompts (one and one way)
29
+ - **`system.md`** — the design LANGUAGE prompt: paste as a system prompt to make any
30
+ model generate Hanzo-looking output (monochrome, true-black, token-only).
31
+ - **`studio-designer.md`** — the AGENTIC prompt Hanzo Studio's Design System designer
32
+ hands the Hanzo agent stack to GENERATE/EDIT this repo's file tree with its file
33
+ tools, grounded in `guidelines/DESIGN.md`. Uses `system.md`'s language rules.