@motion-proto/live-tokens 0.6.2 → 0.8.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 (232) hide show
  1. package/README.md +14 -13
  2. package/dist-plugin/index.cjs +854 -226
  3. package/dist-plugin/index.d.cts +2 -1
  4. package/dist-plugin/index.d.ts +2 -1
  5. package/dist-plugin/index.js +852 -225
  6. package/package.json +26 -40
  7. package/src/{styles → app}/site.css +1 -1
  8. package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
  9. package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
  10. package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
  11. package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
  12. package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
  13. package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
  14. package/src/editor/component-editor/ImageEditor.svelte +30 -0
  15. package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
  16. package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
  17. package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
  18. package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
  19. package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
  20. package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
  21. package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
  22. package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
  23. package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
  24. package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
  25. package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
  26. package/src/editor/component-editor/editors.d.ts +10 -0
  27. package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
  28. package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
  29. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
  30. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
  31. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
  32. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
  33. package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
  34. package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
  35. package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
  36. package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
  37. package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
  38. package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
  39. package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
  40. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
  41. package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
  42. package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
  43. package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
  44. package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
  45. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
  46. package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
  47. package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
  48. package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
  49. package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
  50. package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
  51. package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
  52. package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
  53. package/src/editor/core/flashStatus.ts +30 -0
  54. package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
  55. package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
  56. package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
  57. package/src/editor/core/manifests/manifestService.ts +171 -0
  58. package/src/editor/core/palettes/familySwap.ts +99 -0
  59. package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
  60. package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
  61. package/src/editor/core/productionPulse.ts +37 -0
  62. package/src/{lib → editor/core/routing}/router.ts +1 -1
  63. package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
  64. package/src/{lib → editor/core/store}/editorCore.ts +24 -8
  65. package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
  66. package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
  67. package/src/{lib → editor/core/store}/editorStore.ts +222 -28
  68. package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
  69. package/src/editor/core/store/gradientSource.ts +192 -0
  70. package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
  71. package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
  72. package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
  73. package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
  74. package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
  75. package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
  76. package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
  77. package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
  78. package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
  79. package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
  80. package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
  81. package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
  82. package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
  83. package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
  84. package/src/{lib → editor/core/themes}/themeService.ts +6 -6
  85. package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
  86. package/src/editor/index.ts +69 -0
  87. package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
  88. package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
  89. package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
  90. package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
  91. package/src/{pages → editor/pages}/Editor.svelte +4 -4
  92. package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
  93. package/src/{styles → editor/styles}/ui-editor.css +43 -22
  94. package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
  95. package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
  96. package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
  97. package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
  98. package/src/editor/ui/FileLoadList.svelte +367 -0
  99. package/src/editor/ui/FilePill.svelte +80 -0
  100. package/src/editor/ui/FontStackEditor.svelte +499 -0
  101. package/src/editor/ui/GradientEditor.svelte +690 -0
  102. package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
  103. package/src/editor/ui/ManifestFileManager.svelte +438 -0
  104. package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
  105. package/src/editor/ui/ProjectFontsSection.svelte +638 -0
  106. package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
  107. package/src/{ui → editor/ui}/TextTab.svelte +3 -3
  108. package/src/editor/ui/ThemeFileManager.svelte +783 -0
  109. package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
  110. package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
  111. package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
  112. package/src/editor/ui/UIInfoPopover.svelte +243 -0
  113. package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
  114. package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
  115. package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
  116. package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
  117. package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
  118. package/src/editor/ui/UIPillButton.svelte +168 -0
  119. package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
  120. package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
  121. package/src/editor/ui/UISegmentedControl.svelte +114 -0
  122. package/src/editor/ui/UISquareButton.svelte +172 -0
  123. package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
  124. package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
  125. package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
  126. package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
  127. package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
  128. package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
  129. package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
  130. package/src/editor/ui/palette/paletteMath.ts +275 -0
  131. package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
  132. package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
  133. package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
  134. package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
  135. package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
  136. package/src/{components → system/components}/Badge.svelte +0 -36
  137. package/src/{components → system/components}/Button.svelte +2 -2
  138. package/src/{components → system/components}/Card.svelte +34 -60
  139. package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
  140. package/src/{components → system/components}/CornerBadge.svelte +8 -24
  141. package/src/{components → system/components}/Dialog.svelte +1 -1
  142. package/src/system/components/FloatingTokenTags.css +275 -0
  143. package/src/system/components/FloatingTokenTags.svelte +543 -0
  144. package/src/{components → system/components}/InlineEditActions.svelte +6 -4
  145. package/src/system/components/MenuSelect.svelte +229 -0
  146. package/src/{components → system/components}/Notification.svelte +8 -1
  147. package/src/{components → system/components}/ProgressBar.svelte +29 -11
  148. package/src/system/components/SectionDivider.svelte +560 -0
  149. package/src/{components → system/components}/SegmentedControl.svelte +49 -43
  150. package/src/{components → system/components}/TabBar.svelte +81 -65
  151. package/src/{components → system/components}/Table.svelte +17 -3
  152. package/src/{components → system/components}/Tooltip.svelte +6 -4
  153. package/src/system/styles/CONVENTIONS.md +178 -0
  154. package/src/system/styles/fonts.css +20 -0
  155. package/src/system/styles/tokens.css +601 -0
  156. package/src/system/styles/tokens.generated.css +544 -0
  157. package/src/component-editor/ImageEditor.svelte +0 -74
  158. package/src/component-editor/SectionDividerEditor.svelte +0 -265
  159. package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
  160. package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
  161. package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
  162. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
  163. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
  164. package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
  165. package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
  166. package/src/components/SectionDivider.svelte +0 -483
  167. package/src/data/google-fonts.json +0 -75
  168. package/src/lib/index.ts +0 -68
  169. package/src/lib/presetService.ts +0 -214
  170. package/src/lib/productionPulse.ts +0 -32
  171. package/src/styles/fonts.css +0 -30
  172. package/src/styles/tokens.css +0 -1324
  173. package/src/ui/FontStackEditor.svelte +0 -361
  174. package/src/ui/GradientEditor.svelte +0 -470
  175. package/src/ui/PresetFileManager.svelte +0 -1116
  176. package/src/ui/ProjectFontsSection.svelte +0 -645
  177. package/src/ui/ThemeFileManager.svelte +0 -1020
  178. package/src/ui/UnsavedComponentsDialog.svelte +0 -315
  179. /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
  180. /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
  181. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
  182. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
  183. /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
  184. /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
  185. /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
  186. /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
  187. /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
  188. /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
  189. /package/src/{lib → editor/core/storage}/storage.ts +0 -0
  190. /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
  191. /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
  192. /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
  193. /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
  194. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
  195. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
  196. /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
  197. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
  198. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
  199. /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
  200. /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
  201. /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
  202. /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
  203. /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
  204. /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
  205. /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
  206. /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
  207. /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
  208. /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
  209. /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
  210. /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
  211. /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
  212. /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
  213. /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
  214. /package/src/{ui → editor/ui}/index.ts +0 -0
  215. /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
  216. /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
  217. /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
  218. /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
  219. /package/src/{ui → editor/ui}/variantScales.ts +0 -0
  220. /package/src/{assets → system/assets}/newspaper.webp +0 -0
  221. /package/src/{assets → system/assets}/offering.webp +0 -0
  222. /package/src/{components → system/components}/Callout.svelte +0 -0
  223. /package/src/{components → system/components}/Image.svelte +0 -0
  224. /package/src/{components → system/components}/RadioButton.svelte +0 -0
  225. /package/src/{components → system/components}/types.ts +0 -0
  226. /package/src/{styles → system/styles}/_padding.scss +0 -0
  227. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  228. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  229. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  230. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  231. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  232. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
@@ -4,8 +4,8 @@
4
4
  * (`--color-brand-500`); the renderer wraps them in `var(...)` so palette
5
5
  * edits flow through.
6
6
  */
7
- import type { EditorState, GradientToken, GradientTokenStop, GradientType } from '../editorTypes';
8
- import { mutate } from '../editorCore';
7
+ import type { EditorState, GradientToken, GradientTokenStop, GradientType, GradientAliasValue } from '../../store/editorTypes';
8
+ import { mutate } from '../../store/editorCore';
9
9
 
10
10
  export function makeDefaultGradients(): GradientToken[] {
11
11
  return [
@@ -49,12 +49,7 @@ export function makeDefaultGradients(): GradientToken[] {
49
49
  }
50
50
 
51
51
  function formatGradientStop(s: GradientTokenStop): string {
52
- const base = s.color.startsWith('--') ? `var(${s.color})` : s.color;
53
- const opacity = s.opacity ?? 100;
54
- const color = opacity >= 100
55
- ? base
56
- : `color-mix(in srgb, ${base} ${opacity}%, transparent)`;
57
- return `${color} ${s.position}%`;
52
+ return `${formatGradientStopColor(s)} ${s.position}%`;
58
53
  }
59
54
 
60
55
  /** Stops portion only — used by the palette selector to materialize a
@@ -64,10 +59,67 @@ export function formatGradientStops(t: GradientToken): string {
64
59
  return t.stops.map(formatGradientStop).join(', ');
65
60
  }
66
61
 
62
+ /** Serialize a structured gradient value (theme token or component-owned)
63
+ * into a CSS background declaration.
64
+ * - `none` → `transparent` (no background paint).
65
+ * - `solid` → the first stop's color (no gradient function).
66
+ * - `linear` → `linear-gradient(<angle>, <stops>)`.
67
+ * - `radial` → `radial-gradient(<shape> at <centerX>% 50%, <stops>)`.
68
+ * centerX defaults to 50. Shape is `circle [radius]` when the
69
+ * aspect ratio is 1 (or absent); for aspect ≠ 1 we emit
70
+ * `ellipse rx ry` anchored to `radius || 100px`, area-preserved
71
+ * so the R=1 boundary is continuous with the legacy circle. */
72
+ export function formatGradientValue(v: GradientAliasValue): string {
73
+ if (v.type === 'none') return 'transparent';
74
+ if (v.type === 'solid') {
75
+ const first = v.stops[0];
76
+ if (!first) return 'transparent';
77
+ return formatGradientStopColor(first);
78
+ }
79
+ const stops = v.stops.map(formatGradientStop).join(', ');
80
+ if (v.type === 'linear') return `linear-gradient(${v.angle}deg, ${stops})`;
81
+ const cx = v.centerX ?? 50;
82
+ return `radial-gradient(${formatRadialShape(v)} at ${cx}% 50%, ${stops})`;
83
+ }
84
+
85
+ /** Default base radius (px) when the gradient has no explicit `radius` but
86
+ * needs concrete dimensions to express its aspect ratio. Chosen as a
87
+ * pleasant-looking mid-size that reads as a "soft glow" inside typical
88
+ * component containers; the user can dial `radius` to override. */
89
+ const DEFAULT_RADIAL_BASE_PX = 100;
90
+
91
+ function formatRadialShape(v: GradientAliasValue): string {
92
+ const ax = v.aspectX ?? 1;
93
+ const ay = v.aspectY ?? 1;
94
+ if (ax === 1 && ay === 1) {
95
+ return v.radius && v.radius > 0 ? `circle ${v.radius}px` : 'circle';
96
+ }
97
+ const base = v.radius && v.radius > 0 ? v.radius : DEFAULT_RADIAL_BASE_PX;
98
+ const rx = base * ax;
99
+ const ry = base * ay;
100
+ return `ellipse ${rx.toFixed(2)}px ${ry.toFixed(2)}px`;
101
+ }
102
+
103
+ /** Resolve a stop's color + opacity into a CSS color value without the
104
+ * trailing `${position}%`. Shared by the gradient-stop formatter (which
105
+ * appends the position) and the solid path (which doesn't). */
106
+ function formatGradientStopColor(s: GradientTokenStop): string {
107
+ const base = s.color.startsWith('--') ? `var(${s.color})` : s.color;
108
+ const opacity = s.opacity ?? 100;
109
+ return opacity >= 100
110
+ ? base
111
+ : `color-mix(in srgb, ${base} ${opacity}%, transparent)`;
112
+ }
113
+
67
114
  function formatGradient(t: GradientToken): string {
68
- const stops = formatGradientStops(t);
69
- if (t.type === 'linear') return `linear-gradient(${t.angle}deg, ${stops})`;
70
- return `radial-gradient(${stops})`;
115
+ return formatGradientValue({
116
+ type: t.type,
117
+ angle: t.angle,
118
+ centerX: t.centerX,
119
+ aspectX: t.aspectX,
120
+ aspectY: t.aspectY,
121
+ stops: t.stops,
122
+ });
71
123
  }
72
124
 
73
125
  export function gradientsToVars(g: EditorState['gradients']): Record<string, string> {
@@ -80,17 +132,20 @@ function findGradient(s: EditorState, variable: string): GradientToken | undefin
80
132
  return s.gradients.tokens.find((t) => t.variable === variable);
81
133
  }
82
134
 
83
- /** Replace a gradient's type, angle, and stops in one shot. Used by the editor
84
- * to restore a pre-edit snapshot on Cancel. */
135
+ /** Replace a gradient's type, angle, centerX, aspect, and stops in one shot.
136
+ * Used by the editor to restore a pre-edit snapshot on Cancel. */
85
137
  export function setGradient(
86
138
  variable: string,
87
- next: { type: GradientType; angle: number; stops: GradientTokenStop[] },
139
+ next: { type: GradientType; angle: number; centerX?: number; aspectX?: number; aspectY?: number; stops: GradientTokenStop[] },
88
140
  ): void {
89
141
  mutate(`replace gradient ${variable}`, (s) => {
90
142
  const t = findGradient(s, variable);
91
143
  if (!t) return;
92
144
  t.type = next.type;
93
145
  t.angle = next.angle;
146
+ t.centerX = next.centerX;
147
+ t.aspectX = next.aspectX;
148
+ t.aspectY = next.aspectY;
94
149
  t.stops = next.stops.map((st) => ({ ...st }));
95
150
  });
96
151
  }
@@ -109,6 +164,26 @@ export function setGradientAngle(variable: string, angle: number): void {
109
164
  });
110
165
  }
111
166
 
167
+ export function setGradientCenterX(variable: string, centerX: number): void {
168
+ mutate(`set gradient center ${variable}`, (s) => {
169
+ const t = findGradient(s, variable);
170
+ if (t) t.centerX = centerX;
171
+ });
172
+ }
173
+
174
+ export function setGradientAspect(variable: string, aspect: { x: number; y: number }): void {
175
+ mutate(`set gradient aspect ${variable}`, (s) => {
176
+ const t = findGradient(s, variable);
177
+ if (!t) return;
178
+ // Drop axes that equal 1 (the legacy circle baseline) so the persisted
179
+ // shape stays minimal and old data round-trips unchanged.
180
+ if (aspect.x === 1) delete t.aspectX;
181
+ else t.aspectX = aspect.x;
182
+ if (aspect.y === 1) delete t.aspectY;
183
+ else t.aspectY = aspect.y;
184
+ });
185
+ }
186
+
112
187
  export function setGradientStop(variable: string, index: number, stop: Partial<GradientTokenStop>): void {
113
188
  mutate(`set gradient stop ${variable}[${index}]`, (s) => {
114
189
  const t = findGradient(s, variable);
@@ -4,7 +4,7 @@
4
4
  * and diverge from tokens.css by design: the editor starts with a neutral
5
5
  * palette and tokens.css continues to win until first edit.
6
6
  */
7
- import type { EditorState, OverlayToken } from '../editorTypes';
7
+ import type { EditorState, OverlayToken } from '../../store/editorTypes';
8
8
 
9
9
  export function makeDefaultOverlayTokens(): OverlayToken[] {
10
10
  return [
@@ -5,7 +5,7 @@
5
5
  * (palette derivation involves OKLCH + bezier curves) at render time.
6
6
  */
7
7
  import type { PaletteConfig } from '../themeTypes';
8
- import { store, mutate, persist } from '../editorCore';
8
+ import { store, mutate, persist } from '../../store/editorCore';
9
9
 
10
10
  export function setPaletteConfig(label: string, config: PaletteConfig): void {
11
11
  mutate(`update palette ${label}`, (s) => {
@@ -8,8 +8,8 @@
8
8
  * x/y/blur/spread/hsla fields.
9
9
  */
10
10
  import { get } from 'svelte/store';
11
- import type { EditorState, ShadowToken } from '../editorTypes';
12
- import { store, persist } from '../editorCore';
11
+ import type { EditorState, ShadowToken } from '../../store/editorTypes';
12
+ import { store, persist } from '../../store/editorCore';
13
13
 
14
14
  export const SHADOW_VAR_NAMES = [
15
15
  '--shadow-sm', '--shadow-md', '--shadow-lg', '--shadow-xl', '--shadow-2xl',
@@ -38,7 +38,7 @@ export function shadowTokenCss(t: ShadowToken): string {
38
38
  return `${t.x}px ${t.y}px ${t.blur}px ${t.spread}px hsla(${t.hue}, ${t.saturation}%, ${t.lightness}%, ${t.opacity})`;
39
39
  }
40
40
 
41
- export function defaultShadowOverride(): import('../editorTypes').ShadowOverrideFlags {
41
+ export function defaultShadowOverride(): import('../../store/editorTypes').ShadowOverrideFlags {
42
42
  return { angle: false, opacity: false, color: false, distance: false, blur: false, size: false };
43
43
  }
44
44
 
@@ -1,10 +1,10 @@
1
- import type { Theme } from './themeTypes';
2
- import { activeFileName } from './editorConfigStore';
3
- import { migrateThemeFonts } from './fontMigration';
4
- import { applyFontSources, applyFontStacks } from './fontLoader';
5
- import { loadFromFile, seedComponentsFromApi } from './editorStore';
6
- import { getActiveComponentConfig } from './componentConfigService';
7
- import { safeFetch } from './storage';
1
+ import type { AliasDiskValue, Theme } from './themeTypes';
2
+ import { activeFileName } from '../store/editorConfigStore';
3
+ import { migrateThemeFonts } from '../fonts/fontMigration';
4
+ import { applyFontSources, applyFontStacks } from '../fonts/fontLoader';
5
+ import { loadFromFile, seedComponentsFromApi } from '../store/editorStore';
6
+ import { getActiveComponentConfig } from '../components/componentConfigService';
7
+ import { safeFetch } from '../storage/storage';
8
8
 
9
9
  interface ComponentSummaryDto {
10
10
  name: string;
@@ -52,7 +52,7 @@ export async function initializeTheme(): Promise<void> {
52
52
  if (list && Array.isArray(list.components)) {
53
53
  const configs: Record<
54
54
  string,
55
- { activeFile: string; aliases: Record<string, string>; config?: Record<string, unknown>; schemaVersion?: number }
55
+ { activeFile: string; aliases: Record<string, AliasDiskValue>; config?: Record<string, unknown>; schemaVersion?: number }
56
56
  > = {};
57
57
  await Promise.all(
58
58
  list.components.map(async (c) => {
@@ -1,14 +1,14 @@
1
1
  import { tick } from 'svelte';
2
2
  import type { Theme, ThemeMeta } from './themeTypes';
3
- import type { EditorState } from './editorTypes';
3
+ import type { EditorState } from '../store/editorTypes';
4
4
  import {
5
5
  versionedFileResource,
6
6
  sanitizeFileName as sanitizeFileNameImpl,
7
- } from './files/versionedFileResource';
8
- import { loadFromFile as loadEditorState, toTheme, markSaved } from './editorStore';
9
- import { activeFileName } from './editorConfigStore';
10
- import { applyFontSources, applyFontStacks } from './fontLoader';
11
- import { migrateThemeFonts } from './fontMigration';
7
+ } from '../storage/files/versionedFileResourceClient';
8
+ import { loadFromFile as loadEditorState, toTheme, markSaved } from '../store/editorStore';
9
+ import { activeFileName } from '../store/editorConfigStore';
10
+ import { applyFontSources, applyFontStacks } from '../fonts/fontLoader';
11
+ import { migrateThemeFonts } from '../fonts/fontMigration';
12
12
 
13
13
  // ── API helpers ──────────────────────────────────────────────
14
14
  //
@@ -1,4 +1,4 @@
1
- import type { CurveAnchor } from '../ui/curveEngine';
1
+ import type { CurveAnchor } from '../../ui/curveEngine';
2
2
 
3
3
  export type GradientStyle = 'linear' | 'radial' | 'conic';
4
4
 
@@ -27,6 +27,19 @@ export interface PaletteConfig {
27
27
  gradientStops?: GradientStop[];
28
28
  gradientSize?: 'page' | 'window';
29
29
  anchorToBase?: boolean;
30
+ /**
31
+ * Set to true by importers when they overlay `cssVariables[--color-{ns}-*]`
32
+ * without owning the typed-state curves. The storage-layer reconciler uses
33
+ * it as an opt-in switch: snap `baseColor` (or `tintHue`+`tintChroma` for
34
+ * gray palettes) to the imported `--color-{ns}-500` anchor and clear the
35
+ * flag. Editor-authored themes never set this, so the reconciler is a
36
+ * strict no-op for them.
37
+ *
38
+ * Persists on disk for first-load reconciliation. After reconcile strips
39
+ * the palette-derived keys from `cssVariables`, subsequent reconciles find
40
+ * no anchor and become idempotent no-ops regardless of the flag's value.
41
+ */
42
+ _imported?: boolean;
30
43
  }
31
44
 
32
45
  export type FontSourceKind = 'google' | 'typekit' | 'css-url' | 'font-face';
@@ -92,12 +105,20 @@ export interface ThemeMeta {
92
105
  isActive: boolean;
93
106
  }
94
107
 
108
+ /** On-disk shape of a single alias entry. Plain strings carry the bulk of
109
+ * aliases (token refs like `--surface-canvas-low` or literal CSS like `4px`);
110
+ * the gradient object shape is the structured payload for component-owned
111
+ * gradients that can't compress to a single string. */
112
+ export type AliasDiskValue =
113
+ | string
114
+ | { kind: 'gradient'; value: { type: 'linear' | 'radial' | 'solid' | 'none'; angle: number; radius?: number; centerX?: number; aspectX?: number; aspectY?: number; stops: { position: number; color: string; opacity?: number }[] } };
115
+
95
116
  export interface ComponentConfig {
96
117
  name: string;
97
118
  component: string;
98
119
  createdAt: string;
99
120
  updatedAt: string;
100
- aliases: Record<string, string>;
121
+ aliases: Record<string, AliasDiskValue>;
101
122
  config?: Record<string, unknown>;
102
123
  /**
103
124
  * Server-attached file-name marker. Same role as `Theme._fileName`. Set by
@@ -120,16 +141,17 @@ export interface ComponentConfigMeta {
120
141
 
121
142
  /**
122
143
  * Manifest that captures an entire site state — the active theme plus the
123
- * active config for every component. Loading a preset flips the relevant
144
+ * active config for every component. Loading a manifest flips the relevant
124
145
  * `_active.json` pointers; the underlying theme + component-config files stay
125
- * the source of truth, so editing them flows through any preset that
126
- * references them.
146
+ * the source of truth, so editing them flows through any manifest that
147
+ * references them. The currently-active manifest is the live snapshot: theme
148
+ * and component Adopts auto-patch its refs on the server.
127
149
  */
128
- export interface Preset {
150
+ export interface Manifest {
129
151
  name: string;
130
152
  createdAt: string;
131
153
  updatedAt: string;
132
- /** File basename (no `.json`) of the theme this preset pins. */
154
+ /** File basename (no `.json`) of the theme this manifest pins. */
133
155
  theme: string;
134
156
  /** Map of componentId → config file basename. Components omitted here fall
135
157
  * back to "default" at apply time. */
@@ -138,9 +160,46 @@ export interface Preset {
138
160
  _fileName?: string;
139
161
  }
140
162
 
141
- export interface PresetMeta {
163
+ /**
164
+ * Transport artifact for sharing a manifest with someone else. Self-contained:
165
+ * the bundle inlines the referenced theme and every non-default component
166
+ * config so the receiver doesn't need anything else on disk to apply it.
167
+ *
168
+ * Bundles are *not* stored under `manifests/` — they're transient downloads /
169
+ * uploads. Local manifests stay lightweight pointer files; bundles are the
170
+ * import/export envelope. See temp/manifest-robustness-plan.md §11.
171
+ *
172
+ * `componentConfigs` is keyed by `${component}/${configName}` so a single map
173
+ * carries multiple components. Entries whose manifest value is `"default"`
174
+ * are deliberately omitted — the receiver's local `default.json` is the
175
+ * live-tokens package's canonical default, and shipping the sender's default
176
+ * would risk version-divergence with no clean conflict story.
177
+ */
178
+ export interface ManifestBundle {
179
+ /** Discriminator for safe identification of bundle JSON files. */
180
+ kind: 'manifest-bundle';
181
+ /** Bumps when the bundle envelope shape changes. Start at 1. */
182
+ schemaVersion: 1;
183
+ /** Sender's `@motion-proto/live-tokens` package version. Receiver can
184
+ * compare to its own to warn about compatibility drift. */
185
+ liveTokensVersion: string;
186
+ /** ISO timestamp of when the bundle was exported. */
187
+ exportedAt: string;
188
+ /** Full pointer-form manifest (same shape as on-disk manifest files). */
189
+ manifest: Manifest;
190
+ /** Full content of the theme that `manifest.theme` references. */
191
+ theme: Theme;
192
+ /** Full content of each non-default component config referenced by
193
+ * `manifest.componentConfigs`, keyed by `${component}/${configName}`. */
194
+ componentConfigs: Record<string, ComponentConfig>;
195
+ }
196
+
197
+ export interface ManifestMeta {
142
198
  name: string;
143
199
  fileName: string;
144
200
  updatedAt: string;
145
201
  isActive: boolean;
202
+ /** `true` only for `default` — the protected baseline. Cannot be written
203
+ * to or deleted, and theme/component Adopts cannot patch into it. */
204
+ isProtected: boolean;
146
205
  }
@@ -0,0 +1,69 @@
1
+ export { default as LiveEditorOverlay } from './overlay/LiveEditorOverlay.svelte';
2
+ export type { NavLink } from './core/routing/navLinkTypes';
3
+ export { default as ColumnsOverlay } from './overlay/ColumnsOverlay.svelte';
4
+
5
+ export { columnsVisible, toggleColumns, init as initColumnsOverlay } from './overlay/columnsOverlay';
6
+ export { configureEditor, storageKey } from './core/store/editorConfig';
7
+ export { activeFileName } from './core/store/editorConfigStore';
8
+ export { init as initRouter, route, navigate } from './core/routing/router';
9
+ export { init as initCssVarSync } from './core/cssVarSync';
10
+ export { init as initEditorStore } from './core/store/editorStore';
11
+
12
+ export { setCssVar, removeCssVar } from './core/cssVarSync';
13
+
14
+ export {
15
+ listThemes,
16
+ loadTheme,
17
+ saveTheme,
18
+ deleteTheme,
19
+ getActiveTheme,
20
+ setActiveFile,
21
+ getProductionInfo,
22
+ setProductionFile,
23
+ sanitizeFileName,
24
+ } from './core/themes/themeService';
25
+ export type { ProductionInfo } from './core/themes/themeService';
26
+
27
+ export type {
28
+ PaletteConfig,
29
+ Theme,
30
+ ThemeMeta,
31
+ GradientStyle,
32
+ GradientStop,
33
+ FontSource,
34
+ FontSourceKind,
35
+ FontFamily,
36
+ FontStack,
37
+ FontStackSlot,
38
+ FontStackVariable,
39
+ SystemCascadePreset,
40
+ GenericFamily,
41
+ Manifest,
42
+ ManifestMeta,
43
+ } from './core/themes/themeTypes';
44
+
45
+ export {
46
+ listManifests,
47
+ loadManifest,
48
+ saveManifest,
49
+ deleteManifest,
50
+ getActiveManifest,
51
+ setActiveManifest,
52
+ applyManifest,
53
+ saveAsManifest,
54
+ saveActiveManifest,
55
+ } from './core/manifests/manifestService';
56
+ export type { ApplyManifestResult } from './core/manifests/manifestService';
57
+
58
+ export {
59
+ applyFontSources,
60
+ applyFontStacks,
61
+ resolveFontStackValues,
62
+ SYSTEM_CASCADES,
63
+ } from './core/fonts/fontLoader';
64
+ export { migrateThemeFonts, defaultFontSources, defaultFontStacks } from './core/fonts/fontMigration';
65
+
66
+ export { hexToOklch, oklchToHex, gamutClamp } from './core/palettes/oklch';
67
+ export type { Oklch } from './core/palettes/oklch';
68
+
69
+ export { initializeTheme } from './core/themes/themeInit';
@@ -118,7 +118,6 @@
118
118
  font-family: var(--ui-font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace);
119
119
  font-size: 10px;
120
120
  color: rgba(255, 255, 255, 0.75);
121
- letter-spacing: 0.02em;
122
121
  white-space: nowrap;
123
122
  }
124
123