@discourser/design-system 0.22.0 → 0.22.2

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 (33) hide show
  1. package/dist/{chunk-VJN7TIGL.js → chunk-GLPWI7OF.js} +3 -3
  2. package/dist/chunk-GLPWI7OF.js.map +1 -0
  3. package/dist/{chunk-IGCGVSG4.cjs → chunk-NN4YW27E.cjs} +3 -3
  4. package/dist/chunk-NN4YW27E.cjs.map +1 -0
  5. package/dist/figma-codex.json +2 -2
  6. package/dist/index.cjs +4 -4
  7. package/dist/index.js +1 -1
  8. package/dist/languages/transform.d.ts +1 -1
  9. package/dist/preset/index.cjs +2 -2
  10. package/dist/preset/index.js +1 -1
  11. package/dist/stories/foundations/components/ColorSwatch.d.ts +1 -15
  12. package/dist/stories/foundations/components/ColorSwatch.d.ts.map +1 -1
  13. package/dist/stories/foundations/components/ElevationCard.d.ts +3 -6
  14. package/dist/stories/foundations/components/ElevationCard.d.ts.map +1 -1
  15. package/dist/stories/foundations/components/SpacingBox.d.ts.map +1 -1
  16. package/dist/stories/foundations/components/TypeSpecimen.d.ts +2 -1
  17. package/dist/stories/foundations/components/TypeSpecimen.d.ts.map +1 -1
  18. package/package.json +4 -3
  19. package/src/languages/transform.ts +1 -1
  20. package/src/stories/foundations/Borders.stories.tsx +138 -0
  21. package/src/stories/foundations/ColorScale.stories.tsx +737 -0
  22. package/src/stories/foundations/Colors.mdx +2 -131
  23. package/src/stories/foundations/Elevation.mdx +26 -45
  24. package/src/stories/foundations/Motion.stories.tsx +306 -0
  25. package/src/stories/foundations/Shape.stories.tsx +159 -0
  26. package/src/stories/foundations/Spacing.mdx +24 -25
  27. package/src/stories/foundations/Typography.mdx +93 -79
  28. package/src/stories/foundations/components/ColorSwatch.tsx +72 -109
  29. package/src/stories/foundations/components/ElevationCard.tsx +19 -22
  30. package/src/stories/foundations/components/SpacingBox.tsx +15 -2
  31. package/src/stories/foundations/components/TypeSpecimen.tsx +20 -21
  32. package/dist/chunk-IGCGVSG4.cjs.map +0 -1
  33. package/dist/chunk-VJN7TIGL.js.map +0 -1
@@ -0,0 +1,737 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import type React from 'react';
3
+ import { css } from 'styled-system/css';
4
+
5
+ const meta = {
6
+ title: 'Foundations/Color Scale',
7
+ parameters: { layout: 'padded' },
8
+ } satisfies Meta;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+
13
+ type Palette = 'primary' | 'secondary' | 'tertiary' | 'neutral' | 'error';
14
+ const PALETTES: Palette[] = [
15
+ 'primary',
16
+ 'secondary',
17
+ 'tertiary',
18
+ 'neutral',
19
+ 'error',
20
+ ];
21
+ const SCALE_STEPS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] as const;
22
+ const ALPHA_STEPS = [
23
+ 'a1',
24
+ 'a2',
25
+ 'a3',
26
+ 'a4',
27
+ 'a5',
28
+ 'a6',
29
+ 'a7',
30
+ 'a8',
31
+ 'a9',
32
+ 'a10',
33
+ 'a11',
34
+ 'a12',
35
+ ] as const;
36
+
37
+ // ── Pre-declared css() calls — Panda CSS statically extracts these ─────────────
38
+ // (dynamic template literals cannot be extracted; explicit literals are required)
39
+
40
+ const scaleBg: Record<Palette, Record<number, string>> = {
41
+ primary: {
42
+ 1: css({ bg: 'primary.1' }),
43
+ 2: css({ bg: 'primary.2' }),
44
+ 3: css({ bg: 'primary.3' }),
45
+ 4: css({ bg: 'primary.4' }),
46
+ 5: css({ bg: 'primary.5' }),
47
+ 6: css({ bg: 'primary.6' }),
48
+ 7: css({ bg: 'primary.7' }),
49
+ 8: css({ bg: 'primary.8' }),
50
+ 9: css({ bg: 'primary.9' }),
51
+ 10: css({ bg: 'primary.10' }),
52
+ 11: css({ bg: 'primary.11' }),
53
+ 12: css({ bg: 'primary.12' }),
54
+ },
55
+ secondary: {
56
+ 1: css({ bg: 'secondary.1' }),
57
+ 2: css({ bg: 'secondary.2' }),
58
+ 3: css({ bg: 'secondary.3' }),
59
+ 4: css({ bg: 'secondary.4' }),
60
+ 5: css({ bg: 'secondary.5' }),
61
+ 6: css({ bg: 'secondary.6' }),
62
+ 7: css({ bg: 'secondary.7' }),
63
+ 8: css({ bg: 'secondary.8' }),
64
+ 9: css({ bg: 'secondary.9' }),
65
+ 10: css({ bg: 'secondary.10' }),
66
+ 11: css({ bg: 'secondary.11' }),
67
+ 12: css({ bg: 'secondary.12' }),
68
+ },
69
+ tertiary: {
70
+ 1: css({ bg: 'tertiary.1' }),
71
+ 2: css({ bg: 'tertiary.2' }),
72
+ 3: css({ bg: 'tertiary.3' }),
73
+ 4: css({ bg: 'tertiary.4' }),
74
+ 5: css({ bg: 'tertiary.5' }),
75
+ 6: css({ bg: 'tertiary.6' }),
76
+ 7: css({ bg: 'tertiary.7' }),
77
+ 8: css({ bg: 'tertiary.8' }),
78
+ 9: css({ bg: 'tertiary.9' }),
79
+ 10: css({ bg: 'tertiary.10' }),
80
+ 11: css({ bg: 'tertiary.11' }),
81
+ 12: css({ bg: 'tertiary.12' }),
82
+ },
83
+ neutral: {
84
+ 1: css({ bg: 'neutral.1' }),
85
+ 2: css({ bg: 'neutral.2' }),
86
+ 3: css({ bg: 'neutral.3' }),
87
+ 4: css({ bg: 'neutral.4' }),
88
+ 5: css({ bg: 'neutral.5' }),
89
+ 6: css({ bg: 'neutral.6' }),
90
+ 7: css({ bg: 'neutral.7' }),
91
+ 8: css({ bg: 'neutral.8' }),
92
+ 9: css({ bg: 'neutral.9' }),
93
+ 10: css({ bg: 'neutral.10' }),
94
+ 11: css({ bg: 'neutral.11' }),
95
+ 12: css({ bg: 'neutral.12' }),
96
+ },
97
+ error: {
98
+ 1: css({ bg: 'error.1' }),
99
+ 2: css({ bg: 'error.2' }),
100
+ 3: css({ bg: 'error.3' }),
101
+ 4: css({ bg: 'error.4' }),
102
+ 5: css({ bg: 'error.5' }),
103
+ 6: css({ bg: 'error.6' }),
104
+ 7: css({ bg: 'error.7' }),
105
+ 8: css({ bg: 'error.8' }),
106
+ 9: css({ bg: 'error.9' }),
107
+ 10: css({ bg: 'error.10' }),
108
+ 11: css({ bg: 'error.11' }),
109
+ 12: css({ bg: 'error.12' }),
110
+ },
111
+ };
112
+
113
+ const alphaBg: Record<Palette, Record<string, string>> = {
114
+ primary: {
115
+ a1: css({ bg: 'primary.a1' }),
116
+ a2: css({ bg: 'primary.a2' }),
117
+ a3: css({ bg: 'primary.a3' }),
118
+ a4: css({ bg: 'primary.a4' }),
119
+ a5: css({ bg: 'primary.a5' }),
120
+ a6: css({ bg: 'primary.a6' }),
121
+ a7: css({ bg: 'primary.a7' }),
122
+ a8: css({ bg: 'primary.a8' }),
123
+ a9: css({ bg: 'primary.a9' }),
124
+ a10: css({ bg: 'primary.a10' }),
125
+ a11: css({ bg: 'primary.a11' }),
126
+ a12: css({ bg: 'primary.a12' }),
127
+ },
128
+ secondary: {
129
+ a1: css({ bg: 'secondary.a1' }),
130
+ a2: css({ bg: 'secondary.a2' }),
131
+ a3: css({ bg: 'secondary.a3' }),
132
+ a4: css({ bg: 'secondary.a4' }),
133
+ a5: css({ bg: 'secondary.a5' }),
134
+ a6: css({ bg: 'secondary.a6' }),
135
+ a7: css({ bg: 'secondary.a7' }),
136
+ a8: css({ bg: 'secondary.a8' }),
137
+ a9: css({ bg: 'secondary.a9' }),
138
+ a10: css({ bg: 'secondary.a10' }),
139
+ a11: css({ bg: 'secondary.a11' }),
140
+ a12: css({ bg: 'secondary.a12' }),
141
+ },
142
+ tertiary: {
143
+ a1: css({ bg: 'tertiary.a1' }),
144
+ a2: css({ bg: 'tertiary.a2' }),
145
+ a3: css({ bg: 'tertiary.a3' }),
146
+ a4: css({ bg: 'tertiary.a4' }),
147
+ a5: css({ bg: 'tertiary.a5' }),
148
+ a6: css({ bg: 'tertiary.a6' }),
149
+ a7: css({ bg: 'tertiary.a7' }),
150
+ a8: css({ bg: 'tertiary.a8' }),
151
+ a9: css({ bg: 'tertiary.a9' }),
152
+ a10: css({ bg: 'tertiary.a10' }),
153
+ a11: css({ bg: 'tertiary.a11' }),
154
+ a12: css({ bg: 'tertiary.a12' }),
155
+ },
156
+ neutral: {
157
+ a1: css({ bg: 'neutral.a1' }),
158
+ a2: css({ bg: 'neutral.a2' }),
159
+ a3: css({ bg: 'neutral.a3' }),
160
+ a4: css({ bg: 'neutral.a4' }),
161
+ a5: css({ bg: 'neutral.a5' }),
162
+ a6: css({ bg: 'neutral.a6' }),
163
+ a7: css({ bg: 'neutral.a7' }),
164
+ a8: css({ bg: 'neutral.a8' }),
165
+ a9: css({ bg: 'neutral.a9' }),
166
+ a10: css({ bg: 'neutral.a10' }),
167
+ a11: css({ bg: 'neutral.a11' }),
168
+ a12: css({ bg: 'neutral.a12' }),
169
+ },
170
+ error: {
171
+ a1: css({ bg: 'error.a1' }),
172
+ a2: css({ bg: 'error.a2' }),
173
+ a3: css({ bg: 'error.a3' }),
174
+ a4: css({ bg: 'error.a4' }),
175
+ a5: css({ bg: 'error.a5' }),
176
+ a6: css({ bg: 'error.a6' }),
177
+ a7: css({ bg: 'error.a7' }),
178
+ a8: css({ bg: 'error.a8' }),
179
+ a9: css({ bg: 'error.a9' }),
180
+ a10: css({ bg: 'error.a10' }),
181
+ a11: css({ bg: 'error.a11' }),
182
+ a12: css({ bg: 'error.a12' }),
183
+ },
184
+ };
185
+
186
+ const semanticClasses: Record<
187
+ Palette,
188
+ {
189
+ solidBg: string;
190
+ subtleBg: string;
191
+ surfaceBg: string;
192
+ outlineBorderColor: string;
193
+ plainFg: string;
194
+ }
195
+ > = {
196
+ primary: {
197
+ solidBg: css({ bg: 'primary.solid.bg' }),
198
+ subtleBg: css({ bg: 'primary.subtle.bg' }),
199
+ surfaceBg: css({ bg: 'primary.surface.bg' }),
200
+ outlineBorderColor: css({ borderColor: 'primary.outline.border' }),
201
+ plainFg: css({ color: 'primary.plain.fg' }),
202
+ },
203
+ secondary: {
204
+ solidBg: css({ bg: 'secondary.solid.bg' }),
205
+ subtleBg: css({ bg: 'secondary.subtle.bg' }),
206
+ surfaceBg: css({ bg: 'secondary.surface.bg' }),
207
+ outlineBorderColor: css({ borderColor: 'secondary.outline.border' }),
208
+ plainFg: css({ color: 'secondary.plain.fg' }),
209
+ },
210
+ tertiary: {
211
+ solidBg: css({ bg: 'tertiary.solid.bg' }),
212
+ subtleBg: css({ bg: 'tertiary.subtle.bg' }),
213
+ surfaceBg: css({ bg: 'tertiary.surface.bg' }),
214
+ outlineBorderColor: css({ borderColor: 'tertiary.outline.border' }),
215
+ plainFg: css({ color: 'tertiary.plain.fg' }),
216
+ },
217
+ neutral: {
218
+ solidBg: css({ bg: 'neutral.solid.bg' }),
219
+ subtleBg: css({ bg: 'neutral.subtle.bg' }),
220
+ surfaceBg: css({ bg: 'neutral.surface.bg' }),
221
+ outlineBorderColor: css({ borderColor: 'neutral.outline.border' }),
222
+ plainFg: css({ color: 'neutral.plain.fg' }),
223
+ },
224
+ error: {
225
+ solidBg: css({ bg: 'error.solid.bg' }),
226
+ subtleBg: css({ bg: 'error.subtle.bg' }),
227
+ surfaceBg: css({ bg: 'error.surface.bg' }),
228
+ outlineBorderColor: css({ borderColor: 'error.outline.border' }),
229
+ plainFg: css({ color: 'error.plain.fg' }),
230
+ },
231
+ };
232
+
233
+ // ── Swatch components ──────────────────────────────────────────────────────────
234
+
235
+ const swatchBase: React.CSSProperties = {
236
+ width: '52px',
237
+ height: '52px',
238
+ borderRadius: '6px',
239
+ flexShrink: 0,
240
+ };
241
+
242
+ function ScaleStepSwatch({
243
+ palette,
244
+ step,
245
+ }: {
246
+ palette: Palette;
247
+ step: number;
248
+ }) {
249
+ const isSolidAction = step === 9;
250
+ return (
251
+ <div
252
+ style={{
253
+ display: 'flex',
254
+ flexDirection: 'column',
255
+ alignItems: 'center',
256
+ gap: '4px',
257
+ }}
258
+ >
259
+ <div
260
+ className={scaleBg[palette][step]}
261
+ style={{
262
+ ...swatchBase,
263
+ border: '1px solid rgba(0,0,0,0.08)',
264
+ outline: isSolidAction ? '2px solid rgba(0,0,0,0.35)' : undefined,
265
+ outlineOffset: isSolidAction ? '2px' : undefined,
266
+ }}
267
+ title={`${palette}.${step}`}
268
+ />
269
+ <span
270
+ style={{
271
+ fontSize: '10px',
272
+ fontFamily: 'monospace',
273
+ color: '#666',
274
+ textAlign: 'center',
275
+ lineHeight: 1.2,
276
+ }}
277
+ >
278
+ {step}
279
+ </span>
280
+ {isSolidAction && (
281
+ <span
282
+ style={{
283
+ fontSize: '9px',
284
+ color: '#888',
285
+ textAlign: 'center',
286
+ lineHeight: 1.2,
287
+ }}
288
+ >
289
+ solid
290
+ <br />
291
+ action
292
+ </span>
293
+ )}
294
+ </div>
295
+ );
296
+ }
297
+
298
+ function AlphaStepSwatch({
299
+ palette,
300
+ step,
301
+ }: {
302
+ palette: Palette;
303
+ step: string;
304
+ }) {
305
+ return (
306
+ <div
307
+ style={{
308
+ display: 'flex',
309
+ flexDirection: 'column',
310
+ alignItems: 'center',
311
+ gap: '4px',
312
+ }}
313
+ >
314
+ <div
315
+ className={alphaBg[palette][step]}
316
+ style={{
317
+ ...swatchBase,
318
+ border: '1px solid rgba(255,255,255,0.2)',
319
+ }}
320
+ title={`${palette}.${step}`}
321
+ />
322
+ <span
323
+ style={{
324
+ fontSize: '10px',
325
+ fontFamily: 'monospace',
326
+ color: '#ddd',
327
+ textAlign: 'center',
328
+ lineHeight: 1.2,
329
+ }}
330
+ >
331
+ {step}
332
+ </span>
333
+ </div>
334
+ );
335
+ }
336
+
337
+ function SemanticRow({ palette }: { palette: Palette }) {
338
+ const classes = semanticClasses[palette];
339
+ const label = (text: string) => (
340
+ <span
341
+ style={{
342
+ fontSize: '9px',
343
+ fontFamily: 'monospace',
344
+ color: '#666',
345
+ textAlign: 'center',
346
+ marginTop: '4px',
347
+ lineHeight: 1.2,
348
+ }}
349
+ >
350
+ {text}
351
+ </span>
352
+ );
353
+
354
+ return (
355
+ <div
356
+ style={{
357
+ display: 'flex',
358
+ gap: '8px',
359
+ alignItems: 'flex-end',
360
+ flexWrap: 'wrap',
361
+ }}
362
+ >
363
+ <div
364
+ style={{
365
+ display: 'flex',
366
+ flexDirection: 'column',
367
+ alignItems: 'center',
368
+ }}
369
+ >
370
+ <div
371
+ className={classes.solidBg}
372
+ style={{ ...swatchBase, border: '1px solid rgba(0,0,0,0.08)' }}
373
+ />
374
+ {label('solid.bg')}
375
+ </div>
376
+
377
+ <div
378
+ style={{
379
+ display: 'flex',
380
+ flexDirection: 'column',
381
+ alignItems: 'center',
382
+ }}
383
+ >
384
+ <div
385
+ className={classes.subtleBg}
386
+ style={{ ...swatchBase, border: '1px solid rgba(0,0,0,0.08)' }}
387
+ />
388
+ {label('subtle.bg')}
389
+ </div>
390
+
391
+ <div
392
+ style={{
393
+ display: 'flex',
394
+ flexDirection: 'column',
395
+ alignItems: 'center',
396
+ }}
397
+ >
398
+ <div
399
+ className={classes.surfaceBg}
400
+ style={{ ...swatchBase, border: '1px solid rgba(0,0,0,0.08)' }}
401
+ />
402
+ {label('surface.bg')}
403
+ </div>
404
+
405
+ <div
406
+ style={{
407
+ display: 'flex',
408
+ flexDirection: 'column',
409
+ alignItems: 'center',
410
+ }}
411
+ >
412
+ <div
413
+ className={classes.outlineBorderColor}
414
+ style={{ ...swatchBase, borderWidth: '2px', borderStyle: 'solid' }}
415
+ />
416
+ {label('outline.border')}
417
+ </div>
418
+
419
+ <div
420
+ style={{
421
+ display: 'flex',
422
+ flexDirection: 'column',
423
+ alignItems: 'center',
424
+ }}
425
+ >
426
+ <div
427
+ style={{
428
+ ...swatchBase,
429
+ border: '1px dashed rgba(0,0,0,0.15)',
430
+ display: 'flex',
431
+ alignItems: 'center',
432
+ justifyContent: 'center',
433
+ }}
434
+ >
435
+ <span
436
+ className={classes.plainFg}
437
+ style={{ fontSize: '18px', fontWeight: '700' }}
438
+ >
439
+ Aa
440
+ </span>
441
+ </div>
442
+ {label('plain.fg')}
443
+ </div>
444
+ </div>
445
+ );
446
+ }
447
+
448
+ function PaletteLabel({ palette }: { palette: Palette }) {
449
+ return (
450
+ <span
451
+ style={{
452
+ fontSize: '12px',
453
+ fontWeight: '600',
454
+ textTransform: 'capitalize',
455
+ color: '#444',
456
+ fontFamily: 'Inter, system-ui, sans-serif',
457
+ minWidth: '72px',
458
+ display: 'inline-block',
459
+ }}
460
+ >
461
+ {palette}
462
+ </span>
463
+ );
464
+ }
465
+
466
+ function SectionHeading({
467
+ title,
468
+ description,
469
+ }: {
470
+ title: string;
471
+ description: string;
472
+ }) {
473
+ return (
474
+ <div style={{ marginBottom: '24px' }}>
475
+ <h2
476
+ style={{
477
+ fontSize: '18px',
478
+ fontWeight: '600',
479
+ margin: '0 0 8px',
480
+ fontFamily: 'Inter, system-ui, sans-serif',
481
+ }}
482
+ >
483
+ {title}
484
+ </h2>
485
+ <p
486
+ style={{ fontSize: '14px', color: '#666', margin: 0, lineHeight: 1.5 }}
487
+ >
488
+ {description}
489
+ </p>
490
+ </div>
491
+ );
492
+ }
493
+
494
+ // ── Section 1: Scale steps (1–12) ─────────────────────────────────────────────
495
+
496
+ export const ScaleSteps: Story = {
497
+ name: '1 · Scale Steps (1–12)',
498
+ render: () => (
499
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
500
+ <SectionHeading
501
+ title="Scale Steps (1–12)"
502
+ description="12-step Radix-style scale mapped from the M3 tonal palette. Steps increase from lightest background (1) to highest-contrast text (12). Step 9 is the primary action color — e.g. the fill for a solid button."
503
+ />
504
+ {PALETTES.map((palette) => (
505
+ <div key={palette}>
506
+ <PaletteLabel palette={palette} />
507
+ <div
508
+ style={{
509
+ display: 'flex',
510
+ gap: '6px',
511
+ flexWrap: 'wrap',
512
+ marginTop: '8px',
513
+ }}
514
+ >
515
+ {SCALE_STEPS.map((step) => (
516
+ <ScaleStepSwatch key={step} palette={palette} step={step} />
517
+ ))}
518
+ </div>
519
+ </div>
520
+ ))}
521
+ </div>
522
+ ),
523
+ };
524
+
525
+ // ── Section 2: Alpha steps (a1–a12) ───────────────────────────────────────────
526
+
527
+ export const AlphaSteps: Story = {
528
+ name: '2 · Alpha Steps (a1–a12)',
529
+ render: () => (
530
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
531
+ <SectionHeading
532
+ title="Alpha Steps (a1–a12)"
533
+ description="Transparent variants for overlays, tinted surfaces, and layered UI. Rendered on a mid-tone background here so transparency is visible. a1 is near-invisible; a12 is ~94% opaque."
534
+ />
535
+ {PALETTES.map((palette) => (
536
+ <div
537
+ key={palette}
538
+ style={{
539
+ padding: '16px 20px',
540
+ borderRadius: '8px',
541
+ background: '#777',
542
+ }}
543
+ >
544
+ <span
545
+ style={{
546
+ fontSize: '12px',
547
+ fontWeight: '600',
548
+ textTransform: 'capitalize',
549
+ color: '#eee',
550
+ fontFamily: 'Inter, system-ui, sans-serif',
551
+ display: 'block',
552
+ marginBottom: '10px',
553
+ }}
554
+ >
555
+ {palette}
556
+ </span>
557
+ <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
558
+ {ALPHA_STEPS.map((step) => (
559
+ <AlphaStepSwatch key={step} palette={palette} step={step} />
560
+ ))}
561
+ </div>
562
+ </div>
563
+ ))}
564
+ </div>
565
+ ),
566
+ };
567
+
568
+ // ── Section 3: Semantic variants ──────────────────────────────────────────────
569
+
570
+ export const SemanticVariants: Story = {
571
+ name: '3 · Semantic Variants',
572
+ render: () => (
573
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
574
+ <SectionHeading
575
+ title="Semantic Variants"
576
+ description="Pre-composed token paths for common component patterns. Use these in recipes instead of raw scale steps — they adapt correctly to light and dark mode."
577
+ />
578
+ <div
579
+ style={{
580
+ display: 'grid',
581
+ gridTemplateColumns: 'auto 1fr',
582
+ gap: '16px 24px',
583
+ alignItems: 'start',
584
+ }}
585
+ >
586
+ {PALETTES.map((palette) => (
587
+ <>
588
+ <div key={`${palette}-label`} style={{ paddingTop: '6px' }}>
589
+ <PaletteLabel palette={palette} />
590
+ </div>
591
+ <SemanticRow key={`${palette}-row`} palette={palette} />
592
+ </>
593
+ ))}
594
+ </div>
595
+ </div>
596
+ ),
597
+ };
598
+
599
+ // ── Section 4: Usage guidance ─────────────────────────────────────────────────
600
+
601
+ export const UsageGuidance: Story = {
602
+ name: '4 · Usage Guidance',
603
+ render: () => (
604
+ <div
605
+ style={{ maxWidth: '680px', fontFamily: 'Inter, system-ui, sans-serif' }}
606
+ >
607
+ <h2 style={{ fontSize: '18px', fontWeight: '600', margin: '0 0 20px' }}>
608
+ Usage Guidance
609
+ </h2>
610
+
611
+ <table
612
+ style={{ width: '100%', borderCollapse: 'collapse', fontSize: '14px' }}
613
+ >
614
+ <thead>
615
+ <tr style={{ borderBottom: '2px solid #e5e5e5' }}>
616
+ <th
617
+ style={{
618
+ textAlign: 'left',
619
+ padding: '8px 12px',
620
+ fontWeight: '600',
621
+ color: '#333',
622
+ width: '160px',
623
+ }}
624
+ >
625
+ Token
626
+ </th>
627
+ <th
628
+ style={{
629
+ textAlign: 'left',
630
+ padding: '8px 12px',
631
+ fontWeight: '600',
632
+ color: '#333',
633
+ }}
634
+ >
635
+ Use for
636
+ </th>
637
+ </tr>
638
+ </thead>
639
+ <tbody>
640
+ {(
641
+ [
642
+ ['1–2', 'App and page backgrounds'],
643
+ ['3–4', 'Subtle hover and interactive backgrounds'],
644
+ ['5–6', 'UI element fills (progress bars, indicators)'],
645
+ ['7–8', 'Borders and separators'],
646
+ ['9', 'Solid interactive fill — primary button background'],
647
+ ['10', 'Hovered solid fill'],
648
+ ['11–12', 'High-contrast text and icons'],
649
+ [
650
+ 'a1–a12',
651
+ 'Transparent overlays — render on a background to see them',
652
+ ],
653
+ ['solid.bg', 'Filled/solid variant buttons and badges'],
654
+ ['subtle.bg', 'Subtle/soft variant buttons and badges'],
655
+ [
656
+ 'surface.bg',
657
+ 'Card and surface backgrounds within a color context',
658
+ ],
659
+ [
660
+ 'outline.*',
661
+ 'Outline/ghost variant buttons (border color + optional hover bg)',
662
+ ],
663
+ [
664
+ 'plain.*',
665
+ 'Plain/text variant buttons and links (fg color only, bg transparent)',
666
+ ],
667
+ ] as [string, string][]
668
+ ).map(([token, use], i) => (
669
+ <tr
670
+ key={token}
671
+ style={{
672
+ borderBottom: '1px solid #f0f0f0',
673
+ background: i % 2 === 0 ? undefined : '#fafafa',
674
+ }}
675
+ >
676
+ <td
677
+ style={{
678
+ padding: '8px 12px',
679
+ fontFamily: 'monospace',
680
+ fontSize: '13px',
681
+ color: '#444',
682
+ }}
683
+ >
684
+ {token}
685
+ </td>
686
+ <td
687
+ style={{ padding: '8px 12px', color: '#555', lineHeight: 1.5 }}
688
+ >
689
+ {use}
690
+ </td>
691
+ </tr>
692
+ ))}
693
+ </tbody>
694
+ </table>
695
+
696
+ <h3
697
+ style={{ fontSize: '15px', fontWeight: '600', margin: '32px 0 12px' }}
698
+ >
699
+ Example Usage
700
+ </h3>
701
+ <pre
702
+ style={{
703
+ background: '#f5f5f5',
704
+ padding: '16px',
705
+ borderRadius: '8px',
706
+ fontSize: '13px',
707
+ lineHeight: 1.6,
708
+ overflow: 'auto',
709
+ margin: 0,
710
+ }}
711
+ >
712
+ {`import { css } from 'styled-system/css';
713
+
714
+ // Solid action button background
715
+ css({ bg: 'primary.solid.bg', color: 'primary.solid.fg' })
716
+
717
+ // Subtle tinted button
718
+ css({ bg: 'primary.subtle.bg', color: 'primary.subtle.fg' })
719
+
720
+ // Outline/ghost button
721
+ css({
722
+ bg: 'primary.outline.bg',
723
+ borderColor: 'primary.outline.border',
724
+ color: 'primary.outline.fg',
725
+ })
726
+
727
+ // Plain/text link
728
+ css({ color: 'primary.plain.fg' })
729
+
730
+ // Step-based (for custom components)
731
+ css({ bg: 'primary.1' }) // page background
732
+ css({ bg: 'primary.9' }) // solid action color
733
+ css({ color: 'primary.11' }) // readable body text`}
734
+ </pre>
735
+ </div>
736
+ ),
737
+ };