@motion-proto/live-tokens 0.74.0 → 0.76.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 (171) hide show
  1. package/.claude/skills/live-tokens-check-compliance/SKILL.md +33 -38
  2. package/.claude/skills/live-tokens-create-component/SKILL copy.md +196 -0
  3. package/.claude/skills/live-tokens-create-component/SKILL.md +198 -146
  4. package/.claude/skills/live-tokens-create-component/references/contract-tests.md +95 -52
  5. package/.claude/skills/live-tokens-create-component/references/intrinsics.md +2 -2
  6. package/.claude/skills/live-tokens-create-component/references/linked-siblings.md +2 -2
  7. package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +12 -12
  8. package/.claude/skills/live-tokens-create-component/references/token-naming.md +2 -1
  9. package/.claude/skills/live-tokens-create-page/SKILL.md +187 -0
  10. package/.claude/skills/live-tokens-create-page/references/interaction-sources.md +66 -0
  11. package/.claude/skills/live-tokens-create-page/references/layout-sources.md +87 -0
  12. package/.claude/skills/live-tokens-create-theme/SKILL.md +52 -48
  13. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
  14. package/.claude/skills/live-tokens-fix-findings/SKILL.md +69 -60
  15. package/.claude/skills/live-tokens-pick-component/SKILL.md +64 -79
  16. package/.claude/skills/live-tokens-set-colors/SKILL.md +47 -38
  17. package/.claude/skills/live-tokens-set-geometry/SKILL.md +58 -35
  18. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +5 -3
  19. package/.claude/skills/live-tokens-set-type/SKILL.md +30 -30
  20. package/CHANGELOG.md +138 -0
  21. package/README.md +17 -7
  22. package/bin/check-component.mjs +91 -19
  23. package/bin/check-page.mjs +102 -21
  24. package/bin/cli.mjs +87 -113
  25. package/bin/contractRunner.mjs +945 -0
  26. package/bin/create.mjs +1 -1
  27. package/bin/lib/catalogue.mjs +37 -30
  28. package/bin/lib/findings.mjs +46 -15
  29. package/bin/lib/report.mjs +3 -3
  30. package/bin/lib/tokenVocabulary.mjs +4 -4
  31. package/bin/migrate-routes.mjs +5 -5
  32. package/bin/migrate.mjs +4 -4
  33. package/bin/save-theme.mjs +8 -9
  34. package/bin/set-colors.mjs +9 -11
  35. package/bin/set-geometry.mjs +7 -7
  36. package/bin/set-type.mjs +5 -7
  37. package/bin/setup-claude.mjs +110 -0
  38. package/dist-plugin/{chunk-W6Y4BWFB.js → chunk-6WGFOJXO.js} +22 -0
  39. package/dist-plugin/{chunk-7VRTBGJT.js → chunk-PDNL4NC5.js} +9 -2
  40. package/dist-plugin/{chunk-V3YF6CGT.js → chunk-SWXRVZKT.js} +43 -1
  41. package/dist-plugin/{dataPaths-BhWzd5cL.d.cts → dataPaths-BpIK_Obx.d.cts} +1 -0
  42. package/dist-plugin/{dataPaths-BhWzd5cL.d.ts → dataPaths-BpIK_Obx.d.ts} +1 -0
  43. package/dist-plugin/index.cjs +310 -147
  44. package/dist-plugin/index.d.cts +1 -1
  45. package/dist-plugin/index.d.ts +1 -1
  46. package/dist-plugin/index.js +218 -122
  47. package/dist-plugin/migrateData/index.cjs +66 -2
  48. package/dist-plugin/migrateData/index.d.cts +1 -1
  49. package/dist-plugin/migrateData/index.d.ts +1 -1
  50. package/dist-plugin/migrateData/index.js +3 -3
  51. package/dist-plugin/setColors/index.cjs +61 -4
  52. package/dist-plugin/setColors/index.d.cts +1 -1
  53. package/dist-plugin/setColors/index.d.ts +1 -1
  54. package/dist-plugin/setColors/index.js +5 -5
  55. package/dist-plugin/setGeometry/index.cjs +107 -44
  56. package/dist-plugin/setGeometry/index.d.cts +5 -5
  57. package/dist-plugin/setGeometry/index.d.ts +5 -5
  58. package/dist-plugin/setGeometry/index.js +51 -45
  59. package/dist-plugin/setType/index.cjs +15 -0
  60. package/dist-plugin/setType/index.d.cts +1 -1
  61. package/dist-plugin/setType/index.d.ts +1 -1
  62. package/dist-plugin/setType/index.js +1 -1
  63. package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
  64. package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
  65. package/dist-plugin/tokensCssMigrations/index.js +1 -1
  66. package/package.json +35 -8
  67. package/src/app/site.css +19 -9
  68. package/src/editor/bootstrap.ts +2 -0
  69. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +4 -4
  70. package/src/editor/component-editor/DialogEditor.svelte +4 -4
  71. package/src/editor/component-editor/MenuSelectEditor.svelte +4 -1
  72. package/src/editor/component-editor/SegmentedControlEditor.svelte +6 -1
  73. package/src/editor/component-editor/TabBarEditor.svelte +1 -1
  74. package/src/editor/component-editor/TableEditor.svelte +2 -2
  75. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +6 -3
  76. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +41 -20
  77. package/src/editor/core/components/adjustAliases.ts +59 -45
  78. package/src/editor/core/components/aliasKinds.ts +9 -5
  79. package/src/editor/core/preview/themePreview.ts +9 -2
  80. package/src/editor/core/sketch/sketchLayer.ts +22 -0
  81. package/src/editor/core/store/editorStore.ts +10 -1
  82. package/src/editor/core/themes/buildColors.ts +3 -3
  83. package/src/editor/core/themes/liveStateStream.ts +26 -0
  84. package/src/editor/core/themes/migrations/2026-09-07-stroke-role-renames.ts +52 -0
  85. package/src/editor/core/themes/migrations/index.ts +2 -0
  86. package/src/editor/core/themes/themeDocumentSync.ts +22 -11
  87. package/src/editor/core/themes/themeService.ts +9 -2
  88. package/src/editor/pages/ComponentEditorPage.svelte +17 -1
  89. package/src/editor/pages/liveTokensEditorHandle.ts +23 -0
  90. package/src/editor/skill-atlas/SkillAtlas.svelte +75 -573
  91. package/src/editor/skill-atlas/TreeCanvas.svelte +263 -0
  92. package/src/editor/skill-atlas/TreeNodeCard.svelte +136 -53
  93. package/src/editor/skill-atlas/edges.ts +31 -0
  94. package/src/editor/skill-atlas/skillSources.generated.ts +20 -19
  95. package/src/editor/skill-atlas/skillTrees.ts +19 -3840
  96. package/src/editor/skill-atlas/trees/check-compliance.ts +183 -0
  97. package/src/editor/skill-atlas/trees/create-component.ts +275 -0
  98. package/src/editor/skill-atlas/trees/create-page.ts +320 -0
  99. package/src/editor/skill-atlas/trees/create-theme.ts +255 -0
  100. package/src/editor/skill-atlas/trees/fix-findings.ts +469 -0
  101. package/src/editor/skill-atlas/trees/pick-component.ts +300 -0
  102. package/src/editor/skill-atlas/trees/set-colors.ts +148 -0
  103. package/src/editor/skill-atlas/trees/set-geometry.ts +136 -0
  104. package/src/editor/skill-atlas/trees/set-type.ts +142 -0
  105. package/src/editor/skill-atlas/types.ts +3 -4
  106. package/src/editor/skill-atlas/wireLayout.ts +287 -0
  107. package/src/live-tokens/data/themes/autumn.json +15 -15
  108. package/src/live-tokens/data/themes/halloween.json +15 -15
  109. package/src/live-tokens/data/themes/midnight-study.json +15 -15
  110. package/src/live-tokens/data/themes/ocean.json +15 -15
  111. package/src/live-tokens/data/themes/royal-velvet.json +15 -15
  112. package/src/live-tokens/data/themes/sketchy.json +15 -15
  113. package/src/live-tokens/data/themes/spring-meadow.json +15 -15
  114. package/src/live-tokens/data/themes/sunset.json +15 -15
  115. package/src/system/components/Badge.svelte +7 -0
  116. package/src/system/components/Button.svelte +7 -0
  117. package/src/system/components/Callout.svelte +10 -6
  118. package/src/system/components/Card.svelte +23 -4
  119. package/src/system/components/CodeSnippet.svelte +4 -3
  120. package/src/system/components/CollapsibleSection.svelte +23 -8
  121. package/src/system/components/CornerBadge.svelte +6 -0
  122. package/src/system/components/Dialog.svelte +13 -6
  123. package/src/system/components/IconButton.svelte +9 -0
  124. package/src/system/components/Image.svelte +8 -0
  125. package/src/system/components/ImageLightbox.svelte +6 -0
  126. package/src/system/components/InlineEditActions.svelte +7 -0
  127. package/src/system/components/Input.svelte +7 -0
  128. package/src/system/components/MenuSelect.svelte +7 -0
  129. package/src/system/components/Notification.svelte +7 -0
  130. package/src/system/components/Panel.svelte +6 -0
  131. package/src/system/components/ProgressBar.svelte +5 -0
  132. package/src/system/components/RadioButton.svelte +11 -5
  133. package/src/system/components/SectionDivider.svelte +8 -0
  134. package/src/system/components/SegmentedControl.svelte +6 -0
  135. package/src/system/components/SideNavigation.svelte +6 -0
  136. package/src/system/components/Slider.svelte +7 -4
  137. package/src/system/components/TabBar.svelte +15 -9
  138. package/src/system/components/Table.svelte +8 -3
  139. package/src/system/components/Toggle.svelte +4 -4
  140. package/src/system/components/Tooltip.svelte +6 -0
  141. package/src/testing-js/chunk-AO7EZHYV.js +776 -0
  142. package/src/testing-js/chunk-AO7EZHYV.js.map +1 -0
  143. package/src/testing-js/chunk-FAFOAWYL.js +39 -0
  144. package/src/testing-js/chunk-FAFOAWYL.js.map +1 -0
  145. package/src/testing-js/chunk-L73N4NSO.js +23 -0
  146. package/src/testing-js/chunk-L73N4NSO.js.map +1 -0
  147. package/src/testing-js/chunk-LXR3MN6N.js +3063 -0
  148. package/src/testing-js/chunk-LXR3MN6N.js.map +1 -0
  149. package/src/testing-js/chunk-ZMSX6CXR.js +53 -0
  150. package/src/testing-js/chunk-ZMSX6CXR.js.map +1 -0
  151. package/src/testing-js/component-alias.contract.js +81 -0
  152. package/src/testing-js/component-alias.contract.js.map +1 -0
  153. package/src/testing-js/component-editor.contract.js +62 -0
  154. package/src/testing-js/component-editor.contract.js.map +1 -0
  155. package/src/testing-js/component-render.contract.js +568 -0
  156. package/src/testing-js/component-render.contract.js.map +1 -0
  157. package/src/testing-js/index.d.ts +293 -0
  158. package/src/testing-js/index.js +222 -0
  159. package/src/testing-js/index.js.map +1 -0
  160. package/src/testing-js/registry.contract.js +39 -0
  161. package/src/testing-js/registry.contract.js.map +1 -0
  162. package/src/testing-js/vitest-BE6uGF31.d.ts +73 -0
  163. package/src/testing-js/vitest.d.ts +3 -0
  164. package/src/testing-js/vitest.js +13 -0
  165. package/src/testing-js/vitest.js.map +1 -0
  166. package/template/README.md +13 -0
  167. package/template/_gitignore +6 -0
  168. package/template/package.json +3 -1
  169. package/template/src/pages/Home.svelte +4 -18
  170. package/.claude/skills/live-tokens-build-page/SKILL.md +0 -103
  171. package/.claude/skills/live-tokens-build-page/references/layout-sources.md +0 -48
@@ -1,3844 +1,23 @@
1
1
  import type { SkillTree } from './types';
2
+ import { createTheme } from './trees/create-theme';
3
+ import { setColors } from './trees/set-colors';
4
+ import { setType } from './trees/set-type';
5
+ import { setGeometry } from './trees/set-geometry';
6
+ import { pickComponent } from './trees/pick-component';
7
+ import { createPage } from './trees/create-page';
8
+ import { createComponent } from './trees/create-component';
9
+ import { checkCompliance } from './trees/check-compliance';
10
+ import { fixFindings } from './trees/fix-findings';
2
11
 
12
+ // Tab order: the theme route and its three set skills, the page path, then the audit pair.
3
13
  export const skillTrees: Record<string, SkillTree> = {
4
- "create-theme": {
5
- "id": "live-tokens-create-theme",
6
- "digest": "sha256:7a87f61fa686368c",
7
- "title": "create-theme",
8
- "tagline": "One reading of the request becomes three intents, routed to three skills and saved as one theme.",
9
- "nodes": [
10
- {
11
- "id": "ct-trig",
12
- "row": 0,
13
- "kind": "trigger",
14
- "title": "Define or refine a whole look",
15
- "desc": "A theme, look, vibe, or brand feel by mood, style, era, season, holiday, or hue. One dimension alone goes straight to set-colors, set-type, or set-geometry.",
16
- "lines": [
17
- 2,
18
- 19
19
- ],
20
- "anchor": "name: live-tokens-create-theme",
21
- "anchorEnd": "never edit the data tree directly."
22
- },
23
- {
24
- "id": "ct-direction",
25
- "row": 1,
26
- "kind": "step",
27
- "n": "1",
28
- "title": "State the design direction",
29
- "desc": "One or two lines fix the mood, the hue family, the scheme, and the type and geometry that mood implies, naming the default where the request leaves a dimension open.",
30
- "lines": [
31
- 23,
32
- 23
33
- ],
34
- "anchor": "Read the request once and state the design direction to the "
35
- },
36
- {
37
- "id": "ct-index",
38
- "row": 2,
39
- "kind": "ref",
40
- "title": "Name the anchor",
41
- "desc": "A feeling, an idiom, or an occasion. An idiom sets constraints and a feeling moves dials inside them, so a request matching both reads the idiom first.",
42
- "reference": "references/design-directions.md",
43
- "lines": [
44
- 24,
45
- 24
46
- ],
47
- "anchor": "Read `references/design-directions.md` and name the **anchor"
48
- },
49
- {
50
- "id": "ct-intents",
51
- "row": 3,
52
- "kind": "step",
53
- "n": "3",
54
- "title": "State the three intents",
55
- "desc": "The color, type, and geometry intents each name an outcome in a line. The anchor name travels with each one so the contributing skill can read its own column.",
56
- "lines": [
57
- 25,
58
- 25
59
- ],
60
- "anchor": "State the three intents the design direction and the anchor ",
61
- "chips": [
62
- {
63
- "label": "What each contributing skill owns",
64
- "lines": [
65
- 39,
66
- 43
67
- ],
68
- "anchor": "| Dimension | Contributing skill | It decides |",
69
- "anchorEnd": "| geometry | live-tokens-set-geometry | radius, padding, gap"
70
- }
71
- ]
72
- },
73
- {
74
- "id": "ct-colors",
75
- "row": 4,
76
- "kind": "hand",
77
- "title": "Hand the color intent to set-colors",
78
- "desc": "This hand-off never skips: a theme request names a color identity, so color is the one dimension every look fixes.",
79
- "lines": [
80
- 26,
81
- 26
82
- ],
83
- "anchor": "Invoke **live-tokens-set-colors** with the color intent. Thi"
84
- },
85
- {
86
- "id": "ct-type-q",
87
- "row": 5,
88
- "kind": "decide",
89
- "title": "Does the look need new type?",
90
- "desc": "Type is skipped only when the user asked to leave it alone.",
91
- "lines": [
92
- 27,
93
- 27
94
- ],
95
- "anchor": "Invoke **live-tokens-set-type** with the type intent. Skip o"
96
- },
97
- {
98
- "id": "ct-type",
99
- "row": 6,
100
- "kind": "hand",
101
- "title": "Hand the type intent to set-type",
102
- "desc": "The contributing skill chooses the families. This skill passes an outcome and never a family name.",
103
- "lines": [
104
- 27,
105
- 27
106
- ],
107
- "anchor": "Invoke **live-tokens-set-type** with the type intent. Skip o"
108
- },
109
- {
110
- "id": "ct-geo-q",
111
- "row": 7,
112
- "kind": "decide",
113
- "title": "Does the look need geometry changes?",
114
- "desc": "Geometry is skipped when the geometry intent is to leave it alone.",
115
- "lines": [
116
- 28,
117
- 28
118
- ],
119
- "anchor": "Invoke **live-tokens-set-geometry** with the geometry intent"
120
- },
121
- {
122
- "id": "ct-geo",
123
- "row": 8,
124
- "kind": "hand",
125
- "title": "Hand the geometry intent to set-geometry",
126
- "desc": "The contributing skill chooses the ops. This skill passes an outcome and never a radius or a token.",
127
- "lines": [
128
- 28,
129
- 28
130
- ],
131
- "anchor": "Invoke **live-tokens-set-geometry** with the geometry intent"
132
- },
133
- {
134
- "id": "ct-save",
135
- "row": 9,
136
- "kind": "cli",
137
- "n": "7",
138
- "title": "Save the theme",
139
- "desc": "One verb composes the three buffers into themes/<slug>.json and opens it, so nothing is left unsaved.",
140
- "lines": [
141
- 29,
142
- 29
143
- ],
144
- "anchor": "Take the theme name from the design direction and run `npx l",
145
- "command": "npx live-tokens save-theme \"<name>\"",
146
- "chips": [
147
- {
148
- "label": "A set of themes",
149
- "lines": [
150
- 32,
151
- 33
152
- ],
153
- "anchor": "A set of themes runs steps 4 to 7 once per theme, with `--no",
154
- "anchorEnd": "save but the last, so each theme starts from the same live l"
155
- }
156
- ]
157
- },
158
- {
159
- "id": "ct-assemble",
160
- "row": 10,
161
- "kind": "step",
162
- "n": "8",
163
- "title": "Assemble the three reports",
164
- "desc": "One summary carries the design direction, what each contributing skill changed, the theme that was written, and anything one of them flagged.",
165
- "lines": [
166
- 30,
167
- 30
168
- ],
169
- "anchor": "Assemble the three reports into the assembled report: the de"
170
- },
171
- {
172
- "id": "ct-ver",
173
- "row": 11,
174
- "kind": "step",
175
- "title": "Verify the whole look",
176
- "desc": "Each contributing skill reports back, save-theme names the theme it wrote, and the running app shows the look after a reload.",
177
- "lines": [
178
- 74,
179
- 80
180
- ],
181
- "anchor": "## Verify",
182
- "anchorEnd": "- To return to the previous look, load the earlier theme fro"
183
- },
184
- {
185
- "id": "ct-refine-q",
186
- "row": 12,
187
- "kind": "decide",
188
- "title": "Refine the look?",
189
- "desc": "One adjective usually names one dimension, and that dimension owns the refinement.",
190
- "lines": [
191
- 49,
192
- 52
193
- ],
194
- "anchor": "## Refining a look",
195
- "anchorEnd": "usually names one dimension. Route it rather than re-reading"
196
- },
197
- {
198
- "id": "ct-refine",
199
- "row": 13,
200
- "kind": "step",
201
- "title": "Route the refinement to one contributing skill",
202
- "desc": "Warmer and calmer go to set-colors, a type voice to set-type, rounder and tighter to set-geometry.",
203
- "lines": [
204
- 54,
205
- 58
206
- ],
207
- "anchor": "| The user says | Goes to |",
208
- "anchorEnd": "| rounder, sharper, pill buttons, tighter, airier, thicker b"
209
- },
210
- {
211
- "id": "ct-done",
212
- "row": 13,
213
- "kind": "done",
214
- "title": "Look complete",
215
- "desc": "save-theme wrote the theme and opened it, which cleared the three buffers. Adopt, in the editor, ships it.",
216
- "lines": [
217
- 66,
218
- 72
219
- ],
220
- "anchor": "Color, type, and geometry each write an unsaved buffer, whic",
221
- "anchorEnd": "new families."
222
- }
223
- ],
224
- "edges": [
225
- {
226
- "from": "ct-trig",
227
- "to": "ct-direction"
228
- },
229
- {
230
- "from": "ct-direction",
231
- "to": "ct-index"
232
- },
233
- {
234
- "from": "ct-index",
235
- "to": "ct-intents"
236
- },
237
- {
238
- "from": "ct-intents",
239
- "to": "ct-colors"
240
- },
241
- {
242
- "from": "ct-colors",
243
- "to": "ct-type-q"
244
- },
245
- {
246
- "from": "ct-type-q",
247
- "to": "ct-type",
248
- "label": "set type"
249
- },
250
- {
251
- "from": "ct-type-q",
252
- "to": "ct-geo-q",
253
- "label": "keep type"
254
- },
255
- {
256
- "from": "ct-type",
257
- "to": "ct-geo-q"
258
- },
259
- {
260
- "from": "ct-geo-q",
261
- "to": "ct-geo",
262
- "label": "set geometry"
263
- },
264
- {
265
- "from": "ct-geo-q",
266
- "to": "ct-save",
267
- "label": "keep geometry"
268
- },
269
- {
270
- "from": "ct-geo",
271
- "to": "ct-save"
272
- },
273
- {
274
- "from": "ct-save",
275
- "to": "ct-assemble"
276
- },
277
- {
278
- "from": "ct-assemble",
279
- "to": "ct-ver"
280
- },
281
- {
282
- "from": "ct-ver",
283
- "to": "ct-refine-q"
284
- },
285
- {
286
- "from": "ct-refine-q",
287
- "to": "ct-refine",
288
- "label": "one dimension"
289
- },
290
- {
291
- "from": "ct-refine-q",
292
- "to": "ct-direction",
293
- "label": "spans dimensions",
294
- "back": true
295
- },
296
- {
297
- "from": "ct-refine-q",
298
- "to": "ct-done",
299
- "label": "done"
300
- },
301
- {
302
- "from": "ct-refine",
303
- "to": "ct-done"
304
- }
305
- ]
306
- },
307
- "set-colors": {
308
- "id": "live-tokens-set-colors",
309
- "digest": "sha256:ed316c987e1cb5c4",
310
- "title": "set-colors",
311
- "tagline": "Ten base colors become every ramp, gated on AA contrast, written into the live look.",
312
- "nodes": [
313
- {
314
- "id": "sc-trig",
315
- "row": 0,
316
- "kind": "trigger",
317
- "title": "Set or refine a palette",
318
- "desc": "A palette, colors, or hues by mood, style, or hue, and every color refinement. create-theme supplies the color intent for a whole look.",
319
- "lines": [
320
- 2,
321
- 15
322
- ],
323
- "anchor": "name: live-tokens-set-colors",
324
- "anchorEnd": "theme in the editor, or running `save-theme`, turns the live"
325
- },
326
- {
327
- "id": "sc-anchor",
328
- "row": 1,
329
- "kind": "ref",
330
- "title": "Read the color anchor",
331
- "desc": "An anchor the color intent names overrides the generic bands. Say which anchor you took.",
332
- "reference": "references/color-anchors.md",
333
- "lines": [
334
- 19,
335
- 19
336
- ],
337
- "anchor": "Read the color intent. When it names an anchor (a feeling, a"
338
- },
339
- {
340
- "id": "sc-base-colors",
341
- "row": 2,
342
- "kind": "step",
343
- "n": "2",
344
- "title": "Define ten OKLCH base colors",
345
- "desc": "Brand, Accent, Special, Canvas, Neutral, Alternate, and four statuses go to scratch/<slug>-base-colors.json, which is the only copy.",
346
- "lines": [
347
- 20,
348
- 20
349
- ],
350
- "anchor": "Translate the intent into ten base colors using the framewor"
351
- },
352
- {
353
- "id": "sc-cons",
354
- "row": 3,
355
- "kind": "chipset",
356
- "title": "Apply all palette constraints",
357
- "lines": [
358
- 27,
359
- 120
360
- ],
361
- "anchor": "## The base color file",
362
- "anchorEnd": "Shadow opacity derives from Canvas lightness and re-derives ",
363
- "chips": [
364
- {
365
- "label": "Base color file schema",
366
- "lines": [
367
- 27,
368
- 49
369
- ],
370
- "anchor": "## The base color file",
371
- "anchorEnd": "Roles: **Brand** is the dominant chromatic identity; **Accen"
372
- },
373
- {
374
- "label": "Chroma budget",
375
- "lines": [
376
- 51,
377
- 61
378
- ],
379
- "anchor": "## Chroma budget: color is inversely proportional to area",
380
- "anchorEnd": "A good theme reads as 3 or 4 hue families on screen, never 1"
381
- },
382
- {
383
- "label": "Role bands",
384
- "lines": [
385
- 63,
386
- 75
387
- ],
388
- "anchor": "## Per-role bands",
389
- "anchorEnd": "| Danger | shared status L, C 0.15 to 0.20 | same | H 20 to "
390
- },
391
- {
392
- "label": "Canvas commitment",
393
- "lines": [
394
- 77,
395
- 81
396
- ],
397
- "anchor": "**The canvas carries the theme's identity, so commit to it.*",
398
- "anchorEnd": "*Full-color ground* (holiday and statement intents): the can"
399
- },
400
- {
401
- "label": "Dark scheme and status lightness",
402
- "lines": [
403
- 83,
404
- 89
405
- ],
406
- "anchor": "Also:",
407
- "anchorEnd": "- Status hues never rotate with the harmony; only their L an"
408
- },
409
- {
410
- "label": "Mood dials",
411
- "lines": [
412
- 91,
413
- 97
414
- ],
415
- "anchor": "## Mood dials",
416
- "anchorEnd": "Avoid mid-lightness yellow-green (H 100 to 120 at L 0.5 to 0"
417
- },
418
- {
419
- "label": "Gamut guardrails",
420
- "lines": [
421
- 99,
422
- 106
423
- ],
424
- "anchor": "## Gamut guardrails",
425
- "anchorEnd": "- Peak chroma anchors: red H20 C 0.25 at L 0.63; orange H60 "
426
- },
427
- {
428
- "label": "Hue harmony",
429
- "lines": [
430
- 108,
431
- 114
432
- ],
433
- "anchor": "## Harmony",
434
- "anchorEnd": "- Drama or maximum contrast: complementary, triadic, or tetr"
435
- },
436
- {
437
- "label": "Canvas gradient and shadows",
438
- "lines": [
439
- 116,
440
- 120
441
- ],
442
- "anchor": "## Canvas sky and shadows",
443
- "anchorEnd": "Shadow opacity derives from Canvas lightness and re-derives "
444
- }
445
- ]
446
- },
447
- {
448
- "id": "sc-cli",
449
- "row": 4,
450
- "kind": "cli",
451
- "n": "3",
452
- "title": "Write the color buffer",
453
- "desc": "The CLI builds every ramp, enforces AA contrast on the derived text tokens, writes the result into the unsaved buffer the page already runs, and prints a contrast report.",
454
- "lines": [
455
- 21,
456
- 21
457
- ],
458
- "anchor": "Run `npx live-tokens set-colors scratch/<slug>-base-colors.j",
459
- "command": "npx live-tokens set-colors scratch/<slug>-base-colors.json",
460
- "chips": [
461
- {
462
- "label": "Flags",
463
- "lines": [
464
- 25,
465
- 25
466
- ],
467
- "anchor": "Flags: `--dry-run` prints the contrast report without writin"
468
- }
469
- ]
470
- },
471
- {
472
- "id": "sc-fail",
473
- "row": 5,
474
- "kind": "gate",
475
- "title": "A base color fails validation",
476
- "desc": "Each failure line names the base color to change, usually by raising its lightness or cutting its chroma.",
477
- "lines": [
478
- 22,
479
- 22
480
- ],
481
- "anchor": "Read the report. Exit 0 passes, and auto-corrected values co"
482
- },
483
- {
484
- "id": "sc-pass",
485
- "row": 5,
486
- "kind": "ok",
487
- "title": "Colors pass validation",
488
- "desc": "Auto-corrected values count as passing.",
489
- "lines": [
490
- 22,
491
- 22
492
- ],
493
- "anchor": "Read the report. Exit 0 passes, and auto-corrected values co"
494
- },
495
- {
496
- "id": "sc-report",
497
- "row": 6,
498
- "kind": "step",
499
- "n": "5",
500
- "title": "Report back",
501
- "desc": "The line back to create-theme names the scheme, the hue families on screen, the canvas commitment level, and anything auto-corrected.",
502
- "lines": [
503
- 23,
504
- 23
505
- ],
506
- "anchor": "Report back in a line: the scheme, the hue families on scree"
507
- },
508
- {
509
- "id": "sc-refine-q",
510
- "row": 7,
511
- "kind": "decide",
512
- "title": "Refine the color?",
513
- "desc": "Warmer, calmer, or more contrast arrives against a theme that is already open, and the answer is a new base color file.",
514
- "lines": [
515
- 122,
516
- 124
517
- ],
518
- "anchor": "## Refining the color of a theme that exists",
519
- "anchorEnd": "\"Warmer\", \"calmer\", \"more contrast\" arrive against a theme t"
520
- },
521
- {
522
- "id": "sc-refine",
523
- "row": 8,
524
- "kind": "step",
525
- "title": "Move one dial and re-run",
526
- "desc": "One adjective moves one dial. A re-run replaces the buffer's whole color state, so every base color the user did not name stays where it was.",
527
- "lines": [
528
- 126,
529
- 126
530
- ],
531
- "anchor": "One adjective moves one dial. Warmer and cooler rotate hue; "
532
- },
533
- {
534
- "id": "sc-done",
535
- "row": 8,
536
- "kind": "done",
537
- "title": "Color set",
538
- "desc": "The buffer holds the new color state, and type and geometry carried forward. A Save or a save-theme run keeps it, Adopt ships it.",
539
- "lines": [
540
- 128,
541
- 133
542
- ],
543
- "anchor": "## Scope",
544
- "anchorEnd": "ships it."
545
- }
546
- ],
547
- "edges": [
548
- {
549
- "from": "sc-trig",
550
- "to": "sc-anchor"
551
- },
552
- {
553
- "from": "sc-anchor",
554
- "to": "sc-base-colors"
555
- },
556
- {
557
- "from": "sc-base-colors",
558
- "to": "sc-cons"
559
- },
560
- {
561
- "from": "sc-cons",
562
- "to": "sc-cli"
563
- },
564
- {
565
- "from": "sc-cli",
566
- "to": "sc-fail",
567
- "label": "exit 1"
568
- },
569
- {
570
- "from": "sc-cli",
571
- "to": "sc-pass",
572
- "label": "exit 0"
573
- },
574
- {
575
- "from": "sc-fail",
576
- "to": "sc-cli",
577
- "label": "rerun",
578
- "back": true
579
- },
580
- {
581
- "from": "sc-pass",
582
- "to": "sc-report"
583
- },
584
- {
585
- "from": "sc-report",
586
- "to": "sc-refine-q"
587
- },
588
- {
589
- "from": "sc-refine-q",
590
- "to": "sc-refine",
591
- "label": "refine"
592
- },
593
- {
594
- "from": "sc-refine",
595
- "to": "sc-cli",
596
- "label": "regenerate",
597
- "back": true
598
- },
599
- {
600
- "from": "sc-refine-q",
601
- "to": "sc-done",
602
- "label": "done"
603
- }
604
- ]
605
- },
606
- "set-type": {
607
- "id": "live-tokens-set-type",
608
- "digest": "sha256:9a82b5b14ddebdc0",
609
- "title": "set-type",
610
- "tagline": "Choose the families; the CLI verifies them and builds URLs for their available weights.",
611
- "nodes": [
612
- {
613
- "id": "st-trig",
614
- "row": 0,
615
- "kind": "trigger",
616
- "title": "Choose or pair font families",
617
- "desc": "The pairing selects or restyles font families. create-theme supplies the type intent for complete themes.",
618
- "lines": [
619
- 2,
620
- 6
621
- ],
622
- "anchor": "name: live-tokens-set-type",
623
- "anchorEnd": "# Setting a theme's fonts"
624
- },
625
- {
626
- "id": "st-anchor",
627
- "row": 1,
628
- "kind": "ref",
629
- "title": "Read the type anchor",
630
- "desc": "An anchor the type intent names overrides the voice table. Occasions fix color only, so their type comes from the feeling they imply.",
631
- "reference": "references/type-anchors.md",
632
- "lines": [
633
- 12,
634
- 12
635
- ],
636
- "anchor": "Read the type intent. When it names an anchor (a feeling, an"
637
- },
638
- {
639
- "id": "st-pool",
640
- "row": 2,
641
- "kind": "step",
642
- "title": "Use Google Fonts with the CLI",
643
- "desc": "The CLI manages Google Fonts. The editor's Project fonts section handles other sources.",
644
- "lines": [
645
- 8,
646
- 8
647
- ],
648
- "anchor": "You choose the families; the CLI verifies each against Googl"
649
- },
650
- {
651
- "id": "st-body",
652
- "row": 3,
653
- "kind": "step",
654
- "title": "Choose the body face first",
655
- "desc": "Body faces need regular, bold, italic, open apertures, a large x-height, and low or moderate contrast. Families that miss a requirement belong in display.",
656
- "lines": [
657
- 30,
658
- 32
659
- ],
660
- "anchor": "## Choose the body face first",
661
- "anchorEnd": "The body face is the anchor. It carries most of the words, a"
662
- },
663
- {
664
- "id": "st-spec",
665
- "row": 4,
666
- "kind": "decide",
667
- "title": "Does the type intent name a specific voice?",
668
- "desc": "A specific voice follows the full matrix. A vague or quiet type intent takes a conservative pairing.",
669
- "lines": [
670
- 68,
671
- 70
672
- ],
673
- "anchor": "## Shortcuts",
674
- "anchorEnd": "These find an adequate pairing fast and skip the reasoning; "
675
- },
676
- {
677
- "id": "st-matrix",
678
- "row": 5,
679
- "kind": "step",
680
- "title": "Classify each face by form and finish",
681
- "desc": "Form describes its model: dynamic, rational, or geometric. Finish describes stroke contrast and serif treatment.",
682
- "lines": [
683
- 36,
684
- 44
685
- ],
686
- "anchor": "## The font matrix: the decision rule",
687
- "anchorEnd": "| **Geometric** | monolinear, circle-and-line | technical, m"
688
- },
689
- {
690
- "id": "st-short",
691
- "row": 5,
692
- "kind": "step",
693
- "title": "Choose a conservative pairing",
694
- "desc": "Conservative options include a superfamily, one family across weights, two families by one designer, or a serif display face with a sans body.",
695
- "lines": [
696
- 68,
697
- 75
698
- ],
699
- "anchor": "## Shortcuts",
700
- "anchorEnd": "- **Serif display over sans body** when nothing else decides"
701
- },
702
- {
703
- "id": "st-rule",
704
- "row": 6,
705
- "kind": "chipset",
706
- "title": "Compare form and finish",
707
- "chips": [
708
- {
709
- "label": "Same form, different finish: reliable",
710
- "lines": [
711
- 46,
712
- 46
713
- ],
714
- "anchor": "- **Same skeleton, different flesh: reliable.** Helvetica an"
715
- },
716
- {
717
- "label": "Same finish, different form: clashes",
718
- "lines": [
719
- 47,
720
- 47
721
- ],
722
- "anchor": "- **Same flesh, different skeleton: the failure case.** The "
723
- },
724
- {
725
- "label": "Different on both: deliberate contrast",
726
- "lines": [
727
- 48,
728
- 48
729
- ],
730
- "anchor": "- **Far apart on both: works, deliberately.** An unmistakabl"
731
- },
732
- {
733
- "label": "Faces between models",
734
- "lines": [
735
- 50,
736
- 50
737
- ],
738
- "anchor": "Many faces sit between columns. When one straddles, say so a"
739
- }
740
- ],
741
- "tag": "pairing rule"
742
- },
743
- {
744
- "id": "st-voice",
745
- "row": 7,
746
- "kind": "step",
747
- "title": "Match the pairing to the design direction",
748
- "desc": "The pairing matches type and color to the same design direction. Conflicting voices make them feel unrelated.",
749
- "lines": [
750
- 52,
751
- 66
752
- ],
753
- "anchor": "## Voice",
754
- "anchorEnd": "Match the type to the same design direction the color came f"
755
- },
756
- {
757
- "id": "st-watch",
758
- "row": 8,
759
- "kind": "chipset",
760
- "title": "Check four pairing risks",
761
- "chips": [
762
- {
763
- "label": "x-height parity",
764
- "lines": [
765
- 79,
766
- 79
767
- ],
768
- "anchor": "- **x-height parity.** Both faces are set from one size scal"
769
- },
770
- {
771
- "label": "Small-size legibility",
772
- "lines": [
773
- 80,
774
- 80
775
- ],
776
- "anchor": "- **Print faces at small sizes.** Delicate serifs and high s"
777
- },
778
- {
779
- "label": "More than two families",
780
- "lines": [
781
- 81,
782
- 81
783
- ],
784
- "anchor": "- **Every family is a download.** Two is the target; three n"
785
- },
786
- {
787
- "label": "Repeated families across theme sets",
788
- "lines": [
789
- 82,
790
- 82
791
- ],
792
- "anchor": "- **Sets of themes:** no two share a display face or a body "
793
- }
794
- ],
795
- "lines": [
796
- 77,
797
- 77
798
- ],
799
- "anchor": "## Watch for",
800
- "tag": "risks"
801
- },
802
- {
803
- "id": "st-pairing",
804
- "row": 9,
805
- "kind": "step",
806
- "n": "1",
807
- "title": "Write scratch/font-pairing.json",
808
- "desc": "The pairing file changes listed slots and preserves the rest. Display maps to --font-display; body maps to --font-sans. Serif, mono, and editorial serve specialized roles.",
809
- "lines": [
810
- 12,
811
- 12
812
- ],
813
- "anchor": "Read the type intent. When it names an anchor (a feeling, an"
814
- },
815
- {
816
- "id": "st-shape",
817
- "row": 10,
818
- "kind": "chipset",
819
- "title": "Check pairing file fields and flags",
820
- "chips": [
821
- {
822
- "label": "Slots and stacks",
823
- "lines": [
824
- 22,
825
- 28
826
- ],
827
- "anchor": "## The pairing file",
828
- "anchorEnd": "Every slot is optional and an omitted slot is left exactly a"
829
- },
830
- {
831
- "label": "Pairing rationale",
832
- "lines": [
833
- 18,
834
- 18
835
- ],
836
- "anchor": "State your reasoning when you propose the pairing: each face"
837
- },
838
- {
839
- "label": "Flags",
840
- "lines": [
841
- 20,
842
- 20
843
- ],
844
- "anchor": "Flags: `--dry-run` reports without writing. `--no-verify` sk"
845
- }
846
- ],
847
- "tag": "pairing file"
848
- },
849
- {
850
- "id": "st-cli",
851
- "row": 11,
852
- "kind": "cli",
853
- "n": "2",
854
- "title": "Validate and apply the font stacks",
855
- "desc": "The report lists changed stacks, each family's weights and URL, and every required-weight gap.",
856
- "lines": [
857
- 13,
858
- 13
859
- ],
860
- "anchor": "Run `npx live-tokens set-type scratch/font-pairing.json`. I",
861
- "command": "npx live-tokens set-type scratch/font-pairing.json"
862
- },
863
- {
864
- "id": "st-fail",
865
- "row": 12,
866
- "kind": "gate",
867
- "title": "Google Fonts lacks a family",
868
- "desc": "The next run uses a valid Google Fonts family name.",
869
- "lines": [
870
- 14,
871
- 14
872
- ],
873
- "anchor": "Read the report. A weight gap is a quality note: name it and"
874
- },
875
- {
876
- "id": "st-gap",
877
- "row": 12,
878
- "kind": "ok",
879
- "n": "3",
880
- "title": "The CLI applies the font stacks",
881
- "desc": "Meaningful gaps include body 400, 700, or italic and display 600. Display 300 remains optional.",
882
- "lines": [
883
- 14,
884
- 14
885
- ],
886
- "anchor": "Read the report. A weight gap is a quality note: name it and"
887
- },
888
- {
889
- "id": "st-report",
890
- "row": 13,
891
- "kind": "step",
892
- "n": "4",
893
- "title": "Report back",
894
- "desc": "The line back to create-theme names both families, the form model behind each, and any weight gap worth naming.",
895
- "lines": [
896
- 15,
897
- 15
898
- ],
899
- "anchor": "Report back in a line: the two families, the form model behi"
900
- },
901
- {
902
- "id": "st-tell",
903
- "row": 14,
904
- "kind": "step",
905
- "n": "5",
906
- "title": "Reload and review the type",
907
- "desc": "Reloading before Save gives the editor the new buffer. Save then keeps the change.",
908
- "lines": [
909
- 16,
910
- 16
911
- ],
912
- "anchor": "Tell the user to reload the editor page before saving. A run"
913
- },
914
- {
915
- "id": "st-scope",
916
- "row": 15,
917
- "kind": "chipset",
918
- "title": "Font-family scope",
919
- "desc": "Font-family changes preserve color, component aliases, geometry, and the type scale.",
920
- "chips": [
921
- {
922
- "label": "Buffer, Save, and Adopt",
923
- "lines": [
924
- 84,
925
- 86
926
- ],
927
- "anchor": "## Scope",
928
- "anchorEnd": "Type only. Color, component aliases, shape, and the type sca"
929
- }
930
- ],
931
- "tag": "scope"
932
- },
933
- {
934
- "id": "st-ver",
935
- "row": 16,
936
- "kind": "done",
937
- "title": "Verify the type",
938
- "desc": "The report lists stacks and weights; the CLI builds matching URLs. Reloading shows the new type. Reselecting the open theme restores the previous type.",
939
- "lines": [
940
- 88,
941
- 93
942
- ],
943
- "anchor": "## Verify",
944
- "anchorEnd": "- To revert, run the inverse pairing file, or load the open "
945
- }
946
- ],
947
- "edges": [
948
- {
949
- "from": "st-trig",
950
- "to": "st-anchor"
951
- },
952
- {
953
- "from": "st-anchor",
954
- "to": "st-pool"
955
- },
956
- {
957
- "from": "st-pool",
958
- "to": "st-body"
959
- },
960
- {
961
- "from": "st-body",
962
- "to": "st-spec"
963
- },
964
- {
965
- "from": "st-spec",
966
- "to": "st-matrix",
967
- "label": "specific"
968
- },
969
- {
970
- "from": "st-spec",
971
- "to": "st-short",
972
- "label": "vague or quiet"
973
- },
974
- {
975
- "from": "st-matrix",
976
- "to": "st-rule"
977
- },
978
- {
979
- "from": "st-rule",
980
- "to": "st-voice"
981
- },
982
- {
983
- "from": "st-short",
984
- "to": "st-voice"
985
- },
986
- {
987
- "from": "st-voice",
988
- "to": "st-watch"
989
- },
990
- {
991
- "from": "st-watch",
992
- "to": "st-pairing"
993
- },
994
- {
995
- "from": "st-pairing",
996
- "to": "st-shape"
997
- },
998
- {
999
- "from": "st-shape",
1000
- "to": "st-cli"
1001
- },
1002
- {
1003
- "from": "st-cli",
1004
- "to": "st-fail",
1005
- "label": "exit 1"
1006
- },
1007
- {
1008
- "from": "st-cli",
1009
- "to": "st-gap",
1010
- "label": "exit 0"
1011
- },
1012
- {
1013
- "from": "st-fail",
1014
- "to": "st-cli",
1015
- "label": "rerun",
1016
- "back": true
1017
- },
1018
- {
1019
- "from": "st-gap",
1020
- "to": "st-report"
1021
- },
1022
- {
1023
- "from": "st-report",
1024
- "to": "st-tell"
1025
- },
1026
- {
1027
- "from": "st-tell",
1028
- "to": "st-scope"
1029
- },
1030
- {
1031
- "from": "st-scope",
1032
- "to": "st-ver"
1033
- }
1034
- ]
1035
- },
1036
- "set-geometry": {
1037
- "id": "live-tokens-set-geometry",
1038
- "digest": "sha256:c5b43383a2da10d2",
1039
- "title": "set-geometry",
1040
- "tagline": "The CLI reads a small ops file, moves each alias along its token scale, and reports the result.",
1041
- "nodes": [
1042
- {
1043
- "id": "sg-trig",
1044
- "row": 0,
1045
- "kind": "trigger",
1046
- "title": "Adjust shape or spacing",
1047
- "desc": "Geometry changes cover radius, padding, gaps, border width, and density. create-theme supplies the geometry intent for complete themes.",
1048
- "lines": [
1049
- 2,
1050
- 8
1051
- ],
1052
- "anchor": "name: live-tokens-set-geometry",
1053
- "anchorEnd": "You translate the request into a small ops file; the CLI res"
1054
- },
1055
- {
1056
- "id": "sg-anchor",
1057
- "row": 1,
1058
- "kind": "ref",
1059
- "title": "Read the geometry anchor",
1060
- "desc": "An anchor the geometry intent names overrides the idiom table. Occasions fix color only, so their geometry comes from the feeling they imply.",
1061
- "reference": "references/geometry-anchors.md",
1062
- "lines": [
1063
- 12,
1064
- 12
1065
- ],
1066
- "anchor": "Read the geometry intent. When it names an anchor (a feeling"
1067
- },
1068
- {
1069
- "id": "sg-live",
1070
- "row": 2,
1071
- "kind": "step",
1072
- "title": "Read the live configuration",
1073
- "desc": "Each run reads the buffer or falls back to the open theme and shipped default. Relative shifts compound across runs.",
1074
- "lines": [
1075
- 18,
1076
- 18
1077
- ],
1078
- "anchor": "Each run reads the LIVE config (buffer, else the open theme,"
1079
- },
1080
- {
1081
- "id": "sg-target",
1082
- "row": 3,
1083
- "kind": "step",
1084
- "title": "Choose a global or component target",
1085
- "desc": "An absent target applies globally. Component IDs map windows and modals to dialog, cards to card, and tabs to tabbar. Unknown IDs fail.",
1086
- "lines": [
1087
- 35,
1088
- 35
1089
- ],
1090
- "anchor": "- `target` (optional): a component id (the folder names unde"
1091
- },
1092
- {
1093
- "id": "sg-kind",
1094
- "row": 4,
1095
- "kind": "chipset",
1096
- "title": "Choose the geometry property",
1097
- "chips": [
1098
- {
1099
- "label": "radius",
1100
- "lines": [
1101
- 36,
1102
- 36
1103
- ],
1104
- "anchor": "- `kind`: `radius | padding | gap | border-width`."
1105
- },
1106
- {
1107
- "label": "padding",
1108
- "lines": [
1109
- 36,
1110
- 36
1111
- ],
1112
- "anchor": "- `kind`: `radius | padding | gap | border-width`."
1113
- },
1114
- {
1115
- "label": "gap",
1116
- "lines": [
1117
- 36,
1118
- 36
1119
- ],
1120
- "anchor": "- `kind`: `radius | padding | gap | border-width`."
1121
- },
1122
- {
1123
- "label": "border-width",
1124
- "lines": [
1125
- 36,
1126
- 36
1127
- ],
1128
- "anchor": "- `kind`: `radius | padding | gap | border-width`."
1129
- }
1130
- ],
1131
- "tag": "property"
1132
- },
1133
- {
1134
- "id": "sg-op",
1135
- "row": 5,
1136
- "kind": "decide",
1137
- "title": "Set or shift?",
1138
- "desc": "Set selects a token on the property's scale. Shift moves a whole number of steps and clamps at either end.",
1139
- "lines": [
1140
- 37,
1141
- 37
1142
- ],
1143
- "anchor": "- `set` or `shift`, exactly one of the two. `set` takes an e"
1144
- },
1145
- {
1146
- "id": "sg-shift",
1147
- "row": 6,
1148
- "kind": "step",
1149
- "title": "Shift by steps",
1150
- "desc": "'Slightly' and 'a bit' each move 1 step; an unqualified request moves 1–2; 'much,' 'way,' and 'really' move 2–3. 'Softer' increases radius and spacing.",
1151
- "lines": [
1152
- 58,
1153
- 58
1154
- ],
1155
- "anchor": "Magnitude words: \"slightly\" or \"a bit\" is 1 step, unqualifie"
1156
- },
1157
- {
1158
- "id": "sg-set",
1159
- "row": 6,
1160
- "kind": "step",
1161
- "title": "Set an exact token",
1162
- "desc": "Set selects a token from the property's scale. A pill operation sets --radius-full. The full flag belongs to radius shifts.",
1163
- "lines": [
1164
- 38,
1165
- 38
1166
- ],
1167
- "anchor": "- `full` (radius shifts only): admits `--radius-full` as the"
1168
- },
1169
- {
1170
- "id": "sg-idiom",
1171
- "row": 7,
1172
- "kind": "step",
1173
- "title": "Map common phrases to operations",
1174
- "desc": "The table translates pill, corner, density, and border requests into exact operations.",
1175
- "lines": [
1176
- 40,
1177
- 54
1178
- ],
1179
- "anchor": "## Idioms",
1180
- "anchorEnd": "| thicker, thinner borders | border-width `shift: 1` or `-1`"
1181
- },
1182
- {
1183
- "id": "sg-squeeze",
1184
- "row": 8,
1185
- "kind": "step",
1186
- "title": "Protect controls during compaction",
1187
- "desc": "Global compaction stops at shift: -1 because larger shifts crush controls. Further compaction targets named containers. Global expansion remains safe.",
1188
- "lines": [
1189
- 60,
1190
- 64
1191
- ],
1192
- "anchor": "## Controls squeeze before containers",
1193
- "anchorEnd": "So a global compaction is `shift: -1`. When the request wants "
1194
- },
1195
- {
1196
- "id": "sg-pill",
1197
- "row": 9,
1198
- "kind": "decide",
1199
- "title": "Does the request create a pill?",
1200
- "desc": "--radius-full curves into the end glyphs. Large-text pills need at least --space-8 horizontal padding.",
1201
- "lines": [
1202
- 66,
1203
- 66
1204
- ],
1205
- "anchor": "A pill needs the room most. `--radius-full` bends the corner"
1206
- },
1207
- {
1208
- "id": "sg-pillop",
1209
- "row": 10,
1210
- "kind": "step",
1211
- "title": "Set pill radius and padding together",
1212
- "desc": "The radius and padding operations share a target. The padding set follows global compaction so it wins.",
1213
- "lines": [
1214
- 68,
1215
- 68
1216
- ],
1217
- "anchor": "```json",
1218
- "anchorEnd": "```"
1219
- },
1220
- {
1221
- "id": "sg-ladder",
1222
- "row": 11,
1223
- "kind": "chipset",
1224
- "title": "Respect token scales and padding floors",
1225
- "chips": [
1226
- {
1227
- "label": "Radius, space, and border-width scales",
1228
- "lines": [
1229
- 78,
1230
- 78
1231
- ],
1232
- "anchor": "Radius runs `none, sm, md, lg, xl, 2xl, 3xl, 4xl`, with `ful"
1233
- },
1234
- {
1235
- "label": "Content padding floor: --space-4",
1236
- "lines": [
1237
- 80,
1238
- 80
1239
- ],
1240
- "anchor": "Content insets stop at `--space-4`. Below it the text sits a"
1241
- },
1242
- {
1243
- "label": "Text-control padding floor: --space-6",
1244
- "lines": [
1245
- 82,
1246
- 82
1247
- ],
1248
- "anchor": "Padding that wraps a line of type stops a rung higher, at `-"
1249
- },
1250
- {
1251
- "label": "Margin shifts use the full scale",
1252
- "lines": [
1253
- 84,
1254
- 84
1255
- ],
1256
- "anchor": "The floor guards `-padding` only. Outer space is exempt, bec"
1257
- },
1258
- {
1259
- "label": "Off-subset aliases first reach a listed rung",
1260
- "lines": [
1261
- 86,
1262
- 86
1263
- ],
1264
- "anchor": "An alias sitting off the subset spends its first step reachi"
1265
- }
1266
- ],
1267
- "lines": [
1268
- 76,
1269
- 76
1270
- ],
1271
- "anchor": "## Ladders",
1272
- "tag": "ladders and floors"
1273
- },
1274
- {
1275
- "id": "sg-write",
1276
- "row": 12,
1277
- "kind": "step",
1278
- "n": "1",
1279
- "title": "Write scratch/geometry-ops.json",
1280
- "lines": [
1281
- 12,
1282
- 12
1283
- ],
1284
- "anchor": "Read the geometry intent. When it names an anchor (a feeling"
1285
- },
1286
- {
1287
- "id": "sg-shapes",
1288
- "row": 13,
1289
- "kind": "chipset",
1290
- "title": "Check operation forms",
1291
- "chips": [
1292
- {
1293
- "label": "Global, relative",
1294
- "lines": [
1295
- 22,
1296
- 24
1297
- ],
1298
- "anchor": "Global, relative:",
1299
- "anchorEnd": "```"
1300
- },
1301
- {
1302
- "label": "Targeted, absolute",
1303
- "lines": [
1304
- 28,
1305
- 30
1306
- ],
1307
- "anchor": "Targeted, absolute:",
1308
- "anchorEnd": "```"
1309
- },
1310
- {
1311
- "label": "The CLI ignores name",
1312
- "lines": [
1313
- 34,
1314
- 34
1315
- ],
1316
- "anchor": "- `name`: ignored. Buffers are fixed slots, so a name names "
1317
- }
1318
- ],
1319
- "lines": [
1320
- 20,
1321
- 20
1322
- ],
1323
- "anchor": "## The ops file",
1324
- "tag": "ops file"
1325
- },
1326
- {
1327
- "id": "sg-cli",
1328
- "row": 14,
1329
- "kind": "cli",
1330
- "n": "2",
1331
- "title": "Apply the geometry operations",
1332
- "desc": "The CLI writes each changed component to component-configs/<id>/_working.json, the page's active buffer. --dry-run limits the operation to reporting.",
1333
- "lines": [
1334
- 13,
1335
- 13
1336
- ],
1337
- "anchor": "Run `npx live-tokens set-geometry scratch/geometry-ops.json",
1338
- "command": "npx live-tokens set-geometry scratch/geometry-ops.json"
1339
- },
1340
- {
1341
- "id": "sg-fail",
1342
- "row": 15,
1343
- "kind": "gate",
1344
- "title": "The CLI rejects an operation",
1345
- "desc": "The report names the invalid operation or missing input. The repair resolves that issue before the next run.",
1346
- "lines": [
1347
- 14,
1348
- 14
1349
- ],
1350
- "anchor": "Read the report card: every changed alias old → new, plus sk"
1351
- },
1352
- {
1353
- "id": "sg-card",
1354
- "row": 15,
1355
- "kind": "ok",
1356
- "n": "3",
1357
- "title": "The buffers hold the new geometry",
1358
- "desc": "The report lists every outcome. --space-6 is the padding floor for buttons, badges, inputs, and tabs. Pills at that floor need a targeted lift.",
1359
- "lines": [
1360
- 14,
1361
- 14
1362
- ],
1363
- "anchor": "Read the report card: every changed alias old → new, plus sk"
1364
- },
1365
- {
1366
- "id": "sg-report",
1367
- "row": 16,
1368
- "kind": "step",
1369
- "n": "4",
1370
- "title": "Report back",
1371
- "desc": "The line back to create-theme names every alias that moved and any skip or clamp worth naming.",
1372
- "lines": [
1373
- 15,
1374
- 15
1375
- ],
1376
- "anchor": "Report back in a line: every alias that moved, and any skip "
1377
- },
1378
- {
1379
- "id": "sg-tell",
1380
- "row": 17,
1381
- "kind": "step",
1382
- "n": "5",
1383
- "title": "Reload and review the geometry",
1384
- "desc": "Reloading before Save gives the editor the current buffer. Save keeps the change, and inverse operations undo it.",
1385
- "lines": [
1386
- 16,
1387
- 16
1388
- ],
1389
- "anchor": "Tell the user to reload the page before saving. The editor k"
1390
- },
1391
- {
1392
- "id": "sg-scope",
1393
- "row": 18,
1394
- "kind": "chipset",
1395
- "title": "Geometry scope",
1396
- "desc": "Geometry operations remap component aliases to existing tokens and preserve colors, fonts, tokens.css, and saved themes.",
1397
- "chips": [
1398
- {
1399
- "label": "Buffers, Save, and Adopt",
1400
- "lines": [
1401
- 88,
1402
- 90
1403
- ],
1404
- "anchor": "## Scope",
1405
- "anchorEnd": "Every value written is an existing token; nothing new is min"
1406
- }
1407
- ],
1408
- "tag": "scope"
1409
- },
1410
- {
1411
- "id": "sg-ver",
1412
- "row": 19,
1413
- "kind": "done",
1414
- "title": "Verify the geometry",
1415
- "desc": "The command exits 0 with expected changes and explained skips. Controls remain readable after reload. Each reported component has a _working.json.",
1416
- "lines": [
1417
- 92,
1418
- 98
1419
- ],
1420
- "anchor": "## Verify",
1421
- "anchorEnd": "- To revert, run the inverse ops, or load a theme in the The"
1422
- }
1423
- ],
1424
- "edges": [
1425
- {
1426
- "from": "sg-trig",
1427
- "to": "sg-anchor"
1428
- },
1429
- {
1430
- "from": "sg-anchor",
1431
- "to": "sg-live"
1432
- },
1433
- {
1434
- "from": "sg-live",
1435
- "to": "sg-target"
1436
- },
1437
- {
1438
- "from": "sg-target",
1439
- "to": "sg-kind"
1440
- },
1441
- {
1442
- "from": "sg-kind",
1443
- "to": "sg-op"
1444
- },
1445
- {
1446
- "from": "sg-op",
1447
- "to": "sg-shift",
1448
- "label": "shift"
1449
- },
1450
- {
1451
- "from": "sg-op",
1452
- "to": "sg-set",
1453
- "label": "set"
1454
- },
1455
- {
1456
- "from": "sg-shift",
1457
- "to": "sg-idiom"
1458
- },
1459
- {
1460
- "from": "sg-set",
1461
- "to": "sg-idiom"
1462
- },
1463
- {
1464
- "from": "sg-idiom",
1465
- "to": "sg-squeeze"
1466
- },
1467
- {
1468
- "from": "sg-squeeze",
1469
- "to": "sg-pill"
1470
- },
1471
- {
1472
- "from": "sg-pill",
1473
- "to": "sg-pillop",
1474
- "label": "pill"
1475
- },
1476
- {
1477
- "from": "sg-pillop",
1478
- "to": "sg-ladder"
1479
- },
1480
- {
1481
- "from": "sg-ladder",
1482
- "to": "sg-write"
1483
- },
1484
- {
1485
- "from": "sg-write",
1486
- "to": "sg-shapes"
1487
- },
1488
- {
1489
- "from": "sg-shapes",
1490
- "to": "sg-cli"
1491
- },
1492
- {
1493
- "from": "sg-cli",
1494
- "to": "sg-fail",
1495
- "label": "exit 1"
1496
- },
1497
- {
1498
- "from": "sg-cli",
1499
- "to": "sg-card",
1500
- "label": "exit 0"
1501
- },
1502
- {
1503
- "from": "sg-fail",
1504
- "to": "sg-cli",
1505
- "label": "rerun",
1506
- "back": true
1507
- },
1508
- {
1509
- "from": "sg-card",
1510
- "to": "sg-report"
1511
- },
1512
- {
1513
- "from": "sg-report",
1514
- "to": "sg-tell"
1515
- },
1516
- {
1517
- "from": "sg-tell",
1518
- "to": "sg-scope"
1519
- },
1520
- {
1521
- "from": "sg-scope",
1522
- "to": "sg-ver"
1523
- },
1524
- {
1525
- "from": "sg-pill",
1526
- "to": "sg-ladder",
1527
- "label": "other geometry"
1528
- }
1529
- ]
1530
- },
1531
- "pick-component": {
1532
- "id": "live-tokens-pick-component",
1533
- "digest": "sha256:8a49229102d83d69",
1534
- "title": "pick-component",
1535
- "tagline": "Purpose determines the component. Similar-looking components serve different jobs.",
1536
- "nodes": [
1537
- {
1538
- "id": "pk-trig",
1539
- "row": 0,
1540
- "kind": "trigger",
1541
- "title": "Choose a component for a UX need",
1542
- "desc": "Purpose, interaction, and content map the need to the catalogue before custom implementation.",
1543
- "lines": [
1544
- 2,
1545
- 8
1546
- ],
1547
- "anchor": "name: live-tokens-pick-component",
1548
- "anchorEnd": "This skill helps you choose between shipped components when "
1549
- },
1550
- {
1551
- "id": "pk-cat",
1552
- "row": 1,
1553
- "kind": "step",
1554
- "title": "Scan the catalogue",
1555
- "desc": "The catalogue groups 26 shipped components into six families. Slider belongs to the Input family; CodeSnippet presents commands the reader should run.",
1556
- "lines": [
1557
- 12,
1558
- 14
1559
- ],
1560
- "anchor": "## Catalogue",
1561
- "anchorEnd": "Action: `Button`, `IconButton`, `InlineEditActions`. Input: "
1562
- },
1563
- {
1564
- "id": "pk-reg",
1565
- "row": 2,
1566
- "kind": "cli",
1567
- "title": "Inspect available components",
1568
- "desc": "The list combines shipped and registered project components. A component ID reveals its purpose, variants, props, accepted values, and token defaults.",
1569
- "lines": [
1570
- 16,
1571
- 22
1572
- ],
1573
- "anchor": "That line is the shipped set. A project can register compone",
1574
- "anchorEnd": "union accepts, and its tokens with defaults; `--json` return",
1575
- "command": "npx live-tokens components"
1576
- },
1577
- {
1578
- "id": "pk-fam",
1579
- "row": 3,
1580
- "kind": "decide",
1581
- "title": "Component job?",
1582
- "desc": "The component's primary job selects a family and its deciding question.",
1583
- "lines": [
1584
- 14,
1585
- 14
1586
- ],
1587
- "anchor": "Action: `Button`, `IconButton`, `InlineEditActions`. Input: "
1588
- },
1589
- {
1590
- "id": "pk-act",
1591
- "row": 4,
1592
- "kind": "ask",
1593
- "tag": "action",
1594
- "title": "Action content?",
1595
- "desc": "IconButton handles a clear icon action and requires ariaLabel. Button carries text. InlineEditActions supplies a consistent confirm-and-cancel pair.",
1596
- "lines": [
1597
- 24,
1598
- 31
1599
- ],
1600
- "anchor": "## Action family: Button vs IconButton",
1601
- "anchorEnd": "- `InlineEditActions` is the confirm-and-cancel pair that fo",
1602
- "chips": [
1603
- {
1604
- "label": "Clear icon: IconButton",
1605
- "lines": [
1606
- 29,
1607
- 29
1608
- ],
1609
- "anchor": "- `IconButton` is icon-only and square. Use it for compact, "
1610
- },
1611
- {
1612
- "label": "Needs text: Button",
1613
- "lines": [
1614
- 28,
1615
- 28
1616
- ],
1617
- "anchor": "- `Button` carries a text label, optionally with a leading o"
1618
- },
1619
- {
1620
- "label": "Confirm and cancel: InlineEditActions",
1621
- "lines": [
1622
- 31,
1623
- 31
1624
- ],
1625
- "anchor": "- `InlineEditActions` is the confirm-and-cancel pair that fo"
1626
- }
1627
- ]
1628
- },
1629
- {
1630
- "id": "pk-sel",
1631
- "row": 4,
1632
- "kind": "ask",
1633
- "tag": "single selection",
1634
- "title": "Selection context?",
1635
- "desc": "SegmentedControl handles 2–4 inline alternatives; TabBar handles 2–7 page panels. RadioButton suits form choices or long labels. MenuSelect contains overflowing options.",
1636
- "lines": [
1637
- 33,
1638
- 47
1639
- ],
1640
- "anchor": "## Single-selection family: SegmentedControl vs TabBar vs Ra",
1641
- "anchorEnd": "- **Don't pick `SegmentedControl` when option labels are lon",
1642
- "chips": [
1643
- {
1644
- "label": "Page content: TabBar",
1645
- "lines": [
1646
- 40,
1647
- 40
1648
- ],
1649
- "anchor": "| `TabBar` | Switching between *tab panels* (conten"
1650
- },
1651
- {
1652
- "label": "Inline setting: SegmentedControl",
1653
- "lines": [
1654
- 39,
1655
- 39
1656
- ],
1657
- "anchor": "| `SegmentedControl`| Inline switch between alternative *vie"
1658
- },
1659
- {
1660
- "label": "Form choice: RadioButton",
1661
- "lines": [
1662
- 41,
1663
- 41
1664
- ],
1665
- "anchor": "| `RadioButton` | Form-style selection where the user re"
1666
- },
1667
- {
1668
- "label": "Many options: MenuSelect",
1669
- "lines": [
1670
- 42,
1671
- 42
1672
- ],
1673
- "anchor": "| `MenuSelect` | A list of options, one checked; render"
1674
- },
1675
- {
1676
- "label": "Labels that wrap: RadioButton",
1677
- "lines": [
1678
- 47,
1679
- 47
1680
- ],
1681
- "anchor": "- **Don't pick `SegmentedControl` when option labels are lon"
1682
- }
1683
- ]
1684
- },
1685
- {
1686
- "id": "pk-text",
1687
- "row": 4,
1688
- "kind": "ask",
1689
- "tag": "text entry",
1690
- "title": "Answer set?",
1691
- "desc": "Fixed answers take selection controls; open answers take Input. Slider suits position or two bounds; numeric Input suits values users prefer to type. Input's error state holds validation messages.",
1692
- "lines": [
1693
- 49,
1694
- 55
1695
- ],
1696
- "anchor": "## Text entry: Input vs the selection family",
1697
- "anchorEnd": "- Its four variants are `default`, `focused`, `disabled`, an",
1698
- "chips": [
1699
- {
1700
- "label": "Short list: selection family",
1701
- "lines": [
1702
- 52,
1703
- 52
1704
- ],
1705
- "anchor": "- The boundary is whether you can list the answers. A short "
1706
- },
1707
- {
1708
- "label": "Long list: MenuSelect",
1709
- "lines": [
1710
- 52,
1711
- 52
1712
- ],
1713
- "anchor": "- The boundary is whether you can list the answers. A short "
1714
- },
1715
- {
1716
- "label": "Open-ended: Input",
1717
- "lines": [
1718
- 51,
1719
- 51
1720
- ],
1721
- "anchor": "- `Input` takes an answer the page cannot enumerate: a name,"
1722
- },
1723
- {
1724
- "label": "Position or two bounds: Slider",
1725
- "lines": [
1726
- 53,
1727
- 53
1728
- ],
1729
- "anchor": "- `Slider` takes a number inside a known range where the pos"
1730
- },
1731
- {
1732
- "label": "Binary state: Toggle",
1733
- "lines": [
1734
- 54,
1735
- 54
1736
- ],
1737
- "anchor": "- **Don't use it for on/off.** That is `Toggle`, and a one-f"
1738
- }
1739
- ]
1740
- },
1741
- {
1742
- "id": "pk-con",
1743
- "row": 4,
1744
- "kind": "ask",
1745
- "tag": "containers",
1746
- "title": "Container role?",
1747
- "desc": "Card groups content. CollapsibleSection hides secondary content. Panel fixes a stage's height. Dialog pauses page interaction for a focused task.",
1748
- "lines": [
1749
- 57,
1750
- 69
1751
- ],
1752
- "anchor": "## Container family: Card vs CollapsibleSection vs Dialog",
1753
- "anchorEnd": "- **Don't use `Dialog` for routine forms.** Reach for it onl",
1754
- "chips": [
1755
- {
1756
- "label": "Grouped content: Card",
1757
- "lines": [
1758
- 66,
1759
- 66
1760
- ],
1761
- "anchor": "- Default to `Card`. It's the workhorse. For full-bleed medi"
1762
- },
1763
- {
1764
- "label": "Secondary content: CollapsibleSection",
1765
- "lines": [
1766
- 67,
1767
- 67
1768
- ],
1769
- "anchor": "- Reach for `CollapsibleSection` only when the content is *l"
1770
- },
1771
- {
1772
- "label": "Stage: Panel",
1773
- "lines": [
1774
- 68,
1775
- 68
1776
- ],
1777
- "anchor": "- `Panel` is a stage, not a content container. It pins its o"
1778
- },
1779
- {
1780
- "label": "Blocking task: Dialog",
1781
- "lines": [
1782
- 69,
1783
- 69
1784
- ],
1785
- "anchor": "- **Don't use `Dialog` for routine forms.** Reach for it onl"
1786
- }
1787
- ]
1788
- },
1789
- {
1790
- "id": "pk-msg",
1791
- "row": 4,
1792
- "kind": "ask",
1793
- "tag": "messaging",
1794
- "title": "Message role?",
1795
- "desc": "Callout provides persistent content; Notification provides transient feedback. Tooltip supplements visible content. Badge sits inline; CornerBadge overlays another element.",
1796
- "lines": [
1797
- 71,
1798
- 84
1799
- ],
1800
- "anchor": "## Messaging family: Callout vs Notification vs Tooltip vs B",
1801
- "anchorEnd": "- `Badge` and `CornerBadge` differ only in positioning. `Cor",
1802
- "chips": [
1803
- {
1804
- "label": "Persistent content: Callout",
1805
- "lines": [
1806
- 81,
1807
- 81
1808
- ],
1809
- "anchor": "- `Callout` is *content*. Part of the section, written into "
1810
- },
1811
- {
1812
- "label": "Transient feedback: Notification",
1813
- "lines": [
1814
- 82,
1815
- 82
1816
- ],
1817
- "anchor": "- `Notification` is *feedback*. Appears in response to an ac"
1818
- },
1819
- {
1820
- "label": "Supplementary hint: Tooltip",
1821
- "lines": [
1822
- 83,
1823
- 83
1824
- ],
1825
- "anchor": "- `Tooltip` is for *what an element means*. **Don't use `Too"
1826
- },
1827
- {
1828
- "label": "Status: Badge or CornerBadge",
1829
- "lines": [
1830
- 84,
1831
- 84
1832
- ],
1833
- "anchor": "- `Badge` and `CornerBadge` differ only in positioning. `Cor"
1834
- }
1835
- ]
1836
- },
1837
- {
1838
- "id": "pk-bin",
1839
- "row": 4,
1840
- "kind": "ask",
1841
- "tag": "on or off",
1842
- "title": "Binary-choice context?",
1843
- "desc": "Toggle controls one named feature and acts immediately. SegmentedControl compares two named states. RadioButton belongs in a larger form submission.",
1844
- "lines": [
1845
- 95,
1846
- 107
1847
- ],
1848
- "anchor": "## Toggle vs SegmentedControl vs RadioButton (for on/off)",
1849
- "anchorEnd": "- `Toggle` flips immediately; `RadioButton` pair is for form",
1850
- "chips": [
1851
- {
1852
- "label": "Same name: Toggle",
1853
- "lines": [
1854
- 105,
1855
- 105
1856
- ],
1857
- "anchor": "- If the off and on states share a name (the feature itself)"
1858
- },
1859
- {
1860
- "label": "Distinct names: SegmentedControl",
1861
- "lines": [
1862
- 106,
1863
- 106
1864
- ],
1865
- "anchor": "- If the two states have different names you want users to c"
1866
- },
1867
- {
1868
- "label": "Larger form: RadioButton pair",
1869
- "lines": [
1870
- 107,
1871
- 107
1872
- ],
1873
- "anchor": "- `Toggle` flips immediately; `RadioButton` pair is for form"
1874
- }
1875
- ]
1876
- },
1877
- {
1878
- "id": "pk-disp",
1879
- "row": 4,
1880
- "kind": "ask",
1881
- "tag": "display",
1882
- "title": "Display content?",
1883
- "desc": "Table presents records; Cards present actionable items. ImageLightbox reveals detail; ProgressBar reports progress; CodeSnippet offers copyable commands or values. SideNavigation changes URLs; TabBar changes panels.",
1884
- "lines": [
1885
- 86,
1886
- 93
1887
- ],
1888
- "anchor": "## Display family: shown, not asked",
1889
- "anchorEnd": "- `SectionDivider` separates sections of one page. `SideNavi",
1890
- "chips": [
1891
- {
1892
- "label": "Inline picture: Image",
1893
- "lines": [
1894
- 88,
1895
- 88
1896
- ],
1897
- "anchor": "- `Image` frames a picture in the flow at one of four sizes,"
1898
- },
1899
- {
1900
- "label": "Detailed picture: ImageLightbox",
1901
- "lines": [
1902
- 89,
1903
- 89
1904
- ],
1905
- "anchor": "- `ImageLightbox` adds click-to-open at full size and takes "
1906
- },
1907
- {
1908
- "label": "Records: Table",
1909
- "lines": [
1910
- 90,
1911
- 90
1912
- ],
1913
- "anchor": "- `Table` themes your own rows and cells without owning the "
1914
- },
1915
- {
1916
- "label": "Progress readout: ProgressBar",
1917
- "lines": [
1918
- 91,
1919
- 91
1920
- ],
1921
- "anchor": "- `ProgressBar` reports progress against a labelled track. I"
1922
- },
1923
- {
1924
- "label": "Copyable command or value: CodeSnippet",
1925
- "lines": [
1926
- 92,
1927
- 92
1928
- ],
1929
- "anchor": "- `CodeSnippet` is for a single-line command or value the re"
1930
- },
1931
- {
1932
- "label": "Sections: SectionDivider; URLs: SideNavigation",
1933
- "lines": [
1934
- 93,
1935
- 93
1936
- ],
1937
- "anchor": "- `SectionDivider` separates sections of one page. `SideNavi"
1938
- }
1939
- ]
1940
- },
1941
- {
1942
- "id": "pk-fits",
1943
- "row": 5,
1944
- "kind": "decide",
1945
- "title": "Does anything in the catalogue fit?",
1946
- "desc": "A catalogue fit limits maintenance. A catalogue gap warrants a custom component.",
1947
- "lines": [
1948
- 109,
1949
- 111
1950
- ],
1951
- "anchor": "---",
1952
- "anchorEnd": "If nothing in the catalogue fits (a `DatePicker`, a `Stepper"
1953
- },
1954
- {
1955
- "id": "pk-place",
1956
- "row": 6,
1957
- "kind": "hand",
1958
- "title": "Continue with build-page",
1959
- "desc": "The page uses the selected component.",
1960
- "lines": [
1961
- 10,
1962
- 10
1963
- ],
1964
- "anchor": "For composing a page once you've picked components, see **li"
1965
- },
1966
- {
1967
- "id": "pk-make",
1968
- "row": 6,
1969
- "kind": "hand",
1970
- "title": "Continue with create-component",
1971
- "desc": "The custom path builds a token-driven DatePicker, Stepper, or other uncovered need.",
1972
- "lines": [
1973
- 111,
1974
- 111
1975
- ],
1976
- "anchor": "If nothing in the catalogue fits (a `DatePicker`, a `Stepper"
1977
- }
1978
- ],
1979
- "edges": [
1980
- {
1981
- "from": "pk-trig",
1982
- "to": "pk-cat"
1983
- },
1984
- {
1985
- "from": "pk-cat",
1986
- "to": "pk-reg"
1987
- },
1988
- {
1989
- "from": "pk-fam",
1990
- "to": "pk-act",
1991
- "label": "action"
1992
- },
1993
- {
1994
- "from": "pk-act",
1995
- "to": "pk-fits"
1996
- },
1997
- {
1998
- "from": "pk-fam",
1999
- "to": "pk-sel",
2000
- "label": "selection"
2001
- },
2002
- {
2003
- "from": "pk-sel",
2004
- "to": "pk-fits"
2005
- },
2006
- {
2007
- "from": "pk-fam",
2008
- "to": "pk-con",
2009
- "label": "container"
2010
- },
2011
- {
2012
- "from": "pk-con",
2013
- "to": "pk-fits"
2014
- },
2015
- {
2016
- "from": "pk-fam",
2017
- "to": "pk-msg",
2018
- "label": "message"
2019
- },
2020
- {
2021
- "from": "pk-msg",
2022
- "to": "pk-fits"
2023
- },
2024
- {
2025
- "from": "pk-fam",
2026
- "to": "pk-bin",
2027
- "label": "on/off"
2028
- },
2029
- {
2030
- "from": "pk-bin",
2031
- "to": "pk-fits"
2032
- },
2033
- {
2034
- "from": "pk-fits",
2035
- "to": "pk-place",
2036
- "label": "catalogue fit"
2037
- },
2038
- {
2039
- "from": "pk-fits",
2040
- "to": "pk-make",
2041
- "label": "catalogue gap"
2042
- },
2043
- {
2044
- "from": "pk-fam",
2045
- "to": "pk-text",
2046
- "label": "text entry"
2047
- },
2048
- {
2049
- "from": "pk-text",
2050
- "to": "pk-fits"
2051
- },
2052
- {
2053
- "from": "pk-fam",
2054
- "to": "pk-disp",
2055
- "label": "display"
2056
- },
2057
- {
2058
- "from": "pk-disp",
2059
- "to": "pk-fits"
2060
- },
2061
- {
2062
- "from": "pk-reg",
2063
- "to": "pk-fam"
2064
- }
2065
- ]
2066
- },
2067
- "build-page": {
2068
- "id": "live-tokens-build-page",
2069
- "digest": "sha256:6bb7df43ef2c7de4",
2070
- "title": "build-page",
2071
- "tagline": "Catalogue components cover established needs. Theme tokens drive every theme-owned value.",
2072
- "nodes": [
2073
- {
2074
- "id": "bp-trig",
2075
- "row": 0,
2076
- "kind": "trigger",
2077
- "title": "Build a page, route, or screen",
2078
- "desc": "The page combines catalogue components and theme tokens, then adds routing and repaint verification.",
2079
- "lines": [
2080
- 2,
2081
- 8
2082
- ],
2083
- "anchor": "name: live-tokens-build-page",
2084
- "anchorEnd": "Two rules above all else:"
2085
- },
2086
- {
2087
- "id": "bp-fit",
2088
- "row": 2,
2089
- "kind": "decide",
2090
- "n": "1",
2091
- "title": "Does an existing component fit?",
2092
- "desc": "A catalogue component enters contract inspection. A catalogue gap opens the custom UI paths.",
2093
- "lines": [
2094
- 10,
2095
- 10
2096
- ],
2097
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2098
- },
2099
- {
2100
- "id": "bp-pick",
2101
- "row": 1,
2102
- "kind": "hand",
2103
- "title": "Check with pick-component",
2104
- "desc": "pick-component tests the need against shipped and registered project components.",
2105
- "lines": [
2106
- 10,
2107
- 10
2108
- ],
2109
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2110
- },
2111
- {
2112
- "id": "bp-use",
2113
- "row": 3,
2114
- "kind": "step",
2115
- "title": "Import the existing component",
2116
- "desc": "Shipped components come from @motion-proto/live-tokens/components/<Name>.svelte; project components come from their local path.",
2117
- "lines": [
2118
- 10,
2119
- 10
2120
- ],
2121
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2122
- },
2123
- {
2124
- "id": "bp-custom-q",
2125
- "row": 3,
2126
- "kind": "decide",
2127
- "title": "Custom UI scope?",
2128
- "desc": "Page-local markup suits one-off layout. create-component supports reusable UI and Live Tokens editing.",
2129
- "lines": [
2130
- 10,
2131
- 10
2132
- ],
2133
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2134
- },
2135
- {
2136
- "id": "bp-local",
2137
- "row": 4,
2138
- "kind": "step",
2139
- "title": "Write page-local markup",
2140
- "desc": "The markup follows the page's token, typography, grid, routing, and validation rules.",
2141
- "lines": [
2142
- 10,
2143
- 10
2144
- ],
2145
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2146
- },
2147
- {
2148
- "id": "bp-make",
2149
- "row": 4,
2150
- "kind": "hand",
2151
- "title": "Create the missing component",
2152
- "desc": "create-component builds reusable, editable UI. The completed component returns here for contract inspection.",
2153
- "lines": [
2154
- 10,
2155
- 10
2156
- ],
2157
- "anchor": "**Use a shipped component if one fits.** Import from `@motio"
2158
- },
2159
- {
2160
- "id": "bp-props",
2161
- "row": 5,
2162
- "kind": "cli",
2163
- "title": "Inspect the component contract",
2164
- "desc": "The component receives declared props and accepted variant and size values. The checker flags unsupported values before the runtime drops them.",
2165
- "lines": [
2166
- 10,
2167
- 10
2168
- ],
2169
- "anchor": "**Use a shipped component if one fits.** Import from `@motio",
2170
- "command": "npx live-tokens components <id>"
2171
- },
2172
- {
2173
- "id": "bp-tok",
2174
- "row": 6,
2175
- "kind": "step",
2176
- "n": "2",
2177
- "title": "Use tokens for theme-owned values",
2178
- "desc": "Theme tokens supply colours, spacing, strokes, radii, shadows, font sizes, and font families in <style>, style=, and style: directives. Literals remain for layout dimensions.",
2179
- "lines": [
2180
- 11,
2181
- 11
2182
- ],
2183
- "anchor": "**Use theme tokens for every value.** Every color, spacing, "
2184
- },
2185
- {
2186
- "id": "bp-text",
2187
- "row": 7,
2188
- "kind": "step",
2189
- "title": "Use a complete text-style token",
2190
- "desc": "The --heading-*, --body-*, --editorial-*, --eyebrow, and --code tokens set family, size, weight, line height, and letter spacing together. Theme changes update the complete style.",
2191
- "lines": [
2192
- 13,
2193
- 13
2194
- ],
2195
- "anchor": "For text, reach for a whole text style rather than assemblin"
2196
- },
2197
- {
2198
- "id": "bp-prose-q",
2199
- "row": 8,
2200
- "kind": "decide",
2201
- "title": "Container prose override?",
2202
- "desc": "Card and CollapsibleSection style nested prose by default. Page-owned text and full-bleed media disable prose.",
2203
- "lines": [
2204
- 15,
2205
- 15
2206
- ],
2207
- "anchor": "Text inside a `Card` or a `CollapsibleSection` is typed by"
2208
- },
2209
- {
2210
- "id": "bp-prose",
2211
- "row": 9,
2212
- "kind": "step",
2213
- "title": "Pass prose={false}",
2214
- "desc": "This prop gives the page control of nested text and full-bleed media.",
2215
- "lines": [
2216
- 15,
2217
- 15
2218
- ],
2219
- "anchor": "Text inside a `Card` or a `CollapsibleSection` is typed by"
2220
- },
2221
- {
2222
- "id": "bp-grid",
2223
- "row": 12,
2224
- "kind": "step",
2225
- "title": "Use the page column grid",
2226
- "desc": "The page uses --columns-count, --columns-gutter, and --columns-max-width. Page-aligned children span 1 / -1 and redeclare repeat(var(--columns-count), 1fr) with --columns-gutter.",
2227
- "lines": [
2228
- 35,
2229
- 37
2230
- ],
2231
- "anchor": "Pages sit inside the column grid via `--columns-count`, `--c",
2232
- "anchorEnd": "To place children at specific page-column positions, span th"
2233
- },
2234
- {
2235
- "id": "bp-wire",
2236
- "row": 15,
2237
- "kind": "decide",
2238
- "title": "Does the app use LiveTokensRouter?",
2239
- "desc": "The route follows App.svelte's pattern and lazy-loads the page. Static imports evaluate every page module at startup and leak CSS into editor routes.",
2240
- "lines": [
2241
- 53,
2242
- 58
2243
- ],
2244
- "anchor": "## Wiring",
2245
- "anchorEnd": "Either way use `lazy`, not a static top-level import: static"
2246
- },
2247
- {
2248
- "id": "bp-router",
2249
- "row": 16,
2250
- "kind": "step",
2251
- "title": "Add a lazy page entry",
2252
- "desc": "The entry sets lazy and source. label and icon add navigation; resolve(path) handles dynamic routes. A URL-only route omits label.",
2253
- "lines": [
2254
- 56,
2255
- 56
2256
- ],
2257
- "anchor": "- **`<LiveTokensRouter pages={...}>`** (the usual case): add"
2258
- },
2259
- {
2260
- "id": "bp-overlay",
2261
- "row": 16,
2262
- "kind": "step",
2263
- "title": "Wire LiveEditorOverlay manually",
2264
- "desc": "$derived.by(() => import(...)) loads the page, and pageSources registers its source.",
2265
- "lines": [
2266
- 57,
2267
- 57
2268
- ],
2269
- "anchor": "- **Manual `<LiveEditorOverlay>`**: dispatch with `$derived."
2270
- },
2271
- {
2272
- "id": "bp-css",
2273
- "row": 17,
2274
- "kind": "step",
2275
- "title": "Import site.css in each page",
2276
- "desc": "Each page imports site.css in its script block. A main.ts import leaks page CSS into editor routes.",
2277
- "lines": [
2278
- 59,
2279
- 59
2280
- ],
2281
- "anchor": "- Import `site.css` from each page's `<script>` block, never"
2282
- },
2283
- {
2284
- "id": "bp-avoid",
2285
- "row": 18,
2286
- "kind": "chipset",
2287
- "title": "Follow seven page safeguards",
2288
- "chips": [
2289
- {
2290
- "label": "Theme tokens for colour and geometry",
2291
- "lines": [
2292
- 78,
2293
- 78
2294
- ],
2295
- "anchor": "- Colour literals, and px or rem in spacing, stroke, radius,"
2296
- },
2297
- {
2298
- "label": "Page grids use --columns-count",
2299
- "lines": [
2300
- 79,
2301
- 79
2302
- ],
2303
- "anchor": "- Hardcoded page-grid counts (`repeat(10, 1fr)`). Use `repea"
2304
- },
2305
- {
2306
- "label": "Component changes through the editor",
2307
- "lines": [
2308
- 80,
2309
- 80
2310
- ],
2311
- "anchor": "- Utility classes overriding shipped components. Extend via "
2312
- },
2313
- {
2314
- "label": "Label the box with a text style",
2315
- "lines": [
2316
- 81,
2317
- 81
2318
- ],
2319
- "anchor": "- A card header as a section label in a tool UI, and a page "
2320
- },
2321
- {
2322
- "label": "Public package imports",
2323
- "lines": [
2324
- 82,
2325
- 82
2326
- ],
2327
- "anchor": "- Deep imports from `node_modules/@motion-proto/live-tokens/"
2328
- },
2329
- {
2330
- "label": "Editor routes own editor mounts",
2331
- "lines": [
2332
- 83,
2333
- 83
2334
- ],
2335
- "anchor": "- Mounting `Editor` or `ComponentEditorPage` outside their d"
2336
- },
2337
- {
2338
- "label": "The package owns /live-tokens/* routes",
2339
- "lines": [
2340
- 84,
2341
- 84
2342
- ],
2343
- "anchor": "- A page route under `/live-tokens/*`. That namespace is re"
2344
- }
2345
- ],
2346
- "lines": [
2347
- 76,
2348
- 76
2349
- ],
2350
- "anchor": "## Avoid",
2351
- "tag": "safeguards"
2352
- },
2353
- {
2354
- "id": "bp-check",
2355
- "row": 19,
2356
- "kind": "cli",
2357
- "title": "Check the page",
2358
- "desc": "The checker rejects invalid components, props, imports, tokens, colours, and routes. Strict mode adds px/rem geometry, fixed page columns, raw type axes, and source-free routes.",
2359
- "lines": [
2360
- 88,
2361
- 97
2362
- ],
2363
- "anchor": "Run the checker and fix what it reports. Repeat until it exi",
2364
- "anchorEnd": "Warnings do not fail the run. `--strict` makes them fail, wh",
2365
- "command": "npx live-tokens check-page src/pages/YourPage.svelte --strict --json"
2366
- },
2367
- {
2368
- "id": "bp-fail",
2369
- "row": 20,
2370
- "kind": "gate",
2371
- "title": "Fix page-check findings",
2372
- "desc": "Each repair clears one reported rule before the next run.",
2373
- "lines": [
2374
- 88,
2375
- 97
2376
- ],
2377
- "anchor": "Run the checker and fix what it reports. Repeat until it exi",
2378
- "anchorEnd": "Warnings do not fail the run. `--strict` makes them fail, wh"
2379
- },
2380
- {
2381
- "id": "bp-pass",
2382
- "row": 20,
2383
- "kind": "ok",
2384
- "title": "Page check passes",
2385
- "desc": "The page meets its component, token, import, and routing contracts.",
2386
- "lines": [
2387
- 88,
2388
- 97
2389
- ],
2390
- "anchor": "Run the checker and fix what it reports. Repeat until it exi",
2391
- "anchorEnd": "Warnings do not fail the run. `--strict` makes them fail, wh"
2392
- },
2393
- {
2394
- "id": "bp-ver",
2395
- "row": 21,
2396
- "kind": "done",
2397
- "title": "Verify the page repaints",
2398
- "desc": "A colour change confirms repainting. Page Source confirms the route source. The columns overlay confirms that content stays within --columns-max-width.",
2399
- "lines": [
2400
- 103,
2401
- 103
2402
- ],
2403
- "anchor": "Then in dev: change a colour in `/live-tokens/editor` and co"
2404
- },
2405
- {
2406
- "id": "bp-laws",
2407
- "row": 10,
2408
- "kind": "step",
2409
- "title": "The purpose of a layout",
2410
- "desc": "The page shows one thing; each mark that is not content must earn its place. Separate with the smallest difference that separates: space, then a hairline rule, then a second surface. Content, labels, and scaffolding each take their own token. On a tool page the stage takes the space and controls take the smallest size that still works.",
2411
- "reference": "references/layout-sources.md",
2412
- "lines": [
2413
- 19,
2414
- 29
2415
- ],
2416
- "anchor": "**The purpose of a layout.** The page shows one thing. All o",
2417
- "anchorEnd": "`references/layout-sources.md` names the sources for these l"
2418
- },
2419
- {
2420
- "id": "bp-bands",
2421
- "row": 11,
2422
- "kind": "step",
2423
- "title": "Name the bands by their job",
2424
- "desc": "Name each band by its job: what the user looks at, types into, presses. A tool page runs stage, inputs, then one toolbar along the bottom edge. Separate bands with space and a rule; stretch a band's boxes to one height so their bottom edges make one line.",
2425
- "reference": "references/layout-sources.md",
2426
- "lines": [
2427
- 31,
2428
- 33
2429
- ],
2430
- "anchor": "Decide the bands before the columns. Read the page top to bo",
2431
- "anchorEnd": "Separate bands with space and a rule, `padding-top: var(--sp"
2432
- },
2433
- {
2434
- "id": "bp-contain",
2435
- "row": 13,
2436
- "kind": "step",
2437
- "title": "Containers by job",
2438
- "desc": "Panel is a stage. Card is a titled block of content, typed by its own tokens; compact drops a size. A box in a tool UI is a bare compact Card labelled from a text style. A toolbar is a flex row of small buttons with no card around it.",
2439
- "reference": "references/layout-sources.md",
2440
- "lines": [
2441
- 39,
2442
- 44
2443
- ],
2444
- "anchor": "### Containers by job",
2445
- "anchorEnd": "- A toolbar is a flex row of small buttons on the band's bot"
2446
- },
2447
- {
2448
- "id": "bp-density",
2449
- "row": 14,
2450
- "kind": "step",
2451
- "title": "Density",
2452
- "desc": "size=\"small\" in toolbars and compose rows; fullWidth comes off in a row. A custom wrapper forwards size. Text in a card body inherits the card's size unless typed. MenuSelect renders open; a picker toggles it from a Button.",
2453
- "reference": "references/layout-sources.md",
2454
- "lines": [
2455
- 46,
2456
- 51
2457
- ],
2458
- "anchor": "### Density",
2459
- "anchorEnd": "- `MenuSelect` renders its list open. For a picker, toggle i"
2460
- }
2461
- ],
2462
- "edges": [
2463
- {
2464
- "from": "bp-trig",
2465
- "to": "bp-pick"
2466
- },
2467
- {
2468
- "from": "bp-pick",
2469
- "to": "bp-fit"
2470
- },
2471
- {
2472
- "from": "bp-fit",
2473
- "to": "bp-use",
2474
- "label": "catalogue fit"
2475
- },
2476
- {
2477
- "from": "bp-fit",
2478
- "to": "bp-custom-q",
2479
- "label": "catalogue gap"
2480
- },
2481
- {
2482
- "from": "bp-custom-q",
2483
- "to": "bp-local",
2484
- "label": "one-off page"
2485
- },
2486
- {
2487
- "from": "bp-custom-q",
2488
- "to": "bp-make",
2489
- "label": "reusable or editable"
2490
- },
2491
- {
2492
- "from": "bp-use",
2493
- "to": "bp-props"
2494
- },
2495
- {
2496
- "from": "bp-make",
2497
- "to": "bp-props"
2498
- },
2499
- {
2500
- "from": "bp-local",
2501
- "to": "bp-tok"
2502
- },
2503
- {
2504
- "from": "bp-tok",
2505
- "to": "bp-text"
2506
- },
2507
- {
2508
- "from": "bp-text",
2509
- "to": "bp-prose-q"
2510
- },
2511
- {
2512
- "from": "bp-prose-q",
2513
- "to": "bp-prose",
2514
- "label": "page text or full bleed"
2515
- },
2516
- {
2517
- "from": "bp-wire",
2518
- "to": "bp-router",
2519
- "label": "LiveTokensRouter"
2520
- },
2521
- {
2522
- "from": "bp-wire",
2523
- "to": "bp-overlay",
2524
- "label": "manual overlay"
2525
- },
2526
- {
2527
- "from": "bp-router",
2528
- "to": "bp-css"
2529
- },
2530
- {
2531
- "from": "bp-overlay",
2532
- "to": "bp-css"
2533
- },
2534
- {
2535
- "from": "bp-css",
2536
- "to": "bp-avoid"
2537
- },
2538
- {
2539
- "from": "bp-avoid",
2540
- "to": "bp-check"
2541
- },
2542
- {
2543
- "from": "bp-props",
2544
- "to": "bp-tok"
2545
- },
2546
- {
2547
- "from": "bp-check",
2548
- "to": "bp-fail",
2549
- "label": "exit 1"
2550
- },
2551
- {
2552
- "from": "bp-check",
2553
- "to": "bp-pass",
2554
- "label": "exit 0"
2555
- },
2556
- {
2557
- "from": "bp-pass",
2558
- "to": "bp-ver"
2559
- },
2560
- {
2561
- "from": "bp-fail",
2562
- "to": "bp-check",
2563
- "label": "rerun",
2564
- "back": true
2565
- },
2566
- {
2567
- "from": "bp-prose-q",
2568
- "to": "bp-laws",
2569
- "label": "default handling"
2570
- },
2571
- {
2572
- "from": "bp-prose",
2573
- "to": "bp-laws"
2574
- },
2575
- {
2576
- "from": "bp-laws",
2577
- "to": "bp-bands"
2578
- },
2579
- {
2580
- "from": "bp-bands",
2581
- "to": "bp-grid"
2582
- },
2583
- {
2584
- "from": "bp-grid",
2585
- "to": "bp-contain"
2586
- },
2587
- {
2588
- "from": "bp-contain",
2589
- "to": "bp-density"
2590
- },
2591
- {
2592
- "from": "bp-density",
2593
- "to": "bp-wire"
2594
- }
2595
- ]
2596
- },
2597
- "create-component": {
2598
- "id": "live-tokens-create-component",
2599
- "digest": "sha256:8bd2a011d9d5b878",
2600
- "title": "create-component",
2601
- "tagline": "A runtime/editor pair exposes full token editing in the CUSTOM catalogue.",
2602
- "nodes": [
2603
- {
2604
- "id": "cc-trig",
2605
- "row": 0,
2606
- "kind": "trigger",
2607
- "title": "Create or expose an editable component",
2608
- "desc": "A runtime/editor pair adds token editing to a new or existing Svelte component after the catalogue check.",
2609
- "lines": [
2610
- 2,
2611
- 8
2612
- ],
2613
- "anchor": "name: live-tokens-create-component",
2614
- "anchorEnd": "The end state is a runtime Svelte file, an editor Svelte fil"
2615
- },
2616
- {
2617
- "id": "cc-read",
2618
- "row": 1,
2619
- "kind": "step",
2620
- "title": "Study the closest shipped example",
2621
- "desc": "Shipped patterns include Card parts, Badge variants, Button states, Dialog structure, and SegmentedControl linked siblings. Custom files live in src/system/components/.",
2622
- "lines": [
2623
- 10,
2624
- 22
2625
- ],
2626
- "anchor": "## Worked examples ship inside the package",
2627
- "anchorEnd": "Shipped editors live in `src/editor/component-editor/` becau"
2628
- },
2629
- {
2630
- "id": "cc-run",
2631
- "row": 3,
2632
- "kind": "step",
2633
- "n": "1",
2634
- "title": "Write the runtime file",
2635
- "desc": "Every editable CSS variable lives in :global(:root) with a theme-token default. The plugin seeds default.json from this block.",
2636
- "lines": [
2637
- 24,
2638
- 26
2639
- ],
2640
- "anchor": "## The recipe",
2641
- "anchorEnd": "**Runtime file**, `src/system/components/MyWidget.svelte`. D"
2642
- },
2643
- {
2644
- "id": "cc-ed",
2645
- "row": 4,
2646
- "kind": "step",
2647
- "n": "2",
2648
- "title": "Write the editor file",
2649
- "desc": "The module declares the component ID, one states map per VariantGroup, and the flat allTokens union. The markup renders those groups in ComponentEditorBase.",
2650
- "lines": [
2651
- 27,
2652
- 27
2653
- ],
2654
- "anchor": "**Editor file**, `src/system/components/MyWidgetEditor.svelt"
2655
- },
2656
- {
2657
- "id": "cc-ext",
2658
- "row": 5,
2659
- "kind": "chipset",
2660
- "title": "Choose the applicable extensions",
2661
- "desc": "The linked-sibling reference covers shared variant values; the intrinsics reference covers structural controls. Every component reads the sketch reference.",
2662
- "chips": [
2663
- {
2664
- "label": "Shared variants: linked siblings",
2665
- "lines": [
2666
- 169,
2667
- 169
2668
- ],
2669
- "anchor": "- `references/linked-siblings.md`: variants that share base "
2670
- },
2671
- {
2672
- "label": "Structural controls: intrinsics",
2673
- "lines": [
2674
- 170,
2675
- 170
2676
- ],
2677
- "anchor": "- `references/intrinsics.md`: structural or display choices "
2678
- },
2679
- {
2680
- "label": "Sketch mode, required",
2681
- "lines": [
2682
- 171,
2683
- 171
2684
- ],
2685
- "anchor": "- `references/sketch-mode.md`: joining the sketch layer. **E"
2686
- }
2687
- ],
2688
- "lines": [
2689
- 165,
2690
- 171
2691
- ],
2692
- "anchor": "## Extensions",
2693
- "anchorEnd": "- `references/sketch-mode.md`: joining the sketch layer. **E",
2694
- "tag": "extension references"
2695
- },
2696
- {
2697
- "id": "cc-reg",
2698
- "row": 6,
2699
- "kind": "step",
2700
- "n": "3",
2701
- "title": "Register through bootLiveTokens",
2702
- "desc": "bootLiveTokens receives a unique component ID and registers it after editor initialization. Manually mounted apps call registerComponent immediately before mount.",
2703
- "lines": [
2704
- 28,
2705
- 45
2706
- ],
2707
- "anchor": "**Register** by passing the component to `bootLiveTokens` in",
2708
- "anchorEnd": "`bootLiveTokens` calls `registerComponent` for you after its"
2709
- },
2710
- {
2711
- "id": "cc-desc",
2712
- "row": 7,
2713
- "kind": "step",
2714
- "n": "4",
2715
- "title": "Describe the component's purpose",
2716
- "desc": "A leading HTML comment names the job and limits; the catalogue pairs it with ID, variants, and props. componentDirs adds other source directories.",
2717
- "lines": [
2718
- 46,
2719
- 46
2720
- ],
2721
- "anchor": "**Say what it is for.** The runtime file's leading HTML comm"
2722
- },
2723
- {
2724
- "id": "cc-sk",
2725
- "row": 8,
2726
- "kind": "step",
2727
- "n": "5",
2728
- "title": "Join the sketch layer",
2729
- "desc": "Project components choose a reserved class by size and declare five --sketch-* values. The class requires normal flow, visible overflow, and free pseudo-elements. Package components register PartSpec.",
2730
- "lines": [
2731
- 47,
2732
- 47
2733
- ],
2734
- "anchor": "**Join the sketch layer.** The effect draws a fixed set of p"
2735
- },
2736
- {
2737
- "id": "cc-gate",
2738
- "row": 9,
2739
- "kind": "cli",
2740
- "n": "6",
2741
- "title": "Run the strict component check",
2742
- "desc": "Strict mode turns warnings into failures; JSON adds stable rule IDs. An ID scopes one component; the default scope covers src/system/components/.",
2743
- "lines": [
2744
- 48,
2745
- 54
2746
- ],
2747
- "anchor": "**Gate on the checker.** Run it, fix every error, and run it",
2748
- "anchorEnd": "If it rejects a suffix, do not invent a new name for the rol",
2749
- "command": "npx live-tokens check-component <id> --strict --json"
2750
- },
2751
- {
2752
- "id": "cc-disc",
2753
- "row": 2,
2754
- "kind": "chipset",
2755
- "title": "Apply the token rules",
2756
- "desc": "These rules govern every token in the runtime and editor files.",
2757
- "chips": [
2758
- {
2759
- "label": "Token names",
2760
- "lines": [
2761
- 57,
2762
- 81
2763
- ],
2764
- "anchor": "## Token discipline",
2765
- "anchorEnd": ""
2766
- },
2767
- {
2768
- "label": "Allowed suffixes",
2769
- "lines": [
2770
- 71,
2771
- 92
2772
- ],
2773
- "anchor": "### Suffix vocabulary",
2774
- "anchorEnd": "compete. A suffix outside that list fails `check-component`."
2775
- },
2776
- {
2777
- "label": "Common failures",
2778
- "lines": [
2779
- 97,
2780
- 103
2781
- ],
2782
- "anchor": "### Rules that bite",
2783
- "anchorEnd": "- **Text aliases.** Neutral scale is `--text-primary` / `--t"
2784
- },
2785
- {
2786
- "label": "Typography groupKey",
2787
- "lines": [
2788
- 104,
2789
- 114
2790
- ],
2791
- "anchor": "- **Typography `groupKey` on multi-slot components must incl",
2792
- "anchorEnd": "The helper strips the `--<component>-` prefix and those segm"
2793
- },
2794
- {
2795
- "label": "State model for stateful components",
2796
- "lines": [
2797
- 116,
2798
- 159
2799
- ],
2800
- "anchor": "## State model",
2801
- "anchorEnd": "```"
2802
- },
2803
- {
2804
- "label": "Editor copy",
2805
- "lines": [
2806
- 142,
2807
- 146
2808
- ],
2809
- "anchor": "## User-facing copy",
2810
- "anchorEnd": "Custom chrome inside an editor snippet is rare, since `Compo"
2811
- },
2812
- {
2813
- "label": "Public import paths",
2814
- "lines": [
2815
- 148,
2816
- 163
2817
- ],
2818
- "anchor": "## Public imports only",
2819
- "anchorEnd": "**Never deep-import `node_modules/@motion-proto/live-tokens/"
2820
- },
2821
- {
2822
- "label": "Toggle example",
2823
- "lines": [
2824
- 19,
2825
- 19
2826
- ],
2827
- "anchor": "- Every rule below in the fewest lines: `Toggle`. Component "
2828
- }
2829
- ],
2830
- "tag": "global rules"
2831
- },
2832
- {
2833
- "id": "cc-fail",
2834
- "row": 10,
2835
- "kind": "gate",
2836
- "title": "Fix component-check findings",
2837
- "desc": "Each pass repairs one rule group. A rejected suffix takes the role name from a shipped component that paints the same element.",
2838
- "lines": [
2839
- 48,
2840
- 54
2841
- ],
2842
- "anchor": "**Gate on the checker.** Run it, fix every error, and run it",
2843
- "anchorEnd": "If it rejects a suffix, do not invent a new name for the rol"
2844
- },
2845
- {
2846
- "id": "cc-ver",
2847
- "row": 10,
2848
- "kind": "ok",
2849
- "n": "7",
2850
- "title": "Static contract passes",
2851
- "desc": "The checker confirms file layout, token names, state order, imports, registration, editor/runtime parity, and valid theme-backed defaults or declared intrinsics.",
2852
- "lines": [
2853
- 173,
2854
- 175
2855
- ],
2856
- "anchor": "## Verification checklist",
2857
- "anchorEnd": "Step 6 of the recipe is the static gate: `npx live-tokens ch",
2858
- "chips": [
2859
- {
2860
- "label": "Verification checklist",
2861
- "lines": [
2862
- 55,
2863
- 55
2864
- ],
2865
- "anchor": "**Verify** with the checklist at the bottom of this file, th"
2866
- }
2867
- ]
2868
- },
2869
- {
2870
- "id": "cc-test",
2871
- "row": 11,
2872
- "kind": "step",
2873
- "title": "Run the registry contract test",
2874
- "desc": "The test checks registration, unique variables, runtime declarations, default.json seeds, opacity floors, and alias round trips. checkRegistryEntry covers custom components; builtInRegistry covers shipped components.",
2875
- "lines": [
2876
- 177,
2877
- 177
2878
- ],
2879
- "anchor": "**Then run the registry contract test.** `checkRegistryEntry"
2880
- },
2881
- {
2882
- "id": "cc-intr",
2883
- "row": 13,
2884
- "kind": "step",
2885
- "title": "Run the intrinsics contract test",
2886
- "desc": "The test verifies that every intrinsic and variant has matching, allowed runtime and editor defaults.",
2887
- "lines": [
2888
- 179,
2889
- 179
2890
- ],
2891
- "anchor": "**If your component declares `intrinsics`, the intrinsics co"
2892
- },
2893
- {
2894
- "id": "cc-intr-q",
2895
- "row": 12,
2896
- "kind": "decide",
2897
- "title": "Does the component declare intrinsics?",
2898
- "desc": "Components with structural or display choices run the intrinsics contract test.",
2899
- "lines": [
2900
- 179,
2901
- 179
2902
- ],
2903
- "anchor": "**If your component declares `intrinsics`, the intrinsics co"
2904
- },
2905
- {
2906
- "id": "cc-man",
2907
- "row": 14,
2908
- "kind": "step",
2909
- "title": "Verify the component at runtime",
2910
- "desc": "The runtime review at /live-tokens/components checks the CUSTOM entry, token controls, default derivation, persistence, Reset, clean boot, and sketch mode. Linked components also verify linked-block sync.",
2911
- "lines": [
2912
- 181,
2913
- 189
2914
- ],
2915
- "anchor": "Finally navigate to `/live-tokens/components` and confirm th",
2916
- "anchorEnd": "- [ ] Switch Sketch mode on in the editor and walk the check"
2917
- },
2918
- {
2919
- "id": "cc-place",
2920
- "row": 15,
2921
- "kind": "hand",
2922
- "title": "Continue with build-page",
2923
- "desc": "build-page places the completed component on a page.",
2924
- "lines": [
2925
- 55,
2926
- 55
2927
- ],
2928
- "anchor": "**Verify** with the checklist at the bottom of this file, th"
2929
- }
2930
- ],
2931
- "edges": [
2932
- {
2933
- "from": "cc-trig",
2934
- "to": "cc-read"
2935
- },
2936
- {
2937
- "from": "cc-read",
2938
- "to": "cc-disc"
2939
- },
2940
- {
2941
- "from": "cc-disc",
2942
- "to": "cc-run"
2943
- },
2944
- {
2945
- "from": "cc-run",
2946
- "to": "cc-ed"
2947
- },
2948
- {
2949
- "from": "cc-ed",
2950
- "to": "cc-ext"
2951
- },
2952
- {
2953
- "from": "cc-ext",
2954
- "to": "cc-reg"
2955
- },
2956
- {
2957
- "from": "cc-reg",
2958
- "to": "cc-desc"
2959
- },
2960
- {
2961
- "from": "cc-desc",
2962
- "to": "cc-sk"
2963
- },
2964
- {
2965
- "from": "cc-sk",
2966
- "to": "cc-gate"
2967
- },
2968
- {
2969
- "from": "cc-ver",
2970
- "to": "cc-test"
2971
- },
2972
- {
2973
- "from": "cc-test",
2974
- "to": "cc-intr-q"
2975
- },
2976
- {
2977
- "from": "cc-intr-q",
2978
- "to": "cc-intr",
2979
- "label": "has intrinsics"
2980
- },
2981
- {
2982
- "from": "cc-intr-q",
2983
- "to": "cc-man",
2984
- "label": "token values only"
2985
- },
2986
- {
2987
- "from": "cc-intr",
2988
- "to": "cc-man"
2989
- },
2990
- {
2991
- "from": "cc-man",
2992
- "to": "cc-place"
2993
- },
2994
- {
2995
- "from": "cc-gate",
2996
- "to": "cc-fail",
2997
- "label": "exit 1"
2998
- },
2999
- {
3000
- "from": "cc-gate",
3001
- "to": "cc-ver",
3002
- "label": "exit 0"
3003
- },
3004
- {
3005
- "from": "cc-fail",
3006
- "to": "cc-gate",
3007
- "label": "rerun",
3008
- "back": true
3009
- }
3010
- ]
3011
- },
3012
- "check-compliance": {
3013
- "id": "live-tokens-check-compliance",
3014
- "digest": "sha256:495beffadd041e80",
3015
- "title": "check-compliance",
3016
- "tagline": "A read-only report explains project compliance and repair cost, then hands findings to fix-findings.",
3017
- "nodes": [
3018
- {
3019
- "id": "cc2-trig",
3020
- "row": 0,
3021
- "kind": "trigger",
3022
- "title": "Review design-system compliance",
3023
- "desc": "The report covers migrations, components, usage, checker findings, and repair cost. fix-findings applies repairs; the editor handles single tokens.",
3024
- "lines": [
3025
- 2,
3026
- 3
3027
- ],
3028
- "anchor": "name: live-tokens-check-compliance",
3029
- "anchorEnd": "description: Check an existing @motion-proto/live-tokens pro"
3030
- },
3031
- {
3032
- "id": "cc2-why",
3033
- "row": 1,
3034
- "kind": "step",
3035
- "title": "Keep the audit read-only",
3036
- "desc": "The command supplies every fact. The review explains each finding and estimates its repair cost.",
3037
- "lines": [
3038
- 8,
3039
- 8
3040
- ],
3041
- "anchor": "The answer to \"check this project\" is a report. Every fact i"
3042
- },
3043
- {
3044
- "id": "cc2-run",
3045
- "row": 2,
3046
- "kind": "cli",
3047
- "n": "1",
3048
- "title": "Generate the compliance report",
3049
- "desc": "The report reads files and exits 0 even when it finds problems.",
3050
- "lines": [
3051
- 12,
3052
- 12
3053
- ],
3054
- "anchor": "Run `npx live-tokens report --json`. It always exits 0: it i",
3055
- "command": "npx live-tokens report --json"
3056
- },
3057
- {
3058
- "id": "cc2-upgrade",
3059
- "row": 3,
3060
- "kind": "gate",
3061
- "title": "Upgrade to get the report command",
3062
- "desc": "Upgrading @motion-proto/live-tokens restores the command. The next run generates the report.",
3063
- "lines": [
3064
- 12,
3065
- 12
3066
- ],
3067
- "anchor": "Run `npx live-tokens report --json`. It always exits 0: it i"
3068
- },
3069
- {
3070
- "id": "cc2-sections",
3071
- "row": 3,
3072
- "kind": "chipset",
3073
- "title": "Read each report section",
3074
- "desc": "Each section names a project fact and the repair cost for each actionable finding.",
3075
- "lines": [
3076
- 19,
3077
- 30
3078
- ],
3079
- "anchor": "## The report's sections",
3080
- "anchorEnd": "| `findings.pages`, `findings.components` | Both checkers' f",
3081
- "chips": [
3082
- {
3083
- "label": "migrations",
3084
- "lines": [
3085
- 23,
3086
- 23
3087
- ],
3088
- "anchor": "| `migrations` | Whether `tokens.css` is behind the installe"
3089
- },
3090
- {
3091
- "label": "components[].unread",
3092
- "lines": [
3093
- 24,
3094
- 24
3095
- ],
3096
- "anchor": "| `components[].unread` | Tokens a component declares that n"
3097
- },
3098
- {
3099
- "label": "components[].registered",
3100
- "lines": [
3101
- 25,
3102
- 25
3103
- ],
3104
- "anchor": "| `components[].registered` | A component file with no `boot"
3105
- },
3106
- {
3107
- "label": "components[].described",
3108
- "lines": [
3109
- 26,
3110
- 26
3111
- ],
3112
- "anchor": "| `components[].described` | Whether the runtime file has th"
3113
- },
3114
- {
3115
- "label": "usage.byPage",
3116
- "lines": [
3117
- 27,
3118
- 27
3119
- ],
3120
- "anchor": "| `usage.byPage` | Which catalogue component each page rende"
3121
- },
3122
- {
3123
- "label": "usage.unusedShipped",
3124
- "lines": [
3125
- 28,
3126
- 28
3127
- ],
3128
- "anchor": "| `usage.unusedShipped` | Shipped components no page renders"
3129
- },
3130
- {
3131
- "label": "usage.customUnregistered / usage.customUnused",
3132
- "lines": [
3133
- 29,
3134
- 29
3135
- ],
3136
- "anchor": "| `usage.customUnregistered`, `usage.customUnused` | The pro"
3137
- },
3138
- {
3139
- "label": "findings.pages / findings.components",
3140
- "lines": [
3141
- 30,
3142
- 30
3143
- ],
3144
- "anchor": "| `findings.pages`, `findings.components` | Both checkers' f"
3145
- }
3146
- ]
3147
- },
3148
- {
3149
- "id": "cc2-drill-q",
3150
- "row": 4,
3151
- "kind": "decide",
3152
- "title": "Does a finding need more evidence?",
3153
- "desc": "A component or token-scale query supplies additional evidence for classification.",
3154
- "lines": [
3155
- 17,
3156
- 17
3157
- ],
3158
- "anchor": "`npx live-tokens components <id>` and `npx live-tokens token"
3159
- },
3160
- {
3161
- "id": "cc2-drill",
3162
- "row": 5,
3163
- "kind": "cli",
3164
- "title": "Inspect the component or scale",
3165
- "desc": "components <id> lists props, values, and tokens. tokens --family <name> lists one scale. Both commands accept --json.",
3166
- "lines": [
3167
- 17,
3168
- 17
3169
- ],
3170
- "anchor": "`npx live-tokens components <id>` and `npx live-tokens token",
3171
- "command": "npx live-tokens components <id> --json\nnpx live-tokens tokens --family <name> --json"
3172
- },
3173
- {
3174
- "id": "cc2-read",
3175
- "row": 6,
3176
- "kind": "step",
3177
- "n": "2",
3178
- "title": "Classify each fix",
3179
- "desc": "Mechanical fixes follow a fixed mapping; judgement calls require a semantic choice. The classification names the choice and any visible shift.",
3180
- "lines": [
3181
- 32,
3182
- 35
3183
- ],
3184
- "anchor": "## Mechanical or judgement",
3185
- "anchorEnd": "- **Judgement**: a colour literal mapped by the role it play"
3186
- },
3187
- {
3188
- "id": "cc2-deliberate-q",
3189
- "row": 7,
3190
- "kind": "decide",
3191
- "title": "Deliberate finding?",
3192
- "desc": "Overlays, project-owned layout sizes, artwork, and vendored CSS require an intent check.",
3193
- "lines": [
3194
- 37,
3195
- 39
3196
- ],
3197
- "anchor": "## Deliberate findings",
3198
- "anchorEnd": "A translucent overlay on an app shell, or a layout size the "
3199
- },
3200
- {
3201
- "id": "cc2-deliberate",
3202
- "row": 8,
3203
- "kind": "step",
3204
- "n": "3",
3205
- "title": "Name the narrowest config entry",
3206
- "desc": "The review names a rule-severity entry or file exclusion and identifies the narrower choice. The user controls the config change.",
3207
- "lines": [
3208
- 37,
3209
- 39
3210
- ],
3211
- "anchor": "## Deliberate findings",
3212
- "anchorEnd": "A translucent overlay on an app shell, or a layout size the "
3213
- },
3214
- {
3215
- "id": "cc2-report",
3216
- "row": 9,
3217
- "kind": "chipset",
3218
- "n": "4",
3219
- "title": "Report six sections with counts",
3220
- "desc": "The summary lists files for current errors, orders fixes by the fix-findings sequence, and marks each as mechanical or judgement.",
3221
- "lines": [
3222
- 41,
3223
- 48
3224
- ],
3225
- "anchor": "## Summary",
3226
- "anchorEnd": "Recommended fixes, in the order **live-tokens-fix-findings**",
3227
- "chips": [
3228
- {
3229
- "label": "Pending migrations",
3230
- "lines": [
3231
- 43,
3232
- 43
3233
- ],
3234
- "anchor": "Migrations pending, and the one command that clears them."
3235
- },
3236
- {
3237
- "label": "Current build errors",
3238
- "lines": [
3239
- 44,
3240
- 44
3241
- ],
3242
- "anchor": "What fails the build now: errors by rule, with the files."
3243
- },
3244
- {
3245
- "label": "Strict warnings",
3246
- "lines": [
3247
- 45,
3248
- 45
3249
- ],
3250
- "anchor": "What the strict count adds: warnings by rule."
3251
- },
3252
- {
3253
- "label": "Components",
3254
- "lines": [
3255
- 46,
3256
- 46
3257
- ],
3258
- "anchor": "Components: unread tokens, unregistered, undescribed."
3259
- },
3260
- {
3261
- "label": "Usage",
3262
- "lines": [
3263
- 47,
3264
- 47
3265
- ],
3266
- "anchor": "Usage: what each page renders, and what is used nowhere."
3267
- },
3268
- {
3269
- "label": "Recommended fixes",
3270
- "lines": [
3271
- 48,
3272
- 48
3273
- ],
3274
- "anchor": "Recommended fixes, in the order **live-tokens-fix-findings**"
3275
- }
3276
- ]
3277
- },
3278
- {
3279
- "id": "cc2-done",
3280
- "row": 10,
3281
- "kind": "hand",
3282
- "title": "Hand off the fixes",
3283
- "desc": "The hand-off offers live-tokens-fix-findings for the full set or a selected subset. The audit preserves project files.",
3284
- "lines": [
3285
- 50,
3286
- 50
3287
- ],
3288
- "anchor": "End with the hand-off: \"Run live-tokens-fix-findings to appl"
3289
- }
3290
- ],
3291
- "edges": [
3292
- {
3293
- "from": "cc2-trig",
3294
- "to": "cc2-why"
3295
- },
3296
- {
3297
- "from": "cc2-why",
3298
- "to": "cc2-run"
3299
- },
3300
- {
3301
- "from": "cc2-run",
3302
- "to": "cc2-upgrade",
3303
- "label": "unknown command"
3304
- },
3305
- {
3306
- "from": "cc2-upgrade",
3307
- "to": "cc2-run",
3308
- "label": "retry",
3309
- "back": true
3310
- },
3311
- {
3312
- "from": "cc2-run",
3313
- "to": "cc2-sections",
3314
- "label": "report ready"
3315
- },
3316
- {
3317
- "from": "cc2-read",
3318
- "to": "cc2-deliberate-q"
3319
- },
3320
- {
3321
- "from": "cc2-deliberate-q",
3322
- "to": "cc2-deliberate",
3323
- "label": "possible exception"
3324
- },
3325
- {
3326
- "from": "cc2-deliberate-q",
3327
- "to": "cc2-report",
3328
- "label": "ordinary finding"
3329
- },
3330
- {
3331
- "from": "cc2-deliberate",
3332
- "to": "cc2-report"
3333
- },
3334
- {
3335
- "from": "cc2-report",
3336
- "to": "cc2-done"
3337
- },
3338
- {
3339
- "from": "cc2-sections",
3340
- "to": "cc2-drill-q"
3341
- },
3342
- {
3343
- "from": "cc2-drill-q",
3344
- "to": "cc2-drill",
3345
- "label": "needs evidence"
3346
- },
3347
- {
3348
- "from": "cc2-drill-q",
3349
- "to": "cc2-read",
3350
- "label": "enough evidence"
3351
- },
3352
- {
3353
- "from": "cc2-drill",
3354
- "to": "cc2-read"
3355
- }
3356
- ]
3357
- },
3358
- "fix-findings": {
3359
- "id": "live-tokens-fix-findings",
3360
- "digest": "sha256:f31b82cb3aefa302",
3361
- "title": "fix-findings",
3362
- "tagline": "The repair loop clears the largest error group first, repeats by rule, and ends with strict validation.",
3363
- "nodes": [
3364
- {
3365
- "id": "ff-trig",
3366
- "row": 0,
3367
- "kind": "trigger",
3368
- "title": "Fix design-system findings",
3369
- "desc": "The loop groups existing findings by rule, applies each recipe, and reruns both checkers. check-compliance supplies the read-only report.",
3370
- "lines": [
3371
- 2,
3372
- 3
3373
- ],
3374
- "anchor": "name: live-tokens-fix-findings",
3375
- "anchorEnd": "description: Bring an existing @motion-proto/live-tokens pro"
3376
- },
3377
- {
3378
- "id": "ff-why",
3379
- "row": 1,
3380
- "kind": "step",
3381
- "title": "Enforce page and component contracts",
3382
- "desc": "The page checker enforces catalogue components, declared props, and tokenized CSS. The component checker enforces semantic token names and theme-backed defaults. Passing files repaint.",
3383
- "lines": [
3384
- 8,
3385
- 10
3386
- ],
3387
- "anchor": "Two checkers hold a project to its design system. `check-pag",
3388
- "anchorEnd": "This skill is the loop for code that already exists. When th"
3389
- },
3390
- {
3391
- "id": "ff-run",
3392
- "row": 2,
3393
- "kind": "cli",
3394
- "n": "1",
3395
- "title": "Collect all findings",
3396
- "desc": "Each finding includes a stable rule, file, and line. A page path scopes check-page; a component ID scopes check-component.",
3397
- "lines": [
3398
- 14,
3399
- 19
3400
- ],
3401
- "anchor": "Run both checkers with `--json`. Each finding carries a stab",
3402
- "anchorEnd": "`check-page src/pages/Home.svelte` and `check-component <id>",
3403
- "command": "npx live-tokens check-page --json\nnpx live-tokens check-component --json"
3404
- },
3405
- {
3406
- "id": "ff-blocked",
3407
- "row": 3,
3408
- "kind": "gate",
3409
- "title": "Upgrade to get the checkers",
3410
- "desc": "A package upgrade supplies the checkers. migrate --check plans token changes; migrate --write applies them. --tokens identifies a custom tokens.css path.",
3411
- "lines": [
3412
- 19,
3413
- 19
3414
- ],
3415
- "anchor": "`check-page src/pages/Home.svelte` and `check-component <id>"
3416
- },
3417
- {
3418
- "id": "ff-empty",
3419
- "row": 3,
3420
- "kind": "ok",
3421
- "title": "Default checks pass",
3422
- "desc": "Strict validation now reveals advisory warnings.",
3423
- "lines": [
3424
- 23,
3425
- 23
3426
- ],
3427
- "anchor": "Run once with `--strict` and report what it adds, so the use"
3428
- },
3429
- {
3430
- "id": "ff-loop",
3431
- "row": 4,
3432
- "kind": "step",
3433
- "n": "2",
3434
- "title": "Group findings by rule",
3435
- "desc": "Errors precede warnings. The largest rule group gives one recipe the widest effect.",
3436
- "lines": [
3437
- 20,
3438
- 20
3439
- ],
3440
- "anchor": "Group by rule. Take errors before warnings, and the rule wit"
3441
- },
3442
- {
3443
- "id": "ff-never",
3444
- "row": 5,
3445
- "kind": "chipset",
3446
- "title": "Protect three constraints",
3447
- "desc": "--off applies to one working run. Severity changes require user approval. Repairs use existing tokens and report every visible shift.",
3448
- "chips": [
3449
- {
3450
- "label": "Keep project rule severity",
3451
- "lines": [
3452
- 29,
3453
- 29
3454
- ],
3455
- "anchor": "- **Silence a rule to pass.** `--off=<rule>` is for a single"
3456
- },
3457
- {
3458
- "label": "Map to existing tokens",
3459
- "lines": [
3460
- 30,
3461
- 30
3462
- ],
3463
- "anchor": "- **Mint a token.** A literal with no token behind it is rem"
3464
- },
3465
- {
3466
- "label": "Report visible changes",
3467
- "lines": [
3468
- 31,
3469
- 31
3470
- ],
3471
- "anchor": "- **Change what the page looks like without saying so.** Mos"
3472
- }
3473
- ]
3474
- },
3475
- {
3476
- "id": "ff-recipe",
3477
- "row": 6,
3478
- "kind": "decide",
3479
- "n": "3",
3480
- "title": "Finding type?",
3481
- "desc": "One recipe covers the group: page colours by role, geometry by scale, or the rule table. Unknown components enter a separate hand-off.",
3482
- "lines": [
3483
- 21,
3484
- 21
3485
- ],
3486
- "anchor": "Apply that rule's recipe to every finding in the group: colo"
3487
- },
3488
- {
3489
- "id": "ff-colour",
3490
- "row": 7,
3491
- "kind": "step",
3492
- "title": "Map page colours by role",
3493
- "desc": "Each page literal maps by job: text, fill, stroke, scrim, tint, transparency, or gradient. Role tokens then move coherently with the theme.",
3494
- "lines": [
3495
- 33,
3496
- 48
3497
- ],
3498
- "anchor": "## Colour by role, never by hue",
3499
- "anchorEnd": "A `var(--x, #fff)` fallback is not a finding. A named colour"
3500
- },
3501
- {
3502
- "id": "ff-geom",
3503
- "row": 7,
3504
- "kind": "step",
3505
- "title": "Map geometry to its scale",
3506
- "desc": "Theme-owned geometry maps to token scales: nearest-step spacing, matching stroke and corner tokens, whole-shadow replacements, and tokenized geometry inside calc(). Layout sizing remains intact.",
3507
- "lines": [
3508
- 50,
3509
- 62
3510
- ],
3511
- "anchor": "## Geometry by scale",
3512
- "anchorEnd": "While in the file, motion values take `--duration-*` and `--"
3513
- },
3514
- {
3515
- "id": "ff-rest",
3516
- "row": 7,
3517
- "kind": "chipset",
3518
- "title": "Apply the rule's recipe",
3519
- "desc": "The table supplies one repair for every finding in the current rule group.",
3520
- "lines": [
3521
- 64,
3522
- 81
3523
- ],
3524
- "anchor": "## Every other rule",
3525
- "anchorEnd": "| `invalid-id`, `missing-file`, `missing-root-block`, `no-to",
3526
- "chips": [
3527
- {
3528
- "label": "unknown-token",
3529
- "lines": [
3530
- 68,
3531
- 68
3532
- ],
3533
- "anchor": "| `unknown-token` | A typo or a rename. Search `tokens.css` "
3534
- },
3535
- {
3536
- "label": "raw-text-axis",
3537
- "lines": [
3538
- 69,
3539
- 69
3540
- ],
3541
- "anchor": "| `raw-text-axis` | Set the whole axis set from one text sty"
3542
- },
3543
- {
3544
- "label": "unknown-prop, unknown-prop-value",
3545
- "lines": [
3546
- 71,
3547
- 72
3548
- ],
3549
- "anchor": "| `unknown-prop` | The component drops it at runtime. `npx l",
3550
- "anchorEnd": "| `unknown-prop-value` | Pick a value from the union the mes"
3551
- },
3552
- {
3553
- "label": "hardcoded-columns",
3554
- "lines": [
3555
- 73,
3556
- 73
3557
- ],
3558
- "anchor": "| `hardcoded-columns` | `repeat(var(--columns-count), 1fr)` "
3559
- },
3560
- {
3561
- "label": "site-css-in-main, missing-source, reserved-route",
3562
- "lines": [
3563
- 74,
3564
- 76
3565
- ],
3566
- "anchor": "| `site-css-in-main` | Delete the import from `main.ts` and ",
3567
- "anchorEnd": "| `reserved-route` | Move the route out of `/live-tokens/*`;"
3568
- },
3569
- {
3570
- "label": "deep-import",
3571
- "lines": [
3572
- 77,
3573
- 77
3574
- ],
3575
- "anchor": "| `deep-import` | Import from `@motion-proto/live-tokens` or"
3576
- },
3577
- {
3578
- "label": "Token naming",
3579
- "lines": [
3580
- 78,
3581
- 78
3582
- ],
3583
- "anchor": "| `unknown-suffix`, `state-after-property`, `disabled-is-ter"
3584
- },
3585
- {
3586
- "label": "Component defaults",
3587
- "lines": [
3588
- 79,
3589
- 79
3590
- ],
3591
- "anchor": "| `color-literal`, `unknown-token-ref`, `default-not-token` "
3592
- },
3593
- {
3594
- "label": "Editor/runtime mismatches",
3595
- "lines": [
3596
- 80,
3597
- 80
3598
- ],
3599
- "anchor": "| `phantom-editor-token`, `phantom-link` | The editor names "
3600
- },
3601
- {
3602
- "label": "Component wiring",
3603
- "lines": [
3604
- 81,
3605
- 81
3606
- ],
3607
- "anchor": "| `invalid-id`, `missing-file`, `missing-root-block`, `no-to"
3608
- }
3609
- ]
3610
- },
3611
- {
3612
- "id": "ff-hand",
3613
- "row": 7,
3614
- "kind": "hand",
3615
- "title": "Resolve the unknown component",
3616
- "desc": "pick-component finds a catalogue match. create-component builds a new editable component.",
3617
- "lines": [
3618
- 70,
3619
- 70
3620
- ],
3621
- "anchor": "| `unknown-component` | Not in the catalogue. Read **live-to"
3622
- },
3623
- {
3624
- "id": "ff-gate",
3625
- "row": 8,
3626
- "kind": "decide",
3627
- "n": "4",
3628
- "title": "Rerun result?",
3629
- "desc": "Repairable findings return to the grouped loop. An unmatched literal enters the report with its rationale.",
3630
- "lines": [
3631
- 22,
3632
- 22
3633
- ],
3634
- "anchor": "Run again. New findings can appear as old ones clear: a toke"
3635
- },
3636
- {
3637
- "id": "ff-strict",
3638
- "row": 9,
3639
- "kind": "cli",
3640
- "n": "5",
3641
- "title": "Run strict validation",
3642
- "desc": "--strict exposes advisory warnings after the default checks pass.",
3643
- "lines": [
3644
- 23,
3645
- 23
3646
- ],
3647
- "anchor": "Run once with `--strict` and report what it adds, so the use",
3648
- "command": "npx live-tokens check-page --strict --json\nnpx live-tokens check-component --strict --json"
3649
- },
3650
- {
3651
- "id": "ff-warn",
3652
- "row": 10,
3653
- "kind": "decide",
3654
- "title": "Clear strict warnings now?",
3655
- "desc": "The user selects the warnings to repair. Accepted warnings return to the rule loop and both validation stages.",
3656
- "lines": [
3657
- 23,
3658
- 23
3659
- ],
3660
- "anchor": "Run once with `--strict` and report what it adds, so the use"
3661
- },
3662
- {
3663
- "id": "ff-clean",
3664
- "row": 10,
3665
- "kind": "ok",
3666
- "title": "Strict checks pass",
3667
- "desc": "Both strict checks exit 0.",
3668
- "lines": [
3669
- 23,
3670
- 23
3671
- ],
3672
- "anchor": "Run once with `--strict` and report what it adds, so the use"
3673
- },
3674
- {
3675
- "id": "ff-report",
3676
- "row": 11,
3677
- "kind": "step",
3678
- "title": "Report changes by rule",
3679
- "desc": "The final report gives each rule's count and visible shifts, explains unresolved findings, records approved config entries, and includes both commands with exit codes.",
3680
- "lines": [
3681
- 83,
3682
- 85
3683
- ],
3684
- "anchor": "## Report",
3685
- "anchorEnd": "Say what changed by rule, one line per rule with the count a"
3686
- },
3687
- {
3688
- "id": "ff-script",
3689
- "row": 12,
3690
- "kind": "step",
3691
- "title": "Gate builds with check:design",
3692
- "desc": "Scaffolded projects include check:design. Other projects add both checkers to that script and run it before vite build.",
3693
- "lines": [
3694
- 25,
3695
- 25
3696
- ],
3697
- "anchor": "A project scaffolded by `create` has a `check:design` script"
3698
- },
3699
- {
3700
- "id": "ff-ver",
3701
- "row": 13,
3702
- "kind": "done",
3703
- "title": "Verify that every touched file repaints",
3704
- "desc": "A surface-colour and spacing change in /live-tokens/editor tests every touched file. Any repaint failure becomes a reported checker gap.",
3705
- "lines": [
3706
- 87,
3707
- 89
3708
- ],
3709
- "anchor": "## Verify",
3710
- "anchorEnd": "Open `/live-tokens/editor` in dev and change a surface colou"
3711
- }
3712
- ],
3713
- "edges": [
3714
- {
3715
- "from": "ff-trig",
3716
- "to": "ff-why"
3717
- },
3718
- {
3719
- "from": "ff-why",
3720
- "to": "ff-run"
3721
- },
3722
- {
3723
- "from": "ff-run",
3724
- "to": "ff-blocked",
3725
- "label": "unknown command"
3726
- },
3727
- {
3728
- "from": "ff-blocked",
3729
- "to": "ff-run",
3730
- "label": "retry",
3731
- "back": true
3732
- },
3733
- {
3734
- "from": "ff-run",
3735
- "to": "ff-loop",
3736
- "label": "findings"
3737
- },
3738
- {
3739
- "from": "ff-run",
3740
- "to": "ff-empty",
3741
- "label": "clean"
3742
- },
3743
- {
3744
- "from": "ff-empty",
3745
- "to": "ff-strict"
3746
- },
3747
- {
3748
- "from": "ff-loop",
3749
- "to": "ff-never"
3750
- },
3751
- {
3752
- "from": "ff-never",
3753
- "to": "ff-recipe"
3754
- },
3755
- {
3756
- "from": "ff-recipe",
3757
- "to": "ff-colour",
3758
- "label": "page colour"
3759
- },
3760
- {
3761
- "from": "ff-recipe",
3762
- "to": "ff-geom",
3763
- "label": "geometry"
3764
- },
3765
- {
3766
- "from": "ff-recipe",
3767
- "to": "ff-rest",
3768
- "label": "other rule"
3769
- },
3770
- {
3771
- "from": "ff-recipe",
3772
- "to": "ff-hand",
3773
- "label": "unknown component"
3774
- },
3775
- {
3776
- "from": "ff-colour",
3777
- "to": "ff-gate"
3778
- },
3779
- {
3780
- "from": "ff-geom",
3781
- "to": "ff-gate"
3782
- },
3783
- {
3784
- "from": "ff-rest",
3785
- "to": "ff-gate"
3786
- },
3787
- {
3788
- "from": "ff-hand",
3789
- "to": "ff-gate"
3790
- },
3791
- {
3792
- "from": "ff-gate",
3793
- "to": "ff-loop",
3794
- "label": "repairable findings",
3795
- "back": true
3796
- },
3797
- {
3798
- "from": "ff-gate",
3799
- "to": "ff-report",
3800
- "label": "unmatched literal"
3801
- },
3802
- {
3803
- "from": "ff-gate",
3804
- "to": "ff-strict",
3805
- "label": "clean"
3806
- },
3807
- {
3808
- "from": "ff-strict",
3809
- "to": "ff-warn",
3810
- "label": "warnings"
3811
- },
3812
- {
3813
- "from": "ff-strict",
3814
- "to": "ff-clean",
3815
- "label": "clean"
3816
- },
3817
- {
3818
- "from": "ff-warn",
3819
- "to": "ff-loop",
3820
- "label": "clear now",
3821
- "back": true
3822
- },
3823
- {
3824
- "from": "ff-warn",
3825
- "to": "ff-report",
3826
- "label": "defer repairs"
3827
- },
3828
- {
3829
- "from": "ff-clean",
3830
- "to": "ff-report"
3831
- },
3832
- {
3833
- "from": "ff-report",
3834
- "to": "ff-script"
3835
- },
3836
- {
3837
- "from": "ff-script",
3838
- "to": "ff-ver"
3839
- }
3840
- ]
3841
- }
14
+ 'create-theme': createTheme,
15
+ 'set-colors': setColors,
16
+ 'set-type': setType,
17
+ 'set-geometry': setGeometry,
18
+ 'pick-component': pickComponent,
19
+ 'create-page': createPage,
20
+ 'create-component': createComponent,
21
+ 'check-compliance': checkCompliance,
22
+ 'fix-findings': fixFindings,
3842
23
  };
3843
-
3844
- export const skillKeys = Object.keys(skillTrees);