@motion-proto/live-tokens 0.1.1 → 0.3.2

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 (224) hide show
  1. package/README.md +168 -21
  2. package/dist-plugin/index.cjs +823 -336
  3. package/dist-plugin/index.d.cts +9 -7
  4. package/dist-plugin/index.d.ts +9 -7
  5. package/dist-plugin/index.js +822 -335
  6. package/package.json +46 -20
  7. package/src/assets/newspaper.webp +0 -0
  8. package/src/assets/offering.webp +0 -0
  9. package/src/component-editor/BadgeEditor.svelte +170 -0
  10. package/src/component-editor/CalloutEditor.svelte +103 -0
  11. package/src/component-editor/CardEditor.svelte +184 -0
  12. package/src/component-editor/CollapsibleSectionEditor.svelte +167 -0
  13. package/src/component-editor/CornerBadgeEditor.svelte +207 -0
  14. package/src/component-editor/DialogEditor.svelte +172 -0
  15. package/src/component-editor/ImageEditor.svelte +72 -0
  16. package/src/component-editor/InlineEditActionsEditor.svelte +83 -0
  17. package/src/component-editor/NotificationEditor.svelte +160 -0
  18. package/src/component-editor/ProgressBarEditor.svelte +124 -0
  19. package/src/component-editor/RadioButtonEditor.svelte +140 -0
  20. package/src/component-editor/SectionDividerEditor.svelte +263 -0
  21. package/src/component-editor/SegmentedControlEditor.svelte +154 -0
  22. package/src/component-editor/StandardButtonsEditor.svelte +178 -0
  23. package/src/component-editor/TabBarEditor.svelte +137 -0
  24. package/src/component-editor/TableEditor.svelte +128 -0
  25. package/src/component-editor/TooltipEditor.svelte +122 -0
  26. package/src/component-editor/editorTokens.test.ts +93 -0
  27. package/src/component-editor/groupKeySlots.test.ts +67 -0
  28. package/src/component-editor/groupKeySnapshot.test.ts +52 -0
  29. package/src/component-editor/index.ts +5 -0
  30. package/src/component-editor/registry.ts +246 -0
  31. package/src/component-editor/scaffolding/AngleDial.svelte +185 -0
  32. package/src/component-editor/scaffolding/ComponentEditorBase.svelte +96 -0
  33. package/src/component-editor/scaffolding/ComponentFileManager.svelte +682 -0
  34. package/src/component-editor/scaffolding/ComponentFileMenu.svelte +312 -0
  35. package/src/component-editor/scaffolding/ComponentsTab.svelte +69 -0
  36. package/src/component-editor/scaffolding/CopyFromMenu.svelte +246 -0
  37. package/src/component-editor/scaffolding/DemoHeader.svelte +21 -0
  38. package/src/component-editor/scaffolding/DividerEditor.svelte +81 -0
  39. package/src/component-editor/scaffolding/FieldsetWrapper.svelte +46 -0
  40. package/src/component-editor/scaffolding/GradientCard.svelte +291 -0
  41. package/src/component-editor/scaffolding/LinkageChart.svelte +297 -0
  42. package/src/component-editor/scaffolding/LinkedBlock.svelte +418 -0
  43. package/src/component-editor/scaffolding/NonStylableConfig.svelte +57 -0
  44. package/src/component-editor/scaffolding/SaveAsDialog.svelte +177 -0
  45. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +25 -0
  46. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +56 -0
  47. package/src/component-editor/scaffolding/StateBlock.svelte +115 -0
  48. package/src/component-editor/scaffolding/TokenLayout.svelte +511 -0
  49. package/src/component-editor/scaffolding/TypeEditor.svelte +82 -0
  50. package/src/component-editor/scaffolding/VariantGroup.svelte +277 -0
  51. package/src/component-editor/scaffolding/buildTypeGroupTokens.ts +97 -0
  52. package/src/component-editor/scaffolding/componentSectionType.ts +8 -0
  53. package/src/component-editor/scaffolding/componentSources.ts +9 -0
  54. package/src/component-editor/scaffolding/defaultSections.ts +16 -0
  55. package/src/component-editor/scaffolding/editorContext.ts +44 -0
  56. package/src/component-editor/scaffolding/linkedBlock.ts +226 -0
  57. package/src/component-editor/scaffolding/siblings.ts +33 -0
  58. package/src/component-editor/scaffolding/types.ts +39 -0
  59. package/src/components/Badge.svelte +231 -42
  60. package/src/components/Button.svelte +324 -124
  61. package/src/components/Callout.svelte +145 -0
  62. package/src/components/Card.svelte +123 -25
  63. package/src/components/CollapsibleSection.svelte +213 -35
  64. package/src/components/CornerBadge.svelte +224 -0
  65. package/src/components/Dialog.svelte +137 -114
  66. package/src/components/Image.svelte +43 -0
  67. package/src/components/InlineEditActions.svelte +74 -14
  68. package/src/components/Notification.svelte +184 -163
  69. package/src/components/ProgressBar.svelte +216 -22
  70. package/src/components/RadioButton.svelte +110 -40
  71. package/src/components/SectionDivider.svelte +428 -74
  72. package/src/components/SegmentedControl.svelte +203 -0
  73. package/src/components/TabBar.svelte +146 -21
  74. package/src/components/Table.svelte +102 -0
  75. package/src/components/Tooltip.svelte +45 -19
  76. package/src/components/types.ts +51 -0
  77. package/src/data/google-fonts.json +75 -0
  78. package/src/lib/ColumnsOverlay.svelte +20 -7
  79. package/src/lib/LiveEditorOverlay.svelte +257 -78
  80. package/src/lib/columnsOverlay.ts +21 -17
  81. package/src/lib/componentConfig.test.ts +204 -0
  82. package/src/lib/componentConfigKeys.ts +19 -0
  83. package/src/lib/componentConfigService.ts +88 -0
  84. package/src/lib/copyPopover.ts +30 -0
  85. package/src/lib/cssVarSync.ts +59 -7
  86. package/src/lib/editorConfigStore.ts +0 -10
  87. package/src/lib/editorCore.ts +402 -0
  88. package/src/lib/editorKeybindings.ts +52 -0
  89. package/src/lib/editorPersistence.ts +106 -0
  90. package/src/lib/editorRenderer.ts +74 -0
  91. package/src/lib/editorStore.test.ts +328 -0
  92. package/src/lib/editorStore.ts +412 -0
  93. package/src/lib/editorTypes.ts +100 -0
  94. package/src/lib/editorViewStore.ts +55 -0
  95. package/src/lib/files/versionedFileResource.ts +140 -0
  96. package/src/lib/fontLoader.ts +130 -0
  97. package/src/lib/fontMigration.ts +140 -0
  98. package/src/lib/fontParse.ts +168 -0
  99. package/src/lib/index.ts +48 -30
  100. package/src/lib/lazyConfig.test.ts +54 -0
  101. package/src/lib/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +64 -0
  102. package/src/lib/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +71 -0
  103. package/src/lib/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +43 -0
  104. package/src/lib/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +68 -0
  105. package/src/lib/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +35 -0
  106. package/src/lib/migrations/2026-05-10-sectiondivider-gradient-stops.ts +50 -0
  107. package/src/lib/migrations/2026-05-13-primary-to-brand.ts +90 -0
  108. package/src/lib/migrations/index.ts +93 -0
  109. package/src/lib/migrations/migrations.test.ts +341 -0
  110. package/src/lib/navLinkTypes.ts +1 -0
  111. package/src/lib/overlayState.ts +3 -0
  112. package/src/lib/paletteDerivation.ts +300 -0
  113. package/src/lib/parentRouteStore.ts +42 -0
  114. package/src/lib/parsers/globalRootBlock.ts +32 -0
  115. package/src/lib/presetService.ts +94 -0
  116. package/src/lib/router.ts +42 -10
  117. package/src/lib/scrollSection.ts +45 -0
  118. package/src/lib/slices/columns.ts +59 -0
  119. package/src/lib/slices/components.ts +362 -0
  120. package/src/lib/slices/domainVars.ts +15 -0
  121. package/src/lib/slices/fonts.ts +30 -0
  122. package/src/lib/slices/gradients.ts +153 -0
  123. package/src/lib/slices/overlays.ts +132 -0
  124. package/src/lib/slices/palettes.ts +26 -0
  125. package/src/lib/slices/shadows.ts +123 -0
  126. package/src/lib/storage.ts +88 -0
  127. package/src/lib/themeInit.ts +74 -0
  128. package/src/lib/themeService.ts +101 -0
  129. package/src/lib/themeTypes.ts +146 -0
  130. package/src/lib/tokenRegistry.ts +148 -0
  131. package/src/pages/ComponentEditorPage.svelte +384 -0
  132. package/src/pages/ComponentEditorPage.svelte.d.ts +2 -0
  133. package/src/pages/Editor.svelte +98 -0
  134. package/src/pages/Editor.svelte.d.ts +2 -0
  135. package/src/pages/EditorShell.svelte +348 -0
  136. package/src/styles/_padding.scss +34 -0
  137. package/src/styles/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  138. package/src/styles/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  139. package/src/styles/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  140. package/src/styles/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  141. package/src/styles/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  142. package/src/styles/fonts/Manrope/Manrope-latin.woff2 +0 -0
  143. package/src/styles/fonts.css +22 -10
  144. package/src/styles/form-controls.css +14 -16
  145. package/src/styles/tokens.css +1322 -0
  146. package/src/styles/ui-editor.css +126 -0
  147. package/src/{showcase → ui}/BezierCurveEditor.svelte +14 -14
  148. package/src/{showcase → ui}/ColorEditPanel.svelte +42 -36
  149. package/src/ui/EditorViewSwitcher.svelte +180 -0
  150. package/src/ui/FontStackEditor.svelte +360 -0
  151. package/src/ui/GradientEditor.svelte +461 -0
  152. package/src/ui/GradientStopPicker.svelte +74 -0
  153. package/src/ui/PaletteEditor.svelte +1590 -0
  154. package/src/ui/PaletteEditor.test.ts +108 -0
  155. package/src/ui/PresetFileManager.svelte +567 -0
  156. package/src/ui/ProjectFontsSection.svelte +645 -0
  157. package/src/{showcase → ui}/SurfacesTab.svelte +39 -39
  158. package/src/{showcase → ui}/TextTab.svelte +27 -27
  159. package/src/{showcase/TokenFileManager.svelte → ui/ThemeFileManager.svelte} +196 -112
  160. package/src/ui/Toggle.svelte +108 -0
  161. package/src/ui/UICopyPopover.svelte +78 -0
  162. package/src/{showcase/EditorDialog.svelte → ui/UIDialog.svelte} +66 -25
  163. package/src/ui/UIFontFamilySelector.svelte +309 -0
  164. package/src/ui/UIFontSizeSelector.svelte +165 -0
  165. package/src/ui/UIFontWeightSelector.svelte +52 -0
  166. package/src/ui/UILineHeightSelector.svelte +47 -0
  167. package/src/ui/UILinkToggle.svelte +60 -0
  168. package/src/ui/UIOptionItem.svelte +74 -0
  169. package/src/ui/UIOptionList.svelte +27 -0
  170. package/src/ui/UIPaddingSelector.svelte +661 -0
  171. package/src/ui/UIPaletteSelector.svelte +1084 -0
  172. package/src/ui/UIRadio.svelte +72 -0
  173. package/src/ui/UIRadioGroup.svelte +59 -0
  174. package/src/ui/UIRelinkConfirmPopover.svelte +235 -0
  175. package/src/ui/UITokenSelector.svelte +509 -0
  176. package/src/ui/UIVariantSelector.svelte +145 -0
  177. package/src/ui/VariablesTab.svelte +252 -0
  178. package/src/ui/index.ts +31 -0
  179. package/src/ui/keepInViewport.ts +84 -0
  180. package/src/ui/palette/GradientStopEditor.svelte +482 -0
  181. package/src/ui/palette/OverridesPanel.svelte +526 -0
  182. package/src/ui/palette/PaletteBase.svelte +165 -0
  183. package/src/ui/palette/ScaleCurveEditor.svelte +38 -0
  184. package/src/ui/palette/paletteEditorState.ts +89 -0
  185. package/src/ui/sections/ColumnsSection.svelte +273 -0
  186. package/src/ui/sections/GradientsSection.svelte +147 -0
  187. package/src/ui/sections/OverlaysSection.svelte +670 -0
  188. package/src/ui/sections/ShadowsSection.svelte +1250 -0
  189. package/src/ui/sections/TokenScaleTable.svelte +332 -0
  190. package/src/ui/sections/tokenScales.ts +81 -0
  191. package/src/ui/variantScales.ts +108 -0
  192. package/src/components/DetailNav.svelte +0 -78
  193. package/src/components/Toggle.svelte +0 -86
  194. package/src/lib/tokenInit.ts +0 -29
  195. package/src/lib/tokenService.ts +0 -144
  196. package/src/lib/tokenTypes.ts +0 -45
  197. package/src/pages/Admin.svelte +0 -100
  198. package/src/pages/ShowcasePage.svelte +0 -144
  199. package/src/showcase/BackupBrowser.svelte +0 -617
  200. package/src/showcase/ComponentsTab.svelte +0 -105
  201. package/src/showcase/PaletteEditor.svelte +0 -2579
  202. package/src/showcase/PaletteSelector.svelte +0 -627
  203. package/src/showcase/TokenMap.svelte +0 -54
  204. package/src/showcase/VariablesTab.svelte +0 -2655
  205. package/src/showcase/VisualsTab.svelte +0 -231
  206. package/src/showcase/demos/BadgeDemo.svelte +0 -56
  207. package/src/showcase/demos/CardDemo.svelte +0 -50
  208. package/src/showcase/demos/ChoiceButtonsDemo.svelte +0 -192
  209. package/src/showcase/demos/CollapsibleSectionDemo.svelte +0 -54
  210. package/src/showcase/demos/DialogDemo.svelte +0 -42
  211. package/src/showcase/demos/InlineEditActionsDemo.svelte +0 -25
  212. package/src/showcase/demos/NotificationDemo.svelte +0 -147
  213. package/src/showcase/demos/ProgressBarDemo.svelte +0 -54
  214. package/src/showcase/demos/RadioButtonDemo.svelte +0 -56
  215. package/src/showcase/demos/SectionDividerDemo.svelte +0 -77
  216. package/src/showcase/demos/StandardButtonsDemo.svelte +0 -455
  217. package/src/showcase/demos/TabBarDemo.svelte +0 -58
  218. package/src/showcase/demos/TooltipDemo.svelte +0 -52
  219. package/src/showcase/editor.css +0 -93
  220. package/src/showcase/index.ts +0 -17
  221. package/src/styles/fonts/Domine/Domine-VariableFont_wght.ttf +0 -0
  222. package/src/styles/fonts/Domine/OFL.txt +0 -97
  223. package/src/styles/fonts/Domine/README.txt +0 -66
  224. /package/src/{showcase → ui}/curveEngine.ts +0 -0
@@ -0,0 +1,252 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import PaletteEditor from './PaletteEditor.svelte';
4
+ import FontStackEditor from './FontStackEditor.svelte';
5
+ import ProjectFontsSection from './ProjectFontsSection.svelte';
6
+ import ColumnsSection from './sections/ColumnsSection.svelte';
7
+ import TokenScaleTable from './sections/TokenScaleTable.svelte';
8
+ import OverlaysSection from './sections/OverlaysSection.svelte';
9
+ import GradientsSection from './sections/GradientsSection.svelte';
10
+ import ShadowsSection from './sections/ShadowsSection.svelte';
11
+ import {
12
+ SPACING_VARS, BORDER_WIDTH_VARS, RADIUS_VARS, FONT_SIZE_VARS,
13
+ ICON_SIZE_VARS, FONT_WEIGHT_VARS, LINE_HEIGHT_VARS,
14
+ DURATION_TOKENS, Z_INDEX_TOKENS, OPACITY_TOKENS,
15
+ } from './sections/tokenScales';
16
+
17
+ /** Visual flash for the copy-to-clipboard chip, kept short enough to
18
+ * feel like immediate confirmation but long enough to register. */
19
+ const COPIED_FLASH_MS = 1000;
20
+
21
+ // Bumped on breakpoint flips; passed to TokenScaleTable so it re-resolves.
22
+ // tokens.css declares responsive overrides at 768px and 480px.
23
+ let liveVersion = 0;
24
+ const BREAKPOINTS = ['(max-width: 768px)', '(max-width: 480px)'] as const;
25
+
26
+ onMount(() => {
27
+ liveVersion++; // initial read once the DOM has tokens.css applied
28
+ if (typeof window === 'undefined') return;
29
+ const mqls = BREAKPOINTS.map((q) => window.matchMedia(q));
30
+ const bump = () => { liveVersion++; };
31
+ for (const m of mqls) m.addEventListener('change', bump);
32
+ return () => {
33
+ for (const m of mqls) m.removeEventListener('change', bump);
34
+ };
35
+ });
36
+
37
+ let copiedVar: string | null = null;
38
+ function copyVariable(v: string) {
39
+ navigator.clipboard.writeText(v);
40
+ copiedVar = v;
41
+ setTimeout(() => { copiedVar = null; }, COPIED_FLASH_MS);
42
+ }
43
+ </script>
44
+
45
+ <div class="variables-container">
46
+ <!-- Palette Editor -->
47
+ <section class="section" id="palette-editor">
48
+ <h2 class="section-title">Palette Editor</h2>
49
+ <p class="editor-intro">Derived palettes via <code>color-mix(in oklch)</code>. Change a base color to update all derived steps. Click any derived swatch to add a manual override.</p>
50
+ <div class="palette-editors">
51
+ <PaletteEditor label="Brand" initialColor="#c93636" cssNamespace="brand" />
52
+ <PaletteEditor label="Accent" initialColor="#f49e0b" cssNamespace="accent" />
53
+ <PaletteEditor label="Background" initialColor="#1a1a2e" cssNamespace="canvas" emptySelector />
54
+ <PaletteEditor mode="gray" label="Neutral" cssNamespace="neutral"/>
55
+ <PaletteEditor mode="gray" label="Alternate" displayLabel="Alternate (neutral)" cssNamespace="alternate" />
56
+ <PaletteEditor label="Special" initialColor="#8b5cf6" cssNamespace="special" />
57
+ <PaletteEditor label="Info" initialColor="#3077e8" cssNamespace="info" />
58
+ <PaletteEditor label="Success" initialColor="#21c45d" cssNamespace="success" />
59
+ <PaletteEditor label="Warning" initialColor="#e66e1a" cssNamespace="warning" />
60
+ <PaletteEditor label="Danger" initialColor="#e8304f" cssNamespace="danger" />
61
+ </div>
62
+ </section>
63
+
64
+ <!-- Spacing & Borders -->
65
+ <section class="section" id="spacing">
66
+ <h2 class="section-title">Spacing &amp; Borders</h2>
67
+ <h3 class="subsection-title">Spacing</h3>
68
+ <TokenScaleTable kind="spacing" vars={SPACING_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
69
+ <h3 class="subsection-title">Borders</h3>
70
+ <TokenScaleTable kind="border" vars={BORDER_WIDTH_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
71
+ </section>
72
+
73
+ <!-- Columns -->
74
+ <ColumnsSection />
75
+
76
+ <!-- Border Radius -->
77
+ <section class="section" id="border-radius">
78
+ <h2 class="section-title">Border Radius</h2>
79
+ <TokenScaleTable kind="radius" vars={RADIUS_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
80
+ </section>
81
+
82
+ <!-- Typography -->
83
+ <section class="section" id="typography">
84
+ <h2 class="section-title">Typography</h2>
85
+
86
+ <div class="typography-columns">
87
+ <div class="typography-group font-families-group">
88
+ <ProjectFontsSection />
89
+ <h3 class="group-title">Font Families</h3>
90
+ <FontStackEditor />
91
+ </div>
92
+
93
+ <div class="typography-group">
94
+ <h3 class="group-title">Font Sizes</h3>
95
+ <TokenScaleTable kind="font-size" vars={FONT_SIZE_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
96
+ </div>
97
+
98
+ <div class="typography-group">
99
+ <h3 class="group-title">Font Weights</h3>
100
+ <TokenScaleTable kind="font-weight" vars={FONT_WEIGHT_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
101
+ </div>
102
+
103
+ <div class="typography-group">
104
+ <h3 class="group-title">Line Heights</h3>
105
+ <TokenScaleTable kind="line-height" vars={LINE_HEIGHT_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
106
+ </div>
107
+ </div>
108
+ </section>
109
+
110
+ <!-- Icon Sizes -->
111
+ <section class="section" id="icon-sizes">
112
+ <h2 class="section-title">Icon Sizes</h2>
113
+ <TokenScaleTable kind="icon-size" vars={ICON_SIZE_VARS} {liveVersion} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
114
+ </section>
115
+
116
+
117
+ <!-- Shadows -->
118
+ <ShadowsSection {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
119
+
120
+
121
+ <!-- Overlays -->
122
+ <OverlaysSection {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
123
+
124
+ <!-- Gradients -->
125
+ <GradientsSection {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
126
+
127
+ <!-- Utility Tokens -->
128
+ <section class="section" id="utility-tokens">
129
+ <h2 class="section-title">Utility Tokens</h2>
130
+ <div class="utility-columns">
131
+ <div class="utility-group">
132
+ <h3 class="group-title">Durations</h3>
133
+ <TokenScaleTable kind="line-height" tokens={DURATION_TOKENS} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
134
+ </div>
135
+
136
+ <div class="utility-group">
137
+ <h3 class="group-title">Z-Index Layers</h3>
138
+ <TokenScaleTable kind="line-height" tokens={Z_INDEX_TOKENS} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
139
+ </div>
140
+
141
+ <div class="utility-group">
142
+ <h3 class="group-title">Opacity</h3>
143
+ <TokenScaleTable kind="line-height" tokens={OPACITY_TOKENS} {copiedVar} on:copy={(e) => copyVariable(e.detail)} />
144
+ </div>
145
+ </div>
146
+ </section>
147
+ </div>
148
+
149
+ <style>
150
+ .variables-container {
151
+ display: flex;
152
+ flex-direction: column;
153
+ gap: var(--ui-space-32);
154
+ }
155
+
156
+ .section {
157
+ display: flex;
158
+ flex-direction: column;
159
+ gap: var(--ui-space-16);
160
+ }
161
+
162
+ .section-title {
163
+ font-size: var(--ui-font-size-lg);
164
+ font-weight: var(--ui-font-weight-semibold);
165
+ color: var(--ui-text-primary);
166
+ margin: 0;
167
+ padding-bottom: var(--ui-space-8);
168
+ border-bottom: 1px solid var(--ui-border-subtle);
169
+ }
170
+
171
+ .group-title {
172
+ font-size: var(--ui-font-size-md);
173
+ font-weight: var(--ui-font-weight-semibold);
174
+ color: var(--ui-text-secondary);
175
+ margin: 0;
176
+ }
177
+
178
+ /* Subsection title (used by Spacing & Borders) */
179
+ .subsection-title {
180
+ margin: var(--ui-space-16) 0 var(--ui-space-8);
181
+ font-size: var(--ui-font-size-sm);
182
+ font-weight: var(--ui-font-weight-semibold);
183
+ color: var(--ui-text-secondary);
184
+ text-transform: uppercase;
185
+ letter-spacing: 0.04em;
186
+ }
187
+
188
+ .subsection-title:first-child,
189
+ .section-title + .subsection-title {
190
+ margin-top: 0;
191
+ }
192
+
193
+ /* Typography */
194
+ .typography-columns {
195
+ display: grid;
196
+ grid-template-columns: repeat(auto-fill, minmax(min(22rem, 100%), 1fr));
197
+ gap: var(--ui-space-24);
198
+ align-items: start;
199
+ }
200
+
201
+ .typography-group {
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: var(--ui-space-8);
205
+ min-width: 0;
206
+ }
207
+
208
+ .font-families-group {
209
+ grid-column: 1 / -1;
210
+ }
211
+
212
+ /* Utility Tokens */
213
+ .utility-columns {
214
+ display: grid;
215
+ grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
216
+ gap: var(--ui-space-24);
217
+ align-items: start;
218
+ }
219
+
220
+ .utility-group {
221
+ display: flex;
222
+ flex-direction: column;
223
+ gap: var(--ui-space-8);
224
+ }
225
+
226
+ /* Palette Editor */
227
+ .editor-intro {
228
+ font-size: var(--ui-font-size-md);
229
+ color: var(--ui-text-tertiary);
230
+ margin: 0;
231
+ }
232
+
233
+ .editor-intro code {
234
+ font-size: var(--ui-font-size-md);
235
+ color: var(--ui-text-accent);
236
+ background: var(--ui-surface-lowest);
237
+ padding: var(--ui-space-2) var(--ui-space-4);
238
+ border-radius: var(--ui-radius-sm);
239
+ font-family: var(--ui-font-mono);
240
+ }
241
+
242
+ .palette-editors {
243
+ display: flex;
244
+ flex-direction: column;
245
+ gap: var(--ui-space-16);
246
+ }
247
+
248
+ /* Utility fill tightens at narrow widths */
249
+ .utility-columns {
250
+ grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
251
+ }
252
+ </style>
@@ -0,0 +1,31 @@
1
+ // Generic primitives
2
+ export { default as UIDialog } from './UIDialog.svelte';
3
+ export { default as UILinkToggle } from './UILinkToggle.svelte';
4
+ export { default as UITokenSelector } from './UITokenSelector.svelte';
5
+ export { default as UIVariantSelector } from './UIVariantSelector.svelte';
6
+ export { default as UIOptionList } from './UIOptionList.svelte';
7
+ export { default as UIOptionItem } from './UIOptionItem.svelte';
8
+
9
+ // Semantic-property selectors
10
+ export { default as UIPaletteSelector } from './UIPaletteSelector.svelte';
11
+ export { default as UIFontFamilySelector } from './UIFontFamilySelector.svelte';
12
+ export { default as UIFontWeightSelector } from './UIFontWeightSelector.svelte';
13
+ // Scale data spread into UIVariantSelector — replaces the per-scale wrappers.
14
+ export * from './variantScales';
15
+
16
+ // Editor tabs & panels
17
+ export { default as VariablesTab } from './VariablesTab.svelte';
18
+ export { default as TextTab } from './TextTab.svelte';
19
+ export { default as SurfacesTab } from './SurfacesTab.svelte';
20
+
21
+ // Palette editor stack
22
+ export { default as PaletteEditor } from './PaletteEditor.svelte';
23
+ export { default as ColorEditPanel } from './ColorEditPanel.svelte';
24
+ export { default as BezierCurveEditor } from './BezierCurveEditor.svelte';
25
+
26
+ // Font editors
27
+ export { default as FontStackEditor } from './FontStackEditor.svelte';
28
+ export { default as ProjectFontsSection } from './ProjectFontsSection.svelte';
29
+
30
+ // Theme persistence UI
31
+ export { default as ThemeFileManager } from './ThemeFileManager.svelte';
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Svelte action: keep an absolutely-positioned element inside the viewport.
3
+ *
4
+ * Measures the element after layout, computes how far it overflows any
5
+ * viewport edge, and shifts it back via CSS `translate`. The original
6
+ * positioning (top/left/right/bottom) stays untouched so the *natural*
7
+ * placement is preserved when there's room — the action only nudges when
8
+ * the element would otherwise draw off-screen.
9
+ *
10
+ * Use on popovers and dropdowns whose trigger position is dynamic
11
+ * (cards in a wrapping flex grid, dropdowns near a panel edge, etc.).
12
+ *
13
+ * The CSS `translate` property is used instead of `transform` so it doesn't
14
+ * collide with `transform`-based entrance animations.
15
+ *
16
+ * Recomputes on:
17
+ * - mount (after first paint)
18
+ * - element resize (content reflow)
19
+ * - window resize
20
+ * - any scroll up the ancestor chain
21
+ *
22
+ * Usage:
23
+ * <div class="popover" use:keepInViewport>...</div>
24
+ * <div class="popover" use:keepInViewport={{ margin: 12 }}>...</div>
25
+ */
26
+
27
+ export type KeepInViewportOptions = {
28
+ /** Minimum gap (px) between the element and the viewport edges. Default 8. */
29
+ margin?: number;
30
+ };
31
+
32
+ export function keepInViewport(
33
+ node: HTMLElement,
34
+ options: KeepInViewportOptions = {},
35
+ ) {
36
+ let margin = options.margin ?? 8;
37
+ let pendingFrame: number | null = null;
38
+
39
+ function measure(): void {
40
+ if (pendingFrame !== null) return;
41
+ pendingFrame = requestAnimationFrame(() => {
42
+ pendingFrame = null;
43
+ // Reset our own translate before measuring so the rect reflects the
44
+ // element's natural placement, not last frame's correction.
45
+ node.style.translate = '';
46
+ const rect = node.getBoundingClientRect();
47
+ const vw = window.innerWidth;
48
+ const vh = window.innerHeight;
49
+ let dx = 0;
50
+ let dy = 0;
51
+ if (rect.left < margin) dx = margin - rect.left;
52
+ else if (rect.right > vw - margin) dx = vw - margin - rect.right;
53
+ if (rect.top < margin) dy = margin - rect.top;
54
+ else if (rect.bottom > vh - margin) dy = vh - margin - rect.bottom;
55
+ if (dx !== 0 || dy !== 0) {
56
+ node.style.translate = `${dx}px ${dy}px`;
57
+ }
58
+ });
59
+ }
60
+
61
+ measure();
62
+
63
+ const ro = new ResizeObserver(measure);
64
+ ro.observe(node);
65
+ window.addEventListener('resize', measure);
66
+ // Capture-phase scroll listener: catches scroll on any ancestor, not just
67
+ // window. The trigger's nearest scrolling parent (a panel, a modal body)
68
+ // shifts the popover's viewport position when scrolled.
69
+ window.addEventListener('scroll', measure, true);
70
+
71
+ return {
72
+ update(next: KeepInViewportOptions = {}) {
73
+ margin = next.margin ?? 8;
74
+ measure();
75
+ },
76
+ destroy() {
77
+ if (pendingFrame !== null) cancelAnimationFrame(pendingFrame);
78
+ ro.disconnect();
79
+ window.removeEventListener('resize', measure);
80
+ window.removeEventListener('scroll', measure, true);
81
+ node.style.translate = '';
82
+ },
83
+ };
84
+ }