@motion-proto/live-tokens 0.73.0 → 0.75.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 (196) 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 +84 -0
  13. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +94 -0
  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 +149 -0
  17. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +80 -0
  18. package/.claude/skills/live-tokens-set-geometry/SKILL.md +121 -0
  19. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +63 -0
  20. package/.claude/skills/live-tokens-set-type/SKILL.md +93 -0
  21. package/.claude/skills/live-tokens-set-type/references/type-anchors.md +60 -0
  22. package/CHANGELOG.md +194 -0
  23. package/README.md +27 -18
  24. package/bin/check-component.mjs +91 -19
  25. package/bin/check-page.mjs +105 -24
  26. package/bin/cli.mjs +154 -97
  27. package/bin/contractRunner.mjs +945 -0
  28. package/bin/create.mjs +1 -1
  29. package/bin/lib/catalogue.mjs +37 -30
  30. package/bin/lib/findings.mjs +46 -15
  31. package/bin/lib/liveState.mjs +110 -0
  32. package/bin/lib/report.mjs +3 -3
  33. package/bin/lib/tokenVocabulary.mjs +4 -4
  34. package/bin/migrate-routes.mjs +5 -5
  35. package/bin/migrate.mjs +4 -4
  36. package/bin/save-theme.mjs +176 -0
  37. package/bin/set-colors.mjs +189 -0
  38. package/bin/{adjust.mjs → set-geometry.mjs} +25 -57
  39. package/bin/{set-fonts.mjs → set-type.mjs} +26 -62
  40. package/dist-plugin/{chunk-W6Y4BWFB.js → chunk-6WGFOJXO.js} +22 -0
  41. package/dist-plugin/{chunk-RIXO2E55.js → chunk-PDNL4NC5.js} +9 -2
  42. package/dist-plugin/{chunk-YLCOIGQC.js → chunk-SWXRVZKT.js} +98 -2
  43. package/dist-plugin/{dataPaths-BhWzd5cL.d.ts → dataPaths-BpIK_Obx.d.cts} +1 -0
  44. package/dist-plugin/{dataPaths-BhWzd5cL.d.cts → dataPaths-BpIK_Obx.d.ts} +1 -0
  45. package/dist-plugin/index.cjs +366 -148
  46. package/dist-plugin/index.d.cts +1 -1
  47. package/dist-plugin/index.d.ts +1 -1
  48. package/dist-plugin/index.js +226 -130
  49. package/dist-plugin/migrateData/index.cjs +121 -2
  50. package/dist-plugin/migrateData/index.d.cts +1 -1
  51. package/dist-plugin/migrateData/index.d.ts +1 -1
  52. package/dist-plugin/migrateData/index.js +3 -3
  53. package/dist-plugin/{generateColorsAndType → setColors}/index.cjs +594 -499
  54. package/dist-plugin/{generateColorsAndType → setColors}/index.d.cts +34 -25
  55. package/dist-plugin/{generateColorsAndType → setColors}/index.d.ts +34 -25
  56. package/dist-plugin/{generateColorsAndType → setColors}/index.js +48 -66
  57. package/dist-plugin/{adjust → setGeometry}/index.cjs +166 -48
  58. package/dist-plugin/{adjust → setGeometry}/index.d.cts +6 -6
  59. package/dist-plugin/{adjust → setGeometry}/index.d.ts +6 -6
  60. package/dist-plugin/{adjust → setGeometry}/index.js +51 -45
  61. package/dist-plugin/{fontPairing → setType}/index.cjs +19 -4
  62. package/dist-plugin/{fontPairing → setType}/index.d.cts +2 -2
  63. package/dist-plugin/{fontPairing → setType}/index.d.ts +2 -2
  64. package/dist-plugin/{fontPairing → setType}/index.js +1 -1
  65. package/dist-plugin/{themeTypes-DSV3Zisf.d.cts → themeTypes-BxRtuN5V.d.cts} +1 -1
  66. package/dist-plugin/{themeTypes-DSV3Zisf.d.ts → themeTypes-BxRtuN5V.d.ts} +1 -1
  67. package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
  68. package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
  69. package/dist-plugin/tokensCssMigrations/index.js +1 -1
  70. package/package.json +36 -8
  71. package/src/app/site.css +19 -9
  72. package/src/editor/bootstrap.ts +2 -0
  73. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +4 -4
  74. package/src/editor/component-editor/DialogEditor.svelte +4 -4
  75. package/src/editor/component-editor/MenuSelectEditor.svelte +4 -1
  76. package/src/editor/component-editor/SegmentedControlEditor.svelte +6 -1
  77. package/src/editor/component-editor/TabBarEditor.svelte +1 -1
  78. package/src/editor/component-editor/TableEditor.svelte +2 -2
  79. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +6 -3
  80. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +41 -20
  81. package/src/editor/core/components/adjustAliases.ts +59 -45
  82. package/src/editor/core/components/aliasKinds.ts +9 -5
  83. package/src/editor/core/preview/themePreview.ts +9 -2
  84. package/src/editor/core/sketch/sketchLayer.ts +22 -0
  85. package/src/editor/core/store/editorStore.ts +10 -1
  86. package/src/editor/core/themes/{generateColorsAndType.ts → buildColors.ts} +84 -98
  87. package/src/editor/core/themes/liveStateStream.ts +26 -0
  88. package/src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts +62 -0
  89. package/src/editor/core/themes/migrations/2026-09-07-stroke-role-renames.ts +52 -0
  90. package/src/editor/core/themes/migrations/index.ts +4 -0
  91. package/src/editor/core/themes/themeDocumentSync.ts +22 -11
  92. package/src/editor/core/themes/themeService.ts +9 -2
  93. package/src/editor/docs/content/themes-workflow.md +2 -2
  94. package/src/editor/docs/content.generated.ts +1 -1
  95. package/src/editor/overlay/LiveEditorOverlay.svelte +519 -28
  96. package/src/editor/pages/ComponentEditorPage.svelte +17 -1
  97. package/src/editor/pages/liveTokensEditorHandle.ts +23 -0
  98. package/src/editor/skill-atlas/SkillAtlas.svelte +76 -574
  99. package/src/editor/skill-atlas/TreeCanvas.svelte +263 -0
  100. package/src/editor/skill-atlas/TreeNodeCard.svelte +136 -53
  101. package/src/editor/skill-atlas/edges.ts +31 -0
  102. package/src/editor/skill-atlas/skillSources.generated.ts +29 -24
  103. package/src/editor/skill-atlas/skillTrees.ts +19 -3687
  104. package/src/editor/skill-atlas/trees/check-compliance.ts +183 -0
  105. package/src/editor/skill-atlas/trees/create-component.ts +275 -0
  106. package/src/editor/skill-atlas/trees/create-page.ts +320 -0
  107. package/src/editor/skill-atlas/trees/create-theme.ts +255 -0
  108. package/src/editor/skill-atlas/trees/fix-findings.ts +469 -0
  109. package/src/editor/skill-atlas/trees/pick-component.ts +300 -0
  110. package/src/editor/skill-atlas/trees/set-colors.ts +148 -0
  111. package/src/editor/skill-atlas/trees/set-geometry.ts +136 -0
  112. package/src/editor/skill-atlas/trees/set-type.ts +142 -0
  113. package/src/editor/skill-atlas/types.ts +3 -4
  114. package/src/editor/skill-atlas/wireLayout.ts +287 -0
  115. package/src/live-tokens/data/colors-and-type/autumn.json +1 -37
  116. package/src/live-tokens/data/colors-and-type/default.json +1 -37
  117. package/src/live-tokens/data/colors-and-type/halloween.json +1 -37
  118. package/src/live-tokens/data/colors-and-type/midnight-study.json +1 -37
  119. package/src/live-tokens/data/colors-and-type/ocean.json +1 -37
  120. package/src/live-tokens/data/colors-and-type/royal-velvet.json +1 -37
  121. package/src/live-tokens/data/colors-and-type/sketchy.json +1 -37
  122. package/src/live-tokens/data/colors-and-type/spring-meadow.json +1 -37
  123. package/src/live-tokens/data/colors-and-type/sunset.json +1 -37
  124. package/src/live-tokens/data/themes/autumn.json +16 -52
  125. package/src/live-tokens/data/themes/halloween.json +16 -52
  126. package/src/live-tokens/data/themes/midnight-study.json +16 -52
  127. package/src/live-tokens/data/themes/ocean.json +16 -52
  128. package/src/live-tokens/data/themes/royal-velvet.json +16 -52
  129. package/src/live-tokens/data/themes/sketchy.json +16 -52
  130. package/src/live-tokens/data/themes/spring-meadow.json +16 -52
  131. package/src/live-tokens/data/themes/sunset.json +16 -52
  132. package/src/live-tokens/data/tokens.generated.css +0 -36
  133. package/src/system/components/Badge.svelte +7 -0
  134. package/src/system/components/Button.svelte +7 -0
  135. package/src/system/components/Callout.svelte +10 -6
  136. package/src/system/components/Card.svelte +23 -4
  137. package/src/system/components/CodeSnippet.svelte +4 -3
  138. package/src/system/components/CollapsibleSection.svelte +23 -8
  139. package/src/system/components/CornerBadge.svelte +6 -0
  140. package/src/system/components/Dialog.svelte +13 -6
  141. package/src/system/components/IconButton.svelte +9 -0
  142. package/src/system/components/Image.svelte +8 -0
  143. package/src/system/components/ImageLightbox.svelte +6 -0
  144. package/src/system/components/InlineEditActions.svelte +7 -0
  145. package/src/system/components/Input.svelte +7 -0
  146. package/src/system/components/MenuSelect.svelte +7 -0
  147. package/src/system/components/Notification.svelte +7 -0
  148. package/src/system/components/Panel.svelte +6 -0
  149. package/src/system/components/ProgressBar.svelte +5 -0
  150. package/src/system/components/RadioButton.svelte +11 -5
  151. package/src/system/components/SectionDivider.svelte +8 -0
  152. package/src/system/components/SegmentedControl.svelte +6 -0
  153. package/src/system/components/SideNavigation.svelte +6 -0
  154. package/src/system/components/Slider.svelte +7 -4
  155. package/src/system/components/TabBar.svelte +15 -9
  156. package/src/system/components/Table.svelte +8 -3
  157. package/src/system/components/Toggle.svelte +4 -4
  158. package/src/system/components/Tooltip.svelte +6 -0
  159. package/src/testing-js/chunk-AO7EZHYV.js +776 -0
  160. package/src/testing-js/chunk-AO7EZHYV.js.map +1 -0
  161. package/src/testing-js/chunk-FAFOAWYL.js +39 -0
  162. package/src/testing-js/chunk-FAFOAWYL.js.map +1 -0
  163. package/src/testing-js/chunk-L73N4NSO.js +23 -0
  164. package/src/testing-js/chunk-L73N4NSO.js.map +1 -0
  165. package/src/testing-js/chunk-LXR3MN6N.js +3063 -0
  166. package/src/testing-js/chunk-LXR3MN6N.js.map +1 -0
  167. package/src/testing-js/chunk-ZMSX6CXR.js +53 -0
  168. package/src/testing-js/chunk-ZMSX6CXR.js.map +1 -0
  169. package/src/testing-js/component-alias.contract.js +81 -0
  170. package/src/testing-js/component-alias.contract.js.map +1 -0
  171. package/src/testing-js/component-editor.contract.js +62 -0
  172. package/src/testing-js/component-editor.contract.js.map +1 -0
  173. package/src/testing-js/component-render.contract.js +568 -0
  174. package/src/testing-js/component-render.contract.js.map +1 -0
  175. package/src/testing-js/index.d.ts +293 -0
  176. package/src/testing-js/index.js +222 -0
  177. package/src/testing-js/index.js.map +1 -0
  178. package/src/testing-js/registry.contract.js +39 -0
  179. package/src/testing-js/registry.contract.js.map +1 -0
  180. package/src/testing-js/vitest-BE6uGF31.d.ts +73 -0
  181. package/src/testing-js/vitest.d.ts +3 -0
  182. package/src/testing-js/vitest.js +13 -0
  183. package/src/testing-js/vitest.js.map +1 -0
  184. package/template/README.md +13 -0
  185. package/template/_gitignore +2 -0
  186. package/template/package.json +2 -1
  187. package/template/src/pages/Home.svelte +4 -18
  188. package/.claude/skills/live-tokens-adjust-geometry/SKILL.md +0 -93
  189. package/.claude/skills/live-tokens-build-page/SKILL.md +0 -103
  190. package/.claude/skills/live-tokens-build-page/references/layout-sources.md +0 -48
  191. package/.claude/skills/live-tokens-generate-theme/SKILL.md +0 -156
  192. package/.claude/skills/live-tokens-generate-theme/references/mood-vocabulary.md +0 -43
  193. package/.claude/skills/live-tokens-generate-theme/references/named-themes.md +0 -18
  194. package/.claude/skills/live-tokens-generate-theme/references/style-vocabulary.md +0 -35
  195. package/.claude/skills/live-tokens-pair-fonts/SKILL.md +0 -90
  196. package/bin/generate-theme.mjs +0 -260
@@ -1,50 +1,45 @@
1
1
  ---
2
2
  name: live-tokens-check-compliance
3
- description: Check an existing @motion-proto/live-tokens project against its design system and report, without changing a file: which tokens each component reads, which page renders which component, what the two checkers find, and a list of recommended fixes handed to live-tokens-fix-findings. Use when the user asks to check, audit, validate, or review the project, a page, or a component against the design system; asks how compliant it is, what is off, or what it would take to make the build pass; or wants a look before an upgrade. Not for making the changes (live-tokens-fix-findings), and not for a single token (use the editor).
3
+ description: Report an existing project's adherence to @motion-proto/live-tokens from one run of npx live-tokens report. Checks for correct use of components, properties, and tokens. The report names the tokens each component reads, the component each page renders, the findings of both checkers, and the recommended fixes. Called as the verification step by live-tokens-create-page and live-tokens-create-component. Use when the user asks to check, audit, or review the project. Edits no file. Hands the fix list to live-tokens-fix-findings.
4
4
  ---
5
5
 
6
- # Checking a project against its design system
6
+ # Checking a project's adherence to live-tokens
7
7
 
8
- The answer to "check this project" is a report. Every fact in it comes from one command; the reading of those facts, and what fixing them would cost, is yours. This skill edits nothing. When the user wants the changes made, that is **live-tokens-fix-findings**, and this report is what it starts from.
8
+ Run `npx live-tokens report`. The CLI prints a report with the sections in the Report sections table. Say what each finding means and what the fix would cost. When live-tokens-create-page or live-tokens-create-component calls this skill, lead with the findings on the file it built. Edit no file. When the user wants the fixes applied, hand the fix list to **live-tokens-fix-findings**.
9
9
 
10
- ## Workflow
11
-
12
- 1. Run `npx live-tokens report --json`. It always exits 0: it is a reading, not a gate. Unknown command means the installed package predates it; upgrade `@motion-proto/live-tokens` first.
13
- 2. Read each section against the table below. For every rule with findings, say in a line what the rule holds and whether the fix is mechanical or a judgement.
14
- 3. Where a finding looks deliberate, name the config entry that would record the decision, and leave the decision to the user.
15
- 4. Report in the order under Summary, each line carrying its count, and end by handing the list to **live-tokens-fix-findings**. Do not start applying fixes here, even one-liners, because the user asked how things stand.
16
-
17
- `npx live-tokens components <id>` and `npx live-tokens tokens --family <name>` (both take `--json`) answer any question the report raises about one component or one scale.
10
+ `report` never runs the component contract suites. The `check-component` test run does, and it is what live-tokens-create-component calls to validate a component's runtime behavior.
18
11
 
19
- ## The report's sections
20
-
21
- | Section | Fact | When it is not clean |
22
- | --- | --- | --- |
23
- | `migrations` | Whether `tokens.css` is behind the installed package | A stale file shows up downstream as unknown tokens. This is the first fix, and it is one command: `npx live-tokens migrate --check`, then `--write` (`--tokens <path>` for a tokens.css in an unusual place). |
24
- | `components[].unread` | Tokens a component declares that nothing in its file reads | An editor row that edits nothing. Each is a token to wire into the CSS or to remove. |
25
- | `components[].registered` | A component file with no `bootLiveTokens` or `registerComponent` entry | It renders on the page but has no editor. |
26
- | `components[].described` | Whether the runtime file has the header comment the picker reads | Without one, `live-tokens components` cannot say what it is for. |
27
- | `usage.byPage` | Which catalogue component each page renders, and how many times | A page rendering none is either chrome or hand-rolled markup that a shipped component covers. |
28
- | `usage.unusedShipped` | Shipped components no page renders | Information, not a finding. |
29
- | `usage.customUnregistered`, `usage.customUnused` | The project's own components that are unregistered or unused | Dead or half-wired work. |
30
- | `findings.pages`, `findings.components` | Both checkers' findings by rule, under the project's severities and again under `--strict` | The errors are what fails the build today; the strict count is what a fully tokenized project would fail. |
31
-
32
- ## Mechanical or judgement
33
-
34
- - **Mechanical**: a spacing literal to its nearest `--space-*` step, a stroke to `--border-width-*`, a hardcoded column count to `var(--columns-count)`, `site.css` moved out of `main.ts`, a route given its `source`. Name any visible shift, such as a `14px` margin becoming `16px`.
35
- - **Judgement**: a colour literal mapped by the role it plays rather than its hue, a raw type axis set from a text style, a prop the component does not declare mapped or dropped. Say what the choice is, not what you would pick.
12
+ ## Workflow
36
13
 
37
- ## Deliberate findings
14
+ When `report` is an unknown command, route the dependency upgrade to **live-tokens-fix-findings**. Resume the audit after the upgrade.
38
15
 
39
- A translucent overlay on an app shell, or a layout size the project owns, may be a decision rather than a miss. Say so and name the entry that would record it: `"checks": { "rules": { "<rule>": "warn" } }` in `live-tokens.config.json`. Where a whole file is not a themed surface at all, hand-tuned artwork or vendored CSS, the entry is `"checks": { "exclude": ["src/art/hero.css"] }`: a project-relative path, a directory covering what is under it, and naming the file on the command line still checks it. Prefer the narrower one: an exclusion drops one file, a severity change drops a rule everywhere. Recording either is the user's call, not yours.
16
+ 1. Run `npx live-tokens report --json`.
17
+ 2. Read each section of the report with the Report sections table.
18
+ 3. When a finding needs component or token scale details, run the matching inspection command below. Otherwise continue with classification.
19
+ 4. Classify each finding as Mechanical, Judgement, or Deliberate. For Deliberate findings, name the narrower config entry.
20
+ 5. Reply with the findings of each section in the table's order, each with its count.
21
+ 6. List the recommended fixes, each marked with its finding class, in the order **live-tokens-fix-findings** takes them.
22
+ 7. End with the hand-off: run **live-tokens-fix-findings** on the list, or on the subset the user chooses.
40
23
 
41
- ## Summary
24
+ For one component, run `npx live-tokens components <id>`. For one token scale, run `npx live-tokens tokens --scale <name>`. Both take `--json`.
42
25
 
43
- 1. Migrations pending, and the one command that clears them.
44
- 2. What fails the build now: errors by rule, with the files.
45
- 3. What `--strict` would add: warnings by rule.
46
- 4. Components: unread tokens, unregistered, undescribed.
47
- 5. Usage: what each page renders, and what is used nowhere.
48
- 6. Recommended fixes, in the order **live-tokens-fix-findings** would take them: migrations, then the largest group of errors, then the rest, then warnings. Mark each as mechanical or judgement.
26
+ ## Report sections
49
27
 
50
- End with the hand-off: "Run live-tokens-fix-findings to apply these", or the subset the user chooses.
28
+ | Section | Contents | Fix |
29
+ | --- | --- | --- |
30
+ | Pending token migrations (`migrations`) | Whether `tokens.css` is behind the installed package. `status` is `pending`, `none pending`, `no tokens.css`, or `unavailable`. A stale file shows downstream as unknown tokens. | Fix this first. Run `npx live-tokens migrate --check` to see the plan, then `npx live-tokens migrate` to apply it. `--write` also rewrites the route references the plan lists. `--tokens <path>` names a tokens.css in an unusual place. |
31
+ | Checker findings by rule (`findings.pages`, `findings.components`) | Both checkers' findings by rule under the project's severities, and one strict total with every warning as an error. Errors fail the build today. The strict total is what a fully tokenized project would fail. | Classify each finding under Finding classes. |
32
+ | Tokens a component never reads (`components[].unread`) | Tokens a component declares and never reads. Each is an editor row that edits nothing. | Wire each token into the CSS, or remove it. No checker rule covers this, so confirm with a second `report` run. |
33
+ | Component registration (`components[].registered`) | Whether the component has a `bootLiveTokens` or `registerComponent` entry. Without one it renders with no editor. | Register it. |
34
+ | Component usage comment (`components[].described`) | Whether the runtime file has the header comment the picker reads. Without one, `live-tokens components` cannot say what the component is for. | Add the comment. No checker rule covers this, so confirm with a second `report` run. |
35
+ | Components each page renders (`usage.byPage`) | Which component each page imports, and how many times the page renders it. | When a page renders none, say whether it is chrome or markup that a shipped component covers. |
36
+ | Shipped components no page renders (`usage.unusedShipped`) | Shipped components no page renders. | None. Information only. |
37
+ | Project components unregistered or unused (`usage.customUnregistered`, `usage.customUnused`) | The project's own components that are unregistered or unused. | Register or delete each. `check-component` sees a component only under `src/system/components`, so confirm with a second `report` run. |
38
+
39
+ ## Finding classes
40
+
41
+ Every finding is one of three. Say which.
42
+
43
+ - **Mechanical.** The value determines the token, such as a spacing literal and its nearest `--space-*` step. When the fix shifts a rendered value, name the shift.
44
+ - **Judgement.** A role determines the token, such as a color literal and the role it plays. Say what the options are. Ask the user to choose.
45
+ - **Deliberate.** The finding records a decision, such as a layout size the project owns. Name the config entry that would record the decision. Leave the decision to the user. To lower a rule's severity everywhere, the entry is `"checks": { "rules": { "<rule>": "warn" } }` in `live-tokens.config.json`. To drop one file that is not a themed surface, the entry is `"checks": { "exclude": ["src/art/hero.css"] }`. The path is project-relative, and a directory covers what is under it. Prefer the narrower entry.
@@ -0,0 +1,196 @@
1
+ app---
2
+ name: live-tokens-create-component
3
+ description: Create a custom Svelte component in a @motion-proto/live-tokens project with semantic properties that reference the existing theme tokens, a live editor, and registration. Use for a new component or to make an existing component editable. Use live-tokens-create-page to place existing components on a page.
4
+ ---
5
+
6
+ # Creating a Live Tokens component
7
+
8
+ Create a component whose structure and behavior serve the user's purpose. Give each editable visual property a semantic name and assign its default from the design system's existing token vocabulary. Deliver the runtime component, its editor, and its registration together.
9
+
10
+ ## Design model
11
+
12
+ Live Tokens has two token layers:
13
+
14
+ | Layer | Responsibility | Example |
15
+ |---|---|---|
16
+ | Theme tokens | Define the available colors, typography, geometry, and motion values. Theme presets change these values. | `--space-16`, `--radius-md`, `--surface-neutral` |
17
+ | Component properties | Name the visual roles within a component and reference theme tokens. Component presets record these assignments. | `--statcard-frame-padding: var(--space-16)` |
18
+
19
+ The rendering chain is **theme token → semantic component property → CSS declaration**. The editor changes the assignment; the runtime reads the property. Keep the assignment as a token reference so a theme change reaches the component.
20
+
21
+ A property describes its purpose: `--statcard-value-text`, `--statcard-frame-radius`, `--statcard-label-font-size`. Its name stays stable when its assigned color or size changes. Use role names such as `surface` and `text`, and full words for component ids and parts.
22
+
23
+ Build distinct components through their anatomy, proportions, content hierarchy, behavior, and choice of existing tokens. Create only the variants and states the task requires. Keep the theme vocabulary intact during component creation; a new theme token belongs in a separate theme change.
24
+
25
+ Component props carry content and behavior, such as `value`, `label`, `selected`, and callbacks. Semantic CSS properties carry the editable appearance. Expose variants through props when they represent meaningful component choices.
26
+
27
+ ## Source inspection
28
+
29
+ Read the project's `package.json`, `live-tokens.config.json`, and application bootstrap before writing files. Run `npx live-tokens components` to inspect the catalogue and `npx live-tokens components <id>` for a candidate's props. Use an existing component when it fulfills the request; create a new component when the request needs distinct structure or behavior.
30
+
31
+ Locate the installed package at `node_modules/@motion-proto/live-tokens`. When working inside the Live Tokens repository, use the repository root instead. Read these sources from that root:
32
+
33
+ - `src/system/styles/tokens.css` for the available default tokens, and the project's theme files for overrides. Treat `tokens.generated.css` as generated output.
34
+ - `src/system/components/<Name>.svelte` and `src/editor/component-editor/<Name>Editor.svelte` for a matching runtime/editor pair. Use `Toggle` for interaction states, `Badge` for variants and linking, and `Card` for separate text and container parts.
35
+ - `src/editor/core/components/aliasKinds.ts` for the suffixes that select editor controls.
36
+ - `src/editor/component-editor/index.ts` and the package exports for available authoring APIs.
37
+
38
+ Use the current source as the contract when older prose differs. For example, the current brand color family uses `--surface-brand`, `--border-brand`, and `--text-brand`; `--text-primary` names neutral primary text.
39
+
40
+ Read [references/token-naming.md](references/token-naming.md) when choosing property suffixes. Read the other references at the steps that need them.
41
+
42
+ ## Property design
43
+
44
+ Before implementation, identify the component's parts, text roles, variants, and states. Make a short property map that connects each editable role to an existing default token and the CSS property it controls. Keep separate roles independent even when they start with the same value.
45
+
46
+ | Component property | Default assignment | CSS use |
47
+ |---|---|---|
48
+ | `--statcard-frame-surface` | `--surface-neutral` | `background` |
49
+ | `--statcard-frame-border` | `--border-neutral` | `border-color` |
50
+ | `--statcard-frame-border-width` | `--border-width-1` | `border-width` |
51
+ | `--statcard-frame-radius` | `--radius-md` | `border-radius` |
52
+ | `--statcard-frame-padding` | `--space-16` | `padding` |
53
+ | `--statcard-value-text` | `--text-primary` | `color` |
54
+ | `--statcard-label-text` | `--text-secondary` | `color` |
55
+
56
+ Choose defaults from tokens that exist in the target project. Prefer the color role that matches the purpose: surfaces for fills, borders for outlines, and text tokens for text. Select geometry from the relevant spacing, radius, stroke, and icon scales. Give each text role its own family, size, weight, line height, and letter spacing properties, using existing typography tokens.
57
+
58
+ Name properties with the component id first and the property suffix last:
59
+
60
+ ```text
61
+ --<componentId>-<part-or-variant>[-<state>][-<element>]-<property>
62
+ ```
63
+
64
+ Use a lowercase id with no dashes that matches the runtime filename: `StatCard.svelte` has id `statcard`. Include the segments that distinguish the role. Follow the closest shipped component for components with both variants and parts. Put state segments before the final property: `--statcard-frame-hover-surface`.
65
+
66
+ The suffix selects the editor control. Use `-surface` for a fill, `-border` for border color, `-border-width` for stroke thickness, `-radius` for corners, and `-padding` or `-gap` for spacing. Use the full typography suffixes such as `-font-size`. Verify other suffixes against `aliasKinds.ts`.
67
+
68
+ ## Runtime component
69
+
70
+ Create `src/system/components/StatCard.svelte`. Use Svelte 5 props and snippets, semantic HTML, and the behavior the task requires. Start with a short HTML comment that states the component's purpose, suitable uses, and an alternative for uses outside its scope. The component CLI reads this comment and `interface Props` to describe the component.
71
+
72
+ Declare every editable property explicitly in a literal `:global(:root)` block. The discovery parser reads the Svelte source to seed `component-configs/<id>/default.json`; it needs concrete property names. Keep SCSS loops and interpolation out of this declaration block.
73
+
74
+ ```svelte
75
+ <style>
76
+ :global(:root) {
77
+ --statcard-frame-surface: var(--surface-neutral);
78
+ --statcard-frame-border: var(--border-neutral);
79
+ --statcard-frame-border-width: var(--border-width-1);
80
+ --statcard-frame-radius: var(--radius-md);
81
+ --statcard-frame-padding: var(--space-16);
82
+ --statcard-value-text: var(--text-primary);
83
+ --statcard-label-text: var(--text-secondary);
84
+ }
85
+
86
+ .statcard {
87
+ display: grid;
88
+ background: var(--statcard-frame-surface);
89
+ border: var(--statcard-frame-border-width) solid var(--statcard-frame-border);
90
+ border-radius: var(--statcard-frame-radius);
91
+ padding: var(--statcard-frame-padding);
92
+ }
93
+
94
+ .value { color: var(--statcard-value-text); }
95
+ .label { color: var(--statcard-label-text); }
96
+ </style>
97
+ ```
98
+
99
+ This excerpt shows the assignment chain. Add typography, spacing, and other properties from the component's actual property map.
100
+
101
+ Route editable styling through component properties. Keep structural CSS such as `display: grid`, `width: 100%`, and `align-items: center` in the component's layout rules. Use token references for visual defaults. A token expression such as `calc(var(--space-64) * 4)` can express a dimension beyond the scale when the component needs it; prefer a direct assignment when a preset value fits.
102
+
103
+ For persistent structural choices such as alignment or visibility, read [references/intrinsics.md](references/intrinsics.md). Declare an `IntrinsicSpec`, mirror its default in `:global(:root)`, and register it through the `intrinsics` field. Keep these choices outside `allTokens`.
104
+
105
+ ## Variants and states
106
+
107
+ Parts coexist, variants provide alternative presentations, and states reflect runtime conditions. Preserve those distinctions in both the component API and the editor.
108
+
109
+ Use the default state for shared geometry and typography. Add state properties for the values that change. Follow `Toggle` for a component state such as `on` with an interaction state such as `hover`. Live Tokens treats `disabled` as terminal: its editor fieldset is flat, and its tokens carry no combined hover or selected state.
110
+
111
+ Make the preview render the state whose properties the user edits. Pair each hover selector with a `.force-hover` selector and expose a class prop so the editor can show hover without a pointer. Preserve native disabled behavior, keyboard operation, and visible focus for interactive controls.
112
+
113
+ For action emphasis, use `primary` for the single action that completes the page's main task, `secondary` for supporting or directly related actions, and `outline` for unrelated or informational actions. Use `danger` for actions that destroy saved work. The page chooses the one primary action; a component supplies the relevant variants.
114
+
115
+ ## Component editor
116
+
117
+ Create `src/system/components/StatCardEditor.svelte` beside the custom runtime file. Shipped editors use a separate internal directory; custom components keep both files together.
118
+
119
+ In `<script module lang="ts">`, declare `const component = 'statcard'`, define the token lists, and export their flat union as `allTokens: Token[]`. Each editable runtime property has one schema entry with the exact variable name. Use `element` to group rows by part and a short `label` to name the property.
120
+
121
+ ```ts
122
+ import type { Token } from '@motion-proto/live-tokens/component-editor';
123
+
124
+ const component = 'statcard';
125
+ const states: Record<string, Token[]> = {
126
+ default: [
127
+ { label: 'surface', element: 'frame', variable: '--statcard-frame-surface' },
128
+ { label: 'padding', element: 'frame', variable: '--statcard-frame-padding' },
129
+ { label: 'text', element: 'value', variable: '--statcard-value-text' },
130
+ { label: 'text', element: 'label', variable: '--statcard-label-text' },
131
+ ],
132
+ };
133
+ export const allTokens: Token[] = Object.values(states).flat();
134
+ ```
135
+
136
+ Expand this illustrative schema to cover the full property map. In the instance script, import the runtime component and the editor primitives. Mount `ComponentEditorBase` with `component` and `tokens={allTokens}`, then a `VariantGroup` for each variant with its `states`, `component`, and runtime preview. Follow the matching shipped editor for the exact snippet API.
137
+
138
+ Use public imports in consumer projects:
139
+
140
+ ```ts
141
+ import { ComponentEditorBase, VariantGroup } from '@motion-proto/live-tokens/component-editor';
142
+ import StatCard from './StatCard.svelte';
143
+ ```
144
+
145
+ Read shipped source files for examples; import package APIs through their public exports. Use `--ui-*` tokens for custom editor chrome and let the runtime preview consume the theme through its component properties.
146
+
147
+ When variants should share properties, read [references/linked-siblings.md](references/linked-siblings.md). Declare intentional sibling sets with `groupKey`, enable the linked controls with `canBeLinked`, and wire the linked block using the shipped helpers. Scope keys to the role: `value-font-size` and `label-font-size` stay independent. When using `buildTypeGroup*` helpers, pass `{ component, variants }` so they derive keys for each slot.
148
+
149
+ ## Registration and persistence
150
+
151
+ Add the custom component to the existing `bootLiveTokens` call, preserving the project's other registrations and setup:
152
+
153
+ ```ts
154
+ import StatCardEditor, { allTokens as statCardTokens } from './system/components/StatCardEditor.svelte';
155
+
156
+ bootLiveTokens(App, '#app', {
157
+ components: [{
158
+ id: 'statcard',
159
+ label: 'Stat Card',
160
+ icon: 'fas fa-chart-simple',
161
+ sourceFile: 'src/system/components/StatCard.svelte',
162
+ editorComponent: StatCardEditor,
163
+ schema: statCardTokens,
164
+ }],
165
+ });
166
+ ```
167
+
168
+ `bootLiveTokens` registers components after editor initialization and before theme initialization. Use that registration window. For a manual bootstrap, follow the package initialization order and register before mounting the app. Choose a unique id so the registration preserves built-in entries.
169
+
170
+ The runtime root declarations supply the initial assignments. The plugin derives `default.json`; editor saves write `_working.json`, and Save As creates a named preset. Preserve token references through this flow. Verify the project's configured data path rather than creating a second persistence mechanism.
171
+
172
+ For a first-party addition inside the Live Tokens package, follow the internal layout instead: runtime in `src/system/components`, editor in `src/editor/component-editor`, and an entry in `builtInRegistry` in `src/editor/component-editor/registry.ts`. Update the built-in id union and catalogue through the repository's existing conventions.
173
+
174
+ ## Rendering integration
175
+
176
+ Read [references/sketch-mode.md](references/sketch-mode.md) and integrate the component's painted parts with Sketch mode. Custom components use the reserved sketch classes and bind the sketch properties to their own semantic properties. Choose a wrapper that accommodates the layer's positioning, overflow, and pseudo-element requirements. First-party components add the corresponding `PartSpec` entries.
177
+
178
+ For a fixed overlay, read [references/fixed-overlays.md](references/fixed-overlays.md) and portal the layer to `body`. Follow the existing container pattern when the component owns typography inside a content snippet.
179
+
180
+ ## Verification
181
+
182
+ Run `npx live-tokens check-component <id> --strict --json`. Inside the package repository, use `node bin/cli.mjs check-component <id> --strict --json`. Resolve findings and rerun until the command passes. Run the project's Svelte checks and the build or tests that cover the new behavior.
183
+
184
+ Read [references/contract-tests.md](references/contract-tests.md) and verify the registry entry with `checkRegistryEntry`. The contract checks registration, unique schema variables, runtime declarations, seeded defaults, and alias round trips. Include intrinsic checks when the component declares intrinsics.
185
+
186
+ Open `/live-tokens/components` and verify:
187
+
188
+ - The component appears under Custom, or among system components for a first-party addition.
189
+ - Each property has the correct editor control and changes the matching runtime part.
190
+ - Preview variants and states match the controls; keyboard and pointer behavior work.
191
+ - Linked properties change together, and separate roles remain independent.
192
+ - Save and reload retain assignments. Reset restores runtime defaults.
193
+ - Theme changes reach every property that references a theme token.
194
+ - Sketch mode renders each painted part correctly and restores the normal appearance when switched off.
195
+
196
+ Report the files, component id, available props, and verification results. State any checks the environment prevented you from running.