@discourser/design-system 0.22.2 → 0.22.3

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 (75) hide show
  1. package/dist/figma-codex.json +2 -2
  2. package/docs/CSS_USAGE.md +235 -0
  3. package/docs/FIGMA_MAKE_SETUP.md +339 -0
  4. package/docs/GUIDELINES_REVIEW.md +728 -0
  5. package/docs/MAINTAINER_CHECKLIST.md +265 -0
  6. package/docs/TESTING_QUICK_REFERENCE.md +159 -0
  7. package/docs/TESTING_TOKENS.md +340 -0
  8. package/docs/active-stories/README.md +29 -0
  9. package/docs/active-stories/STORY-006a-figma-translation-foundations.md +324 -0
  10. package/docs/active-stories/STORY-006b-figma-translation-components.md +201 -0
  11. package/docs/active-stories/STORY-006c-figma-translation-layout-extension.md +258 -0
  12. package/docs/active-stories/STORY-008-kai-sidecar-fragments.md +137 -0
  13. package/docs/active-stories/STORY-011-verify-translation-docs.md +182 -0
  14. package/docs/archive/ARCHITECTURE-discourser-design-system.md +448 -0
  15. package/docs/claude-feed-back/ARCHITECTURE_DIAGRAM.md +243 -0
  16. package/docs/claude-feed-back/STYLING_VERIFICATION.md +89 -0
  17. package/docs/claude-feed-back/TEST_RESULTS.md +182 -0
  18. package/docs/context-share/ELEVATION_FIX_PLAN.md +903 -0
  19. package/docs/context-share/STORY-001-VALIDATION-PASSED.md +192 -0
  20. package/docs/context-share/STORY-002-IMPLEMENTATION-COMPLETE.md +161 -0
  21. package/docs/context-share/STORYBOOK_MCP_STRATEGY.md +867 -0
  22. package/docs/context-share/TESTING_GAPS_FILLED.md +353 -0
  23. package/docs/context-share/TOKEN_TESTING_SUMMARY.md +388 -0
  24. package/docs/context-share/code-connect-prompt.md +90 -0
  25. package/docs/context-share/dds-autonomous-pipeline.md +765 -0
  26. package/docs/context-share/fix-checkbox-radio-tokens.md +145 -0
  27. package/docs/context-share/icon-component-prompt.md +154 -0
  28. package/docs/context-share/icons/Audience.svg +3 -0
  29. package/docs/context-share/icons/AudioSpeaker.svg +3 -0
  30. package/docs/context-share/icons/BookmarkPlus.svg +3 -0
  31. package/docs/context-share/icons/ClipBoard.svg +8 -0
  32. package/docs/context-share/icons/DiscourserLogo.svg +4 -0
  33. package/docs/context-share/icons/ExitStudio.svg +4 -0
  34. package/docs/context-share/icons/Microphone.svg +5 -0
  35. package/docs/context-share/icons/NotebookPen.svg +3 -0
  36. package/docs/context-share/icons/PausePlay.svg +5 -0
  37. package/docs/context-share/icons/Play.svg +4 -0
  38. package/docs/context-share/icons/Record.svg +6 -0
  39. package/docs/context-share/icons/RepeatQuestion.svg +3 -0
  40. package/docs/context-share/icons/ScrollText.svg +3 -0
  41. package/docs/context-share/icons/Sparkles.svg +3 -0
  42. package/docs/context-share/icons/Speech.svg +3 -0
  43. package/docs/context-share/icons/StopPlay.svg +4 -0
  44. package/docs/context-share/icons/Timer.svg +3 -0
  45. package/docs/context-share/icons/UserProfile.svg +3 -0
  46. package/docs/context-share/m3-token-pipeline-audit.md +125 -0
  47. package/docs/context-share/storybook-mcp-kai-agent-revised-summary.md +211 -0
  48. package/docs/discourser-design-system-prd.md +3698 -0
  49. package/docs/figma-captures/01-typography.png +0 -0
  50. package/docs/figma-captures/02-button-iconbutton.png +0 -0
  51. package/docs/figma-captures/03-form-inputs.png +0 -0
  52. package/docs/figma-captures/04-form-controls.png +0 -0
  53. package/docs/figma-captures/05-data-display.png +0 -0
  54. package/docs/figma-captures/06-feedback.png +0 -0
  55. package/docs/figma-captures/07-overlays.png +0 -0
  56. package/docs/figma-captures/08-navigation-layout.png +0 -0
  57. package/docs/figma-captures/09-custom-components.png +0 -0
  58. package/docs/figma-captures/10-scenario-queue.png +0 -0
  59. package/docs/figma-captures/11-icon-library.png +0 -0
  60. package/docs/figma-make-docs/01-understanding-templates.md +235 -0
  61. package/docs/figma-make-docs/02-prerequisites.md +266 -0
  62. package/docs/figma-make-docs/03-creating-template.md +306 -0
  63. package/docs/figma-make-docs/04-adding-guidelines.md +448 -0
  64. package/docs/figma-make-docs/05-example-starter-code.md +590 -0
  65. package/docs/figma-make-docs/06-publishing-template.md +417 -0
  66. package/docs/figma-make-docs/07-maintenance.md +536 -0
  67. package/docs/figma-make-docs/08-faq.md +490 -0
  68. package/docs/figma-make-docs/README.md +95 -0
  69. package/docs/material-theme.json +418 -0
  70. package/docs/plans/2026-03-12-figma-token-export-rewrite.md +504 -0
  71. package/docs/plans/2026-03-12-step7-panda-token-resolution-design.md +119 -0
  72. package/docs/plans/2026-03-12-step7-panda-token-resolution.md +993 -0
  73. package/docs/token-name-mapping.json +850 -0
  74. package/docs/token-name-mapping.md +251 -0
  75. package/package.json +3 -2
@@ -0,0 +1,993 @@
1
+ # Step 7: Panda Token Resolution for Foundation Stories — Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** Replace raw-value rendering in all four foundation MDX stories with Panda CSS token variables so a broken token produces a blank/invisible output.
6
+
7
+ **Architecture:** Approach A — update the display components in `src/stories/foundations/components/` to accept a token-name prop and look up pre-declared `css()` class strings. The `.mdx` files pass token name strings instead of raw hex/px/shadow values. `material3Language` is removed from all rendering paths.
8
+
9
+ **Tech Stack:** Panda CSS (`css()` from `styled-system/css`), React, MDX (Storybook), TypeScript.
10
+
11
+ ---
12
+
13
+ ## Task 1: Update `ColorSwatch.tsx` — refactor `SemanticSwatch`
14
+
15
+ **Files:**
16
+
17
+ - Modify: `src/stories/foundations/components/ColorSwatch.tsx`
18
+
19
+ The `SemanticSwatch` component currently accepts `lightValue`/`darkValue` hex strings and applies them as inline `backgroundColor`. Replace with a Panda CSS token lookup.
20
+
21
+ **Step 1: Add the `css` import and pre-declare the semantic background lookup**
22
+
23
+ At the top of `ColorSwatch.tsx`, add `import { css } from 'styled-system/css';`.
24
+
25
+ Then add this object **before** the `ColorSwatch` component definition (keep `ColorSwatch` and `TonalSwatch` as-is for now — they may still be imported even if unused):
26
+
27
+ ```tsx
28
+ import { css } from 'styled-system/css';
29
+ import { type CSSProperties } from 'react';
30
+
31
+ // ── Pre-declared css() lookups — Panda CSS statically extracts these ─────────
32
+ // Keys match the `name` prop passed from Colors.mdx (M3 semantic role names).
33
+ // Values use the Panda semantic token path from src/preset/semantic-tokens.ts.
34
+ const semanticBg: Record<string, string> = {
35
+ // Primary
36
+ primary: css({ bg: 'primary' }),
37
+ onPrimary: css({ bg: 'onPrimary' }),
38
+ primaryContainer: css({ bg: 'primary.container' }),
39
+ onPrimaryContainer: css({ bg: 'onPrimary.container' }),
40
+ // Secondary
41
+ secondary: css({ bg: 'secondary' }),
42
+ onSecondary: css({ bg: 'onSecondary' }),
43
+ secondaryContainer: css({ bg: 'secondary.container' }),
44
+ onSecondaryContainer: css({ bg: 'onSecondary.container' }),
45
+ // Tertiary
46
+ tertiary: css({ bg: 'tertiary' }),
47
+ onTertiary: css({ bg: 'onTertiary' }),
48
+ tertiaryContainer: css({ bg: 'tertiary.container' }),
49
+ onTertiaryContainer: css({ bg: 'onTertiary.container' }),
50
+ // Error
51
+ error: css({ bg: 'error' }),
52
+ onError: css({ bg: 'onError' }),
53
+ errorContainer: css({ bg: 'error.container' }),
54
+ onErrorContainer: css({ bg: 'onError.container' }),
55
+ // Surface
56
+ surface: css({ bg: 'surface' }),
57
+ onSurface: css({ bg: 'onSurface' }),
58
+ surfaceVariant: css({ bg: 'surfaceVariant' }),
59
+ onSurfaceVariant: css({ bg: 'onSurface.variant' }),
60
+ // Surface containers
61
+ surfaceContainerLowest: css({ bg: 'surface.container.lowest' }),
62
+ surfaceContainerLow: css({ bg: 'surface.container.low' }),
63
+ surfaceContainer: css({ bg: 'surface.container' }),
64
+ surfaceContainerHigh: css({ bg: 'surface.container.high' }),
65
+ surfaceContainerHighest: css({ bg: 'surface.container.highest' }),
66
+ // Outline
67
+ outline: css({ bg: 'outline' }),
68
+ outlineVariant: css({ bg: 'outline.variant' }),
69
+ // Inverse
70
+ inverseSurface: css({ bg: 'inverseSurface' }),
71
+ inverseOnSurface: css({ bg: 'inverseOnSurface' }),
72
+ inversePrimary: css({ bg: 'inversePrimary' }),
73
+ // Utility
74
+ background: css({ bg: 'background' }),
75
+ onBackground: css({ bg: 'onBackground' }),
76
+ scrim: css({ bg: 'scrim' }),
77
+ shadow: css({ bg: 'shadow' }),
78
+ };
79
+ ```
80
+
81
+ **Step 2: Replace the `SemanticSwatchProps` interface and component**
82
+
83
+ Remove the old `SemanticSwatchProps` interface and `SemanticSwatch` component entirely, replace with:
84
+
85
+ ```tsx
86
+ interface SemanticSwatchProps {
87
+ name: string;
88
+ description?: string;
89
+ }
90
+
91
+ export const SemanticSwatch = ({ name, description }: SemanticSwatchProps) => {
92
+ const bgClass = semanticBg[name] ?? '';
93
+
94
+ const containerStyle: CSSProperties = {
95
+ marginBottom: '16px',
96
+ };
97
+
98
+ const labelStyle: CSSProperties = {
99
+ fontSize: '14px',
100
+ fontWeight: '500',
101
+ marginBottom: '8px',
102
+ fontFamily: 'Inter, sans-serif',
103
+ };
104
+
105
+ const swatchRowStyle: CSSProperties = {
106
+ display: 'grid',
107
+ gridTemplateColumns: '1fr 1fr',
108
+ gap: '8px',
109
+ };
110
+
111
+ const swatchContainerStyle: CSSProperties = {
112
+ display: 'flex',
113
+ flexDirection: 'column',
114
+ gap: '4px',
115
+ };
116
+
117
+ const swatchStyle: CSSProperties = {
118
+ height: '80px',
119
+ borderRadius: '8px',
120
+ border: '1px solid rgba(0, 0, 0, 0.1)',
121
+ };
122
+
123
+ const modeStyle: CSSProperties = {
124
+ fontSize: '10px',
125
+ textTransform: 'uppercase',
126
+ color: '#999',
127
+ fontWeight: '600',
128
+ };
129
+
130
+ const tokenStyle: CSSProperties = {
131
+ fontSize: '11px',
132
+ fontFamily: 'monospace',
133
+ color: '#666',
134
+ };
135
+
136
+ const descStyle: CSSProperties = {
137
+ fontSize: '12px',
138
+ color: '#666',
139
+ marginTop: '8px',
140
+ };
141
+
142
+ return (
143
+ <div style={containerStyle}>
144
+ <div style={labelStyle}>{name}</div>
145
+ <div style={swatchRowStyle}>
146
+ {/* Light mode swatch — inherits default theme */}
147
+ <div style={swatchContainerStyle}>
148
+ <div style={modeStyle}>Light</div>
149
+ <div className={bgClass} style={swatchStyle} />
150
+ <div style={tokenStyle}>{name}</div>
151
+ </div>
152
+ {/* Dark mode swatch — forced via data-theme="dark" */}
153
+ <div style={swatchContainerStyle} data-theme="dark">
154
+ <div style={modeStyle}>Dark</div>
155
+ <div className={bgClass} style={swatchStyle} />
156
+ <div style={tokenStyle}>{name} [dark]</div>
157
+ </div>
158
+ </div>
159
+ {description && <div style={descStyle}>{description}</div>}
160
+ </div>
161
+ );
162
+ };
163
+ ```
164
+
165
+ **Step 3: Verify TypeScript compiles**
166
+
167
+ ```bash
168
+ cd /Users/willstreeter/WebstormProjects/vibe-coding/shifu-project/Discourser-Design-System
169
+ pnpm typecheck
170
+ ```
171
+
172
+ Expected: no new errors (there may be errors from Colors.mdx prop mismatch until Task 2 — that's OK for now, mdx files aren't type-checked the same way).
173
+
174
+ ---
175
+
176
+ ## Task 2: Update `Colors.mdx` — remove tonal grid, update SemanticSwatch calls
177
+
178
+ **Files:**
179
+
180
+ - Modify: `src/stories/foundations/Colors.mdx`
181
+
182
+ **Step 1: Remove the tonal palette section and update imports**
183
+
184
+ Replace the import line:
185
+
186
+ ```mdx
187
+ import {
188
+ ColorSwatch,
189
+ TonalSwatch,
190
+ SemanticSwatch,
191
+ } from './components/ColorSwatch';
192
+ import { material3Language } from '../../languages/material3.language';
193
+ ```
194
+
195
+ With:
196
+
197
+ ```mdx
198
+ import { SemanticSwatch } from './components/ColorSwatch';
199
+ ```
200
+
201
+ **Step 2: Replace the six tonal palette grid sections**
202
+
203
+ The file has six `<div style={{ display: 'grid', gridTemplateColumns: 'repeat(13, 1fr)' ...}}>` blocks (Primary, Secondary, Tertiary, Neutral, Neutral Variant, Error) each containing `{Object.entries(material3Language.colors.X).map(...)}`.
204
+
205
+ Replace **all six** (from `### Primary` through the Error tonal grid `</div>`) plus the `### Primary` through `### Error` subheadings and the paragraphs before each grid.
206
+
207
+ Replace the entire tonal palettes section (everything from `## Tonal Palettes` down to but not including `---`) with:
208
+
209
+ ```mdx
210
+ ## Tonal Palettes
211
+
212
+ > **These are internal pipeline values.** Tonal palette steps (0–100) are used to build the Radix-scale and semantic tokens — they are not Panda CSS tokens and should never be used directly in components. To see the usable color vocabulary, open **Foundations → Color Scale** in the sidebar.
213
+ ```
214
+
215
+ **Step 3: Update all SemanticSwatch JSX calls — remove lightValue and darkValue props**
216
+
217
+ Find every `<SemanticSwatch` block. Each currently looks like:
218
+
219
+ ```jsx
220
+ <SemanticSwatch
221
+ name="primary"
222
+ lightValue={material3Language.semantic.primary}
223
+ darkValue={material3Language.semanticDark.primary}
224
+ description="Primary brand color for key actions and emphasis"
225
+ />
226
+ ```
227
+
228
+ Remove `lightValue={...}` and `darkValue={...}` from every call. Result:
229
+
230
+ ```jsx
231
+ <SemanticSwatch
232
+ name="primary"
233
+ description="Primary brand color for key actions and emphasis"
234
+ />
235
+ ```
236
+
237
+ There are ~34 `<SemanticSwatch` calls. Remove the `lightValue` and `darkValue` props from all of them.
238
+
239
+ **Step 4: Run typecheck**
240
+
241
+ ```bash
242
+ pnpm typecheck
243
+ ```
244
+
245
+ Expected: clean.
246
+
247
+ ---
248
+
249
+ ## Task 3: Token breakage test (verify + revert)
250
+
251
+ This is the manual verification required by the spec. Do NOT skip it.
252
+
253
+ **Step 1: Temporarily break the `primary` token**
254
+
255
+ In `src/preset/semantic-tokens.ts`, find:
256
+
257
+ ```ts
258
+ primary: {
259
+ DEFAULT: { value: { base: s.primary, _dark: d.primary } },
260
+ ```
261
+
262
+ Rename `primary` → `primary_BROKEN`:
263
+
264
+ ```ts
265
+ primary_BROKEN: {
266
+ DEFAULT: { value: { base: s.primary, _dark: d.primary } },
267
+ ```
268
+
269
+ **Step 2: Rebuild Panda**
270
+
271
+ ```bash
272
+ pnpm build:panda
273
+ ```
274
+
275
+ **Step 3: Confirm visual failure**
276
+
277
+ Open Storybook (`pnpm dev`) and navigate to **Foundations → Colors**. The `primary` semantic swatch boxes should appear blank/no color (showing the background color of the page rather than the primary token color). This confirms the swatch is reading from the CSS variable, not from a hardcoded hex.
278
+
279
+ **Step 4: Revert the token rename**
280
+
281
+ Restore `primary_BROKEN` → `primary` in `src/preset/semantic-tokens.ts`.
282
+
283
+ **Step 5: Rebuild Panda and confirm recovery**
284
+
285
+ ```bash
286
+ pnpm build:panda
287
+ ```
288
+
289
+ Storybook: primary swatches return to their correct green color.
290
+
291
+ ---
292
+
293
+ ## Task 4: Commit Colors + test result
294
+
295
+ ```bash
296
+ cd /Users/willstreeter/WebstormProjects/vibe-coding/shifu-project/Discourser-Design-System
297
+ git add src/stories/foundations/components/ColorSwatch.tsx \
298
+ src/stories/foundations/Colors.mdx
299
+ git commit -m "feat: Colors.mdx uses Panda token CSS vars for semantic swatches
300
+
301
+ - SemanticSwatch now accepts name prop (token key) + lookup table
302
+ - Light/dark swatches use data-theme wrapper + same css() class
303
+ - Token labels show token path instead of hex strings
304
+ - Tonal palette grid removed (internal values, not Panda tokens)
305
+ → replaced with note pointing to Color Scale story
306
+ - material3Language removed from all rendering paths in Colors.mdx
307
+
308
+ Test performed: renamed 'primary' → 'primary_BROKEN' in semantic-tokens.ts,
309
+ confirmed primary swatches went blank; reverted, confirmed recovery."
310
+ ```
311
+
312
+ ---
313
+
314
+ ## Task 5: Update `ElevationCard.tsx` — use shadow tokens
315
+
316
+ **Files:**
317
+
318
+ - Modify: `src/stories/foundations/components/ElevationCard.tsx`
319
+
320
+ **Step 1: Add `css` import and pre-declare elevation classes**
321
+
322
+ ```tsx
323
+ import { css } from 'styled-system/css';
324
+ import { type CSSProperties } from 'react';
325
+
326
+ // ── Pre-declared css() calls — Panda CSS statically extracts these ─────────
327
+ const elevationClasses: Record<string, string> = {
328
+ level0: css({ boxShadow: 'level0' }),
329
+ level1: css({ boxShadow: 'level1' }),
330
+ level2: css({ boxShadow: 'level2' }),
331
+ level3: css({ boxShadow: 'level3' }),
332
+ level4: css({ boxShadow: 'level4' }),
333
+ level5: css({ boxShadow: 'level5' }),
334
+ };
335
+
336
+ export { elevationClasses };
337
+ ```
338
+
339
+ **Step 2: Update `ElevationCardProps` — remove `shadow` prop**
340
+
341
+ ```tsx
342
+ interface ElevationCardProps {
343
+ level: string;
344
+ }
345
+ ```
346
+
347
+ **Step 3: Update `ElevationCard` component**
348
+
349
+ Remove `shadow` from the destructured props. Remove `boxShadow` from `cardStyle`. Apply `elevationClasses[level]` as className on the card div:
350
+
351
+ ```tsx
352
+ export const ElevationCard = ({ level }: ElevationCardProps) => {
353
+ const containerStyle: CSSProperties = {
354
+ display: 'flex',
355
+ flexDirection: 'column',
356
+ alignItems: 'center',
357
+ marginBottom: '32px',
358
+ };
359
+
360
+ const cardStyle: CSSProperties = {
361
+ width: '200px',
362
+ height: '120px',
363
+ backgroundColor: '#fff',
364
+ borderRadius: '12px',
365
+ display: 'flex',
366
+ alignItems: 'center',
367
+ justifyContent: 'center',
368
+ marginBottom: '16px',
369
+ // boxShadow applied via className — reads from Panda CSS variable
370
+ };
371
+
372
+ const labelStyle: CSSProperties = {
373
+ fontSize: '16px',
374
+ fontWeight: '600',
375
+ fontFamily: 'Inter, sans-serif',
376
+ marginBottom: '8px',
377
+ color: '#333',
378
+ };
379
+
380
+ return (
381
+ <div style={containerStyle}>
382
+ <div style={labelStyle}>{level}</div>
383
+ <div style={cardStyle} className={elevationClasses[level]}>
384
+ <span style={{ color: '#999', fontSize: '14px' }}>
385
+ {level === 'level0' ? 'No shadow' : 'Elevation'}
386
+ </span>
387
+ </div>
388
+ </div>
389
+ );
390
+ };
391
+ ```
392
+
393
+ **Step 4: Update `ElevationGrid` — remove `elevations` prop, render fixed levels**
394
+
395
+ ```tsx
396
+ export const ElevationGrid = () => {
397
+ const gridStyle: CSSProperties = {
398
+ display: 'grid',
399
+ gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
400
+ gap: '48px',
401
+ marginTop: '32px',
402
+ padding: '32px',
403
+ backgroundColor: '#f5f5f5',
404
+ borderRadius: '8px',
405
+ };
406
+
407
+ return (
408
+ <div style={gridStyle}>
409
+ {(
410
+ ['level0', 'level1', 'level2', 'level3', 'level4', 'level5'] as const
411
+ ).map((level) => (
412
+ <ElevationCard key={level} level={level} />
413
+ ))}
414
+ </div>
415
+ );
416
+ };
417
+ ```
418
+
419
+ **Step 5: Typecheck**
420
+
421
+ ```bash
422
+ pnpm typecheck
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Task 6: Update `Elevation.mdx` — use token classes, remove material3Language
428
+
429
+ **Files:**
430
+
431
+ - Modify: `src/stories/foundations/Elevation.mdx`
432
+
433
+ **Step 1: Update imports**
434
+
435
+ Replace:
436
+
437
+ ```mdx
438
+ import { ElevationGrid } from './components/ElevationCard';
439
+ import { material3Language } from '../../languages/material3.language';
440
+ ```
441
+
442
+ With:
443
+
444
+ ```mdx
445
+ import { ElevationGrid, elevationClasses } from './components/ElevationCard';
446
+ ```
447
+
448
+ **Step 2: Update `<ElevationGrid />` — remove props**
449
+
450
+ Find:
451
+
452
+ ```jsx
453
+ <ElevationGrid elevations={material3Language.elevation.levels} />
454
+ ```
455
+
456
+ Replace with:
457
+
458
+ ```jsx
459
+ <ElevationGrid />
460
+ ```
461
+
462
+ **Step 3: Update "Visual Comparison — Cards with Different Elevations" section**
463
+
464
+ This section has an inline grid with three cards (Level 0, 1, 2). Each div uses `boxShadow: material3Language.elevation.levels.levelX`.
465
+
466
+ Replace `boxShadow: material3Language.elevation.levels.level0` with `className={elevationClasses['level0']}` (and remove the boxShadow from the style object). Do this for level0, level1, level2.
467
+
468
+ For example, the Level 0 card changes from:
469
+
470
+ ```jsx
471
+ <div style={{
472
+ padding: '24px',
473
+ backgroundColor: '#fff',
474
+ borderRadius: '12px',
475
+ boxShadow: material3Language.elevation.levels.level0,
476
+ textAlign: 'center'
477
+ }}>
478
+ ```
479
+
480
+ To:
481
+
482
+ ```jsx
483
+ <div
484
+ className={elevationClasses['level0']}
485
+ style={{ padding: '24px', backgroundColor: '#fff', borderRadius: '12px', textAlign: 'center' }}
486
+ >
487
+ ```
488
+
489
+ **Step 4: Update "Floating Elements" section**
490
+
491
+ Same treatment for level3, level4, level5 cards in the second visual grid.
492
+
493
+ **Step 5: Typecheck**
494
+
495
+ ```bash
496
+ pnpm typecheck
497
+ ```
498
+
499
+ ---
500
+
501
+ ## Task 7: Commit Elevation changes
502
+
503
+ ```bash
504
+ git add src/stories/foundations/components/ElevationCard.tsx \
505
+ src/stories/foundations/Elevation.mdx
506
+ git commit -m "feat: Elevation.mdx uses Panda token CSS vars for shadow swatches
507
+
508
+ - elevationClasses lookup: 6 explicit css({ boxShadow: 'levelX' }) entries
509
+ - ElevationCard uses className instead of inline boxShadow style
510
+ - ElevationGrid renders fixed level array, no longer accepts elevations prop
511
+ - elevationClasses exported for use in Elevation.mdx inline cards
512
+ - material3Language removed from all rendering paths in Elevation.mdx"
513
+ ```
514
+
515
+ ---
516
+
517
+ ## Task 8: Update `SpacingBox.tsx` — use width tokens
518
+
519
+ **Files:**
520
+
521
+ - Modify: `src/stories/foundations/components/SpacingBox.tsx`
522
+
523
+ **Step 1: Add `css` import and pre-declare spacing width classes**
524
+
525
+ ```tsx
526
+ import { css } from 'styled-system/css';
527
+ import { type CSSProperties } from 'react';
528
+
529
+ // ── Pre-declared css() calls — Panda CSS statically extracts these ─────────
530
+ const spacingWidthClasses: Record<string, string> = {
531
+ none: css({ width: 'none' }),
532
+ xxs: css({ width: 'xxs' }),
533
+ xs: css({ width: 'xs' }),
534
+ sm: css({ width: 'sm' }),
535
+ md: css({ width: 'md' }),
536
+ lg: css({ width: 'lg' }),
537
+ xl: css({ width: 'xl' }),
538
+ xxl: css({ width: 'xxl' }),
539
+ xxxl: css({ width: 'xxxl' }),
540
+ };
541
+ ```
542
+
543
+ **Step 2: Update `SpacingBox` component**
544
+
545
+ The `value` prop is kept for the px label. Remove `width: value` from `boxStyle`. Apply `spacingWidthClasses[name]` as className:
546
+
547
+ ```tsx
548
+ export const SpacingBox = ({ name, value }: SpacingBoxProps) => {
549
+ // ... same containerStyle, labelContainerStyle, nameStyle, valueStyle, boxContainerStyle ...
550
+
551
+ const boxStyle: CSSProperties = {
552
+ height: '40px',
553
+ backgroundColor: '#4C662B',
554
+ borderRadius: '4px',
555
+ position: 'relative',
556
+ // width applied via className — reads from Panda CSS variable
557
+ };
558
+
559
+ const dimensionStyle: CSSProperties = {
560
+ position: 'absolute',
561
+ top: '-20px',
562
+ left: '0',
563
+ right: '0',
564
+ fontSize: '10px',
565
+ fontFamily: 'monospace',
566
+ color: '#999',
567
+ textAlign: 'center',
568
+ };
569
+
570
+ return (
571
+ <div style={containerStyle}>
572
+ <div style={labelContainerStyle}>
573
+ <div style={nameStyle}>{name}</div>
574
+ <div style={valueStyle}>{value}</div>
575
+ </div>
576
+ <div style={boxContainerStyle}>
577
+ <div style={boxStyle} className={spacingWidthClasses[name]}>
578
+ <div style={dimensionStyle}>{value}</div>
579
+ </div>
580
+ </div>
581
+ </div>
582
+ );
583
+ };
584
+ ```
585
+
586
+ Keep `SpacingGrid` as-is (it already passes `name` and `value`).
587
+
588
+ **Step 3: Typecheck**
589
+
590
+ ```bash
591
+ pnpm typecheck
592
+ ```
593
+
594
+ ---
595
+
596
+ ## Task 9: Update `Spacing.mdx` — remove material3Language from rendering
597
+
598
+ **Files:**
599
+
600
+ - Modify: `src/stories/foundations/Spacing.mdx`
601
+
602
+ **Step 1: Update imports**
603
+
604
+ Remove the material3Language import entirely:
605
+
606
+ ```mdx
607
+ import { Meta } from '@storybook/addon-docs/blocks';
608
+ import { SpacingBox } from './components/SpacingBox';
609
+ import { material3Language } from '../../languages/material3.language';
610
+ ```
611
+
612
+ Replace with:
613
+
614
+ ```mdx
615
+ import { Meta } from '@storybook/addon-docs/blocks';
616
+ import { SpacingBox } from './components/SpacingBox';
617
+ ```
618
+
619
+ **Step 2: The `<SpacingBox>` calls in the spacing scale section — no change needed**
620
+
621
+ The calls already pass `name` and `value` with static strings:
622
+
623
+ ```jsx
624
+ <SpacingBox name="none" value={material3Language.spacing.none} />
625
+ ```
626
+
627
+ These use `material3Language` for the `value` prop which is **display only** (the px label). The spec says we can keep material3Language for static label text. However, since we're removing the import, we need to replace with static values.
628
+
629
+ Replace the nine `<SpacingBox>` calls with static values:
630
+
631
+ ```jsx
632
+ <SpacingBox name="none" value="0px" />
633
+ <SpacingBox name="xxs" value="2px" />
634
+ <SpacingBox name="xs" value="4px" />
635
+ <SpacingBox name="sm" value="8px" />
636
+ <SpacingBox name="md" value="16px" />
637
+ <SpacingBox name="lg" value="24px" />
638
+ <SpacingBox name="xl" value="32px" />
639
+ <SpacingBox name="xxl" value="48px" />
640
+ <SpacingBox name="xxxl" value="64px" />
641
+ ```
642
+
643
+ **Step 3: Update the Spacing Reference Table**
644
+
645
+ The table uses `{material3Language.spacing.none}` etc. in the Value column. Replace with static values:
646
+
647
+ ```mdx
648
+ | Token | Value | Pixels | Use Case |
649
+ | ------ | ----- | ------ | ------------------------------- |
650
+ | `none` | 0px | 0px | Reset spacing, remove gaps |
651
+ | `xxs` | 2px | 2px | Minimal gaps, fine-tuning |
652
+ | `xs` | 4px | 4px | Tight spacing within components |
653
+ | `sm` | 8px | 8px | Component internal spacing |
654
+ | `md` | 16px | 16px | Default spacing, component gaps |
655
+ | `lg` | 24px | 24px | Section spacing, card padding |
656
+ | `xl` | 32px | 32px | Large section breaks |
657
+ | `xxl` | 48px | 48px | Major section dividers |
658
+ | `xxxl` | 64px | 64px | Page-level spacing |
659
+ ```
660
+
661
+ **Step 4: Update "Visual Examples" section — replace material3Language gap/padding**
662
+
663
+ Three container divs use `gap: material3Language.spacing.sm`, `gap: material3Language.spacing.md`, `gap: material3Language.spacing.lg` and `padding: material3Language.spacing.md/lg/xl`.
664
+
665
+ Replace each with static px strings:
666
+
667
+ - `gap: material3Language.spacing.sm` → `gap: '8px'`
668
+ - `gap: material3Language.spacing.md` → `gap: '16px'`
669
+ - `gap: material3Language.spacing.lg` → `gap: '24px'`
670
+ - `padding: material3Language.spacing.md` → `padding: '16px'`
671
+ - `padding: material3Language.spacing.lg` → `padding: '24px'`
672
+ - `padding: material3Language.spacing.xl` → `padding: '32px'`
673
+
674
+ **Step 5: Typecheck**
675
+
676
+ ```bash
677
+ pnpm typecheck
678
+ ```
679
+
680
+ ---
681
+
682
+ ## Task 10: Commit Spacing changes
683
+
684
+ ```bash
685
+ git add src/stories/foundations/components/SpacingBox.tsx \
686
+ src/stories/foundations/Spacing.mdx
687
+ git commit -m "feat: Spacing.mdx uses Panda token CSS vars for spacing bars
688
+
689
+ - spacingWidthClasses lookup: 9 explicit css({ width: 'tokenName' }) entries
690
+ - SpacingBox uses className for the visual width bar
691
+ - value prop kept for px label display only
692
+ - material3Language removed from Spacing.mdx (static values inlined)"
693
+ ```
694
+
695
+ ---
696
+
697
+ ## Task 11: Update `TypeSpecimen.tsx` — use textStyle tokens
698
+
699
+ **Files:**
700
+
701
+ - Modify: `src/stories/foundations/components/TypeSpecimen.tsx`
702
+
703
+ **Step 1: Add `css` import and pre-declare textStyle classes**
704
+
705
+ ```tsx
706
+ import { css } from 'styled-system/css';
707
+ import { type CSSProperties } from 'react';
708
+
709
+ // ── Pre-declared css() calls — Panda CSS statically extracts these ─────────
710
+ const textStyleClasses: Record<string, string> = {
711
+ displayLarge: css({ textStyle: 'displayLarge' }),
712
+ displayMedium: css({ textStyle: 'displayMedium' }),
713
+ displaySmall: css({ textStyle: 'displaySmall' }),
714
+ headlineLarge: css({ textStyle: 'headlineLarge' }),
715
+ headlineMedium: css({ textStyle: 'headlineMedium' }),
716
+ headlineSmall: css({ textStyle: 'headlineSmall' }),
717
+ titleLarge: css({ textStyle: 'titleLarge' }),
718
+ titleMedium: css({ textStyle: 'titleMedium' }),
719
+ titleSmall: css({ textStyle: 'titleSmall' }),
720
+ bodyLarge: css({ textStyle: 'bodyLarge' }),
721
+ bodyMedium: css({ textStyle: 'bodyMedium' }),
722
+ bodySmall: css({ textStyle: 'bodySmall' }),
723
+ labelLarge: css({ textStyle: 'labelLarge' }),
724
+ labelMedium: css({ textStyle: 'labelMedium' }),
725
+ labelSmall: css({ textStyle: 'labelSmall' }),
726
+ };
727
+ ```
728
+
729
+ **Step 2: Update `TypeSpecimenProps` — add `styleName` prop**
730
+
731
+ ```tsx
732
+ interface TypeSpecimenProps {
733
+ styleName: string;
734
+ name: string;
735
+ fontSize: string;
736
+ lineHeight: string;
737
+ fontWeight: string;
738
+ letterSpacing: string;
739
+ fontFamily: string;
740
+ sampleText?: string;
741
+ }
742
+ ```
743
+
744
+ **Step 3: Update the component — use textStyle class for specimen text**
745
+
746
+ The `specimenStyle` object with raw fontSize/lineHeight/fontWeight/letterSpacing/fontFamily should be removed from the specimen div. The `textStyleClasses[styleName]` class handles all typography. Keep a minimal style for `color` and `marginBottom`:
747
+
748
+ ```tsx
749
+ export const TypeSpecimen = ({
750
+ styleName,
751
+ name,
752
+ fontSize,
753
+ lineHeight,
754
+ fontWeight,
755
+ letterSpacing,
756
+ fontFamily,
757
+ sampleText = 'The quick brown fox jumps over the lazy dog',
758
+ }: TypeSpecimenProps) => {
759
+ // ... containerStyle, headerStyle, nameStyle, propertiesStyle, propertyStyle, propertyLabelStyle stay unchanged ...
760
+
761
+ return (
762
+ <div style={containerStyle}>
763
+ <div style={headerStyle}>
764
+ <div style={nameStyle}>{name}</div>
765
+ </div>
766
+ {/* Specimen text: uses Panda textStyle token — blank if token broken */}
767
+ <div
768
+ className={textStyleClasses[styleName]}
769
+ style={{ color: '#000', marginBottom: '16px' }}
770
+ >
771
+ {sampleText}
772
+ </div>
773
+ {/* Spec table: shows raw token values for reference */}
774
+ <div style={propertiesStyle}>
775
+ <div style={propertyStyle}>
776
+ <div style={propertyLabelStyle}>Font Size</div>
777
+ <div>{fontSize}</div>
778
+ </div>
779
+ <div style={propertyStyle}>
780
+ <div style={propertyLabelStyle}>Line Height</div>
781
+ <div>{lineHeight}</div>
782
+ </div>
783
+ <div style={propertyStyle}>
784
+ <div style={propertyLabelStyle}>Font Weight</div>
785
+ <div>{fontWeight}</div>
786
+ </div>
787
+ <div style={propertyStyle}>
788
+ <div style={propertyLabelStyle}>Letter Spacing</div>
789
+ <div>{letterSpacing}</div>
790
+ </div>
791
+ <div style={propertyStyle}>
792
+ <div style={propertyLabelStyle}>Font Family</div>
793
+ <div>{fontFamily}</div>
794
+ </div>
795
+ </div>
796
+ </div>
797
+ );
798
+ };
799
+ ```
800
+
801
+ Remove the `getFontFamilyString` helper function — it's no longer needed since the specimen uses the Panda textStyle class.
802
+
803
+ **Step 4: Typecheck**
804
+
805
+ ```bash
806
+ pnpm typecheck
807
+ ```
808
+
809
+ ---
810
+
811
+ ## Task 12: Update `Typography.mdx` — add styleName prop, remove material3Language
812
+
813
+ **Files:**
814
+
815
+ - Modify: `src/stories/foundations/Typography.mdx`
816
+
817
+ **Step 1: Update imports**
818
+
819
+ Remove material3Language import:
820
+
821
+ ```mdx
822
+ import { Meta } from '@storybook/addon-docs/blocks';
823
+ import { TypeSpecimen } from './components/TypeSpecimen';
824
+ ```
825
+
826
+ **Step 2: Update Font Families section — replace dynamic font strings with static**
827
+
828
+ Replace three occurrences:
829
+
830
+ - `fontFamily: material3Language.typography.fonts.display` → `fontFamily: '"Fraunces", Georgia, serif'`
831
+ - `fontFamily: material3Language.typography.fonts.body` → `fontFamily: '"Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'`
832
+ - `fontFamily: material3Language.typography.fonts.mono` → `fontFamily: '"JetBrains Mono", "Fira Code", Consolas, monospace'`
833
+
834
+ **Step 3: Add `styleName` prop to all 15 `<TypeSpecimen>` calls**
835
+
836
+ Each call currently looks like:
837
+
838
+ ```jsx
839
+ <TypeSpecimen
840
+ name="Display Large"
841
+ fontSize={material3Language.typography.scale.displayLarge.fontSize}
842
+ lineHeight={material3Language.typography.scale.displayLarge.lineHeight}
843
+ fontWeight={material3Language.typography.scale.displayLarge.fontWeight}
844
+ letterSpacing={material3Language.typography.scale.displayLarge.letterSpacing}
845
+ fontFamily={material3Language.typography.scale.displayLarge.fontFamily}
846
+ sampleText="Display Large"
847
+ />
848
+ ```
849
+
850
+ Add `styleName="displayLarge"` (and keep all existing props for the spec table). The `styleName` value matches the Panda textStyle key:
851
+
852
+ | name prop | styleName |
853
+ | ----------------- | ---------------- |
854
+ | "Display Large" | `displayLarge` |
855
+ | "Display Medium" | `displayMedium` |
856
+ | "Display Small" | `displaySmall` |
857
+ | "Headline Large" | `headlineLarge` |
858
+ | "Headline Medium" | `headlineMedium` |
859
+ | "Headline Small" | `headlineSmall` |
860
+ | "Title Large" | `titleLarge` |
861
+ | "Title Medium" | `titleMedium` |
862
+ | "Title Small" | `titleSmall` |
863
+ | "Body Large" | `bodyLarge` |
864
+ | "Body Medium" | `bodyMedium` |
865
+ | "Body Small" | `bodySmall` |
866
+ | "Label Large" | `labelLarge` |
867
+ | "Label Medium" | `labelMedium` |
868
+ | "Label Small" | `labelSmall` |
869
+
870
+ **Step 4: Replace `material3Language.typography.scale.*` props with static values**
871
+
872
+ After adding `styleName`, the remaining props are for the spec table only. Replace dynamic lookups with static strings from `material3Language.ts`:
873
+
874
+ ```
875
+ displayLarge: 57px / 64px / 400 / -0.25px / display
876
+ displayMedium: 45px / 52px / 400 / 0px / display
877
+ displaySmall: 36px / 44px / 400 / 0px / display
878
+ headlineLarge: 32px / 40px / 400 / 0px / display
879
+ headlineMedium: 28px / 36px / 400 / 0px / display
880
+ headlineSmall: 24px / 32px / 400 / 0px / display
881
+ titleLarge: 22px / 28px / 400 / 0px / body
882
+ titleMedium: 16px / 24px / 500 / 0.15px / body
883
+ titleSmall: 14px / 20px / 500 / 0.1px / body
884
+ bodyLarge: 16px / 24px / 400 / 0.5px / body
885
+ bodyMedium: 14px / 20px / 400 / 0.25px / body
886
+ bodySmall: 12px / 16px / 400 / 0.4px / body
887
+ labelLarge: 14px / 20px / 500 / 0.1px / body
888
+ labelMedium: 12px / 16px / 500 / 0.5px / body
889
+ labelSmall: 11px / 16px / 500 / 0.5px / body
890
+ ```
891
+
892
+ Verify these values against `src/languages/material3.language.ts` before writing them into the mdx — don't assume they're correct from this plan.
893
+
894
+ **Step 5: Typecheck**
895
+
896
+ ```bash
897
+ pnpm typecheck
898
+ ```
899
+
900
+ ---
901
+
902
+ ## Task 13: Commit Typography changes
903
+
904
+ ```bash
905
+ git add src/stories/foundations/components/TypeSpecimen.tsx \
906
+ src/stories/foundations/Typography.mdx
907
+ git commit -m "feat: Typography.mdx uses Panda textStyle tokens for specimen rendering
908
+
909
+ - textStyleClasses lookup: 15 explicit css({ textStyle: '...' }) entries
910
+ - TypeSpecimen specimen div uses className from lookup, not inline specimenStyle
911
+ - styleName prop added to all 15 TypeSpecimen calls in Typography.mdx
912
+ - Font family display uses static strings (font names aren't Panda tokens)
913
+ - material3Language removed from all rendering paths in Typography.mdx"
914
+ ```
915
+
916
+ ---
917
+
918
+ ## Task 14: Final verification
919
+
920
+ **Step 1: Run full test suite**
921
+
922
+ ```bash
923
+ pnpm test
924
+ ```
925
+
926
+ Expected: 306/306 pass (display components have no unit tests; the token-contract test remains valid since we didn't change semantic-tokens.ts).
927
+
928
+ **Step 2: TypeScript check**
929
+
930
+ ```bash
931
+ pnpm typecheck
932
+ ```
933
+
934
+ Expected: 0 errors.
935
+
936
+ **Step 3: Build check**
937
+
938
+ ```bash
939
+ pnpm build
940
+ ```
941
+
942
+ Expected: clean build.
943
+
944
+ **Step 4: Storybook smoke check**
945
+
946
+ ```bash
947
+ pnpm dev
948
+ ```
949
+
950
+ Open each of the four stories:
951
+
952
+ - Foundations → Colors: semantic swatches show token-resolved colors; tonal section shows the reference note
953
+ - Foundations → Elevation: ElevationGrid shows 6 levels via box-shadow tokens; Visual Comparison section renders correctly
954
+ - Foundations → Spacing: SpacingBox bars render at correct widths; px labels still visible
955
+ - Foundations → Typography: TypeSpecimen specimens render with correct font/size via textStyle tokens; spec tables still show raw values
956
+
957
+ No console errors expected.
958
+
959
+ ---
960
+
961
+ ## Task 15: Update sequence status doc + final commit
962
+
963
+ **Step 1: Find the sequence status doc**
964
+
965
+ ```bash
966
+ ls docs/
967
+ ```
968
+
969
+ Look for a file tracking "Steps 1–N complete" — likely `docs/design-system-setup-prompt.md` or similar.
970
+
971
+ **Step 2: Mark Step 7 complete**
972
+
973
+ Find the Step 7 entry and update its status from pending to complete.
974
+
975
+ **Step 3: Final commit**
976
+
977
+ ```bash
978
+ git add docs/
979
+ git commit -m "docs: mark Step 7 complete — Panda token resolution for foundation stories"
980
+ ```
981
+
982
+ ---
983
+
984
+ ## Quick Reference: Panda Token Paths Used
985
+
986
+ | Rendered property | Panda token syntax |
987
+ | -------------------------- | ------------------------------------------------------------------------- |
988
+ | Semantic color backgrounds | `css({ bg: 'primary' })`, `css({ bg: 'primary.container' })` etc. |
989
+ | Box shadow levels | `css({ boxShadow: 'level0' })` … `css({ boxShadow: 'level5' })` |
990
+ | Spacing widths | `css({ width: 'none' })`, `css({ width: 'sm' })` etc. |
991
+ | Typography | `css({ textStyle: 'displayLarge' })` … `css({ textStyle: 'labelSmall' })` |
992
+
993
+ All lookups follow the same pattern as `ColorScale.stories.tsx` — explicit string literals, no dynamic interpolation.