@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.
- package/.claude/skills/live-tokens-check-compliance/SKILL.md +33 -38
- package/.claude/skills/live-tokens-create-component/SKILL copy.md +196 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +198 -146
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +95 -52
- package/.claude/skills/live-tokens-create-component/references/intrinsics.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/linked-siblings.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +12 -12
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +2 -1
- package/.claude/skills/live-tokens-create-page/SKILL.md +187 -0
- package/.claude/skills/live-tokens-create-page/references/interaction-sources.md +66 -0
- package/.claude/skills/live-tokens-create-page/references/layout-sources.md +87 -0
- package/.claude/skills/live-tokens-create-theme/SKILL.md +52 -48
- package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +69 -60
- package/.claude/skills/live-tokens-pick-component/SKILL.md +64 -79
- package/.claude/skills/live-tokens-set-colors/SKILL.md +47 -38
- package/.claude/skills/live-tokens-set-geometry/SKILL.md +58 -35
- package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +5 -3
- package/.claude/skills/live-tokens-set-type/SKILL.md +30 -30
- package/CHANGELOG.md +138 -0
- package/README.md +17 -7
- package/bin/check-component.mjs +91 -19
- package/bin/check-page.mjs +102 -21
- package/bin/cli.mjs +87 -113
- package/bin/contractRunner.mjs +945 -0
- package/bin/create.mjs +1 -1
- package/bin/lib/catalogue.mjs +37 -30
- package/bin/lib/findings.mjs +46 -15
- package/bin/lib/report.mjs +3 -3
- package/bin/lib/tokenVocabulary.mjs +4 -4
- package/bin/migrate-routes.mjs +5 -5
- package/bin/migrate.mjs +4 -4
- package/bin/save-theme.mjs +8 -9
- package/bin/set-colors.mjs +9 -11
- package/bin/set-geometry.mjs +7 -7
- package/bin/set-type.mjs +5 -7
- package/bin/setup-claude.mjs +110 -0
- package/dist-plugin/{chunk-W6Y4BWFB.js → chunk-6WGFOJXO.js} +22 -0
- package/dist-plugin/{chunk-7VRTBGJT.js → chunk-PDNL4NC5.js} +9 -2
- package/dist-plugin/{chunk-V3YF6CGT.js → chunk-SWXRVZKT.js} +43 -1
- package/dist-plugin/{dataPaths-BhWzd5cL.d.cts → dataPaths-BpIK_Obx.d.cts} +1 -0
- package/dist-plugin/{dataPaths-BhWzd5cL.d.ts → dataPaths-BpIK_Obx.d.ts} +1 -0
- package/dist-plugin/index.cjs +310 -147
- package/dist-plugin/index.d.cts +1 -1
- package/dist-plugin/index.d.ts +1 -1
- package/dist-plugin/index.js +218 -122
- package/dist-plugin/migrateData/index.cjs +66 -2
- package/dist-plugin/migrateData/index.d.cts +1 -1
- package/dist-plugin/migrateData/index.d.ts +1 -1
- package/dist-plugin/migrateData/index.js +3 -3
- package/dist-plugin/setColors/index.cjs +61 -4
- package/dist-plugin/setColors/index.d.cts +1 -1
- package/dist-plugin/setColors/index.d.ts +1 -1
- package/dist-plugin/setColors/index.js +5 -5
- package/dist-plugin/setGeometry/index.cjs +107 -44
- package/dist-plugin/setGeometry/index.d.cts +5 -5
- package/dist-plugin/setGeometry/index.d.ts +5 -5
- package/dist-plugin/setGeometry/index.js +51 -45
- package/dist-plugin/setType/index.cjs +15 -0
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/setType/index.js +1 -1
- package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
- package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
- package/dist-plugin/tokensCssMigrations/index.js +1 -1
- package/package.json +35 -8
- package/src/app/site.css +19 -9
- package/src/editor/bootstrap.ts +2 -0
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +4 -4
- package/src/editor/component-editor/DialogEditor.svelte +4 -4
- package/src/editor/component-editor/MenuSelectEditor.svelte +4 -1
- package/src/editor/component-editor/SegmentedControlEditor.svelte +6 -1
- package/src/editor/component-editor/TabBarEditor.svelte +1 -1
- package/src/editor/component-editor/TableEditor.svelte +2 -2
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +6 -3
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +41 -20
- package/src/editor/core/components/adjustAliases.ts +59 -45
- package/src/editor/core/components/aliasKinds.ts +9 -5
- package/src/editor/core/preview/themePreview.ts +9 -2
- package/src/editor/core/sketch/sketchLayer.ts +22 -0
- package/src/editor/core/store/editorStore.ts +10 -1
- package/src/editor/core/themes/buildColors.ts +3 -3
- package/src/editor/core/themes/liveStateStream.ts +26 -0
- package/src/editor/core/themes/migrations/2026-09-07-stroke-role-renames.ts +52 -0
- package/src/editor/core/themes/migrations/index.ts +2 -0
- package/src/editor/core/themes/themeDocumentSync.ts +22 -11
- package/src/editor/core/themes/themeService.ts +9 -2
- package/src/editor/pages/ComponentEditorPage.svelte +17 -1
- package/src/editor/pages/liveTokensEditorHandle.ts +23 -0
- package/src/editor/skill-atlas/SkillAtlas.svelte +75 -573
- package/src/editor/skill-atlas/TreeCanvas.svelte +263 -0
- package/src/editor/skill-atlas/TreeNodeCard.svelte +136 -53
- package/src/editor/skill-atlas/edges.ts +31 -0
- package/src/editor/skill-atlas/skillSources.generated.ts +20 -19
- package/src/editor/skill-atlas/skillTrees.ts +19 -3840
- package/src/editor/skill-atlas/trees/check-compliance.ts +183 -0
- package/src/editor/skill-atlas/trees/create-component.ts +275 -0
- package/src/editor/skill-atlas/trees/create-page.ts +320 -0
- package/src/editor/skill-atlas/trees/create-theme.ts +255 -0
- package/src/editor/skill-atlas/trees/fix-findings.ts +469 -0
- package/src/editor/skill-atlas/trees/pick-component.ts +300 -0
- package/src/editor/skill-atlas/trees/set-colors.ts +148 -0
- package/src/editor/skill-atlas/trees/set-geometry.ts +136 -0
- package/src/editor/skill-atlas/trees/set-type.ts +142 -0
- package/src/editor/skill-atlas/types.ts +3 -4
- package/src/editor/skill-atlas/wireLayout.ts +287 -0
- package/src/live-tokens/data/themes/autumn.json +15 -15
- package/src/live-tokens/data/themes/halloween.json +15 -15
- package/src/live-tokens/data/themes/midnight-study.json +15 -15
- package/src/live-tokens/data/themes/ocean.json +15 -15
- package/src/live-tokens/data/themes/royal-velvet.json +15 -15
- package/src/live-tokens/data/themes/sketchy.json +15 -15
- package/src/live-tokens/data/themes/spring-meadow.json +15 -15
- package/src/live-tokens/data/themes/sunset.json +15 -15
- package/src/system/components/Badge.svelte +7 -0
- package/src/system/components/Button.svelte +7 -0
- package/src/system/components/Callout.svelte +10 -6
- package/src/system/components/Card.svelte +23 -4
- package/src/system/components/CodeSnippet.svelte +4 -3
- package/src/system/components/CollapsibleSection.svelte +23 -8
- package/src/system/components/CornerBadge.svelte +6 -0
- package/src/system/components/Dialog.svelte +13 -6
- package/src/system/components/IconButton.svelte +9 -0
- package/src/system/components/Image.svelte +8 -0
- package/src/system/components/ImageLightbox.svelte +6 -0
- package/src/system/components/InlineEditActions.svelte +7 -0
- package/src/system/components/Input.svelte +7 -0
- package/src/system/components/MenuSelect.svelte +7 -0
- package/src/system/components/Notification.svelte +7 -0
- package/src/system/components/Panel.svelte +6 -0
- package/src/system/components/ProgressBar.svelte +5 -0
- package/src/system/components/RadioButton.svelte +11 -5
- package/src/system/components/SectionDivider.svelte +8 -0
- package/src/system/components/SegmentedControl.svelte +6 -0
- package/src/system/components/SideNavigation.svelte +6 -0
- package/src/system/components/Slider.svelte +7 -4
- package/src/system/components/TabBar.svelte +15 -9
- package/src/system/components/Table.svelte +8 -3
- package/src/system/components/Toggle.svelte +4 -4
- package/src/system/components/Tooltip.svelte +6 -0
- package/src/testing-js/chunk-AO7EZHYV.js +776 -0
- package/src/testing-js/chunk-AO7EZHYV.js.map +1 -0
- package/src/testing-js/chunk-FAFOAWYL.js +39 -0
- package/src/testing-js/chunk-FAFOAWYL.js.map +1 -0
- package/src/testing-js/chunk-L73N4NSO.js +23 -0
- package/src/testing-js/chunk-L73N4NSO.js.map +1 -0
- package/src/testing-js/chunk-LXR3MN6N.js +3063 -0
- package/src/testing-js/chunk-LXR3MN6N.js.map +1 -0
- package/src/testing-js/chunk-ZMSX6CXR.js +53 -0
- package/src/testing-js/chunk-ZMSX6CXR.js.map +1 -0
- package/src/testing-js/component-alias.contract.js +81 -0
- package/src/testing-js/component-alias.contract.js.map +1 -0
- package/src/testing-js/component-editor.contract.js +62 -0
- package/src/testing-js/component-editor.contract.js.map +1 -0
- package/src/testing-js/component-render.contract.js +568 -0
- package/src/testing-js/component-render.contract.js.map +1 -0
- package/src/testing-js/index.d.ts +293 -0
- package/src/testing-js/index.js +222 -0
- package/src/testing-js/index.js.map +1 -0
- package/src/testing-js/registry.contract.js +39 -0
- package/src/testing-js/registry.contract.js.map +1 -0
- package/src/testing-js/vitest-BE6uGF31.d.ts +73 -0
- package/src/testing-js/vitest.d.ts +3 -0
- package/src/testing-js/vitest.js +13 -0
- package/src/testing-js/vitest.js.map +1 -0
- package/template/README.md +13 -0
- package/template/_gitignore +6 -0
- package/template/package.json +3 -1
- package/template/src/pages/Home.svelte +4 -18
- package/.claude/skills/live-tokens-build-page/SKILL.md +0 -103
- package/.claude/skills/live-tokens-build-page/references/layout-sources.md +0 -48
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-set-geometry
|
|
3
|
-
description:
|
|
3
|
+
description: Set a live-tokens theme's geometry: corner radius, padding, gap, and border width. Each moves per component along its shipped scale. Called with an anchor and a geometry intent by live-tokens-create-theme, or with the user's request directly. Use when the user asks for pill or capsule buttons. Use when the user asks for rounded, sharp, square, softer, or harder corners. Use when the user asks for thicker or thinner borders. Use when the user asks for density: space it out, tighter, denser, airier. Changes geometry only. For a request that also names color or type, read live-tokens-create-theme.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Setting a theme's geometry
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Write the request as an ops file. The CLI moves each matching alias along its scale, writes the result to each component's buffer, and prints a report. Never hand-edit the data tree.
|
|
9
|
+
|
|
10
|
+
The result is on screen as soon as the run finishes. The three set skills write the same buffer, so color, type, and geometry compose in any order. When the user accepts the result, run `save-theme` to keep it as a theme. Loading a theme in the editor discards it.
|
|
9
11
|
|
|
10
12
|
## Workflow
|
|
11
13
|
|
|
12
|
-
1. Read the geometry intent. When
|
|
13
|
-
2.
|
|
14
|
-
3.
|
|
15
|
-
4.
|
|
16
|
-
5.
|
|
14
|
+
1. Read the geometry intent and the anchor, when live-tokens-create-theme passed one. When the intent or the anchor names a feeling, an idiom, or a genre, read its entry in `references/geometry-anchors.md`.
|
|
15
|
+
2. Write the ops file to `scratch/geometry-ops.json`.
|
|
16
|
+
3. Run `npx live-tokens set-geometry scratch/geometry-ops.json`. It writes `component-configs/<id>/_working.json` for every component the ops change.
|
|
17
|
+
4. Read the report. It lists every changed alias, old and new, and every skip with its reason.
|
|
18
|
+
5. When the CLI exits 1, fix the op or the input the message names, then re-run.
|
|
19
|
+
6. Reply with every alias that moved and any skip worth naming.
|
|
20
|
+
|
|
21
|
+
`--dry-run` prints the report without writing.
|
|
17
22
|
|
|
18
|
-
Each run reads the
|
|
23
|
+
Each run reads the live config, so "a bit more" and "back one" compound. The live config is the buffer, else the open theme. With no theme loaded, the open theme is the shipped default.
|
|
19
24
|
|
|
20
25
|
## The ops file
|
|
21
26
|
|
|
@@ -31,39 +36,55 @@ Targeted, absolute:
|
|
|
31
36
|
{ "ops": [{ "target": "button", "kind": "radius", "set": "--radius-full" }] }
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
- `
|
|
35
|
-
- `
|
|
36
|
-
- `kind
|
|
37
|
-
- `
|
|
38
|
-
- `full` (radius shifts only): admits `--radius-full` as the ladder's top rung. `set` plus `full` is an error, so a pill request is `set: "--radius-full"` with no `full` flag.
|
|
39
|
+
- `target` (optional): a component id, one of the folder names under `src/live-tokens/data/component-configs/`. "Windows" or "modals" is `dialog`, "cards" is `card`, "tabs" is `tabbar`. "The UI", "everything", or no noun means global, so omit `target`.
|
|
40
|
+
- `kind`: `radius | padding | gap | border-width | divider-width | accent-width`. `border-width` moves `-border-width` aliases. `divider-width` moves dividers, hairline rules, and `-thickness` aliases. `accent-width` moves accent bars and indicators.
|
|
41
|
+
- `set` or `shift`, one of the two. `set` takes a token on that kind's scale. `shift` is a whole number of steps and stops at the ends of the scale.
|
|
42
|
+
- `full` (radius shifts only): admits `--radius-full` as the top of the scale. A pill request is `set: "--radius-full"` with no `full` flag.
|
|
39
43
|
|
|
40
44
|
## Idioms
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
The table covers an intent that names no anchor. An anchor's entry in `references/geometry-anchors.md` overrides the table.
|
|
43
47
|
|
|
44
48
|
| The intent says | Ops |
|
|
45
49
|
|---|---|
|
|
46
|
-
| pill, capsule | radius `set: "--radius-full"`, plus the padding the pill needs (see
|
|
50
|
+
| pill, capsule | radius `set: "--radius-full"`, plus the padding the pill needs (see Compact containers before controls) |
|
|
47
51
|
| sharp, square corners | radius `set: "--radius-none"`, or `--radius-sm` for "mostly sharp" |
|
|
48
52
|
| rounded (a named component) | radius `shift: 2` |
|
|
49
53
|
| softer, rounder (global) | radius `shift: 1` to `2`, no `full` |
|
|
50
54
|
| harder, sharper | radius `shift: -1` to `-2` |
|
|
51
|
-
| increase the radius, less round, more round | radius `shift: 1` or `-1` with `"full": true
|
|
55
|
+
| increase the radius, less round, more round | radius `shift: 1` or `-1` with `"full": true` |
|
|
52
56
|
| space it out, airier, breathing room | padding and gap `shift: 1` |
|
|
53
57
|
| tighter, denser, more compact | padding and gap `shift: -1` |
|
|
54
58
|
| thicker, thinner borders | border-width `shift: 1` or `-1` |
|
|
55
59
|
|
|
56
|
-
A
|
|
60
|
+
A theme intent names a direction.
|
|
61
|
+
|
|
62
|
+
| The direction is | Geometry |
|
|
63
|
+
|---|---|
|
|
64
|
+
| playful, friendly, soft | rounder and a step airier. Warm adds pill buttons. |
|
|
65
|
+
| luxurious, elegant, editorial | sharper corners, airier padding, thin borders |
|
|
66
|
+
| technical, dense, systematic | tighter spacing, a small radius, square corners on containers |
|
|
67
|
+
| calm, minimal | unchanged |
|
|
57
68
|
|
|
58
|
-
Magnitude
|
|
69
|
+
Magnitude follows the qualifier. "Slightly" or "a bit" is 1 step. No qualifier is 1 to 2 steps. "Much", "way", or "really" is 2 to 3 steps. A mood word often means both axes: "softer" is rounder plus airier, "compact" is tighter padding plus smaller gaps.
|
|
59
70
|
|
|
60
|
-
##
|
|
71
|
+
## Compact containers before controls
|
|
61
72
|
|
|
62
|
-
A global op spends the same number of steps everywhere, but a step costs a control
|
|
73
|
+
A global op spends the same number of steps everywhere, but a step costs a control more than a container. `padding shift: -2` takes a card from a 16px inset to 10px and it is still a card. The same op takes a button from 8px to its 6px floor, 12px at each end around an 18px line, and the floor stops it there. Below the floor the button stops reading as a button.
|
|
63
74
|
|
|
64
|
-
So a global compaction is `shift: -1`. When the request wants more, spend the extra steps on the containers by name
|
|
75
|
+
So a global compaction is `shift: -1`. When the request wants more, spend the extra steps on the containers by name and leave the controls alone. The containers are:
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
- `card`
|
|
78
|
+
- `dialog`
|
|
79
|
+
- `panel`
|
|
80
|
+
- `collapsiblesection`
|
|
81
|
+
- `sidenavigation`
|
|
82
|
+
- `table`
|
|
83
|
+
- `codesnippet`
|
|
84
|
+
|
|
85
|
+
Airier is safe globally, because nothing breaks by growing.
|
|
86
|
+
|
|
87
|
+
A pill needs the most room. `--radius-full` bends the corner in over the first and last glyph, so a capsule wants more horizontal inset than a square-cornered control. `--space-8` is the floor for a large-text pill. Compact Midnight Study sits there. The roomier pill presets, Ocean, Sunset, and Royal Velvet, run `--space-10` to `--space-12`. Pair the radius op with a padding `set` on the same target. In the ops list, place the padding `set` after any global padding shift. The later op wins:
|
|
67
88
|
|
|
68
89
|
```json
|
|
69
90
|
{ "ops": [
|
|
@@ -73,26 +94,28 @@ A pill needs the room most. `--radius-full` bends the corner in over the first a
|
|
|
73
94
|
] }
|
|
74
95
|
```
|
|
75
96
|
|
|
76
|
-
##
|
|
97
|
+
## Scales
|
|
98
|
+
|
|
99
|
+
Radius runs `none, sm, md, lg, xl, 2xl, 3xl, 4xl`, with `full` as the gated ninth step. Space (padding and gap) is the editor picker's subset, `0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 48`, so the editor can select every value the CLI writes. Border width is the `--border-width-*` scale from `1` to `24`. A shift never reaches `--border-width-0`, and an alias at 0 is skipped. "No borders" is `set: "--border-width-0"`.
|
|
77
100
|
|
|
78
|
-
|
|
101
|
+
An alias off the subset spends its first step reaching the subset, so `--space-2` with `shift: 1` lands on `--space-4`.
|
|
79
102
|
|
|
80
|
-
|
|
103
|
+
## Floors
|
|
81
104
|
|
|
82
|
-
|
|
105
|
+
Content insets stop at `--space-4`. Below `--space-4` the text sits against its own edge, so `--space-0` and `--space-2` are values a person picks on purpose, through the editor picker or `set`. An alias below the floor still moves up. A shift that would push one under `--space-4` lands on `--space-4`. An alias already at `--space-4` is skipped, and the report says so.
|
|
83
106
|
|
|
84
|
-
|
|
107
|
+
Padding around a line of type stops at `--space-6`. A variant that declares a `-text-font-size` holds text. A component that holds text doubles its padding horizontally, so `--space-4` there is 4px over an 18px line and 8px at each end. No shipped default puts text below `--space-6`.
|
|
85
108
|
|
|
86
|
-
|
|
109
|
+
The floor guards `-padding` only. A 2px gap between an icon and its label, or a 2px margin under a bar, is ordinary design. `-margin` belongs to the `padding` kind, so a padding op moves margins too, without the floor.
|
|
87
110
|
|
|
88
111
|
## Scope
|
|
89
112
|
|
|
90
|
-
|
|
113
|
+
Geometry only. Color, type, saved themes, and `tokens.css` are untouched: `set-geometry` writes existing tokens into each component's buffer and creates no new ones. `save-theme` keeps the result; Adopt ships it.
|
|
91
114
|
|
|
92
115
|
## Verify
|
|
93
116
|
|
|
94
|
-
- The CLI exits 0 and the report
|
|
95
|
-
- The app
|
|
96
|
-
- Buttons still read as buttons: the label has room at both ends, and a pill has more
|
|
97
|
-
- `component-configs/<id>/_working.json` exists for every component the report listed.
|
|
98
|
-
- To revert, run the inverse ops, or load
|
|
117
|
+
- The CLI exits 0 and the report lists the expected changes, with no unexpected skips.
|
|
118
|
+
- The app shows the new shape on each changed component.
|
|
119
|
+
- Buttons still read as buttons: the label has room at both ends, and a pill has more than a square-cornered control. A control whose padding sits at `--space-6` is on its floor. A control that also carries `--radius-full` needs a targeted lift.
|
|
120
|
+
- `component-configs/<id>/_working.json` exists for every component the report listed.
|
|
121
|
+
- To revert, run the inverse ops, or load the open theme to discard the buffer.
|
|
@@ -4,9 +4,11 @@ Read this when the geometry intent names one of these. An anchor overrides the
|
|
|
4
4
|
Idioms table in SKILL.md, because it is tuned to the same direction the color
|
|
5
5
|
came from, and a style's geometry is often targeted rather than global.
|
|
6
6
|
|
|
7
|
-
Entries are written in the ops vocabulary
|
|
8
|
-
"borders +1" a border-width shift of 1
|
|
9
|
-
1.
|
|
7
|
+
Entries are written in the ops vocabulary. "radius +2" is a radius shift of 2.
|
|
8
|
+
"borders +1" is a border-width shift of 1. "padding +1" is a padding and gap
|
|
9
|
+
shift of 1. "hairline borders" is border-width `set: "--border-width-1"`, and
|
|
10
|
+
"no borders" is `set: "--border-width-0"`. "hairline rules" is divider-width
|
|
11
|
+
`set: "--border-width-1"`. A named component means a targeted op. Controls squeeze before containers,
|
|
10
12
|
so a compaction of more than one step still spends its extra steps on
|
|
11
13
|
containers by name.
|
|
12
14
|
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-set-type
|
|
3
|
-
description:
|
|
3
|
+
description: Set a live-tokens theme's type: a Google Fonts pairing for the shipped --font-* stacks. The CLI verifies each family for the weights it ships. Called with an anchor and a type intent by live-tokens-create-theme, or with the user's request directly. Use when the user asks to pair fonts, pick a typeface, or set the fonts. Use when the user describes type by voice: editorial, friendlier, technical, elegant, less generic. Use when the user names a face for a role: a serif for headings, a display font. Changes type only. For a request that also names color or geometry, read live-tokens-create-theme.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Setting a theme's
|
|
6
|
+
# Setting a theme's type
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Choose the families. The CLI verifies each against Google Fonts, builds the URL from the weights the family has, and writes the result to the buffer. Never hand-author font JSON or edit the data tree. Google Fonts is the pool because it is freely licensable and loads by URL. Other sources go in through the editor's Project fonts section.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The result is on screen as soon as the run finishes. The three set skills write the same buffer, so color, type, and geometry compose in any order. When the user accepts the result, run `save-theme` to keep it as a theme. Loading a theme in the editor discards it.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
2. Run `npx live-tokens set-type scratch/font-pairing.json`. It prints each stack that moved, each family's real weights and URL, and the weights your typography tokens ask for that the family lacks.
|
|
14
|
-
3. Read the report. A weight gap is a quality note: name it and offer an alternative only if it matters (a body face without 400, 700, or italic matters; a display face without 300 does not). A family not on Google Fonts fails the run; fix the spelling and re-run.
|
|
15
|
-
4. Report back in a line: the two families, the form model behind each, and any weight gap worth naming.
|
|
16
|
-
5. Tell the user to reload the editor page before saving. A running editor holds its own copy of the buffer this CLI just wrote and never re-reads it, so a Save without a reload writes the stale copy back and the pairing vanishes with a success report still on screen. After the reload the type is on the page, and unsaved until they save the open theme.
|
|
12
|
+
## Workflow
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
1. Read the type intent and any anchor live-tokens-create-theme passed. When either names an anchor (a feeling, an idiom, or a genre), read its entry in `references/type-anchors.md`; it overrides the Voice table below.
|
|
15
|
+
2. Choose the pairing and write it to `scratch/font-pairing.json`.
|
|
16
|
+
3. Run `npx live-tokens set-type scratch/font-pairing.json`. It prints each stack that moved, each family's weights and URL, and, under Weight coverage, the weights the typography tokens ask for that the family lacks.
|
|
17
|
+
4. Read the report. Name a missing weight and offer an alternative only when it matters: a body face without 400, 700, or italic matters, and a display face without 300 does not. A family not on Google Fonts fails the run. Fix the spelling and re-run. A pairing the stacks already hold prints "Nothing to change" and writes nothing. A pairing equal to the open theme's discards the buffer, and the report says so.
|
|
18
|
+
5. Reply with the two families, the form model behind each, the matrix verdict, and any missing weight worth naming.
|
|
19
19
|
|
|
20
|
-
Flags: `--dry-run` reports without writing. `--no-verify` skips the network and requires
|
|
20
|
+
Flags: `--dry-run` reports without writing. `--no-verify` skips the network and requires a URL per family; use it only offline.
|
|
21
21
|
|
|
22
22
|
## The pairing file
|
|
23
23
|
|
|
@@ -25,17 +25,17 @@ Flags: `--dry-run` reports without writing. `--no-verify` skips the network and
|
|
|
25
25
|
{ "display": "Fraunces", "body": "Nunito Sans" }
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Every slot is optional
|
|
28
|
+
Every slot is optional; an omitted slot keeps its family. `display` is `--font-display` and `body` is `--font-sans`. `serif`, `mono`, and `editorial` exist when a theme needs them. `editorial` is `--font-editorial`, the long-reading face behind the `--editorial-*` text styles. An omitted `editorial` keeps its family, so set it only when essays and articles need a face of their own. Weight coverage is reported for `display`, `body`, `serif`, and `mono`. A family bound to `editorial` gets no coverage line. A slot may be `{ "name": "...", "url": "..." }` to pin a URL. A pinned URL is not probed, so the report shows no weights for it and coverage skips it. Spell families as Google does; the CLI reports the canonical spelling.
|
|
29
29
|
|
|
30
30
|
## Choose the body face first
|
|
31
31
|
|
|
32
|
-
The body face is the anchor. It carries most of the words, and text faces survive small sizes where display faces do not. Pick it against the type intent, then pick the display face against it. A body face
|
|
32
|
+
The body face is the anchor. It carries most of the words, and text faces survive small sizes where display faces do not. Pick it against the type intent, then pick the display face against it. A body face has regular, bold, and italic; low to moderate stroke contrast; open apertures; and a large x-height. A face missing any of these is a display face, whatever its name says.
|
|
33
33
|
|
|
34
|
-
The shipped text styles ask the display face for 600
|
|
34
|
+
The shipped text styles ask the display face for 600 and the body face for 400; `strong` and `em` add 700 and italic. Screen candidates against those four weights before running.
|
|
35
35
|
|
|
36
|
-
## The font matrix
|
|
36
|
+
## The font matrix
|
|
37
37
|
|
|
38
|
-
Classify each candidate
|
|
38
|
+
Classify each candidate by form model and by stroke contrast and serifs.
|
|
39
39
|
|
|
40
40
|
| Form model | Construction | Reads as |
|
|
41
41
|
|---|---|---|
|
|
@@ -43,11 +43,11 @@ Classify each candidate on two layers. The **skeleton** is its form model; the *
|
|
|
43
43
|
| **Rational** | vertical stress, closed apertures, drawn not written | orderly, reserved, elegant, authoritative |
|
|
44
44
|
| **Geometric** | monolinear, circle-and-line | technical, modern, systematic, sober |
|
|
45
45
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
46
|
+
- One form model with different stroke contrast or serifs pairs reliably. Helvetica and Bodoni are both rational, one a linear sans and one a high-contrast serif.
|
|
47
|
+
- Different form models with the same stroke contrast and serifs fail. The two look alike and fight underneath. Two arbitrary sans serifs clash for this reason.
|
|
48
|
+
- Different on both counts works. An unmistakable difference reads as a decision.
|
|
49
49
|
|
|
50
|
-
Many faces sit between columns. When one straddles, say so and lean on the
|
|
50
|
+
Many faces sit between columns. When one straddles, say so and lean on the Voice table and the x-height check.
|
|
51
51
|
|
|
52
52
|
## Voice
|
|
53
53
|
|
|
@@ -61,33 +61,33 @@ Many faces sit between columns. When one straddles, say so and lean on the voice
|
|
|
61
61
|
| serious, institutional, trustworthy | rational sans body, rational serif display |
|
|
62
62
|
| quiet, minimal, unbranded | one superfamily across both slots |
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
The table covers an intent that names no anchor. An anchor's row in `references/type-anchors.md` wins.
|
|
65
65
|
|
|
66
|
-
Match the type to the
|
|
66
|
+
Match the type to the design direction the color came from. A warm autumn palette under a cold geometric sans reads as two projects.
|
|
67
67
|
|
|
68
68
|
## Shortcuts
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Use these when the request is vague or the type should stay quiet.
|
|
71
71
|
|
|
72
|
-
- **A superfamily.** Google Fonts
|
|
72
|
+
- **A superfamily.** A Google Fonts family with sans and serif siblings: Alegreya, Ancizar, IBM Plex, Inria, Merriweather, Noto, PT, Roboto, Source. The catalogue moves and this list does not; `set-type` fails on a family that is gone.
|
|
73
73
|
- **One family across weights.**
|
|
74
74
|
- **Same designer or foundry.**
|
|
75
75
|
- **Serif display over sans body** when nothing else decides it.
|
|
76
76
|
|
|
77
77
|
## Watch for
|
|
78
78
|
|
|
79
|
-
- **x-height parity.** Both faces
|
|
79
|
+
- **x-height parity.** Both faces share one size scale, so a small-x-height display face over a large-x-height body face gives a heading weaker than its own body text. Check it on the rendered page.
|
|
80
80
|
- **Print faces at small sizes.** Delicate serifs and high stroke contrast turn to mud below 16px.
|
|
81
81
|
- **Every family is a download.** Two is the target; three needs a reason.
|
|
82
|
-
- **Sets of themes
|
|
82
|
+
- **Sets of themes.** No two share a display face or a body face.
|
|
83
83
|
|
|
84
84
|
## Scope
|
|
85
85
|
|
|
86
|
-
Type only. Color, component aliases, shape, and the type scale are untouched: `set-type`
|
|
86
|
+
Type only. Color, component aliases, shape, and the type scale are untouched: `set-type` writes the font entries in the buffer and carries every other value forward. `save-theme` keeps the result; Adopt ships it and rewrites `fonts.css`, which is how a build without the editor loads the family.
|
|
87
87
|
|
|
88
88
|
## Verify
|
|
89
89
|
|
|
90
90
|
- The CLI exits 0 and names each stack that moved, before and after.
|
|
91
|
-
- Each URL
|
|
92
|
-
- The app shows the new type
|
|
93
|
-
- To revert, run the
|
|
91
|
+
- Each URL matches the family's weights: a range for a variable family, an enumeration for a static one, a bare URL for a single-weight face. A pinned URL is written as given.
|
|
92
|
+
- The app shows the new type, and the editor's Fonts section lists both families with their fallbacks.
|
|
93
|
+
- To revert, run the previous pairing file, or load the open theme to discard the buffer.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,143 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.76.0 — The skills directory matches the release
|
|
4
|
+
|
|
5
|
+
### Changed (breaking)
|
|
6
|
+
|
|
7
|
+
- **`setup-claude --force` now makes `.claude/skills/` match the release.** It
|
|
8
|
+
replaced each bundled skill by merging over it, which left two kinds of stale
|
|
9
|
+
text behind: a skill a release renamed kept its old directory, where it
|
|
10
|
+
shadowed the replacement, and a reference file a release dropped survived
|
|
11
|
+
inside a skill that was otherwise current. Both are invisible until a model
|
|
12
|
+
reads them. A forced run now replaces each bundled directory outright and
|
|
13
|
+
removes any `live-tokens-` skill the release no longer ships, naming each one
|
|
14
|
+
it removed. A skill under any other name is the project's own and is never
|
|
15
|
+
touched, and an unforced run still deletes nothing. 0.75.0's rename of
|
|
16
|
+
`live-tokens-build-page` to `live-tokens-create-page` is the case that
|
|
17
|
+
prompted this; the changelog then told a reader to delete the directory by
|
|
18
|
+
hand.
|
|
19
|
+
|
|
20
|
+
Before a forced run, copy any bundled skill you edited in place to a name of
|
|
21
|
+
your own. A `live-tokens-` directory this release does not ship is deleted
|
|
22
|
+
without a prompt, and one it does ship is replaced rather than merged.
|
|
23
|
+
|
|
24
|
+
`setup-claude` moves out of `bin/cli.mjs` into `bin/setup-claude.mjs` as
|
|
25
|
+
`runSetupClaude` and `formatSetupResult`, matching `create.mjs`, and gains
|
|
26
|
+
`bin/setup-claude.test.ts`.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **The `create` template installs the skills from `postinstall` and gitignores
|
|
31
|
+
them.** A scaffolded project no longer commits nine skill directories the
|
|
32
|
+
package owns, so a version bump stops showing twenty changed files that
|
|
33
|
+
nobody wrote. The skills instead refresh on every `npm install`. The
|
|
34
|
+
postinstall ends in `|| exit 0`: `setup-claude` refuses to run on Windows,
|
|
35
|
+
and a skills copy must never fail an install. A project created before this
|
|
36
|
+
release adds the two lines itself; the README carries them.
|
|
37
|
+
|
|
38
|
+
## 0.75.0 — A component passes when the tests pass
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **`check-component` gains `--tests`.** Beyond the static lint, it runs the
|
|
43
|
+
registry contract under vitest and the component contract suites under
|
|
44
|
+
Playwright, for one component or every authored one, and reports coverage
|
|
45
|
+
by rule: listed, persisted and reset, themed, previewed, and drawn in
|
|
46
|
+
Sketch mode. `@playwright/test`, `vitest`, and `happy-dom` are new optional
|
|
47
|
+
peer dependencies; a missing one is a `tests-not-installed` finding naming
|
|
48
|
+
the install command. The suites ship at
|
|
49
|
+
`@motion-proto/live-tokens/testing` and `/testing/vitest`, and run here
|
|
50
|
+
against the library's own demo app and in a consumer against the
|
|
51
|
+
consumer's own app.
|
|
52
|
+
|
|
53
|
+
**live-tokens-create-component now runs `--tests` as its Verification
|
|
54
|
+
step**, in place of the manual pass through `/live-tokens/components`.
|
|
55
|
+
Every line that step asked a reader to confirm by eye is now a contract
|
|
56
|
+
assertion: the component's listing, its controls and preview, persistence
|
|
57
|
+
and reset, theme projection, linked properties, and Sketch mode.
|
|
58
|
+
live-tokens-fix-findings maps the new rule ids to the create-component
|
|
59
|
+
section that fixes each one, and the `create` template's new
|
|
60
|
+
`test:design` script runs the checks once the three peers are installed.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **Breaking: `tokens --scale` replaces `tokens --family`, and there is no
|
|
65
|
+
alias.** A token scale is the progression of one token across its range,
|
|
66
|
+
such as `space` or `radius`, and it is the one term for that grouping in the
|
|
67
|
+
CLI, the skills, and the skill atlas. "Family" now means a typeface only.
|
|
68
|
+
The `--json` output names the grouping `scales`, each with a `scale` and its
|
|
69
|
+
`tokens`. `bin/cliStrings.test.ts` bans "token family" and `--family`.
|
|
70
|
+
- **Dividers and accents name their stroke role.** Three stroke roles share
|
|
71
|
+
the `--border-width-*` scale: a border encloses, a divider separates, an
|
|
72
|
+
accent emphasises. `set-geometry` moves each role on its own and reads the
|
|
73
|
+
role off the suffix, so a divider named `-border` moved with the borders.
|
|
74
|
+
TabBar's indicator is `--tabbar-<state>-indicator-width`, CollapsibleSection's
|
|
75
|
+
divider is `--collapsiblesection-divider-<state>-hairline-color` and
|
|
76
|
+
`-hairline-thickness`, Dialog's header and footer rules are
|
|
77
|
+
`--dialog-<part>-divider` and `-divider-width`, and Table's header rule is
|
|
78
|
+
`--table-default-header-divider` and `-divider-width`. Component migration 27
|
|
79
|
+
renames the keys in a saved theme; values are unchanged.
|
|
80
|
+
- **CLI output uses the skills' vocabulary.** Every verb's help and report
|
|
81
|
+
lines say "the buffer" for edits a theme file does not hold yet, "load" for
|
|
82
|
+
making a theme the open one, "design token" and "semantic property" for the
|
|
83
|
+
two token classes, "shipped default", and "scale" and "step". The three set
|
|
84
|
+
verbs close with "The buffer holds this edit. Run save-theme to keep it as a
|
|
85
|
+
theme." Report lines print "old to new" in place of an arrow, and
|
|
86
|
+
`set-geometry` labels a skip "raw value", "off the scale", or "at the end of
|
|
87
|
+
the scale". `bin/cliStrings.test.ts` holds the line. The skills are corrected
|
|
88
|
+
where they described the CLI wrongly; the audit is
|
|
89
|
+
`docs/plans/cli-skill-alignment.md`.
|
|
90
|
+
- **`live-tokens-build-page` is renamed `live-tokens-create-page`.** The verb
|
|
91
|
+
now matches `create-theme` and `create-component`. A project that copied the
|
|
92
|
+
skill keeps the old directory until it deletes it.
|
|
93
|
+
- **The `create` template matches the skill.** `Home.svelte` drops the `h1`
|
|
94
|
+
and `p` rules `site.css` already types, the `0.9em` code size, and a `1.6`
|
|
95
|
+
line-height; its two Buttons take `--space-8`. `site.css` sets all five
|
|
96
|
+
axes from one text style on `p`, list items, `code`, and `pre`, and `ol li`
|
|
97
|
+
reads `--body-md-line-height` in place of `1.6`. A project created before
|
|
98
|
+
this release keeps its copied `site.css`.
|
|
99
|
+
|
|
100
|
+
- **A page's type comes from a text style, and the checker fails a page that
|
|
101
|
+
names a raw axis.** `raw-text-axis` is an error, and it now reads a `var()`
|
|
102
|
+
as well as a literal. A `--font-size-*`, `--line-height-*`,
|
|
103
|
+
`--letter-spacing-*`, or a family stack such as `--font-sans` on a text
|
|
104
|
+
property is a finding. A text style token such as `--body-md-font-size` is
|
|
105
|
+
not. A `--font-weight-*` alone is not either, because a weight cannot move
|
|
106
|
+
the scale or the fonts. Two warnings join it. `control-size` reports a
|
|
107
|
+
`size` prop on a shipped component in a page file. `multiple-primary`
|
|
108
|
+
reports a second `variant="primary"` Button in one page file. A project
|
|
109
|
+
retunes a component's default size once, in the components editor. The
|
|
110
|
+
package's own pages, the template, and the `create` starter are all clean
|
|
111
|
+
under `--strict`. The starter's bulleted lists now take the `--body-md-*`
|
|
112
|
+
bundle.
|
|
113
|
+
|
|
114
|
+
**Every shipped component carries a usage comment.** `npx live-tokens
|
|
115
|
+
components` prints it as the description. `report` checks the shipped
|
|
116
|
+
set as it checks a custom component. The comment
|
|
117
|
+
names what the component is, what it is for, and what to reach for instead.
|
|
118
|
+
It never mentions size.
|
|
119
|
+
|
|
120
|
+
- **Callout owns its box; the page owns the space around it.** `.callout` no
|
|
121
|
+
longer sets `margin: var(--space-24) 0`. A stack of callouts now takes its
|
|
122
|
+
spacing from the page's own gap, and a page that wants the old rhythm sets
|
|
123
|
+
`margin-block` on the container. The four `--callout-*-accent-width` defaults
|
|
124
|
+
point at `--border-width-1`, so the left edge matches the other three sides,
|
|
125
|
+
and the default theme follows. The token stays, so a theme can set the thick
|
|
126
|
+
left rule back, and the seven other presets keep the accents they were
|
|
127
|
+
authored with.
|
|
128
|
+
|
|
129
|
+
- **A CLI run shows up in the open editor, and a Save afterwards keeps it.**
|
|
130
|
+
The dev server now watches the unsaved buffers and the active-theme pointer
|
|
131
|
+
and streams every outside change to the page as one frame over
|
|
132
|
+
`GET /api/live-tokens/events`. The editor hydrates from that frame the way
|
|
133
|
+
it does from an Apply, so `set-colors`, `set-type`, `set-geometry`, and
|
|
134
|
+
`save-theme` land on screen as they finish, and a Save afterwards writes
|
|
135
|
+
what is on screen rather than the tab's stale copy. The four verbs no longer
|
|
136
|
+
ask for a reload, and neither do the skills that run them. The server leaves
|
|
137
|
+
its own writes out of the stream, so an editor Save does not hydrate itself.
|
|
138
|
+
A branch switch that moves a buffer or the pointer reaches the page the same
|
|
139
|
+
way; any other JSON changed from outside still needs a reload.
|
|
140
|
+
|
|
3
141
|
## 0.74.0 — A theme is three decisions and one document
|
|
4
142
|
|
|
5
143
|
### Changed
|
package/README.md
CHANGED
|
@@ -322,12 +322,12 @@ npx @motion-proto/live-tokens <command>
|
|
|
322
322
|
| Command | What it does |
|
|
323
323
|
|---|---|
|
|
324
324
|
| `create <dir> [--force]` | Scaffold a new Svelte + Vite app wired up with live-tokens. |
|
|
325
|
-
| `setup-claude [--force]` | Install the bundled Claude Code skills into `./.claude/skills
|
|
325
|
+
| `setup-claude [--force]` | Install the bundled Claude Code skills into `./.claude/skills/`; `--force` makes the directory match this release. |
|
|
326
326
|
| `components [id] [--json]` | List every component the project has, shipped and its own, with the props each takes; with an id, its props, variants, tokens, and defaults. |
|
|
327
|
-
| `tokens [--
|
|
327
|
+
| `tokens [--scale <name>] [--json]` | List every design token the project's `tokens.css` declares, by scale, with its value. |
|
|
328
328
|
| `report [--json]` | The project as facts: pending migrations, tokens each component reads, which page renders which component, and both checkers' findings by rule. Always exits 0. |
|
|
329
329
|
| `check-component [id]` | Validate a component's runtime, editor, and registration against the authoring contract; with no id, every component authored under `src/system/components`. |
|
|
330
|
-
| `check-page [paths...]` | Validate pages against the
|
|
330
|
+
| `check-page [paths...]` | Validate pages against the create-page contract: catalogue components and their props, theme tokens over literals, route wiring. |
|
|
331
331
|
| `set-colors <base-colors.json> [--dry-run]` | Build the theme's whole color identity from 10 OKLCH base colors, enforce AA contrast on the derived text tokens, and write the result to the unsaved colors-and-type buffer. |
|
|
332
332
|
| `set-type <pairing.json> [--dry-run] [--no-verify]` | Bind Google Fonts families to the theme's font stacks, verified against the API. |
|
|
333
333
|
| `set-geometry <ops.json> [--dry-run]` | Move radius, padding, gap, and border-width aliases along their token scales. |
|
|
@@ -346,10 +346,20 @@ The package bundles nine Claude Code skills. They encode the conventions this RE
|
|
|
346
346
|
npx @motion-proto/live-tokens setup-claude
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
This copies every bundled skill into `./.claude/skills/` in the current directory
|
|
349
|
+
This copies every bundled skill into `./.claude/skills/` in the current directory, leaving any that already exist. macOS and Linux only.
|
|
350
350
|
|
|
351
|
-
|
|
352
|
-
|
|
351
|
+
Re-run it with `--force` after upgrading. That makes the directory match the release: each bundled skill is replaced outright, so a reference file the release dropped goes with it, and a `live-tokens-` skill the release no longer ships is removed. A skill under any other name is the project's own and is never touched. Without `--force` nothing is deleted and an existing skill is left alone, so a renamed skill keeps shadowing its replacement until a forced run clears it.
|
|
352
|
+
|
|
353
|
+
A project created with `create` runs the forced form from `postinstall` and gitignores the copy, so the skills track the installed version with nothing to commit. To do the same in an existing project:
|
|
354
|
+
|
|
355
|
+
```jsonc
|
|
356
|
+
// package.json
|
|
357
|
+
"postinstall": "live-tokens setup-claude --force || exit 0"
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
# .gitignore
|
|
362
|
+
.claude/skills/live-tokens-*/
|
|
353
363
|
```
|
|
354
364
|
|
|
355
365
|
### `live-tokens-pick-component`
|
|
@@ -358,7 +368,7 @@ Ask "TabBar or SegmentedControl?", "how do I let someone pick one of four option
|
|
|
358
368
|
|
|
359
369
|
The skill holds the catalogue grouped by job (action, input, selection, containers, messaging, display) and a decision table for each confusable family: `SegmentedControl` vs `TabBar` vs `RadioButton` vs `MenuSelect`, `Card` vs `CollapsibleSection` vs `Dialog`, `Callout` vs `Notification` vs `Tooltip` vs `Badge`, `Button` vs `IconButton`, and the on/off case. It answers the question and writes nothing. Read it before authoring anything new.
|
|
360
370
|
|
|
361
|
-
### `live-tokens-
|
|
371
|
+
### `live-tokens-create-page`
|
|
362
372
|
|
|
363
373
|
Ask for a page, a route, or a screen: "build a pricing page", "add a /settings route", "put a hero at the top of Home".
|
|
364
374
|
|