@motion-proto/live-tokens 0.47.0 → 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.
Files changed (124) hide show
  1. package/.claude/skills/live-tokens-adjust-shape-space/SKILL.md +68 -0
  2. package/.claude/skills/live-tokens-create-component/SKILL.md +2 -2
  3. package/.claude/skills/live-tokens-generate-theme/SKILL.md +152 -0
  4. package/CHANGELOG.md +292 -0
  5. package/README.md +37 -26
  6. package/bin/adjust.mjs +254 -0
  7. package/bin/cli.mjs +94 -7
  8. package/bin/generate-theme.mjs +251 -0
  9. package/bin/migrate.mjs +95 -6
  10. package/dist-plugin/adjust/index.cjs +259 -0
  11. package/dist-plugin/adjust/index.d.cts +45 -0
  12. package/dist-plugin/adjust/index.d.ts +45 -0
  13. package/dist-plugin/adjust/index.js +176 -0
  14. package/dist-plugin/{chunk-H4TRUINI.js → chunk-44RSTAII.js} +0 -48
  15. package/dist-plugin/chunk-6OZFXIQI.js +316 -0
  16. package/dist-plugin/chunk-76TFDTJO.js +556 -0
  17. package/dist-plugin/chunk-D3ZVKOR4.js +52 -0
  18. package/dist-plugin/dataPaths-DBN0RPuT.d.cts +54 -0
  19. package/dist-plugin/dataPaths-DBN0RPuT.d.ts +54 -0
  20. package/dist-plugin/generateColorsAndType/index.cjs +1781 -0
  21. package/dist-plugin/generateColorsAndType/index.d.cts +81 -0
  22. package/dist-plugin/generateColorsAndType/index.d.ts +81 -0
  23. package/dist-plugin/generateColorsAndType/index.js +1210 -0
  24. package/dist-plugin/index.cjs +901 -533
  25. package/dist-plugin/index.d.cts +3 -2
  26. package/dist-plugin/index.d.ts +3 -2
  27. package/dist-plugin/index.js +658 -1082
  28. package/dist-plugin/migrateData/index.cjs +728 -0
  29. package/dist-plugin/migrateData/index.d.cts +60 -0
  30. package/dist-plugin/migrateData/index.d.ts +60 -0
  31. package/dist-plugin/migrateData/index.js +348 -0
  32. package/dist-plugin/themeTypes-DMHZOnUn.d.cts +211 -0
  33. package/dist-plugin/themeTypes-DMHZOnUn.d.ts +211 -0
  34. package/dist-plugin/tokensCssMigrations/index.cjs +2 -1
  35. package/dist-plugin/tokensCssMigrations/index.d.cts +3 -15
  36. package/dist-plugin/tokensCssMigrations/index.d.ts +3 -15
  37. package/dist-plugin/tokensCssMigrations/index.js +4 -2
  38. package/package.json +18 -4
  39. package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +183 -158
  40. package/src/editor/component-editor/scaffolding/ComponentFileMenu.svelte +0 -4
  41. package/src/editor/component-editor/scaffolding/SaveAsDialog.svelte +4 -4
  42. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +2 -59
  43. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +1 -1
  44. package/src/editor/core/components/adjustAliases.ts +180 -0
  45. package/src/editor/core/components/aliasKinds.ts +73 -0
  46. package/src/editor/core/components/componentConfigService.ts +26 -38
  47. package/src/editor/core/flashStatus.ts +1 -1
  48. package/src/editor/core/fonts/fontMigration.ts +13 -13
  49. package/src/editor/core/fonts/fontPairing.ts +35 -0
  50. package/src/editor/core/palettes/paletteDerivation.ts +128 -16
  51. package/src/editor/core/preview/lookPreview.ts +141 -0
  52. package/src/editor/core/productionPulse.ts +34 -21
  53. package/src/editor/core/storage/files/versionedFileResourceClient.ts +18 -45
  54. package/src/editor/core/store/editorConfigStore.ts +2 -2
  55. package/src/editor/core/store/editorPersistence.ts +0 -1
  56. package/src/editor/core/store/editorStore.ts +114 -51
  57. package/src/editor/core/store/editorTypes.ts +0 -1
  58. package/src/editor/core/store/gradientSource.ts +2 -2
  59. package/src/editor/core/themes/colorsAndTypeService.ts +95 -0
  60. package/src/editor/core/themes/generateColorsAndType.ts +433 -0
  61. package/src/editor/core/themes/loadRows.ts +64 -0
  62. package/src/editor/core/themes/lookSummary.ts +75 -0
  63. package/src/editor/core/themes/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +3 -3
  64. package/src/editor/core/themes/migrations/2026-05-13-primary-to-brand.ts +2 -2
  65. package/src/editor/core/themes/migrations/2026-05-26-drop-overlay-extra-stops.ts +3 -3
  66. package/src/editor/core/themes/migrations/2026-08-13-drop-legacy-shape-space-keys.ts +38 -0
  67. package/src/editor/core/themes/migrations/2026-08-15-line-height-scale-rename.ts +57 -0
  68. package/src/editor/core/themes/migrations/index.ts +19 -11
  69. package/src/editor/core/themes/slices/components.ts +4 -4
  70. package/src/editor/core/themes/slices/fonts.ts +1 -1
  71. package/src/editor/core/themes/slices/gradients.ts +22 -0
  72. package/src/editor/core/themes/slices/palettes.ts +2 -2
  73. package/src/editor/core/themes/themeInit.ts +21 -29
  74. package/src/editor/core/themes/themeService.ts +218 -78
  75. package/src/editor/core/themes/themeTypes.ts +94 -51
  76. package/src/editor/docs/Docs.svelte +1 -0
  77. package/src/editor/docs/chapters.ts +1 -0
  78. package/src/editor/docs/content/01-overview.md +1 -1
  79. package/src/editor/docs/content/editing-tokens.md +6 -6
  80. package/src/editor/docs/content/getting-started.md +9 -7
  81. package/src/editor/docs/content/themes-workflow.md +74 -34
  82. package/src/editor/docs/content/where-themes-live.md +61 -0
  83. package/src/editor/docs/content.generated.ts +5 -4
  84. package/src/editor/index.ts +27 -27
  85. package/src/editor/pages/ComponentEditorPage.svelte +2 -2
  86. package/src/editor/pages/EditorShell.svelte +4 -30
  87. package/src/editor/ui/BezierCurveEditor.svelte +2 -2
  88. package/src/editor/ui/ColorEditPanel.svelte +1 -1
  89. package/src/editor/ui/FileLoadList.svelte +67 -7
  90. package/src/editor/ui/GradientEditor.svelte +3 -3
  91. package/src/editor/ui/PaletteEditor.svelte +26 -12
  92. package/src/editor/ui/ThemePanel.svelte +1067 -0
  93. package/src/editor/ui/UIDialog.svelte +11 -9
  94. package/src/editor/ui/UIPillButton.svelte +7 -2
  95. package/src/editor/ui/colors/ColorWheel.svelte +34 -1
  96. package/src/editor/ui/curveEngine.ts +48 -0
  97. package/src/editor/ui/index.ts +4 -2
  98. package/src/editor/ui/palette/PaletteBase.svelte +75 -51
  99. package/src/editor/ui/palette/PaletteJumpButton.svelte +3 -8
  100. package/src/live-tokens/data/colors-and-type/autumn.json +2490 -0
  101. package/src/live-tokens/data/{themes → colors-and-type}/default.json +816 -293
  102. package/src/live-tokens/data/colors-and-type/halloween.json +2529 -0
  103. package/src/live-tokens/data/colors-and-type/midnight-study.json +2536 -0
  104. package/src/live-tokens/data/colors-and-type/ocean.json +2489 -0
  105. package/src/live-tokens/data/colors-and-type/royal-velvet.json +2520 -0
  106. package/src/live-tokens/data/colors-and-type/spring-meadow.json +2476 -0
  107. package/src/live-tokens/data/colors-and-type/sunset.json +2528 -0
  108. package/src/live-tokens/data/themes/autumn.json +3918 -0
  109. package/src/live-tokens/data/themes/halloween.json +3992 -0
  110. package/src/live-tokens/data/themes/midnight-study.json +3932 -0
  111. package/src/live-tokens/data/themes/ocean.json +3917 -0
  112. package/src/live-tokens/data/themes/royal-velvet.json +3983 -0
  113. package/src/live-tokens/data/themes/spring-meadow.json +3904 -0
  114. package/src/live-tokens/data/themes/sunset.json +3931 -0
  115. package/src/live-tokens/data/tokens.generated.css +106 -117
  116. package/src/system/styles/CONVENTIONS.md +1 -1
  117. package/src/system/styles/fonts.css +1 -1
  118. package/template/README.md +7 -5
  119. package/template/_gitignore +0 -6
  120. package/src/editor/core/components/componentPersist.ts +0 -62
  121. package/src/editor/core/manifests/manifestService.ts +0 -172
  122. package/src/editor/ui/ManifestFileManager.svelte +0 -446
  123. package/src/editor/ui/ThemeFileManager.svelte +0 -785
  124. package/src/live-tokens/data/manifests/default.json +0 -35
@@ -1,4 +1,4 @@
1
- /* Generated by themeFileApi from the production theme and component configs. Do not edit. */
1
+ /* Generated by themeFileApi from the production theme. Do not edit. */
2
2
  /* tokens.css holds developer-authored defaults; this file holds editor overrides. */
3
3
 
4
4
  /* Production theme: default */
@@ -15,10 +15,7 @@
15
15
  --badge-trait-text-line-height: var(--line-height-none);
16
16
  --badge-trait-border: var(--border-brand-medium);
17
17
  --badge-trait-border-width: var(--border-width-1);
18
- --badge-trait-radius: var(--radius-full);
19
- --badge-trait-padding: var(--space-6);
20
18
  --badge-trait-shadow: transparent;
21
- --sectiondivider-padding: var(--space-16);
22
19
  --sectiondivider-title: var(--text-primary);
23
20
  --sectiondivider-title-font-family: var(--font-display);
24
21
  --sectiondivider-title-font-size: var(--font-size-5xl);
@@ -35,25 +32,17 @@
35
32
  --dialog-primary-default-text: var(--text-primary);
36
33
  --dialog-primary-default-border: var(--border-neutral-medium);
37
34
  --dialog-primary-default-border-width: var(--border-width-1);
38
- --dialog-primary-default-radius: var(--radius-md);
39
- --dialog-primary-default-padding: var(--space-8);
40
35
  --dialog-primary-hover-surface: var(--surface-neutral-higher);
41
36
  --dialog-primary-hover-text: var(--text-primary);
42
37
  --dialog-primary-hover-border: var(--border-neutral-strong);
43
38
  --dialog-primary-hover-border-width: var(--border-width-1);
44
- --dialog-primary-hover-radius: var(--radius-md);
45
- --dialog-primary-hover-padding: var(--space-8);
46
39
  --dialog-secondary-default-text: var(--text-primary);
47
40
  --dialog-secondary-default-border: var(--border-neutral-medium);
48
41
  --dialog-secondary-default-border-width: var(--border-width-1);
49
- --dialog-secondary-default-radius: var(--radius-md);
50
- --dialog-secondary-default-padding: var(--space-8);
51
42
  --dialog-secondary-hover-surface: var(--surface-neutral-lower);
52
43
  --dialog-secondary-hover-text: var(--text-primary);
53
44
  --dialog-secondary-hover-border: var(--border-neutral-strong);
54
45
  --dialog-secondary-hover-border-width: var(--border-width-1);
55
- --dialog-secondary-hover-radius: var(--radius-md);
56
- --dialog-secondary-hover-padding: var(--space-8);
57
46
  --columns-count: 12;
58
47
  --columns-max-width: 1440px;
59
48
  --columns-gutter: 32px;
@@ -69,17 +58,17 @@
69
58
  --shadow-lg: 5px 5px 9px 0px hsla(237, 18%, 3%, 0.9);
70
59
  --shadow-xl: 6px 7px 13px 0px hsla(237, 18%, 3%, 0.9);
71
60
  --shadow-2xl: 8px 9px 16px 0px hsla(237, 18%, 3%, 0.9);
72
- --color-brand-100: #ffbad3;
73
- --color-brand-200: #ff7fb5;
74
- --color-brand-300: #ff49a1;
75
- --color-brand-400: #fa3199;
76
- --color-brand-500: #fb2898;
77
- --color-brand-600: #df0083;
78
- --color-brand-700: #930055;
79
- --color-brand-800: #5c0033;
80
- --color-brand-850: #38001d;
81
- --color-brand-900: #20000e;
82
- --color-brand-950: #100005;
61
+ --color-brand-100: #ffe7ef;
62
+ --color-brand-200: #ffb5d1;
63
+ --color-brand-300: #ff7cb3;
64
+ --color-brand-400: #fb2898;
65
+ --color-brand-500: #d5007d;
66
+ --color-brand-600: #ab0064;
67
+ --color-brand-700: #85004c;
68
+ --color-brand-800: #610036;
69
+ --color-brand-850: #400022;
70
+ --color-brand-900: #21000f;
71
+ --color-brand-950: #070002;
83
72
  --surface-brand-lowest: #1d000c;
84
73
  --surface-brand-lower: #3e0020;
85
74
  --surface-brand-low: #620037;
@@ -97,17 +86,17 @@
97
86
  --text-brand-tertiary: #953b63;
98
87
  --text-brand-muted: #5c3846;
99
88
  --text-brand-disabled: #403337;
100
- --color-accent-100: #98e1dd;
101
- --color-accent-200: #70beba;
102
- --color-accent-300: #4ba09c;
103
- --color-accent-400: #248582;
104
- --color-accent-500: #006b69;
105
- --color-accent-600: #005351;
106
- --color-accent-700: #003e3d;
107
- --color-accent-800: #002c2b;
108
- --color-accent-850: #001d1c;
109
- --color-accent-900: #00100f;
110
- --color-accent-950: #000606;
89
+ --color-accent-100: #b4fffb;
90
+ --color-accent-200: #84e9e5;
91
+ --color-accent-300: #6ad0cc;
92
+ --color-accent-400: #50b8b4;
93
+ --color-accent-500: #329f9b;
94
+ --color-accent-600: #008582;
95
+ --color-accent-700: #006866;
96
+ --color-accent-800: #004b49;
97
+ --color-accent-850: #002f2e;
98
+ --color-accent-900: #001514;
99
+ --color-accent-950: #000202;
111
100
  --surface-accent-lowest: #000f0e;
112
101
  --surface-accent-lower: #002423;
113
102
  --surface-accent-low: #003c3b;
@@ -125,17 +114,17 @@
125
114
  --text-accent-tertiary: #4d7271;
126
115
  --text-accent-muted: #3c4847;
127
116
  --text-accent-disabled: #313232;
128
- --color-special-100: #d2c8ff;
129
- --color-special-200: #b19cff;
130
- --color-special-300: #9673f5;
131
- --color-special-400: #7d54db;
132
- --color-special-500: #6634c4;
133
- --color-special-600: #5407af;
134
- --color-special-700: #3f0088;
135
- --color-special-800: #2d0064;
136
- --color-special-850: #1d0046;
137
- --color-special-900: #10002d;
138
- --color-special-950: #060019;
117
+ --color-special-100: #efecff;
118
+ --color-special-200: #d3caff;
119
+ --color-special-300: #b9a7ff;
120
+ --color-special-400: #a282ff;
121
+ --color-special-500: #8b5cf6;
122
+ --color-special-600: #733ed8;
123
+ --color-special-700: #5c1bba;
124
+ --color-special-800: #430090;
125
+ --color-special-850: #2a005f;
126
+ --color-special-900: #130033;
127
+ --color-special-950: #03000d;
139
128
  --surface-special-lowest: #0f002b;
140
129
  --surface-special-lower: #250055;
141
130
  --surface-special-low: #3d0084;
@@ -153,17 +142,17 @@
153
142
  --text-special-tertiary: #5c4e8b;
154
143
  --text-special-muted: #3e3a4f;
155
144
  --text-special-disabled: #303032;
156
- --color-canvas-100: #cecfe5;
157
- --color-canvas-200: #abacc2;
158
- --color-canvas-300: #8d8da4;
159
- --color-canvas-400: #727289;
160
- --color-canvas-500: #5a5a72;
161
- --color-canvas-600: #45455c;
162
- --color-canvas-700: #33324a;
163
- --color-canvas-800: #232239;
164
- --color-canvas-850: #15142b;
165
- --color-canvas-900: #0b081f;
166
- --color-canvas-950: #040215;
145
+ --color-canvas-100: #ecedff;
146
+ --color-canvas-200: #d0d0ed;
147
+ --color-canvas-300: #b6b6d2;
148
+ --color-canvas-400: #9c9db8;
149
+ --color-canvas-500: #84849e;
150
+ --color-canvas-600: #6b6c85;
151
+ --color-canvas-700: #53546c;
152
+ --color-canvas-800: #3c3c53;
153
+ --color-canvas-850: #25243a;
154
+ --color-canvas-900: #0f0e21;
155
+ --color-canvas-950: #02000b;
167
156
  --surface-canvas-lowest: #0a0523;
168
157
  --surface-canvas-lower: #1c1a37;
169
158
  --surface-canvas-low: #31304c;
@@ -184,15 +173,15 @@
184
173
  --page-bg: #3c3c53;
185
174
  --page-bg-attachment: scroll;
186
175
  --color-neutral-100: #dde6ed;
187
- --color-neutral-200: #c4cdd4;
188
- --color-neutral-300: #a8b0b7;
189
- --color-neutral-400: #8c949a;
176
+ --color-neutral-200: #c1c9d0;
177
+ --color-neutral-300: #a5adb4;
178
+ --color-neutral-400: #8a9299;
190
179
  --color-neutral-500: #70787e;
191
- --color-neutral-600: #565d63;
192
- --color-neutral-700: #3d4449;
193
- --color-neutral-800: #252c31;
194
- --color-neutral-850: #10161b;
195
- --color-neutral-900: #020407;
180
+ --color-neutral-600: #575e64;
181
+ --color-neutral-700: #3f464b;
182
+ --color-neutral-800: #282f34;
183
+ --color-neutral-850: #13191e;
184
+ --color-neutral-900: #03060a;
196
185
  --color-neutral-950: #000000;
197
186
  --surface-neutral-lowest: #040c13;
198
187
  --surface-neutral-lower: #162027;
@@ -213,16 +202,16 @@
213
202
  --text-disabled: #383838;
214
203
  --text-inverted: #0f0f0f;
215
204
  --color-alternate-100: #eae3e0;
216
- --color-alternate-200: #d2cbc8;
217
- --color-alternate-300: #b7b1ad;
218
- --color-alternate-400: #9c9693;
205
+ --color-alternate-200: #cfc8c5;
206
+ --color-alternate-300: #b5aeab;
207
+ --color-alternate-400: #9b9591;
219
208
  --color-alternate-500: #817b78;
220
- --color-alternate-600: #68625f;
221
- --color-alternate-700: #4f4947;
222
- --color-alternate-800: #383330;
223
- --color-alternate-850: #221d1b;
224
- --color-alternate-900: #0f0b08;
225
- --color-alternate-950: #030101;
209
+ --color-alternate-600: #67615e;
210
+ --color-alternate-700: #4e4845;
211
+ --color-alternate-800: #35302d;
212
+ --color-alternate-850: #1e1917;
213
+ --color-alternate-900: #090604;
214
+ --color-alternate-950: #000000;
226
215
  --surface-alternate-lowest: #100907;
227
216
  --surface-alternate-lower: #241d19;
228
217
  --surface-alternate-low: #39322f;
@@ -240,17 +229,17 @@
240
229
  --text-alternate-tertiary: #8a8786;
241
230
  --text-alternate-muted: #545352;
242
231
  --text-alternate-disabled: #3b3b3b;
243
- --color-info-100: #9adbff;
244
- --color-info-200: #4ebbf1;
245
- --color-info-300: #109bd4;
246
- --color-info-400: #007fae;
247
- --color-info-500: #00658c;
248
- --color-info-600: #004e6d;
249
- --color-info-700: #003a53;
250
- --color-info-800: #00293c;
251
- --color-info-850: #001a28;
252
- --color-info-900: #000e18;
253
- --color-info-950: #00050b;
232
+ --color-info-100: #ddf2ff;
233
+ --color-info-200: #8fd7ff;
234
+ --color-info-300: #00bbff;
235
+ --color-info-400: #009dd7;
236
+ --color-info-500: #0081b1;
237
+ --color-info-600: #00678f;
238
+ --color-info-700: #004f6f;
239
+ --color-info-800: #003850;
240
+ --color-info-850: #002334;
241
+ --color-info-900: #00101a;
242
+ --color-info-950: #000205;
254
243
  --surface-info-lowest: #000d17;
255
244
  --surface-info-lower: #002232;
256
245
  --surface-info-low: #003951;
@@ -268,17 +257,17 @@
268
257
  --text-info-tertiary: #1c506a;
269
258
  --text-info-muted: #1d2c34;
270
259
  --text-info-disabled: #181a1b;
271
- --color-success-100: #92e9a3;
272
- --color-success-200: #69c67e;
273
- --color-success-300: #42a75d;
274
- --color-success-400: #0e8c3f;
275
- --color-success-500: #007030;
276
- --color-success-600: #005723;
277
- --color-success-700: #004119;
278
- --color-success-800: #002f0f;
279
- --color-success-850: #001e08;
280
- --color-success-900: #001103;
281
- --color-success-950: #000701;
260
+ --color-success-100: #c7ffd1;
261
+ --color-success-200: #77f194;
262
+ --color-success-300: #59d47a;
263
+ --color-success-400: #38b85f;
264
+ --color-success-500: #009c45;
265
+ --color-success-600: #007e36;
266
+ --color-success-700: #006128;
267
+ --color-success-800: #00461b;
268
+ --color-success-850: #002c0e;
269
+ --color-success-900: #001404;
270
+ --color-success-950: #000300;
282
271
  --surface-success-lowest: #001003;
283
272
  --surface-success-lower: #00270b;
284
273
  --surface-success-low: #004018;
@@ -296,17 +285,17 @@
296
285
  --text-success-tertiary: #31673e;
297
286
  --text-success-muted: #2c4530;
298
287
  --text-success-disabled: #263429;
299
- --color-warning-100: #ffc673;
300
- --color-warning-200: #dfa13f;
301
- --color-warning-300: #c08100;
302
- --color-warning-400: #9c6900;
303
- --color-warning-500: #7d5300;
304
- --color-warning-600: #624000;
305
- --color-warning-700: #4a2f00;
306
- --color-warning-800: #352000;
307
- --color-warning-850: #231400;
308
- --color-warning-900: #140a00;
309
- --color-warning-950: #090300;
288
+ --color-warning-100: #ffebd1;
289
+ --color-warning-200: #ffd08e;
290
+ --color-warning-300: #ffb01f;
291
+ --color-warning-400: #e09800;
292
+ --color-warning-500: #be8000;
293
+ --color-warning-600: #9b6800;
294
+ --color-warning-700: #784f00;
295
+ --color-warning-800: #563800;
296
+ --color-warning-850: #362100;
297
+ --color-warning-900: #190d00;
298
+ --color-warning-950: #040100;
310
299
  --surface-warning-lowest: #130900;
311
300
  --surface-warning-lower: #372200;
312
301
  --surface-warning-low: #613f00;
@@ -324,17 +313,17 @@
324
313
  --text-warning-tertiary: #a17e4c;
325
314
  --text-warning-muted: #685d4d;
326
315
  --text-warning-disabled: #4d4b4a;
327
- --color-danger-100: #ffbeb8;
328
- --color-danger-200: #ff847d;
329
- --color-danger-300: #ec5552;
330
- --color-danger-400: #d02d33;
331
- --color-danger-500: #b0001c;
332
- --color-danger-600: #8a0013;
333
- --color-danger-700: #6a000c;
334
- --color-danger-800: #4d0006;
335
- --color-danger-850: #350003;
336
- --color-danger-900: #210001;
337
- --color-danger-950: #110000;
316
+ --color-danger-100: #ffe9e6;
317
+ --color-danger-200: #ffc3bd;
318
+ --color-danger-300: #ff9a93;
319
+ --color-danger-400: #ff6a65;
320
+ --color-danger-500: #f0373e;
321
+ --color-danger-600: #d10023;
322
+ --color-danger-700: #a40019;
323
+ --color-danger-800: #78000f;
324
+ --color-danger-850: #4e0006;
325
+ --color-danger-900: #280002;
326
+ --color-danger-950: #080000;
338
327
  --surface-danger-lowest: #1f0001;
339
328
  --surface-danger-lower: #410004;
340
329
  --surface-danger-low: #67000c;
@@ -37,7 +37,7 @@ Editor chrome uses **only** the `--ui-*` font namespace (`--ui-font-sans`, `--ui
37
37
 
38
38
  ## Layer 1 — theme tokens (`tokens.css`)
39
39
 
40
- Theme tokens are the design system's vocabulary. They describe colors, sizes, spacing, shadows, and motion: the things a designer reasons about independent of any one component. Components consume them, and themes in `themes/*.json` recolor or re-scale them.
40
+ Theme tokens are the design system's vocabulary. They describe colors, sizes, spacing, shadows, and motion: the things a designer reasons about independent of any one component. Components consume them, and the colors-and-type files in `colors-and-type/*.json` recolor or re-scale them.
41
41
 
42
42
  ### Category-first naming
43
43
 
@@ -1,4 +1,4 @@
1
- /* Generated from the production theme by syncFontsToCss. Do not edit. */
1
+ /* Generated from the production colors and type by syncFontsToCss. Do not edit. */
2
2
  /* Both fonts.css and fonts/ are in dist/, so relative paths work at runtime. */
3
3
 
4
4
  /* Adobe Typekit — fira-code */
@@ -18,16 +18,18 @@ This project follows the package's [recommended layout](https://github.com/motio
18
18
  a reserved `/live-tokens/*` namespace (so they never collide with your pages):
19
19
  `/live-tokens/editor` (theme tokens), `/live-tokens/components` (per-component
20
20
  aliases), and `/live-tokens/docs` (the user guide).
21
- - `src/system/styles/tokens.css` — your theme token vocabulary. The dev server
22
- writes edits here when you use the in-browser editor.
21
+ - `src/system/styles/tokens.css` — your theme token vocabulary. Hand-authored
22
+ and yours; the editor reads it but never writes it.
23
23
  - `src/styles/site.css` — themed page typography. Yours to edit.
24
24
 
25
25
  ## Editing live
26
26
 
27
27
  Run `npm run dev`, then click **Open Token Editor** on the home page (or visit
28
- `/live-tokens/editor`). Changes persist to `src/system/styles/tokens.css` and the JSON under
29
- `src/live-tokens/data/`. The editor is dev-only — `npm run build` ships plain
30
- CSS variables and the components you used, nothing else.
28
+ `/live-tokens/editor`). Edits live in the JSON under `src/live-tokens/data/`:
29
+ Save keeps them in a theme, and Adopt writes the theme into
30
+ `src/live-tokens/data/tokens.generated.css`, the file your built site ships.
31
+ The editor is dev-only — `npm run build` ships plain CSS variables and the
32
+ components you used, nothing else.
31
33
 
32
34
  ## Adding components
33
35
 
@@ -5,12 +5,6 @@ dist-ssr
5
5
  *.log
6
6
  .npmrc
7
7
 
8
- # Editor-written backups stay local to each machine; the live JSON/CSS commit.
9
- src/live-tokens/data/themes/_backups/
10
- src/live-tokens/data/manifests/_backups/
11
- src/live-tokens/data/component-configs/*/_backups/
12
- src/system/styles/_backups/
13
-
14
8
  .DS_Store
15
9
  .vscode/*
16
10
  !.vscode/extensions.json
@@ -1,62 +0,0 @@
1
- import { get } from 'svelte/store';
2
- import type { AliasDiskValue, ComponentConfig } from '../themes/themeTypes';
3
- import { editorState, markComponentSaved } from '../store/editorStore';
4
- import { refToDiskValue } from '../store/cssVarRef';
5
- import { CURRENT_COMPONENT_SCHEMA_VERSION } from '../themes/migrations';
6
- import {
7
- listComponentConfigs,
8
- saveComponentConfig,
9
- setActiveComponentFile,
10
- } from './componentConfigService';
11
-
12
- /**
13
- * Save the current in-memory state of a component to its active file. Mirrors
14
- * the `persist` flow inside `ComponentFileManager.svelte` so callers without a
15
- * file-manager instance (e.g. an unsaved-components dialog upstream)
16
- * can save a dirty component without duplicating the schema-version + aliases
17
- * stringification logic.
18
- *
19
- * Refuses to overwrite `default` — that's the protected source-derived snapshot.
20
- * Callers that hit `{ ok: false, reason: 'default' }` should prompt for a new
21
- * name and re-route to a Save-As flow.
22
- */
23
- export type SaveActiveComponentResult =
24
- | { ok: true; fileName: string; displayName: string }
25
- | { ok: false; reason: 'default' | 'no-state' | 'error'; error?: unknown };
26
-
27
-
28
- export async function saveActiveComponentConfig(
29
- component: string,
30
- ): Promise<SaveActiveComponentResult> {
31
- const slice = get(editorState).components[component];
32
- if (!slice) return { ok: false, reason: 'no-state' };
33
-
34
- try {
35
- const list = await listComponentConfigs(component);
36
- const fileName = list.activeFile;
37
- if (fileName === 'default') return { ok: false, reason: 'default' };
38
-
39
- const active = list.files.find((f) => f.fileName === fileName);
40
- const displayName = active?.name ?? fileName;
41
-
42
- const now = new Date().toISOString();
43
- const aliases: Record<string, AliasDiskValue> = {};
44
- for (const [k, ref] of Object.entries(slice.aliases)) aliases[k] = refToDiskValue(ref);
45
-
46
- const data: ComponentConfig = {
47
- name: displayName,
48
- component,
49
- createdAt: now,
50
- updatedAt: now,
51
- aliases,
52
- config: { ...slice.config },
53
- schemaVersion: CURRENT_COMPONENT_SCHEMA_VERSION,
54
- };
55
- await saveComponentConfig(component, fileName, data);
56
- await setActiveComponentFile(component, fileName);
57
- markComponentSaved(component);
58
- return { ok: true, fileName, displayName };
59
- } catch (error) {
60
- return { ok: false, reason: 'error', error };
61
- }
62
- }
@@ -1,172 +0,0 @@
1
- import type { Manifest, ManifestMeta, ManifestBundle, Theme, ComponentConfig } from '../themes/themeTypes';
2
- import { versionedFileResource } from '../storage/files/versionedFileResourceClient';
3
- import { API_BASE } from '../storage/apiBase';
4
- import { listComponents } from '../components/componentConfigService';
5
- import { getActiveTheme } from '../themes/themeService';
6
-
7
- /**
8
- * REST client for manifest files. A manifest references one theme file +
9
- * one config file per component (by basename). The active manifest is the
10
- * single live snapshot: theme and component Adopts patch its refs server-side.
11
- *
12
- * `default` is the protected baseline — cannot be overwritten or deleted, and
13
- * Adopts return 409 ACTIVE_IS_PROTECTED while it is active.
14
- */
15
-
16
- const manifestsResource = versionedFileResource<Manifest, ManifestMeta, never>({
17
- baseUrl: `${API_BASE}/manifests`,
18
- });
19
-
20
- export const listManifests = async (): Promise<ManifestMeta[]> => {
21
- const data = await manifestsResource.list();
22
- return data.files;
23
- };
24
-
25
- export const loadManifest = (fileName: string): Promise<Manifest> =>
26
- manifestsResource.load(fileName);
27
- export const saveManifest = (fileName: string, data: Manifest): Promise<void> =>
28
- manifestsResource.save(fileName, data);
29
- export const deleteManifest = (fileName: string): Promise<void> =>
30
- manifestsResource.remove(fileName);
31
- export const getActiveManifest = (): Promise<Manifest | null> => manifestsResource.getActive();
32
- export const setActiveManifest = (fileName: string): Promise<void> =>
33
- manifestsResource.setActive(fileName);
34
-
35
- export interface ApplyManifestResult {
36
- ok: boolean;
37
- manifest: Manifest;
38
- theme: Theme;
39
- componentConfigs: Record<string, ComponentConfig>;
40
- }
41
-
42
- /**
43
- * Server-side atomic apply: validate every referenced file exists, flip the
44
- * theme + each component's `_active.json` and `_production.json` pointers,
45
- * sync tokens.css/fonts.css from the new theme, mark the manifest active, and
46
- * return the resolved theme + component configs in one payload. Clients
47
- * usually follow with a full page reload — manifest load is a "blow up the
48
- * world" action.
49
- */
50
- export async function applyManifest(fileName: string): Promise<ApplyManifestResult> {
51
- const res = await fetch(`${API_BASE}/manifests/${encodeURIComponent(fileName)}/apply`, {
52
- method: 'PUT',
53
- });
54
- if (!res.ok) {
55
- const err = await res.json().catch(() => ({ error: 'Apply failed' }));
56
- throw new Error(err.error || 'Apply failed');
57
- }
58
- return res.json();
59
- }
60
-
61
- /**
62
- * Snapshot the currently-active theme + component-config file pointers into
63
- * a new manifest file and set it active. Used by the manifest panel's Save As
64
- * action and by the SaveAs-then-Adopt recovery flow when active is `default`.
65
- */
66
- export async function saveAsManifest(
67
- fileName: string,
68
- displayName: string,
69
- ): Promise<void> {
70
- const activeTheme = await getActiveTheme();
71
- if (!activeTheme || !activeTheme._fileName) {
72
- throw new Error('No active theme on disk to capture');
73
- }
74
- const components = await listComponents();
75
- const componentConfigs: Record<string, string> = {};
76
- for (const c of components) {
77
- componentConfigs[c.name] = c.activeFile || 'default';
78
- }
79
- const now = new Date().toISOString();
80
- const manifest: Manifest = {
81
- name: displayName,
82
- createdAt: now,
83
- updatedAt: now,
84
- theme: activeTheme._fileName,
85
- componentConfigs,
86
- };
87
- await saveManifest(fileName, manifest);
88
- await setActiveManifest(fileName);
89
- }
90
-
91
- /**
92
- * Re-snapshot the editor's current active pointers into the *currently active*
93
- * manifest file. Used by the manifest panel's Save action. Server rejects with
94
- * 403 if active is `default` (protected).
95
- */
96
- export async function saveActiveManifest(displayName?: string): Promise<void> {
97
- const active = await getActiveManifest();
98
- if (!active || !active._fileName) {
99
- throw new Error('No active manifest');
100
- }
101
- const activeTheme = await getActiveTheme();
102
- if (!activeTheme || !activeTheme._fileName) {
103
- throw new Error('No active theme on disk');
104
- }
105
- const components = await listComponents();
106
- const componentConfigs: Record<string, string> = {};
107
- for (const c of components) {
108
- componentConfigs[c.name] = c.activeFile || 'default';
109
- }
110
- const manifest: Manifest = {
111
- name: displayName ?? active.name,
112
- createdAt: active.createdAt,
113
- updatedAt: new Date().toISOString(),
114
- theme: activeTheme._fileName,
115
- componentConfigs,
116
- };
117
- await saveManifest(active._fileName, manifest);
118
- }
119
-
120
- export interface ImportManifestResult {
121
- ok: boolean;
122
- /** Final manifest filename (may be renamed if it collided with an existing one). */
123
- manifest: string;
124
- /** Keyed `theme:<orig>` / `componentConfig:<comp>/<orig>` / `manifest:<orig>` → final name. */
125
- renames: Record<string, string>;
126
- }
127
-
128
- /**
129
- * Fetch the manifest as a self-contained `ManifestBundle` and trigger a
130
- * browser download. Hidden-anchor trick — no infrastructure beyond the
131
- * existing GET `/api/manifests/:name/export` endpoint.
132
- *
133
- * See temp/manifest-robustness-plan.md §11.
134
- */
135
- export async function exportManifest(fileName: string): Promise<void> {
136
- const res = await fetch(`${API_BASE}/manifests/${encodeURIComponent(fileName)}/export`);
137
- if (!res.ok) {
138
- const err = await res.json().catch(() => ({ error: 'Export failed' }));
139
- throw new Error(err.error || 'Export failed');
140
- }
141
- const blob = await res.blob();
142
- const url = URL.createObjectURL(blob);
143
- try {
144
- const a = document.createElement('a');
145
- a.href = url;
146
- a.download = `${fileName}.bundle.json`;
147
- document.body.appendChild(a);
148
- a.click();
149
- a.remove();
150
- } finally {
151
- URL.revokeObjectURL(url);
152
- }
153
- }
154
-
155
- /**
156
- * POST a `ManifestBundle` to the import endpoint. Server materialises the
157
- * inlined theme + component configs as fresh files (renaming on collision),
158
- * rewrites the manifest's pointers, and returns the final manifest name plus
159
- * the rename map so the UI can surface what got renamed.
160
- */
161
- export async function importManifest(bundle: ManifestBundle): Promise<ImportManifestResult> {
162
- const res = await fetch(`${API_BASE}/manifests/import`, {
163
- method: 'POST',
164
- headers: { 'Content-Type': 'application/json' },
165
- body: JSON.stringify(bundle),
166
- });
167
- if (!res.ok) {
168
- const err = await res.json().catch(() => ({ error: 'Import failed' }));
169
- throw new Error(err.error || 'Import failed');
170
- }
171
- return res.json();
172
- }