@motion-proto/live-tokens 0.47.1 → 0.48.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-adjust-shape-space/SKILL.md +68 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +2 -2
- package/.claude/skills/live-tokens-generate-theme/SKILL.md +152 -0
- package/CHANGELOG.md +270 -0
- package/README.md +37 -26
- package/bin/adjust.mjs +254 -0
- package/bin/cli.mjs +94 -7
- package/bin/generate-theme.mjs +251 -0
- package/bin/migrate.mjs +95 -6
- package/dist-plugin/adjust/index.cjs +259 -0
- package/dist-plugin/adjust/index.d.cts +45 -0
- package/dist-plugin/adjust/index.d.ts +45 -0
- package/dist-plugin/adjust/index.js +176 -0
- package/dist-plugin/{chunk-H4TRUINI.js → chunk-44RSTAII.js} +0 -48
- package/dist-plugin/chunk-6OZFXIQI.js +316 -0
- package/dist-plugin/chunk-76TFDTJO.js +556 -0
- package/dist-plugin/chunk-D3ZVKOR4.js +52 -0
- package/dist-plugin/dataPaths-DBN0RPuT.d.cts +54 -0
- package/dist-plugin/dataPaths-DBN0RPuT.d.ts +54 -0
- package/dist-plugin/generateColorsAndType/index.cjs +1781 -0
- package/dist-plugin/generateColorsAndType/index.d.cts +81 -0
- package/dist-plugin/generateColorsAndType/index.d.ts +81 -0
- package/dist-plugin/generateColorsAndType/index.js +1210 -0
- package/dist-plugin/index.cjs +849 -531
- package/dist-plugin/index.d.cts +3 -2
- package/dist-plugin/index.d.ts +3 -2
- package/dist-plugin/index.js +658 -1132
- package/dist-plugin/migrateData/index.cjs +728 -0
- package/dist-plugin/migrateData/index.d.cts +60 -0
- package/dist-plugin/migrateData/index.d.ts +60 -0
- package/dist-plugin/migrateData/index.js +348 -0
- package/dist-plugin/themeTypes-DMHZOnUn.d.cts +211 -0
- package/dist-plugin/themeTypes-DMHZOnUn.d.ts +211 -0
- package/dist-plugin/tokensCssMigrations/index.cjs +2 -1
- package/dist-plugin/tokensCssMigrations/index.d.cts +3 -15
- package/dist-plugin/tokensCssMigrations/index.d.ts +3 -15
- package/dist-plugin/tokensCssMigrations/index.js +4 -2
- package/package.json +18 -4
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +183 -158
- package/src/editor/component-editor/scaffolding/ComponentFileMenu.svelte +0 -4
- package/src/editor/component-editor/scaffolding/SaveAsDialog.svelte +4 -4
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +2 -59
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +1 -1
- package/src/editor/core/components/adjustAliases.ts +180 -0
- package/src/editor/core/components/aliasKinds.ts +73 -0
- package/src/editor/core/components/componentConfigService.ts +26 -38
- package/src/editor/core/flashStatus.ts +1 -1
- package/src/editor/core/fonts/fontMigration.ts +13 -13
- package/src/editor/core/fonts/fontPairing.ts +35 -0
- package/src/editor/core/palettes/paletteDerivation.ts +83 -13
- package/src/editor/core/preview/lookPreview.ts +141 -0
- package/src/editor/core/productionPulse.ts +34 -21
- package/src/editor/core/storage/files/versionedFileResourceClient.ts +18 -45
- package/src/editor/core/store/editorConfigStore.ts +2 -2
- package/src/editor/core/store/editorPersistence.ts +0 -1
- package/src/editor/core/store/editorStore.ts +114 -51
- package/src/editor/core/store/editorTypes.ts +0 -1
- package/src/editor/core/store/gradientSource.ts +2 -2
- package/src/editor/core/themes/colorsAndTypeService.ts +95 -0
- package/src/editor/core/themes/generateColorsAndType.ts +433 -0
- package/src/editor/core/themes/loadRows.ts +64 -0
- package/src/editor/core/themes/lookSummary.ts +75 -0
- package/src/editor/core/themes/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +3 -3
- package/src/editor/core/themes/migrations/2026-05-13-primary-to-brand.ts +2 -2
- package/src/editor/core/themes/migrations/2026-05-26-drop-overlay-extra-stops.ts +3 -3
- package/src/editor/core/themes/migrations/2026-08-13-drop-legacy-shape-space-keys.ts +38 -0
- package/src/editor/core/themes/migrations/2026-08-15-line-height-scale-rename.ts +57 -0
- package/src/editor/core/themes/migrations/index.ts +19 -11
- package/src/editor/core/themes/slices/components.ts +4 -4
- package/src/editor/core/themes/slices/fonts.ts +1 -1
- package/src/editor/core/themes/slices/gradients.ts +22 -0
- package/src/editor/core/themes/slices/palettes.ts +2 -2
- package/src/editor/core/themes/themeInit.ts +21 -29
- package/src/editor/core/themes/themeService.ts +218 -78
- package/src/editor/core/themes/themeTypes.ts +94 -51
- package/src/editor/docs/Docs.svelte +1 -0
- package/src/editor/docs/chapters.ts +1 -0
- package/src/editor/docs/content/01-overview.md +1 -1
- package/src/editor/docs/content/editing-tokens.md +6 -6
- package/src/editor/docs/content/getting-started.md +9 -7
- package/src/editor/docs/content/themes-workflow.md +74 -34
- package/src/editor/docs/content/where-themes-live.md +61 -0
- package/src/editor/docs/content.generated.ts +5 -4
- package/src/editor/index.ts +27 -27
- package/src/editor/pages/ComponentEditorPage.svelte +2 -2
- package/src/editor/pages/EditorShell.svelte +4 -30
- package/src/editor/ui/FileLoadList.svelte +67 -7
- package/src/editor/ui/GradientEditor.svelte +3 -3
- package/src/editor/ui/ThemePanel.svelte +1067 -0
- package/src/editor/ui/UIDialog.svelte +11 -9
- package/src/editor/ui/index.ts +4 -2
- package/src/live-tokens/data/colors-and-type/autumn.json +2490 -0
- package/src/live-tokens/data/{themes → colors-and-type}/default.json +962 -549
- package/src/live-tokens/data/colors-and-type/halloween.json +2529 -0
- package/src/live-tokens/data/colors-and-type/midnight-study.json +2536 -0
- package/src/live-tokens/data/colors-and-type/ocean.json +2489 -0
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +2520 -0
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +2476 -0
- package/src/live-tokens/data/colors-and-type/sunset.json +2528 -0
- package/src/live-tokens/data/themes/autumn.json +3918 -0
- package/src/live-tokens/data/themes/halloween.json +3992 -0
- package/src/live-tokens/data/themes/midnight-study.json +3932 -0
- package/src/live-tokens/data/themes/ocean.json +3917 -0
- package/src/live-tokens/data/themes/royal-velvet.json +3983 -0
- package/src/live-tokens/data/themes/spring-meadow.json +3904 -0
- package/src/live-tokens/data/themes/sunset.json +3931 -0
- package/src/live-tokens/data/tokens.generated.css +129 -140
- package/src/system/styles/CONVENTIONS.md +1 -1
- package/src/system/styles/fonts.css +1 -1
- package/template/README.md +7 -5
- package/template/_gitignore +0 -6
- package/src/editor/core/components/componentPersist.ts +0 -62
- package/src/editor/core/manifests/manifestService.ts +0 -172
- package/src/editor/ui/ManifestFileManager.svelte +0 -446
- package/src/editor/ui/ThemeFileManager.svelte +0 -785
- package/src/live-tokens/data/manifests/default.json +0 -35
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: live-tokens-adjust-shape-space
|
|
3
|
+
description: Adjust corner radius, padding, gap, and border width across live-tokens components by moving each token alias along the shipped scales. Use when the user asks for pill or capsule buttons, rounded, rounder, sharp, sharper, square corners, softer, harder, a bigger or smaller corner radius, thicker or thinner borders, or talks about spacing and padding. Make the buttons pill shaped, give the cards sharp corners, make the windows sharper, make the UI softer, space it out, tighter, denser, more compact, airier, more breathing room. Changes shape and space aliases per component, never color, fonts, or tokens.css. Not for editing a single token (use the editor) or for color (see live-tokens-generate-theme).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adjusting shape and space
|
|
7
|
+
|
|
8
|
+
You translate the request into a small ops file; the CLI resolves each matching alias on its token ladder, writes the result into each component's unsaved buffer, and prints a report card. Never hand-edit the data tree.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Write the ops file to a temp path (not the project tree), e.g. `/tmp/adjust-ops.json`.
|
|
13
|
+
2. Run `npx live-tokens adjust /tmp/adjust-ops.json`. It writes `component-configs/<id>/_working.json` for every component the ops change, which is the buffer the page already runs. `--dry-run` prints the report without writing.
|
|
14
|
+
3. Read the report card: every changed alias old → new, plus skips (raw value, off the ladder, already at the ladder end, pill preserved). Exit 1 means the run was rejected; the message names the offending op or the missing input, so fix it and re-run.
|
|
15
|
+
4. Tell the user to reload the app and look. Offer the inverse op as the undo, and say the edit is unsaved until they save the open theme.
|
|
16
|
+
|
|
17
|
+
Each run reads the LIVE config (buffer, else the open theme, else the shipped default), so "a bit more" and "back one" compound naturally.
|
|
18
|
+
|
|
19
|
+
## The ops file
|
|
20
|
+
|
|
21
|
+
Global, relative:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{ "ops": [{ "kind": "radius", "shift": 1 }, { "kind": "padding", "shift": 1 }, { "kind": "gap", "shift": 1 }] }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Targeted, absolute:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{ "ops": [{ "target": "button", "kind": "radius", "set": "--radius-full" }] }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- `name`: ignored. Buffers are fixed slots, so a name names no file, and the CLI says it dropped one. Leave it out.
|
|
34
|
+
- `target` (optional): a component id (the folder names under `src/live-tokens/data/component-configs/`). A named component targets its id: "windows" or "modals" is `dialog`, "cards" is `card`, "tabs" is `tabbar`; an unknown target is a hard error. "The UI", "everything", or no noun at all means global, so omit it.
|
|
35
|
+
- `kind`: `radius | padding | gap | border-width`.
|
|
36
|
+
- `set` or `shift`, exactly one of the two. `set` takes an existing token on that kind's ladder. `shift` is a whole number of steps, clamped at the ladder ends.
|
|
37
|
+
- `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.
|
|
38
|
+
|
|
39
|
+
## Idioms
|
|
40
|
+
|
|
41
|
+
| Request | Ops |
|
|
42
|
+
|---|---|
|
|
43
|
+
| pill, capsule | radius `set: "--radius-full"` |
|
|
44
|
+
| sharp, square corners | radius `set: "--radius-none"`, or `--radius-sm` for "mostly sharp" |
|
|
45
|
+
| rounded (a named component) | radius `shift: 2` |
|
|
46
|
+
| softer, rounder (global) | radius `shift: 1` to `2`, no `full` |
|
|
47
|
+
| harder, sharper | radius `shift: -1` to `-2` |
|
|
48
|
+
| increase the radius, less round, more round | radius `shift: 1` or `-1` with `"full": true`, so repeated pushes reach pill and a pill can come back down |
|
|
49
|
+
| space it out, airier, breathing room | padding and gap `shift: 1` |
|
|
50
|
+
| tighter, denser, more compact | padding and gap `shift: -1` |
|
|
51
|
+
| thicker, thinner borders | border-width `shift: 1` or `-1` |
|
|
52
|
+
|
|
53
|
+
Magnitude words: "slightly" or "a bit" is 1 step, unqualified is 1 to 2, "much", "way", or "really" is 2 to 3. Mood words often mean both axes: "softer" is rounder plus airier, "compact" is tighter padding plus smaller gaps.
|
|
54
|
+
|
|
55
|
+
## Ladders
|
|
56
|
+
|
|
57
|
+
Radius runs `none, sm, md, lg, xl, 2xl, 3xl, 4xl`, with `full` as the gated ninth rung. Space (padding and gap) is the editor picker's subset: `0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 48`, so every written value stays re-editable by hand. Border width is the full `--border-width-*` scale. `set` values must be on the ladder (`--space-64` is rejected); an alias sitting off the subset snaps to the nearest rung when shifted, and the report marks a snap that lands against the requested direction.
|
|
58
|
+
|
|
59
|
+
## Scope
|
|
60
|
+
|
|
61
|
+
Every value written is an existing token; nothing new is minted. `tokens.css`, saved themes, colors, and fonts are never touched, so any theme composes with any shape state. An adjustment is an unsaved edit: Save the open theme in the editor to keep it, and Adopt to ship it. Both stay human actions.
|
|
62
|
+
|
|
63
|
+
## Verify
|
|
64
|
+
|
|
65
|
+
- The CLI exits 0 and the report card lists the changes you expected, with no surprising skips.
|
|
66
|
+
- The app (dev server running) shows the new shape on each changed component after a reload.
|
|
67
|
+
- `component-configs/<id>/_working.json` exists for every component the report listed. That buffer is the whole change: it stays until the open theme is saved or another theme is loaded.
|
|
68
|
+
- To revert, run the inverse ops, or load a theme in the Theme panel to discard every unsaved edit.
|
|
@@ -552,7 +552,7 @@ It enforces the file layout, the `:global(:root)` block, token-suffix vocabulary
|
|
|
552
552
|
1. Registration resolves to a real `sourceFile` and a non-empty schema.
|
|
553
553
|
2. Schema variables are unique within the component.
|
|
554
554
|
3. Every editable token (excluding `hidden: true`, `kind: 'gradient'`, and padding-side suffixes) is declared in the runtime `<style>` block.
|
|
555
|
-
4. Every editable token is seeded in
|
|
555
|
+
4. Every editable token is seeded in `src/live-tokens/data/component-configs/<id>/default.json`.
|
|
556
556
|
5. `setComponentAlias` round-trips the alias through the slice.
|
|
557
557
|
|
|
558
558
|
A new first-party component is auto-covered the moment it lands in `builtInRegistry` — `npm test` will fail if any of the five checks miss. For a consumer-authored component, mirror this pattern in your own test suite if you want the same drift protection (the same test logic works against any `registerComponent` registration; iterate `getComponentRegistryEntries()` after your `main.ts` has run).
|
|
@@ -564,6 +564,6 @@ Finally navigate to `/live-tokens/components` and confirm the runtime behaviours
|
|
|
564
564
|
- [ ] The new component appears in the nav rail under the **CUSTOM** group (system entries above, custom below the labeled divider).
|
|
565
565
|
- [ ] Token rows render. Color pickers, radius selectors, font selectors all work.
|
|
566
566
|
- [ ] Linked-block (if your component has linked siblings): shared rows appear with the link toggle. Changing the linked value broadcasts across every variant.
|
|
567
|
-
- [ ]
|
|
567
|
+
- [ ] `component-configs/<id>/default.json` is derived from the `:global(:root)` block at boot. Save writes `_working.json`, the unsaved buffer the open theme captures; Save As also writes a named preset.
|
|
568
568
|
- [ ] Reset returns each variable to its `:global(:root)` default.
|
|
569
569
|
- [ ] Boot validation is clean (no warnings about the component being missing from the server scan, or about disk-vs-registry drift).
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: live-tokens-generate-theme
|
|
3
|
+
description: Generate a complete live-tokens color theme from a natural-language mood brief by choosing 10 OKLCH seeds and running the packaged generator, which enforces AA contrast automatically. Use when the user asks for a color theme, color scheme, or palette by mood, vibe, season, holiday, or hue — make me a bright and cheerful theme, give me a dark and moody night theme, a St. Patrick's Day theme with green and gold, a Christmas theme, a red-based theme, make it warmer, more contrast, a calmer palette. Changes color assignments only, never fonts. Not for editing a single token (use the editor) or building pages (see live-tokens-build-page).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Generating a theme from a mood brief
|
|
7
|
+
|
|
8
|
+
You translate the brief into 10 OKLCH seed colors plus a scheme; the CLI does everything else (curve assembly, AA contrast enforcement with auto-correction, writing the theme, opening it). Never hand-author theme JSON and never edit the data tree directly. Seeds in, valid theme out.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Translate the brief into a seed file using the framework below. Write it to a temp path (not the project tree), e.g. `/tmp/theme-brief.json`.
|
|
13
|
+
2. Run `npx live-tokens generate-theme /tmp/theme-brief.json`. It writes `themes/<slug>.json`, opens that theme, and prints a contrast report card. Exit 1 means unmet floors.
|
|
14
|
+
3. Read the report. Auto-corrections are fine (the engine adjusted text curves to hit the floors). Unmet floors mean the seeds themselves are unworkable; each failure line says which seed to adjust (usually raise the seed's lightness or cut chroma). Fix the brief and re-run — same name, same file, it overwrites.
|
|
15
|
+
4. Tell the user to look at the running app. Offer refinements ("warmer", "more contrast", "less saturated") as seed adjustments to the same brief, re-run.
|
|
16
|
+
|
|
17
|
+
Flags: `--dry-run` prints the report without writing; `--no-activate` writes the theme without opening it. Opening a theme never changes what the site ships: only Adopt, in the editor, does that.
|
|
18
|
+
|
|
19
|
+
Warn once per session when iterating: regeneration replaces the whole color state of that theme, including any manual palette tweaks made in the editor after the last generation.
|
|
20
|
+
|
|
21
|
+
## The brief
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"name": "Spring Meadow",
|
|
26
|
+
"scheme": "light",
|
|
27
|
+
"seeds": {
|
|
28
|
+
"Brand": { "l": 0.62, "c": 0.17, "h": 145 },
|
|
29
|
+
"Accent": { "l": 0.80, "c": 0.15, "h": 95 },
|
|
30
|
+
"Special": { "l": 0.60, "c": 0.19, "h": 300 },
|
|
31
|
+
"Canvas": { "l": 0.97, "c": 0.01, "h": 120 },
|
|
32
|
+
"Neutral": { "l": 0.55, "c": 0.012, "h": 140 },
|
|
33
|
+
"Alternate": { "l": 0.58, "c": 0.009, "h": 60 },
|
|
34
|
+
"Info": { "l": 0.60, "c": 0.15, "h": 255 },
|
|
35
|
+
"Success": { "l": 0.60, "c": 0.16, "h": 150 },
|
|
36
|
+
"Warning": { "l": 0.75, "c": 0.15, "h": 85 },
|
|
37
|
+
"Danger": { "l": 0.58, "c": 0.20, "h": 25 }
|
|
38
|
+
},
|
|
39
|
+
"harmony": { "mode": "analogous" }
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
All 10 seeds are required. A seed may also be a `"#rrggbb"` hex string (converted for you). OKLCH: `l` 0–1 perceptual lightness, `c` chroma (0 grey, ~0.37 max), `h` hue degrees. `name` becomes the theme file slug, tidied to lowercase with hyphens and stripped of any leading underscore (those names are reserved); `"default"` is refused (protected package theme). `harmony` is an optional record of your reasoning; the seeds are ground truth. `canvasGradient` is an optional boolean — see "The canvas sky" below before setting it.
|
|
44
|
+
|
|
45
|
+
Roles: **Brand** is the dominant chromatic identity; **Accent** the supporting color; **Special** the rare expressive tertiary; **Canvas** is the page background verbatim; **Neutral** drives all neutral surfaces and body text; **Alternate** is the second near-grey family; the four status colors are conventional signals.
|
|
46
|
+
|
|
47
|
+
## Chroma budget: color is inversely proportional to area
|
|
48
|
+
|
|
49
|
+
| Tier | Palettes | Chroma |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| Ground (~60% of every screen) | Canvas, Neutral, Alternate | C 0.005–0.03 |
|
|
52
|
+
| Dominant chromatic (~30%) | Brand | C 0.10–0.20 |
|
|
53
|
+
| Garnish (~10%) | Accent, Special | may exceed Brand; at most one at full saturation |
|
|
54
|
+
| Conditional | Info, Success, Warning, Danger | C 0.12–0.19 |
|
|
55
|
+
|
|
56
|
+
A good theme reads as 3–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–60° or as a warm/cool counterpoint), never pure C = 0.
|
|
57
|
+
|
|
58
|
+
## Per-role bands
|
|
59
|
+
|
|
60
|
+
| Seed | Light scheme | Dark scheme | Hue |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| Canvas | L 0.92–0.98, C 0.02–0.06 (see below) | L 0.15–0.28, C 0.01–0.05 | brand hue or its harmony slot |
|
|
63
|
+
| Neutral / Alternate | L ≈ 0.55, C 0.008–0.02 | same | see chroma budget |
|
|
64
|
+
| Brand | L 0.45–0.62, C 0.12–0.20 | L 0.70–0.83, C cut by ~⅓ | the brief's identity hue |
|
|
65
|
+
| Accent | harmony slot, or ΔL ≥ 0.25 from Brand when the mode collapses hue distance | lighten/desaturate like Brand | harmony slot |
|
|
66
|
+
| Special | most expressive; default = Brand hue +60° at ~65% of Brand's C | same transform | harmony slot |
|
|
67
|
+
| Info | shared status L (0.55–0.65 light) | lighten like Brand | H 230–260 |
|
|
68
|
+
| Success | shared status L | same | H 140–155 |
|
|
69
|
+
| Warning | L ≥ 0.75 (vivid yellow must be light) | same | H 70–90 |
|
|
70
|
+
| Danger | shared status L, C 0.15–0.20 | same | H 20–30 |
|
|
71
|
+
|
|
72
|
+
- **The canvas carries the theme's identity — commit to it.** The page background is the largest area on screen and the strongest differentiator between themes; a timid canvas makes every theme look the same. Below C ≈ 0.015 at L ≥ 0.95 a tint is imperceptible: that near-white is a deliberate choice for clean/minimal briefs, never the default. Three escalating levels of commitment, matched to the brief:
|
|
73
|
+
1. *Tinted paper* (most UI briefs): a tint you can actually see — C 0.02–0.06, dropping L to 0.92–0.95 where the hue needs room.
|
|
74
|
+
2. *Colored ground* (expressive briefs): L 0.85–0.92 at C 0.05–0.10 — the page is unmistakably mint, parchment, sky.
|
|
75
|
+
3. *Full-color ground* (holiday and statement briefs): the canvas IS the theme color — a red Christmas page (0.40–0.48, C 0.12–0.16, H 25) with green and gold on it, an orange Halloween page. Keep canvas L ≤ ~0.48 or ≥ ~0.85 so text has somewhere to go; the contrast gate enforces legibility either way. A saturated background is a legitimate choice, not something to correct.
|
|
76
|
+
- **Gamut note for light canvases**: blue tints cap very low at high L (H 264 at L 0.95 barely reaches C 0.03) — for a blue-leaning canvas, lower L instead of fighting the ceiling; yellow/green/cream hues tint generously at high L.
|
|
77
|
+
- **When generating a set of themes, make the canvases pairwise distinct.** Any two Canvas seeds should differ noticeably in hue (at visible chroma) or in L. Two light themes both near (0.97, 0.01, anything) read as the same theme with different buttons. Dark canvases differentiate the same way: deep indigo, plum, and near-black violet are three different nights.
|
|
78
|
+
- **Dark scheme is a transform, not just a dark Canvas**: every chromatic seed lightens to L ≈ 0.75–0.85 and drops about a third of its chroma. Saturated color vibrates on dark grounds.
|
|
79
|
+
- **Equal lightness = equal weight**: give the four statuses one shared L; do the same for Brand vs Accent when they should balance.
|
|
80
|
+
- Status hues never rotate with the harmony; only their L/C adapt to the mood.
|
|
81
|
+
|
|
82
|
+
## Mood dials
|
|
83
|
+
|
|
84
|
+
Empirically: pleasantness rises with lightness (strongly) and saturation (weakly); energy/arousal rises with saturation; drama/dominance rises with dark + saturated.
|
|
85
|
+
|
|
86
|
+
| Brief says | Dials |
|
|
87
|
+
|---|---|
|
|
88
|
+
| cheerful, bright, playful | light scheme; Brand/Accent L 0.7–0.9, C 0.15–0.22; warm hues 40–140 (yellow is the strongest joy hue) |
|
|
89
|
+
| calm, serene, soft | light scheme; C 0.03–0.08 on everything chromatic; cool hues 140–260 |
|
|
90
|
+
| energetic, bold | C ≥ 0.18 at L 0.55–0.65; red/orange/magenta |
|
|
91
|
+
| dark, moody, dramatic, luxurious | dark scheme; Canvas L 0.15–0.25; purple, deep blue, crimson; keep working accents light per the dark transform, reserve dark-saturated color for one or two moments |
|
|
92
|
+
| professional, trustworthy | blue 230–265, C 0.08–0.15; everything else muted |
|
|
93
|
+
| warm / cool | hues 20–110 (plus pink 290–360) / hues 140–290 |
|
|
94
|
+
|
|
95
|
+
Avoid mid-lightness yellow-green (H 100–120 at L 0.5–0.7, C ≈ 0.1) unless the brief asks for olive/toxic.
|
|
96
|
+
|
|
97
|
+
## Gamut guardrails (don't request impossible seeds)
|
|
98
|
+
|
|
99
|
+
- Dark saturated yellow does not exist: H 90 at L 0.4 caps at C ≈ 0.08 and reads olive. Vivid yellow needs L ≥ 0.8. Brown = dark low-chroma orange.
|
|
100
|
+
- Vivid light blue does not exist: H 264 at L 0.9 caps at C ≈ 0.05. Rich blue lives at L 0.40–0.55.
|
|
101
|
+
- Teal/sky cap at C ≈ 0.15; a "vivid teal" is C 0.13–0.15.
|
|
102
|
+
- Peak chroma anchors: red H20 C 0.25 @ L 0.63; orange H60 C 0.18 @ L 0.76; yellow H90 C 0.18 @ L 0.86; green H140 C 0.28 @ L 0.88; blue H264 C 0.28 @ L 0.50; magenta H320 C 0.31 @ L 0.65.
|
|
103
|
+
|
|
104
|
+
The engine gamut-clamps regardless; these rules keep your *intent* achievable rather than silently muted.
|
|
105
|
+
|
|
106
|
+
## Choosing the harmony mode
|
|
107
|
+
|
|
108
|
+
Modes and hue offsets from Brand: complementary +180; split-complementary +150/+210; triadic +120/+240; tetradic +60/+180/+240; square +90 steps; compound +30/+180/+210; analogous ±30; monochromatic same hue.
|
|
109
|
+
|
|
110
|
+
- Vague or single-adjective brief → monochromatic or analogous; differentiate Accent from Brand by L/C, not hue. Polished-UI default: Accent = Brand's hue at ~45% chroma, Special = +60° at ~65% chroma.
|
|
111
|
+
- Brief names two colors → measure their hue gap and pick the matching mode (green + gold ≈ 60–90° → analogous/compound).
|
|
112
|
+
- Drama or maximum contrast → complementary/triadic/tetradic; then never pair max-chroma text with a near-black ground; tone one side down.
|
|
113
|
+
|
|
114
|
+
## The canvas sky (optional page-background gradient)
|
|
115
|
+
|
|
116
|
+
The brief may set `"canvasGradient": true` to render the page background as a
|
|
117
|
+
vertical gradient built from the Canvas ramp. The engine picks the stops itself
|
|
118
|
+
(two ramp steps from the Canvas anchor on the scheme's safe side), so the
|
|
119
|
+
choice you make is only *whether*, never *how*.
|
|
120
|
+
|
|
121
|
+
Default **off**. Turn it on only when the brief evokes atmosphere: sky, night,
|
|
122
|
+
dusk, dawn, sunset, glow, candlelight, underwater, depth — or when the user
|
|
123
|
+
asks for a gradient outright. Keep it off for crisp, clean, flat, minimal, or
|
|
124
|
+
corporate briefs, and whenever in doubt. Most themes should not have one; a sky
|
|
125
|
+
that appears on every generated theme stops meaning anything. When you enable
|
|
126
|
+
it, say why in one sentence when reporting back ("night brief → canvas sky").
|
|
127
|
+
|
|
128
|
+
A sky needs a committed canvas: when the Canvas seed anchors at the ramp edge
|
|
129
|
+
(near-white light canvas, near-black dark one) there is no room on the safe
|
|
130
|
+
side and the engine skips the sky, saying so in the report. An atmospheric
|
|
131
|
+
brief that wants one should already be at canvas commitment level 2–3.
|
|
132
|
+
|
|
133
|
+
## Named themes (canonical OKLCH anchors)
|
|
134
|
+
|
|
135
|
+
Holiday briefs are statement briefs — default to commitment level 2–3 above, not cream. The named colors go on the *ground*, not just the buttons.
|
|
136
|
+
|
|
137
|
+
- **Christmas**: red (0.53, 0.21, 22) + green (0.46, 0.11, 155) + gold (0.77, 0.14, 91). Strongest form: a full red canvas (0.42, 0.14, 25) with green Brand and gold Accent on it (dark scheme). Softer form: evergreen canvas (0.35, 0.07, 160) or deep cream (0.95, 0.04, 85). Never a 50/50 red-green split — one owns the ground, the other highlights.
|
|
138
|
+
- **Halloween**: pumpkin (0.70, 0.20, 46) + purple (0.51, 0.21, 313) + poison green (0.73, 0.20, 137). Strongest form: an orange canvas (0.45, 0.13, 55) with violet and poison-green accents; alternative: near-black violet canvas with pumpkin Brand. Dark scheme either way.
|
|
139
|
+
- **St. Patrick's**: green (0.51, 0.13, 152) Brand, gold Accent, white/beige neutrals.
|
|
140
|
+
- **Ocean**: deep blue (0.35, 0.08, 237) vs aqua (0.78, 0.12, 214); H 180–240.
|
|
141
|
+
- **Sunset**: hues 90 → 320 through red, L falling 0.85 → 0.40.
|
|
142
|
+
- **Autumn / Fall**: leaves and dry grass — canvas warm tan/parchment (0.87, 0.06, 80), rust Brand (0.55, 0.15, 40), golden Accent (0.75, 0.15, 85), moss/olive Special (0.55, 0.10, 120), warm brown neutrals H 50–70. Deep red H 25 welcome. **Spring**: pastels L 0.85–0.95, C 0.04–0.10, greens 130–150 / pinks 0–20, mint canvas.
|
|
143
|
+
|
|
144
|
+
## Scope
|
|
145
|
+
|
|
146
|
+
Fonts are never touched (they carry forward from the live look, as do shadows and component aliases). Swatch gradients (`--gradient-1..4`) carry forward when user-tuned; if they are absent or still stock, the engine rebuilds them from the new theme's families — you never author them. Radius is out of scope for generation. Shipping the theme stays a human action: Adopt, in the editor.
|
|
147
|
+
|
|
148
|
+
## Verify
|
|
149
|
+
|
|
150
|
+
- The CLI exits 0 and the report card shows every check ✓ (auto-corrected is fine).
|
|
151
|
+
- The app (dev server running) shows the new theme after a reload; the editor's Theme panel names it.
|
|
152
|
+
- If the user wants the previous look back, the CLI output names the theme that was open; load it from the Theme panel.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,275 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.48.0 — Themes are documents
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Loading is preview first.** Picking a theme in the Load window paints
|
|
8
|
+
it on the page while the window stays open: switch between looks freely,
|
|
9
|
+
then Save to keep one or Cancel to return to exactly what you had,
|
|
10
|
+
unsaved edits included. The preview is paint only; nothing touches disk
|
|
11
|
+
until Save. A "Colors and type only. Keep my shapes" toggle previews and
|
|
12
|
+
loads just a theme's palette and fonts over your current component
|
|
13
|
+
shapes, and your own saved colors-and-type files appear in the same list
|
|
14
|
+
under a badge, where that mode is implied.
|
|
15
|
+
|
|
16
|
+
- **One Theme panel.** The editor's separate colors-and-type and theme
|
|
17
|
+
managers merge into a single panel: one identity, Save, Save As, Load,
|
|
18
|
+
Import, Export. Colors & Type and a Components drift count appear as
|
|
19
|
+
read-only parts inside it, the way a component shows its parts. The seven
|
|
20
|
+
presets live in this panel's Load list and nowhere else. Save captures the
|
|
21
|
+
look on screen, the colors and type you have been editing included, so
|
|
22
|
+
there is no separate save first.
|
|
23
|
+
|
|
24
|
+
- **Adopt ships the whole look.** Production state and the Adopt action
|
|
25
|
+
live on the Theme panel's root card: one action saves the open theme and
|
|
26
|
+
publishes it, colors and type plus every component it carries, with one
|
|
27
|
+
CSS regeneration. Component editors hold their own unsaved state, which
|
|
28
|
+
the panel cannot write, so Save and Adopt both say how many components are
|
|
29
|
+
waiting on their own editors before they run.
|
|
30
|
+
|
|
31
|
+
- **`generate-theme` turns a mood brief into a complete theme.** `npx
|
|
32
|
+
live-tokens generate-theme <brief.json>` takes ten OKLCH seeds plus a
|
|
33
|
+
scheme, assembles the full curve set, enforces AA contrast with automatic
|
|
34
|
+
correction rounds, writes `themes/<slug>.json`, and opens it. The bundled
|
|
35
|
+
`live-tokens-generate-theme` skill translates natural-language briefs
|
|
36
|
+
("dark and moody night theme", "St. Patrick's Day with green and gold")
|
|
37
|
+
into seeds. Seven preset themes generated this way ship in the package:
|
|
38
|
+
Autumn, Halloween, Midnight Study, Ocean, Royal Velvet, Spring Meadow,
|
|
39
|
+
Sunset.
|
|
40
|
+
|
|
41
|
+
- **`adjust` moves shape and space along the token scales.** `npx
|
|
42
|
+
live-tokens adjust <ops.json>` shifts or sets every matching radius,
|
|
43
|
+
padding, gap, and border-width alias across component configs: relative
|
|
44
|
+
shifts preserve the cross-component hierarchy, `--radius-full` is a
|
|
45
|
+
gated rung so a global "softer" never silently turns the UI into
|
|
46
|
+
capsules, and spacing moves along the editor picker's 12-step subset so
|
|
47
|
+
every written value stays hand-editable. The result lands in each
|
|
48
|
+
component's unsaved buffer, so save the open theme to keep it. The bundled
|
|
49
|
+
`live-tokens-adjust-shape-space` skill maps "make the buttons pill
|
|
50
|
+
shaped", "make the UI softer", "space it out" onto ops files.
|
|
51
|
+
|
|
52
|
+
- **Gradients travel with the theme.** The `--gradient-N` swatch tokens
|
|
53
|
+
round-trip through colors-and-type files as a structured `gradients` field:
|
|
54
|
+
the editable type, angle, and stops, not just the rendered CSS strings, which
|
|
55
|
+
stay in `cssVariables` as a projection for production. Loading restores your
|
|
56
|
+
tuned gradients; files saved before the field existed keep the stock set they
|
|
57
|
+
rendered. `generate-theme` carries tuned gradients forward and rebuilds stock
|
|
58
|
+
ones from the new theme's color families.
|
|
59
|
+
|
|
60
|
+
- **Themes are encapsulated.** A theme now carries its whole look by value
|
|
61
|
+
(`schemaVersion: 3`): its full colors and type plus a copy of every
|
|
62
|
+
non-default component config. Deleting any colors-and-type or component
|
|
63
|
+
file never breaks a saved theme, and the import/export bundle is the same
|
|
64
|
+
format as the file on disk. Existing pointer themes migrate on first
|
|
65
|
+
dev-server start, resolving and embedding what they reference.
|
|
66
|
+
|
|
67
|
+
- **The seven presets ship as full example looks.** One theme per preset
|
|
68
|
+
embeds its colors and type plus a distinct shape personality and a Google
|
|
69
|
+
Fonts pairing: Halloween goes fully square with heavy borders and Mystery
|
|
70
|
+
Quest, Midnight Study pairs sharp windows and round buttons with EB
|
|
71
|
+
Garamond, and no two presets share a corner-radius and spacing profile or
|
|
72
|
+
a font family. Load one to try the complete look, load Motion Proto to
|
|
73
|
+
come back. `npm run generate:preset-themes` regenerates all seven from the
|
|
74
|
+
component defaults.
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- **Themes are documents; the working set is a buffer. (breaking)** A theme file
|
|
79
|
+
is the whole look, `themes/_active.json` names the one the editor has open,
|
|
80
|
+
and `themes/_production.json` names the one your site ships. Anything not yet
|
|
81
|
+
saved into a theme lives in one reserved slot per layer, `_working.json`, and
|
|
82
|
+
a slot exists only where the look sits off the shipped default, so a new
|
|
83
|
+
project has none. The per-layer `_active.json` / `_production.json` pointer
|
|
84
|
+
files, about fifty in a full tree, are retired, and applying a theme no longer
|
|
85
|
+
writes a copy of it under its own slug. The files that piled up, one set per
|
|
86
|
+
theme sampled, go with the mechanism that made them.
|
|
87
|
+
|
|
88
|
+
- **Trying a theme no longer publishes it. (breaking)** Loading a theme used to
|
|
89
|
+
set production in the same step, so sampling the presets rewrote
|
|
90
|
+
`tokens.generated.css` behind your back. Loading now opens the theme and does
|
|
91
|
+
nothing else. Adopt is the only action that changes what your site ships.
|
|
92
|
+
|
|
93
|
+
- **A component ships with its theme. (breaking)** Production is one saved theme
|
|
94
|
+
rather than a mix of per-slice pointers, so a component editor's Adopt saves
|
|
95
|
+
and publishes the open theme, that component with it. The per-slice promote
|
|
96
|
+
door is gone.
|
|
97
|
+
|
|
98
|
+
- **Existing projects need one `npx live-tokens migrate`.** It starts with the
|
|
99
|
+
directories: a project last opened on 0.47.1 or earlier keeps its colors and
|
|
100
|
+
type in `data/themes/` and its whole looks in `data/manifests/`, so the
|
|
101
|
+
migration moves `themes/` to `colors-and-type/` and `manifests/` to `themes/`
|
|
102
|
+
before reading a single file. Then it heals what is inside. It reads what the
|
|
103
|
+
retired pointers resolved to and records it as the production theme, keeps
|
|
104
|
+
live state that had drifted from the open theme as a buffer, deletes the
|
|
105
|
+
copies a saved theme already carries, and clears the pointer files. A file
|
|
106
|
+
matching no theme is yours and is kept; the effective production output never
|
|
107
|
+
changes without being written down as `themes/recovered-production.json`, so
|
|
108
|
+
that file appearing is the normal outcome when your live look had drifted from
|
|
109
|
+
the production pointers, not an error. `--check` prints the whole plan,
|
|
110
|
+
renames included. Until you run it the dev server leaves the data directory
|
|
111
|
+
alone: it writes nothing, rebuilds no CSS, refuses the editor's save doors,
|
|
112
|
+
and prints what to run. Restart it afterwards.
|
|
113
|
+
|
|
114
|
+
Two things to finish by hand. Token references that the migration repaired
|
|
115
|
+
reach `tokens.generated.css` on the next save and adopt, not at migration
|
|
116
|
+
time, so re-save your theme (make any edit, or Save As over it) and adopt it
|
|
117
|
+
once. And a `.gitignore` entry for `data/themes/_backups/` or
|
|
118
|
+
`data/manifests/_backups/` now names the wrong directory: any old backups move
|
|
119
|
+
with their directory, so repath the entry to `data/colors-and-type/_backups/`
|
|
120
|
+
or drop it.
|
|
121
|
+
|
|
122
|
+
- **`npm update` will not bring you here.** Pre-1.0 a caret range pins the
|
|
123
|
+
minor, so `^0.47.1` never resolves to 0.48.0. Ask for it by name: `npm
|
|
124
|
+
install @motion-proto/live-tokens@0.48.0`.
|
|
125
|
+
|
|
126
|
+
- **Re-copy the bundled skills.** `npx live-tokens setup-claude` copies the
|
|
127
|
+
Claude Code skills into your repo's `.claude/skills/`. That copy is a copy: it
|
|
128
|
+
does not follow the package, and a stale one describes CLIs and files this
|
|
129
|
+
release changed. Run the command again after upgrading, with `--force` to
|
|
130
|
+
overwrite.
|
|
131
|
+
|
|
132
|
+
- **The REST surface, before and after.** For anyone who proxies, mocks or
|
|
133
|
+
scripts `/api/live-tokens/*`. A door retired in place answers 405, so a caller
|
|
134
|
+
that still holds one gets an answer it can read. The `/manifests/*` paths are
|
|
135
|
+
not retired in place: they are gone, and the middleware passes them through to
|
|
136
|
+
your app like any unclaimed URL.
|
|
137
|
+
|
|
138
|
+
| Before, through 0.47.1 | Now |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `/themes`, `/themes/:name` (colors and type) | `/colors-and-type`, `/colors-and-type/:name` |
|
|
141
|
+
| `GET /themes/active`, `PUT /themes/active` | `GET /colors-and-type/active`; writes go to `PUT /colors-and-type/working` |
|
|
142
|
+
| `GET`/`PUT /themes/production` (colors and type) | `/colors-and-type/production`, 405 on every method |
|
|
143
|
+
| `PUT /component-configs/:comp/active` | `PUT /component-configs/:comp/working` |
|
|
144
|
+
| `GET`/`PUT /component-configs/:comp/production` | 405 on every method: a component ships with its theme |
|
|
145
|
+
| `/manifests`, `/manifests/:name`, `/manifests/:name/apply`, `/manifests/:name/export`, `/manifests/import` | the same shapes under `/themes` |
|
|
146
|
+
| `GET`/`PUT /manifests/active` | `GET`/`PUT /themes/active` |
|
|
147
|
+
| new | `PUT /production`: adopt the open theme, the only door that publishes |
|
|
148
|
+
| new | `GET /themes/production`: the whole theme your site ships |
|
|
149
|
+
| new | `GET`/`PUT`/`DELETE /colors-and-type/working` and `/component-configs/:comp/working` |
|
|
150
|
+
|
|
151
|
+
- **Public API. (breaking)** `setActiveFile`, `setProductionFile`,
|
|
152
|
+
`getProductionInfo`, the `ProductionInfo` type and the `activeFileName` store
|
|
153
|
+
leave with the per-layer pointers they drove. `getProductionTheme`,
|
|
154
|
+
`writeWorkingColorsAndType`, the `LiveSource` type and the `openThemeSlug`
|
|
155
|
+
store arrive.
|
|
156
|
+
|
|
157
|
+
- **CLIs follow the model.** `generate-theme` writes `themes/<slug>.json` and
|
|
158
|
+
opens it, instead of writing a colors-and-type file and flipping pointers at
|
|
159
|
+
it. `adjust` writes each touched component's buffer; its `--no-activate` flag
|
|
160
|
+
named files that no longer exist, so it is rejected with what to do instead.
|
|
161
|
+
`live-tokens migrate` runs the data heal alongside the tokens.css migrations.
|
|
162
|
+
|
|
163
|
+
- **One Theme panel, one save and load surface.** The editor sidebar holds a
|
|
164
|
+
single Theme panel: Save, Save As, Load with preview, Import, Export, the
|
|
165
|
+
production state and Adopt at the root, with Colors & Type and Components
|
|
166
|
+
as read-only parts under it. Colors and type stops being a file the user
|
|
167
|
+
manages: no list, no Save, no Save As, no lifecycle of its own. It names
|
|
168
|
+
the two faces the page is showing, and no working file name appears
|
|
169
|
+
anywhere in the panel.
|
|
170
|
+
|
|
171
|
+
- **Load can take colors and type alone.** "Colors and type only. Keep my
|
|
172
|
+
shapes." in the Load window previews and applies just the palette and the
|
|
173
|
+
fonts, leaving every component setting as it is. Older colors and type
|
|
174
|
+
files are listed there too, marked, and picking one is always that
|
|
175
|
+
narrower load. `GET /colors-and-type` marks each file `isPackage`, so a
|
|
176
|
+
local copy of a shipped preset stays reachable while the presets
|
|
177
|
+
themselves are offered once, as whole themes.
|
|
178
|
+
|
|
179
|
+
- **The Default theme is written and regenerated at boot.** It is a full set
|
|
180
|
+
derived from the package default colors and type and each component's
|
|
181
|
+
`:global(:root)` defaults, rewritten whenever the derived content drifts
|
|
182
|
+
and restored if deleted outside the file manager. The package no longer
|
|
183
|
+
ships the file; a consumer's boot always materializes a current local
|
|
184
|
+
copy.
|
|
185
|
+
|
|
186
|
+
- **Almost everything is deletable.** Colors-and-type and component files are
|
|
187
|
+
presets now, so nothing live points at one and any of them can go. Deleting
|
|
188
|
+
the theme you have open is legal too: the buffer survives its document, so
|
|
189
|
+
the look on screen stays, and open heals to the shipped version if one
|
|
190
|
+
shadows it, otherwise to Default. Three refusals remain, each about
|
|
191
|
+
something a delete would break: the protected `default` name, the theme in
|
|
192
|
+
production, and a shipped file with no local copy.
|
|
193
|
+
|
|
194
|
+
- **Load applies the complete look.** Loading a theme opens it: its embedded
|
|
195
|
+
copies fill the working buffer and components it does not carry go back to
|
|
196
|
+
their defaults. Components that are not installed are skipped and reported
|
|
197
|
+
instead of silently ignored.
|
|
198
|
+
|
|
199
|
+
- **"Manifest" retires; a theme is the whole look.** The file that carries a
|
|
200
|
+
complete look is a **theme**, and the colors-and-typography layer inside it
|
|
201
|
+
is **Colors & Type**. Every surface follows: `data/manifests/` →
|
|
202
|
+
`data/themes/` and the old `data/themes/` → `data/colors-and-type/`;
|
|
203
|
+
`/api/live-tokens/manifests/*` → `/api/live-tokens/themes/*` and the old
|
|
204
|
+
`/api/live-tokens/themes/*` → `/api/live-tokens/colors-and-type/*`; the
|
|
205
|
+
public exports `listManifests`, `applyManifest`, `saveAsManifest` and their
|
|
206
|
+
siblings become `listThemes`, `applyTheme`, `saveAsTheme`; `npm run
|
|
207
|
+
generate:preset-manifests` and `collapse:manifest` become
|
|
208
|
+
`generate:preset-themes` and `collapse:theme`. The manifest family never
|
|
209
|
+
shipped, and the routes ship as a matched client and server pair, so no
|
|
210
|
+
compatibility shim exists anywhere. The one key a consumer must act on is
|
|
211
|
+
below.
|
|
212
|
+
|
|
213
|
+
- **Config keys follow the vocabulary.** `themesDir` now names the whole-look
|
|
214
|
+
directory, the meaning `manifestsDir` used to carry; the new
|
|
215
|
+
`colorsAndTypeDir` names the colors-and-typography directory that
|
|
216
|
+
`themesDir` used to name. A consumer that set `themesDir` in
|
|
217
|
+
`live-tokens.config.json` before this release must rename it to
|
|
218
|
+
`colorsAndTypeDir`.
|
|
219
|
+
|
|
220
|
+
- **A theme file is `schemaVersion: 3`.** The embedded key `theme` becomes
|
|
221
|
+
`colorsAndType`. The boot migration carries a v1 pointer file or a v2
|
|
222
|
+
encapsulated file to v3 in one pass. Export writes `kind: "theme-bundle"`
|
|
223
|
+
at that version; the `manifest-bundle` kind every release through 0.47.1
|
|
224
|
+
wrote is still imported, and only at its own v1, so a crossed pair stays
|
|
225
|
+
rejected.
|
|
226
|
+
|
|
227
|
+
### Fixed
|
|
228
|
+
|
|
229
|
+
- **Dead shape and space keys dropped from every colors-and-type file**
|
|
230
|
+
(colors-and-type schema version 4): the `--badge-trait-*`,
|
|
231
|
+
`--sectiondivider-padding`, and `--dialog-{primary,secondary}-*` shape keys
|
|
232
|
+
had no consumers since their components were restructured; a migration
|
|
233
|
+
removes them from `cssVariables`.
|
|
234
|
+
|
|
235
|
+
- **Line-height references follow the scale that was renamed under them**
|
|
236
|
+
(colors-and-type schema version 5, component-config schema version 21):
|
|
237
|
+
0.41.0 reshaped `--line-height-{xs..xl}` into leading vocabulary in
|
|
238
|
+
`tokens.css`, but nothing carried a saved file's references across, so every
|
|
239
|
+
one of them pointed at a token that no longer existed. Both layers now migrate
|
|
240
|
+
on load, a colors-and-type file's `cssVariables` and a component config's
|
|
241
|
+
alias values alike: `xs` to `none`, `sm` to `tighter`, `md` to `normal`, `lg`
|
|
242
|
+
to `relaxed`. The retired 2.0 slot (`xl`) lands on `relaxed`, the nearest
|
|
243
|
+
surviving step, which is a visible change to any line that used it.
|
|
244
|
+
|
|
245
|
+
- **A colors-and-type file left among the themes is refused, not read as a
|
|
246
|
+
theme.** Both kinds carry a `schemaVersion` and the sequences overlap, so one
|
|
247
|
+
parsed as a current theme whose colors resolved to the package default: it
|
|
248
|
+
listed as a theme that painted the shipped look, and the boot migration
|
|
249
|
+
rewrote it, taking the palette with it. Every door that reads a theme off disk
|
|
250
|
+
now checks the shape, answers 422, and leaves the file alone.
|
|
251
|
+
|
|
252
|
+
- **Adopting while a shipped theme is active records the adoption.** The
|
|
253
|
+
adopt path used to return success while writing nothing when the active
|
|
254
|
+
theme resolved from the package; it now forks the theme locally,
|
|
255
|
+
shadow-and-restore style.
|
|
256
|
+
|
|
257
|
+
- **Orphan component-config directories removed** (`detailnav`, `stateditor`,
|
|
258
|
+
`slotprobe`, `floatingtokentags`): no shipped component reads them.
|
|
259
|
+
|
|
260
|
+
- **`collapse-theme-to-default` no longer drops `harmonyAxes`** or coerces a
|
|
261
|
+
missing `fontStacks` to an empty object when baking a theme into the
|
|
262
|
+
shipped defaults.
|
|
263
|
+
|
|
264
|
+
### Known limitations
|
|
265
|
+
|
|
266
|
+
- **Production freshness resets on reload.** Nothing on disk records when the
|
|
267
|
+
last bake happened, so the editor tracks it for the session. Save a theme
|
|
268
|
+
after adopting it and the panel reads "out of sync" until you adopt again,
|
|
269
|
+
which is right; reload the page and it reads "in production" again while the
|
|
270
|
+
baked CSS is a version behind. Adopt when in doubt, it costs nothing to
|
|
271
|
+
repeat.
|
|
272
|
+
|
|
3
273
|
## 0.47.1 — Straightened curves
|
|
4
274
|
|
|
5
275
|
### Fixed
|