@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
@@ -3,13 +3,16 @@
3
3
 
4
4
  export let disabled: boolean = false;
5
5
  export let type: 'button' | 'submit' | 'reset' = 'button';
6
- export let variant: 'primary' | 'secondary' | 'outline' | 'small_secondary' | 'success' | 'danger' | 'warning' = 'primary';
6
+ export let variant: 'primary' | 'secondary' | 'outline' | 'success' | 'danger' | 'warning' = 'primary';
7
7
  export let size: 'default' | 'small' = 'default';
8
8
  export let ariaLabel: string | undefined = undefined;
9
9
  export let tooltip: string | undefined = undefined;
10
10
  export let icon: string | undefined = undefined;
11
11
  export let iconPosition: 'left' | 'right' = 'left';
12
12
  export let fullWidth: boolean = false;
13
+ export let buttonRef: HTMLButtonElement | undefined = undefined;
14
+ let className: string = '';
15
+ export { className as class };
13
16
 
14
17
  const dispatch = createEventDispatcher();
15
18
 
@@ -21,8 +24,9 @@
21
24
  </script>
22
25
 
23
26
  <button
27
+ bind:this={buttonRef}
24
28
  {type}
25
- class="button {variant}"
29
+ class="button {variant} {className}"
26
30
  class:small={size === 'small'}
27
31
  class:full-width={fullWidth}
28
32
  {disabled}
@@ -40,19 +44,171 @@
40
44
  </button>
41
45
 
42
46
  <style lang="scss">
47
+ @use '../styles/padding' as *;
48
+
49
+ :global(:root) {
50
+ /* Shared — set to `none` to disable the hover shimmer sweep */
51
+ --button-shimmer: block;
52
+
53
+ /* Primary */
54
+ --button-primary-surface: var(--surface-brand-high);
55
+ --button-primary-text: var(--text-primary);
56
+ --button-primary-text-font-family: var(--font-sans);
57
+ --button-primary-text-font-size: var(--font-size-sm);
58
+ --button-primary-text-font-weight: var(--font-weight-light);
59
+ --button-primary-text-line-height: var(--line-height-snug);
60
+ --button-primary-border: var(--border-brand);
61
+ --button-primary-border-width: var(--border-width-1);
62
+ --button-primary-radius: var(--radius-md);
63
+ --button-primary-padding: var(--space-8);
64
+ --button-primary-hover-surface: var(--surface-brand-higher);
65
+ --button-primary-hover-text: var(--text-primary);
66
+ --button-primary-hover-border: var(--border-brand-strong);
67
+ --button-primary-hover-border-width: var(--border-width-1);
68
+ --button-primary-hover-radius: var(--radius-md);
69
+ --button-primary-hover-padding: var(--space-8);
70
+ --button-primary-disabled-surface: var(--color-neutral-700);
71
+ --button-primary-disabled-text: var(--text-tertiary);
72
+ --button-primary-disabled-border: var(--border-neutral-faint);
73
+ --button-primary-disabled-border-width: var(--border-width-1);
74
+ --button-primary-disabled-radius: var(--radius-md);
75
+ --button-primary-disabled-padding: var(--space-8);
76
+ --button-primary-icon-size: var(--icon-size-sm);
77
+
78
+ /* Secondary */
79
+ --button-secondary-surface: var(--surface-neutral-high);
80
+ --button-secondary-text: var(--text-primary);
81
+ --button-secondary-text-font-family: var(--font-sans);
82
+ --button-secondary-text-font-size: var(--font-size-sm);
83
+ --button-secondary-text-font-weight: var(--font-weight-light);
84
+ --button-secondary-text-line-height: var(--line-height-snug);
85
+ --button-secondary-border: var(--border-neutral);
86
+ --button-secondary-border-width: var(--border-width-1);
87
+ --button-secondary-radius: var(--radius-md);
88
+ --button-secondary-padding: var(--space-8);
89
+ --button-secondary-hover-surface: var(--surface-neutral-higher);
90
+ --button-secondary-hover-text: var(--text-primary);
91
+ --button-secondary-hover-border: var(--border-neutral-strong);
92
+ --button-secondary-hover-border-width: var(--border-width-1);
93
+ --button-secondary-hover-radius: var(--radius-md);
94
+ --button-secondary-hover-padding: var(--space-8);
95
+ --button-secondary-disabled-surface: var(--color-neutral-700);
96
+ --button-secondary-disabled-text: var(--text-tertiary);
97
+ --button-secondary-disabled-border: var(--border-neutral-faint);
98
+ --button-secondary-disabled-border-width: var(--border-width-1);
99
+ --button-secondary-disabled-radius: var(--radius-md);
100
+ --button-secondary-disabled-padding: var(--space-8);
101
+ --button-secondary-icon-size: var(--icon-size-sm);
102
+
103
+ /* Outline */
104
+ --button-outline-surface: var(--color-transparent);
105
+ --button-outline-text: var(--text-primary);
106
+ --button-outline-text-font-family: var(--font-sans);
107
+ --button-outline-text-font-size: var(--font-size-sm);
108
+ --button-outline-text-font-weight: var(--font-weight-light);
109
+ --button-outline-text-line-height: var(--line-height-snug);
110
+ --button-outline-border: var(--border-neutral);
111
+ --button-outline-border-width: var(--border-width-1);
112
+ --button-outline-radius: var(--radius-md);
113
+ --button-outline-padding: var(--space-8);
114
+ --button-outline-hover-surface: var(--surface-neutral-lower);
115
+ --button-outline-hover-text: var(--text-primary);
116
+ --button-outline-hover-border: var(--border-neutral-strong);
117
+ --button-outline-hover-border-width: var(--border-width-1);
118
+ --button-outline-hover-radius: var(--radius-md);
119
+ --button-outline-hover-padding: var(--space-8);
120
+ --button-outline-disabled-surface: var(--color-transparent);
121
+ --button-outline-disabled-text: var(--text-tertiary);
122
+ --button-outline-disabled-border: var(--border-neutral-faint);
123
+ --button-outline-disabled-border-width: var(--border-width-1);
124
+ --button-outline-disabled-radius: var(--radius-md);
125
+ --button-outline-disabled-padding: var(--space-8);
126
+ --button-outline-icon-size: var(--icon-size-sm);
127
+
128
+ /* Success */
129
+ --button-success-surface: var(--surface-success-low);
130
+ --button-success-text: var(--text-success);
131
+ --button-success-text-font-family: var(--font-sans);
132
+ --button-success-text-font-size: var(--font-size-sm);
133
+ --button-success-text-font-weight: var(--font-weight-light);
134
+ --button-success-text-line-height: var(--line-height-snug);
135
+ --button-success-border: var(--border-success);
136
+ --button-success-border-width: var(--border-width-2);
137
+ --button-success-radius: var(--radius-md);
138
+ --button-success-padding: var(--space-8);
139
+ --button-success-hover-surface: var(--surface-success-higher);
140
+ --button-success-hover-text: var(--text-primary);
141
+ --button-success-hover-border: var(--border-success-strong);
142
+ --button-success-hover-border-width: var(--border-width-2);
143
+ --button-success-hover-radius: var(--radius-md);
144
+ --button-success-hover-padding: var(--space-8);
145
+ --button-success-disabled-surface: var(--color-neutral-700);
146
+ --button-success-disabled-text: var(--text-tertiary);
147
+ --button-success-disabled-border: var(--border-neutral-faint);
148
+ --button-success-disabled-border-width: var(--border-width-2);
149
+ --button-success-disabled-radius: var(--radius-md);
150
+ --button-success-disabled-padding: var(--space-8);
151
+ --button-success-icon-size: var(--icon-size-sm);
152
+
153
+ /* Danger */
154
+ --button-danger-surface: var(--surface-danger-low);
155
+ --button-danger-text: var(--text-danger);
156
+ --button-danger-text-font-family: var(--font-sans);
157
+ --button-danger-text-font-size: var(--font-size-sm);
158
+ --button-danger-text-font-weight: var(--font-weight-light);
159
+ --button-danger-text-line-height: var(--line-height-snug);
160
+ --button-danger-border: var(--border-danger);
161
+ --button-danger-border-width: var(--border-width-2);
162
+ --button-danger-radius: var(--radius-md);
163
+ --button-danger-padding: var(--space-8);
164
+ --button-danger-hover-surface: var(--surface-danger-high);
165
+ --button-danger-hover-text: var(--text-primary);
166
+ --button-danger-hover-border: var(--border-danger-medium);
167
+ --button-danger-hover-border-width: var(--border-width-2);
168
+ --button-danger-hover-radius: var(--radius-md);
169
+ --button-danger-hover-padding: var(--space-8);
170
+ --button-danger-disabled-surface: var(--color-neutral-700);
171
+ --button-danger-disabled-text: var(--text-tertiary);
172
+ --button-danger-disabled-border: var(--border-neutral-faint);
173
+ --button-danger-disabled-border-width: var(--border-width-2);
174
+ --button-danger-disabled-radius: var(--radius-md);
175
+ --button-danger-disabled-padding: var(--space-8);
176
+ --button-danger-icon-size: var(--icon-size-sm);
177
+
178
+ /* Warning */
179
+ --button-warning-surface: var(--surface-warning-low);
180
+ --button-warning-text: var(--text-warning);
181
+ --button-warning-text-font-family: var(--font-sans);
182
+ --button-warning-text-font-size: var(--font-size-sm);
183
+ --button-warning-text-font-weight: var(--font-weight-light);
184
+ --button-warning-text-line-height: var(--line-height-snug);
185
+ --button-warning-border: var(--border-warning);
186
+ --button-warning-border-width: var(--border-width-2);
187
+ --button-warning-radius: var(--radius-md);
188
+ --button-warning-padding: var(--space-8);
189
+ --button-warning-hover-surface: var(--surface-warning-high);
190
+ --button-warning-hover-text: var(--text-primary);
191
+ --button-warning-hover-border: var(--border-warning-medium);
192
+ --button-warning-hover-border-width: var(--border-width-2);
193
+ --button-warning-hover-radius: var(--radius-md);
194
+ --button-warning-hover-padding: var(--space-8);
195
+ --button-warning-disabled-surface: var(--color-neutral-700);
196
+ --button-warning-disabled-text: var(--text-tertiary);
197
+ --button-warning-disabled-border: var(--border-neutral-faint);
198
+ --button-warning-disabled-border-width: var(--border-width-2);
199
+ --button-warning-disabled-radius: var(--radius-md);
200
+ --button-warning-disabled-padding: var(--space-8);
201
+ --button-warning-icon-size: var(--icon-size-sm);
202
+ }
203
+
43
204
  .button {
44
- padding: var(--space-8) var(--space-16);
45
- border-radius: var(--radius-md);
46
205
  cursor: pointer;
47
- font-size: var(--font-sm);
48
- font-weight: var(--font-weight-medium);
49
- line-height: 1.2;
50
206
  letter-spacing: 0.0125rem;
51
207
  display: inline-flex;
52
208
  align-items: center;
53
209
  justify-content: center;
54
210
  gap: var(--space-8);
55
- transition: all var(--transition-fast);
211
+ transition: all var(--duration-150);
56
212
  position: relative;
57
213
  overflow: hidden;
58
214
 
@@ -64,6 +220,7 @@
64
220
  // Shimmer effect
65
221
  &::before {
66
222
  content: '';
223
+ display: var(--button-shimmer, block);
67
224
  position: absolute;
68
225
  top: 0;
69
226
  left: -100%;
@@ -72,11 +229,13 @@
72
229
  transition: left 0.5s ease;
73
230
  }
74
231
 
75
- &:hover:not(:disabled)::before {
232
+ &:hover:not(:disabled)::before,
233
+ &.force-hover:not(:disabled)::before {
76
234
  left: 100%;
77
235
  }
78
236
 
79
- &:hover:not(:disabled) {
237
+ &:hover:not(:disabled),
238
+ &.force-hover:not(:disabled) {
80
239
  transform: translateY(-0.0625rem);
81
240
  box-shadow: var(--shadow-md);
82
241
  }
@@ -86,7 +245,6 @@
86
245
  }
87
246
 
88
247
  &:disabled {
89
- opacity: var(--opacity-disabled);
90
248
  cursor: not-allowed;
91
249
 
92
250
  &::before {
@@ -94,24 +252,18 @@
94
252
  }
95
253
  }
96
254
 
97
- // Small size modifier (applies to any variant)
98
- &.small {
99
- padding: var(--space-6) var(--space-12);
100
- font-size: var(--font-xs);
101
- font-weight: var(--font-weight-semibold);
102
- line-height: 1.2;
103
-
104
- :global(i) {
105
- font-size: var(--font-xs);
106
- font-weight: var(--font-weight-bold);
107
- }
108
- }
109
-
110
255
  // Primary variant (default)
111
256
  &.primary {
112
- background: var(--surface-primary-high);
113
- color: var(--text-primary);
114
- border: 1px solid var(--border-primary);
257
+ --button-icon-size: var(--button-primary-icon-size);
258
+ background: var(--button-primary-surface);
259
+ color: var(--button-primary-text);
260
+ border: var(--button-primary-border-width) solid var(--button-primary-border);
261
+ border-radius: var(--button-primary-radius);
262
+ @include themed-padding(--button-primary-padding, $h: 2);
263
+ font-family: var(--button-primary-text-font-family);
264
+ font-size: var(--button-primary-text-font-size);
265
+ font-weight: var(--button-primary-text-font-weight);
266
+ line-height: var(--button-primary-text-line-height);
115
267
 
116
268
  &::before {
117
269
  background: linear-gradient(90deg,
@@ -120,9 +272,13 @@
120
272
  transparent);
121
273
  }
122
274
 
123
- &:hover:not(:disabled) {
124
- background: var(--surface-primary-higher);
125
- border-color: var(--border-primary-strong);
275
+ &:hover:not(:disabled),
276
+ &.force-hover:not(:disabled) {
277
+ background: var(--button-primary-hover-surface);
278
+ border: var(--button-primary-hover-border-width) solid var(--button-primary-hover-border);
279
+ border-radius: var(--button-primary-hover-radius);
280
+ @include themed-padding(--button-primary-hover-padding, $h: 2);
281
+ color: var(--button-primary-hover-text);
126
282
  }
127
283
 
128
284
  &:active:not(:disabled) {
@@ -130,53 +286,79 @@
130
286
  }
131
287
 
132
288
  &:disabled {
133
- background: var(--color-neutral-700);
134
- border-color: var(--border-neutral-faint);
135
- color: var(--text-tertiary);
289
+ background: var(--button-primary-disabled-surface);
290
+ border: var(--button-primary-disabled-border-width) solid var(--button-primary-disabled-border);
291
+ border-radius: var(--button-primary-disabled-radius);
292
+ @include themed-padding(--button-primary-disabled-padding, $h: 2);
293
+ color: var(--button-primary-disabled-text);
136
294
  }
137
295
  }
138
296
 
139
297
  // Secondary variant
140
298
  &.secondary {
141
- background: var(--surface-neutral-high);
142
- color: var(--text-primary);
143
- border: 1px solid var(--border-neutral-default);
299
+ --button-icon-size: var(--button-secondary-icon-size);
300
+ background: var(--button-secondary-surface);
301
+ color: var(--button-secondary-text);
302
+ border: var(--button-secondary-border-width) solid var(--button-secondary-border);
303
+ border-radius: var(--button-secondary-radius);
304
+ @include themed-padding(--button-secondary-padding, $h: 2);
305
+ font-family: var(--button-secondary-text-font-family);
306
+ font-size: var(--button-secondary-text-font-size);
307
+ font-weight: var(--button-secondary-text-font-weight);
308
+ line-height: var(--button-secondary-text-line-height);
144
309
 
145
310
  &::before {
146
311
  background: linear-gradient(90deg,
147
312
  transparent,
148
- var(--hover),
313
+ rgba(255, 255, 255, 0.1),
149
314
  transparent);
150
315
  }
151
316
 
152
- &:hover:not(:disabled) {
153
- background: var(--surface-neutral-higher);
154
- border-color: var(--border-neutral-strong);
317
+ &:hover:not(:disabled),
318
+ &.force-hover:not(:disabled) {
319
+ background: var(--button-secondary-hover-surface);
320
+ border: var(--button-secondary-hover-border-width) solid var(--button-secondary-hover-border);
321
+ border-radius: var(--button-secondary-hover-radius);
322
+ @include themed-padding(--button-secondary-hover-padding, $h: 2);
323
+ color: var(--button-secondary-hover-text);
155
324
  }
156
325
 
157
326
  &:disabled {
158
- background: var(--color-neutral-700);
159
- border-color: var(--border-neutral-faint);
160
- color: var(--text-tertiary);
327
+ background: var(--button-secondary-disabled-surface);
328
+ border: var(--button-secondary-disabled-border-width) solid var(--button-secondary-disabled-border);
329
+ border-radius: var(--button-secondary-disabled-radius);
330
+ @include themed-padding(--button-secondary-disabled-padding, $h: 2);
331
+ color: var(--button-secondary-disabled-text);
161
332
  }
162
333
  }
163
334
 
164
335
  // Outline variant
165
336
  &.outline {
166
- background: transparent;
167
- color: var(--text-primary);
168
- border: 1px solid var(--border-neutral-default);
337
+ --button-icon-size: var(--button-outline-icon-size);
338
+ background: var(--button-outline-surface);
339
+ color: var(--button-outline-text);
340
+ border: var(--button-outline-border-width) solid var(--button-outline-border);
341
+ border-radius: var(--button-outline-radius);
342
+ @include themed-padding(--button-outline-padding, $h: 2);
343
+ font-family: var(--button-outline-text-font-family);
344
+ font-size: var(--button-outline-text-font-size);
345
+ font-weight: var(--button-outline-text-font-weight);
346
+ line-height: var(--button-outline-text-line-height);
169
347
 
170
348
  &::before {
171
349
  background: linear-gradient(90deg,
172
350
  transparent,
173
- var(--hover),
351
+ rgba(255, 255, 255, 0.1),
174
352
  transparent);
175
353
  }
176
354
 
177
- &:hover:not(:disabled) {
178
- background: var(--hover-low);
179
- border-color: var(--border-neutral-strong);
355
+ &:hover:not(:disabled),
356
+ &.force-hover:not(:disabled) {
357
+ background: var(--button-outline-hover-surface);
358
+ border: var(--button-outline-hover-border-width) solid var(--button-outline-hover-border);
359
+ border-radius: var(--button-outline-hover-radius);
360
+ @include themed-padding(--button-outline-hover-padding, $h: 2);
361
+ color: var(--button-outline-hover-text);
180
362
  }
181
363
 
182
364
  &:active:not(:disabled) {
@@ -184,56 +366,26 @@
184
366
  }
185
367
 
186
368
  &:disabled {
187
- background: transparent;
188
- border-color: var(--border-neutral-faint);
189
- color: var(--text-tertiary);
190
- }
191
- }
192
-
193
- // Small Secondary variant (matches add-structure-button)
194
- &.small_secondary {
195
- padding: var(--space-8) var(--space-16);
196
- background: var(--hover);
197
- color: var(--text-primary);
198
- border: 1px solid var(--border-neutral-default);
199
- font-size: var(--font-sm);
200
- font-weight: var(--font-weight-semibold);
201
- line-height: 1.2;
202
-
203
- &::before {
204
- background: linear-gradient(90deg,
205
- transparent,
206
- var(--hover),
207
- transparent);
208
- }
209
-
210
- &:hover:not(:disabled) {
211
- background: var(--hover-high);
212
- border-color: var(--border-neutral-strong);
213
- }
214
-
215
- &:active:not(:disabled) {
216
- background: rgba(255, 255, 255, 0.18);
217
- }
218
-
219
- &:disabled {
220
- background: transparent;
221
- border-color: var(--border-neutral-faint);
222
- color: var(--text-tertiary);
223
- }
224
-
225
- :global(i) {
226
- font-size: var(--font-sm);
227
- font-weight: var(--font-weight-bold);
228
-
369
+ background: var(--button-outline-disabled-surface);
370
+ border: var(--button-outline-disabled-border-width) solid var(--button-outline-disabled-border);
371
+ border-radius: var(--button-outline-disabled-radius);
372
+ @include themed-padding(--button-outline-disabled-padding, $h: 2);
373
+ color: var(--button-outline-disabled-text);
229
374
  }
230
375
  }
231
376
 
232
377
  // Success variant
233
378
  &.success {
234
- background: var(--surface-success-low);
235
- border: 2px solid var(--border-success);
236
- color: var(--text-success);
379
+ --button-icon-size: var(--button-success-icon-size);
380
+ background: var(--button-success-surface);
381
+ border: var(--button-success-border-width) solid var(--button-success-border);
382
+ border-radius: var(--button-success-radius);
383
+ @include themed-padding(--button-success-padding, $h: 2);
384
+ color: var(--button-success-text);
385
+ font-family: var(--button-success-text-font-family);
386
+ font-size: var(--button-success-text-font-size);
387
+ font-weight: var(--button-success-text-font-weight);
388
+ line-height: var(--button-success-text-line-height);
237
389
 
238
390
  &::before {
239
391
  background: linear-gradient(90deg,
@@ -242,24 +394,36 @@
242
394
  transparent);
243
395
  }
244
396
 
245
- &:hover:not(:disabled) {
246
- background: var(--surface-success-higher);
247
- border-color: var(--border-success-strong);
248
- color: var(--text-primary);
397
+ &:hover:not(:disabled),
398
+ &.force-hover:not(:disabled) {
399
+ background: var(--button-success-hover-surface);
400
+ border: var(--button-success-hover-border-width) solid var(--button-success-hover-border);
401
+ border-radius: var(--button-success-hover-radius);
402
+ @include themed-padding(--button-success-hover-padding, $h: 2);
403
+ color: var(--button-success-hover-text);
249
404
  }
250
405
 
251
406
  &:disabled {
252
- background: var(--color-neutral-700);
253
- border-color: var(--border-neutral-faint);
254
- color: var(--text-tertiary);
407
+ background: var(--button-success-disabled-surface);
408
+ border: var(--button-success-disabled-border-width) solid var(--button-success-disabled-border);
409
+ border-radius: var(--button-success-disabled-radius);
410
+ @include themed-padding(--button-success-disabled-padding, $h: 2);
411
+ color: var(--button-success-disabled-text);
255
412
  }
256
413
  }
257
414
 
258
415
  // Danger variant
259
416
  &.danger {
260
- background: var(--surface-danger-low);
261
- border: 2px solid var(--border-danger);
262
- color: var(--text-danger);
417
+ --button-icon-size: var(--button-danger-icon-size);
418
+ background: var(--button-danger-surface);
419
+ border: var(--button-danger-border-width) solid var(--button-danger-border);
420
+ border-radius: var(--button-danger-radius);
421
+ @include themed-padding(--button-danger-padding, $h: 2);
422
+ color: var(--button-danger-text);
423
+ font-family: var(--button-danger-text-font-family);
424
+ font-size: var(--button-danger-text-font-size);
425
+ font-weight: var(--button-danger-text-font-weight);
426
+ line-height: var(--button-danger-text-line-height);
263
427
 
264
428
  &::before {
265
429
  background: linear-gradient(90deg,
@@ -268,24 +432,36 @@
268
432
  transparent);
269
433
  }
270
434
 
271
- &:hover:not(:disabled) {
272
- background: var(--surface-danger-high);
273
- border-color: var(--border-danger-medium);
274
- color: var(--text-primary);
435
+ &:hover:not(:disabled),
436
+ &.force-hover:not(:disabled) {
437
+ background: var(--button-danger-hover-surface);
438
+ border: var(--button-danger-hover-border-width) solid var(--button-danger-hover-border);
439
+ border-radius: var(--button-danger-hover-radius);
440
+ @include themed-padding(--button-danger-hover-padding, $h: 2);
441
+ color: var(--button-danger-hover-text);
275
442
  }
276
443
 
277
444
  &:disabled {
278
- background: var(--color-neutral-700);
279
- border-color: var(--border-neutral-faint);
280
- color: var(--text-tertiary);
445
+ background: var(--button-danger-disabled-surface);
446
+ border: var(--button-danger-disabled-border-width) solid var(--button-danger-disabled-border);
447
+ border-radius: var(--button-danger-disabled-radius);
448
+ @include themed-padding(--button-danger-disabled-padding, $h: 2);
449
+ color: var(--button-danger-disabled-text);
281
450
  }
282
451
  }
283
452
 
284
453
  // Warning variant
285
454
  &.warning {
286
- background: var(--surface-warning-low);
287
- border: 2px solid var(--border-warning);
288
- color: var(--text-warning);
455
+ --button-icon-size: var(--button-warning-icon-size);
456
+ background: var(--button-warning-surface);
457
+ border: var(--button-warning-border-width) solid var(--button-warning-border);
458
+ border-radius: var(--button-warning-radius);
459
+ @include themed-padding(--button-warning-padding, $h: 2);
460
+ color: var(--button-warning-text);
461
+ font-family: var(--button-warning-text-font-family);
462
+ font-size: var(--button-warning-text-font-size);
463
+ font-weight: var(--button-warning-text-font-weight);
464
+ line-height: var(--button-warning-text-line-height);
289
465
 
290
466
  &::before {
291
467
  background: linear-gradient(90deg,
@@ -294,21 +470,45 @@
294
470
  transparent);
295
471
  }
296
472
 
297
- &:hover:not(:disabled) {
298
- background: var(--surface-warning-high);
299
- border-color: var(--border-warning-medium);
300
- color: var(--text-primary);
473
+ &:hover:not(:disabled),
474
+ &.force-hover:not(:disabled) {
475
+ background: var(--button-warning-hover-surface);
476
+ border: var(--button-warning-hover-border-width) solid var(--button-warning-hover-border);
477
+ border-radius: var(--button-warning-hover-radius);
478
+ @include themed-padding(--button-warning-hover-padding, $h: 2);
479
+ color: var(--button-warning-hover-text);
301
480
  }
302
481
 
303
482
  &:disabled {
304
- background: var(--color-neutral-700);
305
- border-color: var(--border-neutral-faint);
306
- color: var(--text-tertiary);
483
+ background: var(--button-warning-disabled-surface);
484
+ border: var(--button-warning-disabled-border-width) solid var(--button-warning-disabled-border);
485
+ border-radius: var(--button-warning-disabled-radius);
486
+ @include themed-padding(--button-warning-disabled-padding, $h: 2);
487
+ color: var(--button-warning-disabled-text);
307
488
  }
308
489
  }
309
490
 
491
+ // Small size modifier (applies to any variant).
492
+ // Declared after variants so equal-specificity rules win on source order;
493
+ // :hover/.force-hover/:disabled are listed so variant state-padding
494
+ // doesn't clobber .small in those states.
495
+ &.small,
496
+ &.small:hover:not(:disabled),
497
+ &.small.force-hover:not(:disabled),
498
+ &.small:disabled {
499
+ padding: var(--space-6) var(--space-12);
500
+ font-size: var(--font-size-xs);
501
+ font-weight: var(--font-weight-normal);
502
+ line-height: var(--line-height-snug);
503
+ }
504
+
505
+ &.small :global(i) {
506
+ font-size: var(--font-size-xs);
507
+ font-weight: var(--font-weight-semibold);
508
+ }
509
+
310
510
  :global(i) {
311
- font-size: var(--font-sm);
511
+ font-size: var(--button-icon-size, var(--icon-size-sm));
312
512
 
313
513
  &.spinning {
314
514
  animation: spin 1s linear infinite;
@@ -322,7 +522,7 @@
322
522
 
323
523
  // Support for slotted content with special styles
324
524
  :global(.badge), :global(.count), :global(.fame-count) {
325
- font-size: var(--font-sm);
525
+ font-size: var(--font-size-sm);
326
526
  opacity: 0.9;
327
527
  padding: var(--space-2) var(--space-6);
328
528
  background: var(--overlay-low);