@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
|
@@ -7,7 +7,7 @@ the direction the three intents come from.
|
|
|
7
7
|
The mechanics live with the executors. Color anchors are in
|
|
8
8
|
live-tokens-set-colors, type anchors in live-tokens-set-type, geometry anchors
|
|
9
9
|
in live-tokens-set-geometry, each keyed on the same names as the tables below.
|
|
10
|
-
Name the anchor
|
|
10
|
+
Name the anchor in the intent, and the sibling reads its own column.
|
|
11
11
|
|
|
12
12
|
Three axes place any request, including one no entry lists:
|
|
13
13
|
|
|
@@ -1,89 +1,98 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-fix-findings
|
|
3
|
-
description:
|
|
3
|
+
description: Fix every finding of check-page and check-component in an existing @motion-proto/live-tokens project until both exit 0. Called with the fix list by live-tokens-check-compliance. Use when the user asks to fix the project. Edits the files the checkers name. Updates tokens.css only through the migration command.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Fixing the
|
|
6
|
+
# Fixing the findings of check-page and check-component
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
This skill is the loop for code that already exists. When the user has not seen the state of the project yet, **live-tokens-check-compliance** presents `npx live-tokens report` without editing; this skill edits.
|
|
8
|
+
Fix every finding of `check-page` and `check-component` until both exit 0. `check-page` checks pages. Every component comes from the catalogue, every prop is declared, and every value in page CSS is a design token. `check-component` checks authored components. Every token names a semantic property, and its default is the design token that property reads. Update `tokens.css` only through the migration command. That command also heals the data tree, and with `--write` rewrites the route references it lists. When live-tokens-check-compliance hands over a fix list, the user's choices in it stand.
|
|
11
9
|
|
|
12
10
|
## Workflow
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
When `check-page` is an unknown command, upgrade `@motion-proto/live-tokens` first.
|
|
13
|
+
|
|
14
|
+
1. Run `npx live-tokens migrate --check` to see the plan, then `npx live-tokens migrate` to apply it. `--tokens <path>` names a tokens.css in an unusual place.
|
|
15
|
+
2. Run both checkers with `--json`. Each finding carries a `rule`, a file, and a line.
|
|
15
16
|
```sh
|
|
16
|
-
npx live-tokens check-page --json
|
|
17
|
-
npx live-tokens check-component --json
|
|
17
|
+
npx live-tokens check-page --json
|
|
18
|
+
npx live-tokens check-component --json
|
|
18
19
|
```
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
3. Group the findings by rule.
|
|
21
|
+
4. Take the largest error group first, then the remaining errors. Take warnings only when the repair scope includes warnings.
|
|
22
|
+
5. Fix every finding in the group with its section: Color by role, Geometry by scale, or The remaining rules.
|
|
23
|
+
6. Run both checkers again. When repairable findings remain in scope, return to step 3. When no token fits a remaining finding, leave it and continue to the reply with its reason.
|
|
24
|
+
7. When the errors are clear, run both checkers with `--strict`. Report what `--strict` adds. Clear warnings within the existing request. Otherwise ask whether to clear the warnings now.
|
|
25
|
+
8. When the repair scope includes warnings, return to step 3 with `--strict`. When strict checks pass or the user defers warnings, continue to the reply.
|
|
26
|
+
9. Reply with:
|
|
27
|
+
- the changes by rule, each with its count and any visible shift
|
|
28
|
+
- the findings left, each with its reason and any config entry the user chose
|
|
29
|
+
- both checker commands with their exit codes
|
|
30
|
+
|
|
31
|
+
`check-page <path>` scopes a run to one page. `check-component <id>` scopes a run to one component: its runtime, its editor, and its registration. The checkers read tokens.css from its default location.
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
When `package.json` has no `check:design` script, add `"check:design": "live-tokens check-page && live-tokens check-component"`. When both checkers exit 0, prepend `npm run check:design &&` to the existing build command. Preserve its other build steps.
|
|
26
34
|
|
|
27
|
-
##
|
|
35
|
+
## Scope
|
|
28
36
|
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
37
|
+
- Add no token to `tokens.css`. Map a literal with no matching token to the nearest existing token by role. When no token fits, leave the finding and say so.
|
|
38
|
+
- When the user has chosen to lower a rule's severity, record it in `live-tokens.config.json` under `"checks": { "rules": { "<rule>": "warn" } }`. `--off=<rule>` silences a rule for one run only.
|
|
39
|
+
- When the nearest token differs from the literal, use the token and name the shift in the report, such as `14px` to `--space-16`.
|
|
32
40
|
|
|
33
|
-
##
|
|
41
|
+
## Color by role
|
|
34
42
|
|
|
35
|
-
`color-literal` is
|
|
43
|
+
`color-literal` is a judgement finding. The replacement is the token for the role the color plays. The theme moves every role together. `npx live-tokens tokens --scale <name>` prints a scale's names and values, with `--json` for data.
|
|
36
44
|
|
|
37
|
-
|
|
|
45
|
+
| Literal | Token | Notes |
|
|
38
46
|
| --- | --- | --- |
|
|
39
|
-
| Text on a surface | `--text-primary
|
|
40
|
-
| Light text on a dark chip
|
|
41
|
-
| A
|
|
42
|
-
| A stroke | `--border-<family>-<level>` | `faint
|
|
43
|
-
| A translucent layer that dims what is behind it | `--scrim-low`, `--scrim`, `--scrim-high` | Behind a modal
|
|
44
|
-
| A translucent wash on a surface | `--tint-low`, `--tint`, `--tint-high` |
|
|
45
|
-
|
|
|
47
|
+
| Text on a surface | `--text-primary` through `--text-disabled` | The neutral text scale. `--text-<family>` for a family color. |
|
|
48
|
+
| Light text on a dark chip | `--text-inverted` | No AA guarantee. |
|
|
49
|
+
| A surface fill | `--surface-<family>-<level>` | The role names the family: `neutral` for chrome, `brand` for emphasis, `danger` for status. |
|
|
50
|
+
| A stroke | `--border-<family>-<level>` | Levels run `faint` to `strong`. |
|
|
51
|
+
| A translucent layer that dims what is behind it | `--scrim-low`, `--scrim`, `--scrim-high` | Behind a modal. |
|
|
52
|
+
| A translucent wash on a surface | `--tint-low`, `--tint`, `--tint-high` | A hover state. |
|
|
53
|
+
| Any other translucent color | The role's token at an opacity: `color-mix(in srgb, var(--surface-brand) 80%, transparent)` | The editor reads that form. |
|
|
54
|
+
| Fully transparent | `--color-transparent` | |
|
|
46
55
|
| A gradient | `--gradient-*` | Or compose one from surface tokens. |
|
|
47
56
|
|
|
48
|
-
A `var(--x, #fff)` fallback is not a finding. A named colour is: `white` and `rebeccapurple` are literals like any hex.
|
|
49
|
-
|
|
50
57
|
## Geometry by scale
|
|
51
58
|
|
|
52
|
-
`dimension-literal`
|
|
59
|
+
`dimension-literal` is a mechanical finding. A size, such as a hero's height, is layout. Leave it.
|
|
53
60
|
|
|
54
|
-
|
|
|
61
|
+
| Literal | Token | Notes |
|
|
55
62
|
| --- | --- | --- |
|
|
56
|
-
|
|
|
63
|
+
| Spacing | `--space-<px>` | `npx live-tokens tokens --scale space` prints the steps. Round to the nearest step. |
|
|
57
64
|
| A stroke width | `--border-width-1`, `-2`, `-4` | Also for `outline`. |
|
|
58
|
-
| A corner | `--radius-sm` through
|
|
59
|
-
| A shadow | `--shadow-sm` through
|
|
65
|
+
| A corner | `--radius-sm` through `--radius-4xl`, or `--radius-full` | |
|
|
66
|
+
| A shadow | `--shadow-sm` through `--shadow-xl` | Replace the whole value. |
|
|
60
67
|
| Part of a `calc()` | The token inside the calc | `calc(var(--space-64) * -2 + var(--space-8))` |
|
|
68
|
+
| A duration or easing | `--duration-*`, `--ease-*` | No rule reports it. Fix it while in the file. |
|
|
69
|
+
| A `blur()` | `--blur-*` | No rule reports it. Fix it while in the file. |
|
|
61
70
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
## Every other rule
|
|
71
|
+
## The remaining rules
|
|
65
72
|
|
|
66
73
|
| Rule | Fix |
|
|
67
74
|
| --- | --- |
|
|
68
|
-
| `unknown-token` |
|
|
69
|
-
| `raw-text-axis` | Set
|
|
70
|
-
| `unknown-component` |
|
|
71
|
-
| `unknown-prop` |
|
|
72
|
-
| `unknown-prop-value` |
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
75
|
+
| `unknown-token` | Search `tokens.css` for the stem. When a contract-family name is gone, `npx live-tokens migrate --check` lists the migration that adds the current name. |
|
|
76
|
+
| `raw-text-axis` | Set every axis from one text style, `-font-family` through `-letter-spacing`. `npx live-tokens tokens --scale heading` prints one text style. The text styles are `heading`, `body`, `editorial`, and `code`. Rewrite a `font:` shorthand the same way. |
|
|
77
|
+
| `unknown-component` | Read **live-tokens-pick-component** for the shipped component that fits. When none fits, author one with **live-tokens-create-component**. |
|
|
78
|
+
| `unknown-prop` | `npx live-tokens components <id>` prints the declared props and their values. Map the prop to one of them, or delete it. |
|
|
79
|
+
| `unknown-prop-value` | Use a value from the union the message lists. |
|
|
80
|
+
| `control-size` | Delete the `size` prop. The shipped default is the page's size. When that default is wrong for the project, retune the component in `/live-tokens/components`. |
|
|
81
|
+
| `multiple-primary` | Keep the action that completes the main task `primary`. A Button with no `variant` counts as `primary`. Use `secondary` for supporting or related actions and `outline` for unrelated or informational actions. |
|
|
82
|
+
| `danger-without-dialog` | Open a `Dialog` from the danger Button or IconButton and run the action from the Dialog's confirm. The rule fires once per page, when the page imports no Dialog. For other actions, assign emphasis by the action's relationship to the main task. |
|
|
83
|
+
| `hardcoded-columns` | `repeat(var(--columns-count), 1fr)` for the page grid. `calc(var(--columns-count) - 2)` for a sub-grid spanning fewer columns. |
|
|
84
|
+
| `site-css-in-main` | Delete the import from `main.ts`. Add it to each page's `<script>`. Page CSS then stays off the editor routes. |
|
|
85
|
+
| `missing-source` | Add `source: 'src/...'` to the route entry. |
|
|
86
|
+
| `reserved-route` | Move the route out of `/live-tokens/*`. |
|
|
87
|
+
| `deep-import` | Import from `@motion-proto/live-tokens`, `/component-editor`, or `/components/<Name>.svelte`. |
|
|
88
|
+
| `fix: property-name` | Rename the token to the name a shipped component uses for the same role. The vocabulary and the state model are in **live-tokens-create-component**. |
|
|
89
|
+
| `fix: property-token` | Make the `:global(:root)` default read a design token, composed when needed. Declare a structural keyword, such as `start`, in the editor's `intrinsics`. |
|
|
90
|
+
| `fix: runtime` | Wire the component as the recipe in **live-tokens-create-component** wires it. |
|
|
91
|
+
| `fix: runtime-defaults` | Make the `:global(:root)` default the value Reset should restore, per the Runtime component section of **live-tokens-create-component**. |
|
|
92
|
+
| `fix: editor` | The editor names a token the runtime never declares, or a property targets the wrong part. Fix the editor's schema, states, or preview props by the Component editor section of **live-tokens-create-component**. |
|
|
93
|
+
| `fix: registration` | Register the component in the shared module the Registration section of **live-tokens-create-component** wires up, importable by the app and by `check-component --tests`. |
|
|
94
|
+
| `fix: sketch` | Add the missing Sketch part or marker, per the Sketch mode and overlays section of **live-tokens-create-component**. |
|
|
95
|
+
| `fix: tooling` | Install the named package (`@playwright/test`, `vitest`, or `happy-dom`) as a devDependency, then `npx playwright install chromium` for a missing browser. A bad path or config is named in the message; fix it and rerun `check-component <id> --tests`. |
|
|
96
|
+
| `fix: coverage` | A contract obligation never ran to a result. Add the missing contract, or find why the suite skipped it, then rerun. |
|
|
97
|
+
|
|
98
|
+
A `tests-*` finding names a problem with the run itself: the tool, the path, or a missing contract. Fix what the message names and rerun `check-component <id> --tests --json` until every applicable rule passes with no rule left `--off`.
|
|
@@ -1,111 +1,96 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-pick-component
|
|
3
|
-
description: Recommend which shipped @motion-proto/live-tokens component fits a UX need, with decision
|
|
3
|
+
description: Recommend which shipped @motion-proto/live-tokens component fits a UX need, with a decision test for each confusable family. Called by live-tokens-create-page when more than one component could fit, and by live-tokens-create-component before it authors anything. Use when the user asks which component to use, or what the difference between two components is. Use when the user asks how to show or capture a UX outcome. Edits no file. For size, emphasis, or placement, read live-tokens-create-page. When the catalogue lacks a component with chrome, read live-tokens-create-component.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Picking
|
|
6
|
+
# Picking a live-tokens component
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
For composing a page once you've picked components, see **live-tokens-build-page**. For authoring a brand-new component when nothing fits, see **live-tokens-create-component** (but read this skill first to confirm nothing in the catalogue fits).
|
|
8
|
+
When more than one shipped component could fit, find the family below that names the candidates. Apply its test, which asks what the choice means to the reader.
|
|
11
9
|
|
|
12
10
|
## Catalogue
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
Before choosing, run `npx live-tokens components`. The list holds every component the project has, shipped and custom, with each one's variants and usage comment. The family tests below name the shipped set only. Weigh a custom component by the same tests.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
and those never appear in this file: run `npx live-tokens components` before
|
|
18
|
-
choosing. It lists every component the project has, shipped and custom, with
|
|
19
|
-
the variants each takes and the purpose its header comment states, so a custom
|
|
20
|
-
component is weighed against the shipped set on the same footing.
|
|
21
|
-
`npx live-tokens components <id>` prints one component's props, the values each
|
|
22
|
-
union accepts, and its tokens with defaults; `--json` returns the same as data.
|
|
14
|
+
## Action family
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
- The action needs a word to be unambiguous: `Button`.
|
|
17
|
+
- The glyph alone is plain (close, edit, delete) and space is short: `IconButton`.
|
|
18
|
+
- The pair that confirms or cancels an inline edit: `InlineEditActions`.
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
## Single-selection family
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
- `IconButton` is icon-only and square. Use it for compact, space-constrained actions whose meaning is obvious from the glyph alone (toolbar controls, close/edit/delete affordances, card overflow menus). It has no text slot, so an `ariaLabel` is required for accessibility.
|
|
30
|
-
- **Don't reach for `IconButton` when the icon's meaning isn't self-evident.** A labelled `Button` (or a `Button` with an icon) avoids the guessing game.
|
|
31
|
-
- `InlineEditActions` is the confirm-and-cancel pair that follows an inline edit (rename a row, edit a value in place). Use it rather than two loose `IconButton`s so every inline edit on the page resolves the same way.
|
|
22
|
+
Four components pick one option from a set. The test is the option count, whether the selection swaps the content below, and how much the choice asks of the reader.
|
|
32
23
|
|
|
33
|
-
|
|
24
|
+
| Component | Test | Option count |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `SegmentedControl` | An inline switch between views of the same data. It sits in a row of controls. | 2 to 4 |
|
|
27
|
+
| `TabBar` | The content area below swaps. | 2 to 7 |
|
|
28
|
+
| `RadioButton` | The reader reads every option as text inside a larger form. | any |
|
|
29
|
+
| `MenuSelect` | The options would overflow a row. | any |
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
- When a label would wrap in a `SegmentedControl`, use `RadioButton` rows.
|
|
32
|
+
- The URL changes: `SideNavigation`. Sections inside one page: `TabBar`.
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|-------------------|-------------------------------------------------------------------------|------------------|--------------|
|
|
39
|
-
| `SegmentedControl`| Inline switch between alternative *views of the same data* | Compact pill | 2–4 |
|
|
40
|
-
| `TabBar` | Switching between *tab panels* (content area swaps below) | Page-section | 2–7 |
|
|
41
|
-
| `RadioButton` | Form-style selection where the user reviews all options as text | Form-row | Any |
|
|
42
|
-
| `MenuSelect` | A list of options, one checked; renders open, so a dropdown toggles it from a `Button` | Open list | Any |
|
|
34
|
+
## Text entry
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
- Use `RadioButton` when labels deserve room to breathe and the user is committing to a larger form.
|
|
46
|
-
- Use `MenuSelect` when options would overflow horizontally or there are too many to display at once.
|
|
47
|
-
- **Don't pick `SegmentedControl` when option labels are long enough to wrap.** It loses its compactness; use `RadioButton` rows instead.
|
|
36
|
+
The test is whether the answer comes from a predefined list of options.
|
|
48
37
|
|
|
49
|
-
|
|
38
|
+
- A predefined list (a status, a currency, a size, a country): the single-selection family, by its own test. Up to four options sit in a row; more go in a `MenuSelect`, which scrolls.
|
|
39
|
+
- No list (a name, a search string, an amount, a message, a street address): `Input`. Validation keeps a typed answer well-formed.
|
|
40
|
+
- A long list the reader would rather filter by typing (a city): no shipped component filters a list. Use `Input` with validation, or author a filtering select with **live-tokens-create-component**.
|
|
41
|
+
- A number where the position on a track carries the meaning (a volume, a price band, a percentage): `Slider`. A number the reader knows and would rather type: `Input` with `type="number"`.
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
- The boundary is whether you can list the answers. A short fixed set is the single-selection family above; a long fixed set is `MenuSelect`; anything you cannot write down is `Input`.
|
|
53
|
-
- `Slider` takes a number inside a known range where the position carries the meaning: a volume, a price band, a percentage. Its `range` variant takes a low and a high bound on one track. A number the user knows exactly and would rather type is `Input` with `type="number"`.
|
|
54
|
-
- **Don't use it for on/off.** That is `Toggle`, and a one-field form asking for yes or no is the usual way this goes wrong.
|
|
55
|
-
- Its four variants are `default`, `focused`, `disabled`, and `error`. A validation message belongs in the `error` variant, not in a `Callout` next to the field.
|
|
43
|
+
## On and off
|
|
56
44
|
|
|
57
|
-
|
|
45
|
+
Three components express a binary choice. The test is whether the two states have names of their own.
|
|
58
46
|
|
|
59
|
-
| Component
|
|
60
|
-
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `Panel` | Inline, fixed stage | A demo or preview surface whose height must not reflow |
|
|
47
|
+
| Component | Test |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `Toggle` | A setting that takes effect at once. The label names the setting. The switch position is the state. |
|
|
50
|
+
| `SegmentedControl` | Two named alternatives the reader compares (Light / Dark, List / Grid). Both labels show at once. |
|
|
51
|
+
| `RadioButton` pair | A yes or no the reader answers inside a larger form. |
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
- Reach for `CollapsibleSection` only when the content is *legitimately secondary* (advanced users open it; most skip). Don't use collapse as a styling choice when the content matters.
|
|
68
|
-
- `Panel` is a stage, not a content container. It pins its own height so what it shows can resize without moving the page, which is what a component preview or a live example needs and what article content does not. Content goes in `Card`.
|
|
69
|
-
- **Don't use `Dialog` for routine forms.** Reach for it only when the page cannot meaningfully continue until the user decides (destructive confirmations, payment, sign-in). Routine forms go inline in a `Card`.
|
|
53
|
+
When the two states share the feature's one name, use `Toggle`. "Email notifications" has no "off" label.
|
|
70
54
|
|
|
71
|
-
##
|
|
55
|
+
## Container family
|
|
72
56
|
|
|
73
|
-
|
|
74
|
-
|-----------------|----------------|-----------------|-------------|------------------------------------------------------|
|
|
75
|
-
| `Callout` | Section-inline | Always present | No | "Heads up about this section" |
|
|
76
|
-
| `Notification` | System-level | Event / save | Yes | "Your changes were saved" |
|
|
77
|
-
| `Tooltip` | Element-inline | Hover / focus | Auto | Definition or hint anchored to an element |
|
|
78
|
-
| `Badge` | Element-inline | Always present | No | Status pill ("Beta", "New", "v2") |
|
|
79
|
-
| `CornerBadge` | Element-corner | Always present | No | Position-anchored marker (count, status dot) |
|
|
57
|
+
Four components hold a block of content. The test is what the block is to the reader: one item, a section of the page, secondary content that stays collapsed until opened, or a decision.
|
|
80
58
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
59
|
+
| Component | Modality | Test |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `Card` | Inline, always open | One item, or each item in a set: a product, a record, a plan. It has a title and can react to hover. |
|
|
62
|
+
| `Panel` | Inline, always open | One section of the page's content in a frame: a stage, a list, a form, a block of copy. `minHeight` holds its height while the content changes. |
|
|
63
|
+
| `CollapsibleSection` | Inline, collapsed until the reader opens it | Secondary content most readers skip. |
|
|
64
|
+
| `Dialog` | Modal, blocks the page | A decision the page cannot continue without: a destructive confirmation, payment, sign-in. |
|
|
85
65
|
|
|
86
|
-
|
|
66
|
+
A set of items is one `Card` per item. A routine form goes inline in a `Panel`.
|
|
87
67
|
|
|
88
|
-
|
|
89
|
-
- `ImageLightbox` adds click-to-open at full size and takes an array for a gallery. Use it when the detail is the point (screenshots, artwork, charts that need reading), and not for decoration: it puts a modal behind every picture it wraps.
|
|
90
|
-
- `Table` themes your own rows and cells without owning the data. Records go here; a set of *things the user acts on* is a stack of `Card`s instead.
|
|
91
|
-
- `ProgressBar` reports progress against a labelled track. It is a read-out, never a control.
|
|
92
|
-
- `CodeSnippet` is for a single-line command or value the reader is meant to copy back into a terminal (install commands, generated keys, ids), with click-to-copy and a brief "Copied" popover. Use it whenever the page asks the reader to *run* something rather than just *read* it.
|
|
93
|
-
- `SectionDivider` separates sections of one page. `SideNavigation` moves between pages, driven by the current path. **Don't use `SideNavigation` to switch panels inside one page;** that is `TabBar`, and the difference is whether the URL changes.
|
|
68
|
+
## Messaging family
|
|
94
69
|
|
|
95
|
-
|
|
70
|
+
Five components carry a message. The test is what the message is about, what brings it on, and whether the reader dismisses it.
|
|
96
71
|
|
|
97
|
-
|
|
72
|
+
| Component | Scope | Trigger | Dismissable | Test |
|
|
73
|
+
|---|---|---|---|---|
|
|
74
|
+
| `Callout` | A section | Always present | No | Something the reader must know about the content around it |
|
|
75
|
+
| `Notification` | The system | An action or event | Yes | Feedback about something that just happened |
|
|
76
|
+
| `Tooltip` | An element | Hover or focus | On leave | A definition or hint the reader can do without |
|
|
77
|
+
| `Badge` | An element | Always present | No | A standing label read at a glance ("Beta", "New", "v2") |
|
|
78
|
+
| `CornerBadge` | A parent's corner | Always present | No | A count or status marker on the thing it describes |
|
|
98
79
|
|
|
99
|
-
|
|
100
|
-
|--------------------|-----------------------------------------------------------------------------------------------------------------------|
|
|
101
|
-
| `Toggle` | A *setting* that's either on or off (notifications on/off, dark mode). The label names the setting; the switch shows the state. |
|
|
102
|
-
| `SegmentedControl` | A *choice between two named alternatives* (Light / Dark, List / Grid). Both labels are visible at once. |
|
|
103
|
-
| `RadioButton` pair | A *form-style choice* where the user reviews both labels before committing (Yes / No questions, opt-in selections). |
|
|
80
|
+
`Badge` and `CornerBadge` differ in position only.
|
|
104
81
|
|
|
105
|
-
|
|
106
|
-
- If the two states have different names you want users to compare, it's `SegmentedControl`.
|
|
107
|
-
- `Toggle` flips immediately; `RadioButton` pair is for forms where the choice is part of a larger submission.
|
|
82
|
+
## Display family
|
|
108
83
|
|
|
109
|
-
|
|
84
|
+
Each pair holds a block the reader views and one the reader interacts with. The test is which of the two the page needs.
|
|
85
|
+
|
|
86
|
+
- A picture the page shows: `Image`. A picture whose detail the reader must open, or a gallery: `ImageLightbox`.
|
|
87
|
+
- Records the reader scans and compares: `Table`. A set of items the reader acts on: one `Card` per item.
|
|
88
|
+
- A read-out of progress: `ProgressBar`. A number the reader sets: `Slider`.
|
|
89
|
+
- Text the reader runs or pastes (an install command, a key, an id): `CodeSnippet`. Prose the reader only reads: a paragraph in its `Card` or `Panel`.
|
|
90
|
+
- A titled break between the sections of one page: `SectionDivider`. Movement between pages: `SideNavigation`.
|
|
91
|
+
|
|
92
|
+
## Nothing fits
|
|
93
|
+
|
|
94
|
+
A native element with no chrome of its own needs no component: an `<input type="file">` behind a Button, a `<canvas>`, an `<img>` inside a stage. When nothing in the catalogue fits a piece with chrome (a `DatePicker`, a `Stepper`), author the component with **live-tokens-create-component**. Size, emphasis, and placement are **live-tokens-create-page**'s.
|
|
110
95
|
|
|
111
|
-
|
|
96
|
+
`npx live-tokens components <id>` prints one component's usage comment, its declared props, and the values each union accepts. `--json` returns the same as data.
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-set-colors
|
|
3
|
-
description: Set a live-tokens theme's color
|
|
3
|
+
description: Set a live-tokens theme's color: ten OKLCH base colors, a light or dark scheme, and a WCAG AA-gated contrast check. Called with an anchor and a color intent by live-tokens-create-theme, or with the user's request directly. Use when the user asks for a palette, colors, or hues by mood, style, era, season, holiday, or hue. Use when the user names only a color. Use when the user refines a theme's color: warmer, cooler, calmer, louder, lighter, darker, moodier, more contrast. Changes color only. For a request that also names type or geometry, read live-tokens-create-theme.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Setting a theme's colors
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
contrast
|
|
10
|
-
|
|
11
|
-
theme JSON and never edit the data tree directly.
|
|
8
|
+
Choose ten base colors. The CLI builds every ramp from them, checks AA
|
|
9
|
+
contrast, and prints a contrast report. Never write theme JSON by hand and
|
|
10
|
+
never edit the data tree.
|
|
12
11
|
|
|
13
|
-
The
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
The result is on screen as soon as the run finishes. The three set skills
|
|
13
|
+
write the same buffer, so color, type, and geometry compose in any order. When
|
|
14
|
+
the user accepts the result, run `save-theme` to keep it as a theme. Loading a
|
|
15
|
+
theme in the editor discards it.
|
|
16
16
|
|
|
17
17
|
## Workflow
|
|
18
18
|
|
|
19
|
-
1. Read the color intent. When
|
|
20
|
-
2. Translate the intent into ten base colors
|
|
21
|
-
3. Run `npx live-tokens set-colors scratch/<slug>-base-colors.json`.
|
|
22
|
-
4. Read the report. Exit 0 passes, and auto-corrected values count as passing.
|
|
23
|
-
5.
|
|
19
|
+
1. Read the color intent and any anchor live-tokens-create-theme passed. When either names an anchor (a feeling, an idiom, an occasion), read its entry in `references/color-anchors.md`; it overrides the generic ranges below.
|
|
20
|
+
2. Translate the intent into ten base colors with the framework below and write them to `scratch/<slug>-base-colors.json`. Keep this file for later refinements. The saved theme also records the base colors.
|
|
21
|
+
3. Run `npx live-tokens set-colors scratch/<slug>-base-colors.json`.
|
|
22
|
+
4. Read the report. Exit 0 passes, and auto-corrected values count as passing. On a contrast failure, exit 1 names the base color to change and the move: raise its lightness or reduce its chroma. On a bad file, exit 1 names the field. Fix the file and re-run.
|
|
23
|
+
5. Reply with the anchor if any, the scheme, the hue families, the Canvas base color, and anything the contrast report auto-corrected.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
`--dry-run` prints the report without writing.
|
|
26
26
|
|
|
27
27
|
## The base color file
|
|
28
28
|
|
|
@@ -44,23 +44,30 @@ Flags: `--dry-run` prints the contrast report without writing.
|
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
A base color is the one color a palette's whole ramp derives from.
|
|
47
|
+
A base color is the one color a palette's whole ramp derives from.
|
|
48
|
+
|
|
49
|
+
- `baseColors`: all ten required. Each is an OKLCH triple or a `"#rrggbb"` string in its place. `l` is lightness, above 0 and below 1. `c` is chroma, 0 for grey and at most 0.4. `h` is hue in degrees.
|
|
50
|
+
- `scheme`: `"light"` or `"dark"`.
|
|
51
|
+
- `canvasGradient` (optional): a boolean, default off. See Canvas sky and shadows.
|
|
52
|
+
- `harmony` (optional): `{ "mode": "<mode>" }`, a record of the harmony the base colors follow. The CLI validates the mode and derives nothing from it. The modes are the ones the Harmony section names, plus `custom`.
|
|
48
53
|
|
|
49
54
|
Roles: **Brand** is the dominant chromatic identity; **Accent** the supporting color; **Special** the rare expressive tertiary; **Canvas** is the page background verbatim; **Neutral** drives neutral surfaces and body text; **Alternate** is the second near-grey family; the four statuses are conventional signals.
|
|
50
55
|
|
|
51
|
-
## Chroma budget
|
|
56
|
+
## Chroma budget
|
|
57
|
+
|
|
58
|
+
The more area a palette covers, the less chroma it gets.
|
|
52
59
|
|
|
53
60
|
| Tier | Palettes | Chroma |
|
|
54
61
|
|---|---|---|
|
|
55
62
|
| Ground (about 60% of every screen) | Neutral, Alternate | C 0.008 to 0.02 |
|
|
56
|
-
| Canvas (the largest single area) | Canvas |
|
|
63
|
+
| Canvas (the largest single area) | Canvas | C 0.02 to 0.14, by commitment level (see Canvas commitment) |
|
|
57
64
|
| Dominant chromatic (about 30%) | Brand | C 0.10 to 0.20 |
|
|
58
65
|
| Garnish (about 10%) | Accent, Special | may exceed Brand; at most one at the gamut cap for its hue (see Gamut guardrails) |
|
|
59
66
|
| Conditional | Info, Success, Warning, Danger | C 0.12 to 0.19 |
|
|
60
67
|
|
|
61
|
-
A good theme reads as 3 or 4 hue families on screen, never 10. Neutral and Alternate stay near-grey
|
|
68
|
+
A good theme reads as 3 or 4 hue families on screen, never 10. Neutral and Alternate stay near-grey, tinted toward the theme: Neutral near Brand's hue, Alternate offset 15 to 60 degrees or a warm/cool counterpoint. Pure C = 0 only when an anchor calls for it.
|
|
62
69
|
|
|
63
|
-
## Per-role
|
|
70
|
+
## Per-role ranges
|
|
64
71
|
|
|
65
72
|
| Base color | Light scheme | Dark scheme | Hue |
|
|
66
73
|
|---|---|---|---|
|
|
@@ -74,25 +81,25 @@ A good theme reads as 3 or 4 hue families on screen, never 10. Neutral and Alter
|
|
|
74
81
|
| Warning | L 0.75 or higher (vivid yellow must be light) | same | H 70 to 90 |
|
|
75
82
|
| Danger | shared status L, C 0.15 to 0.20 | same | H 20 to 30 |
|
|
76
83
|
|
|
77
|
-
|
|
84
|
+
Three rules cross every role:
|
|
85
|
+
|
|
86
|
+
- A dark scheme transforms every base color: each chromatic one lightens to L 0.75 to 0.85 and drops about a third of its chroma, because saturated color vibrates on dark grounds.
|
|
87
|
+
- Equal lightness reads as equal weight: give the four statuses one shared L, and do the same for Brand and Accent when they should balance.
|
|
88
|
+
- Status hues never rotate with the harmony; only their L and C adapt to the mood.
|
|
89
|
+
|
|
90
|
+
**The canvas carries the theme's identity, so commit to it.** The page background is the largest area on screen and the strongest difference between themes; a timid canvas makes every theme look the same. Below C 0.015 at L 0.95 a tint is imperceptible, so near-white is a choice for a clean or minimal intent, never a default. The canvas sits in one of three ranges:
|
|
78
91
|
|
|
79
92
|
1. *Tinted paper* (most UI intents): C 0.02 to 0.06, with L down to 0.92 where the hue needs room.
|
|
80
93
|
2. *Colored ground* (expressive intents): L 0.85 to 0.92 at C 0.05 to 0.10. The page is unmistakably mint, parchment, sky.
|
|
81
94
|
3. *Full-color ground* (holiday and statement intents): the canvas is the theme color, like a red Christmas page with green and gold on it. Keep canvas L at or below 0.48 or at or above 0.85 so text has somewhere to go; the contrast gate enforces legibility either way.
|
|
82
95
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- Blue tints cap very low at high L (H 264 at L 0.95 barely reaches C 0.03): lower L for a blue canvas rather than fighting the ceiling. Yellow, green, and cream tint generously at high L.
|
|
86
|
-
- When generating a set of themes, make the canvases pairwise distinct in hue or in L. Two light themes both near (0.97, 0.01) read as one theme with different buttons.
|
|
87
|
-
- A dark scheme transforms every base color: each chromatic one lightens to L 0.75 to 0.85 and drops about a third of its chroma, because saturated color vibrates on dark grounds.
|
|
88
|
-
- Equal lightness reads as equal weight: give the four statuses one shared L, and do the same for Brand and Accent when they should balance.
|
|
89
|
-
- Status hues never rotate with the harmony; only their L and C adapt to the mood.
|
|
96
|
+
Blue tints cap very low at high L (H 264 at L 0.95 barely reaches C 0.03), so lower L for a blue canvas rather than fighting the ceiling; yellow, green, and cream tint generously at high L. Across a set of themes, make the canvases pairwise distinct in hue or in L. Two light themes both near (0.97, 0.01) read as one theme with different buttons.
|
|
90
97
|
|
|
91
98
|
## Mood dials
|
|
92
99
|
|
|
93
|
-
Pleasantness rises with lightness (strongly) and saturation (weakly); energy rises with saturation; drama rises with dark plus saturated. Dominance, the third axis, is carried by surface contrast, type weight, and tightness rather than by color
|
|
100
|
+
Pleasantness rises with lightness (strongly) and saturation (weakly); energy rises with saturation; drama rises with dark plus saturated. Dominance, the third axis, is carried by surface contrast, type weight, and tightness rather than by color.
|
|
94
101
|
|
|
95
|
-
|
|
102
|
+
Warm is hues 20 to 110 plus pink 290 to 360; cool is 140 to 290. For an intent that names a feeling, read `references/color-anchors.md` rather than guessing the dial settings.
|
|
96
103
|
|
|
97
104
|
Avoid mid-lightness yellow-green (H 100 to 120 at L 0.5 to 0.7, C about 0.1) unless the intent asks for olive or toxic.
|
|
98
105
|
|
|
@@ -115,26 +122,28 @@ Hue offsets from Brand: complementary +180; split-complementary +150/+210; triad
|
|
|
115
122
|
|
|
116
123
|
## Canvas sky and shadows
|
|
117
124
|
|
|
118
|
-
`"canvasGradient": true` renders the page background as a vertical gradient from the Canvas ramp. Default off. Turn it on only when the intent evokes atmosphere (sky, night, dusk, glow, underwater) or asks for a gradient outright; keep it off for crisp, flat, minimal, or corporate intents and whenever in doubt, because a sky on every theme stops meaning anything. It needs a
|
|
125
|
+
`"canvasGradient": true` renders the page background as a vertical gradient from the Canvas ramp. Default off. Turn it on only when the intent evokes atmosphere (sky, night, dusk, glow, underwater) or asks for a gradient outright; keep it off for crisp, flat, minimal, or corporate intents and whenever in doubt, because a sky on every theme stops meaning anything. It needs a Canvas base color with L above 0.10 and below 0.90. Outside that range the engine skips it and says so. Say why it is on, in one line.
|
|
119
126
|
|
|
120
127
|
Shadow opacity derives from Canvas lightness and re-derives on every run, so there is nothing to choose. When shadows read heavy or muddy, raise the Canvas base color's L.
|
|
121
128
|
|
|
122
|
-
## Refining
|
|
129
|
+
## Refining a theme's color
|
|
130
|
+
|
|
131
|
+
"Warmer", "calmer", "more contrast" arrive against a theme that is already open, and the answer is a new base color file. Edit `scratch/<slug>-base-colors.json` when it is still there. When it is not, recover the ten base colors from `src/live-tokens/data/themes/<slug>.json`: each one sits at `colorsAndType.editorConfigs.<Palette>.baseColor` as an OKLCH triple, and the Canvas base color's lightness gives the scheme. Rebuild the base color file from those values, move the dial the user named, and re-run.
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
A re-run replaces the buffer's palette state, including palette edits made in the editor since the last run. Swatch gradients tuned in the editor carry through, and the report says which. Say so once when iterating.
|
|
125
134
|
|
|
126
135
|
One adjective moves one dial. Warmer and cooler rotate hue; calmer and louder move chroma; lighter, darker, and moodier move Canvas L and the scheme; more contrast widens the L gap between Canvas and Brand and takes chroma out of the ground rather than adding it to the garnish. Leave every base color the user did not name alone, because a refinement that re-rolls the whole palette reads as a different theme and loses the thing they liked.
|
|
127
136
|
|
|
128
137
|
## Scope
|
|
129
138
|
|
|
130
|
-
Color only.
|
|
131
|
-
state in the
|
|
132
|
-
|
|
133
|
-
ships it.
|
|
139
|
+
Color only. Fonts, geometry, saved themes, `tokens.css`, and `fonts.css` are
|
|
140
|
+
untouched: `set-colors` replaces the color state in the buffer and carries
|
|
141
|
+
every other value in it forward. `save-theme` keeps the result; Adopt ships it.
|
|
134
142
|
|
|
135
143
|
## Verify
|
|
136
144
|
|
|
137
|
-
- The CLI exits 0 with every check passing (auto-corrected is fine), and the report names
|
|
138
|
-
- The app (dev server running) shows the new palette
|
|
145
|
+
- The CLI exits 0 with every check passing (auto-corrected is fine), and the report names which layer the non-color values came from.
|
|
146
|
+
- The app (dev server running) shows the new palette.
|
|
147
|
+
- The editor's Theme panel marks the open theme as edited. A dry run marks nothing, and neither does a run whose report says the open theme or the shipped default already holds these colors.
|
|
139
148
|
- The canvas is committed: on screen it reads as the theme's color rather than as generic near-white.
|
|
140
149
|
- To revert, re-run with the previous base color file, or load the open theme again to discard the buffer.
|