@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,145 @@
1
+ <script context="module" lang="ts">
2
+ export const calloutVariants = ['info', 'success', 'warning', 'danger'] as const;
3
+ export type CalloutVariant = typeof calloutVariants[number];
4
+ </script>
5
+
6
+ <script lang="ts">
7
+ export let variant: CalloutVariant = 'info';
8
+ export let label: string = '';
9
+ </script>
10
+
11
+ <div class="callout callout-{variant}">
12
+ {#if label}<strong class="callout-label">{label}</strong>{' '}{/if}<span class="callout-message"><slot /></span>
13
+ </div>
14
+
15
+ <style lang="scss">
16
+ @use '../styles/padding' as *;
17
+
18
+ // Kept flat (not collapsed via SCSS @each) so the Layer-2 token-discovery
19
+ // parser (`extractGlobalRootBody` in src/lib/parsers/globalRootBlock.ts)
20
+ // can read the .svelte source verbatim. See parallel comment in
21
+ // Notification.svelte.
22
+ :global(:root) {
23
+ /* Info */
24
+ --callout-info-surface: var(--surface-info-lowest);
25
+ --callout-info-border: var(--border-info-subtle);
26
+ --callout-info-border-width: var(--border-width-1);
27
+ --callout-info-accent-width: var(--border-width-4);
28
+ --callout-info-radius: var(--radius-lg);
29
+ --callout-info-padding: var(--space-12);
30
+ --callout-info-label: var(--text-primary);
31
+ --callout-info-label-font-family: var(--font-serif);
32
+ --callout-info-label-font-size: var(--font-size-md);
33
+ --callout-info-label-font-weight: var(--font-weight-bold);
34
+ --callout-info-label-line-height: var(--line-height-relaxed);
35
+ --callout-info-text: var(--text-info);
36
+ --callout-info-text-font-family: var(--font-serif);
37
+ --callout-info-text-font-size: var(--font-size-md);
38
+ --callout-info-text-font-weight: var(--font-weight-normal);
39
+ --callout-info-text-line-height: var(--line-height-relaxed);
40
+
41
+ /* Success */
42
+ --callout-success-surface: var(--surface-success-lowest);
43
+ --callout-success-border: var(--border-success-subtle);
44
+ --callout-success-border-width: var(--border-width-1);
45
+ --callout-success-accent-width: var(--border-width-4);
46
+ --callout-success-radius: var(--radius-lg);
47
+ --callout-success-padding: var(--space-12);
48
+ --callout-success-label: var(--text-primary);
49
+ --callout-success-label-font-family: var(--font-serif);
50
+ --callout-success-label-font-size: var(--font-size-md);
51
+ --callout-success-label-font-weight: var(--font-weight-bold);
52
+ --callout-success-label-line-height: var(--line-height-relaxed);
53
+ --callout-success-text: var(--text-success);
54
+ --callout-success-text-font-family: var(--font-serif);
55
+ --callout-success-text-font-size: var(--font-size-md);
56
+ --callout-success-text-font-weight: var(--font-weight-normal);
57
+ --callout-success-text-line-height: var(--line-height-relaxed);
58
+
59
+ /* Warning */
60
+ --callout-warning-surface: var(--surface-warning-lowest);
61
+ --callout-warning-border: var(--border-warning-subtle);
62
+ --callout-warning-border-width: var(--border-width-1);
63
+ --callout-warning-accent-width: var(--border-width-4);
64
+ --callout-warning-radius: var(--radius-lg);
65
+ --callout-warning-padding: var(--space-12);
66
+ --callout-warning-label: var(--text-primary);
67
+ --callout-warning-label-font-family: var(--font-serif);
68
+ --callout-warning-label-font-size: var(--font-size-md);
69
+ --callout-warning-label-font-weight: var(--font-weight-bold);
70
+ --callout-warning-label-line-height: var(--line-height-relaxed);
71
+ --callout-warning-text: var(--text-warning);
72
+ --callout-warning-text-font-family: var(--font-serif);
73
+ --callout-warning-text-font-size: var(--font-size-md);
74
+ --callout-warning-text-font-weight: var(--font-weight-normal);
75
+ --callout-warning-text-line-height: var(--line-height-relaxed);
76
+
77
+ /* Danger */
78
+ --callout-danger-surface: var(--surface-danger-lowest);
79
+ --callout-danger-border: var(--border-danger-subtle);
80
+ --callout-danger-border-width: var(--border-width-1);
81
+ --callout-danger-accent-width: var(--border-width-4);
82
+ --callout-danger-radius: var(--radius-lg);
83
+ --callout-danger-padding: var(--space-12);
84
+ --callout-danger-label: var(--text-primary);
85
+ --callout-danger-label-font-family: var(--font-serif);
86
+ --callout-danger-label-font-size: var(--font-size-md);
87
+ --callout-danger-label-font-weight: var(--font-weight-bold);
88
+ --callout-danger-label-line-height: var(--line-height-relaxed);
89
+ --callout-danger-text: var(--text-danger);
90
+ --callout-danger-text-font-family: var(--font-serif);
91
+ --callout-danger-text-font-size: var(--font-size-md);
92
+ --callout-danger-text-font-weight: var(--font-weight-normal);
93
+ --callout-danger-text-line-height: var(--line-height-relaxed);
94
+ }
95
+
96
+ .callout {
97
+ margin: var(--space-24) 0;
98
+
99
+ :global(p) {
100
+ margin: 0;
101
+ display: inline;
102
+ }
103
+
104
+ :global(a) {
105
+ color: inherit;
106
+ text-decoration: underline;
107
+ text-underline-offset: 2px;
108
+
109
+ &:hover {
110
+ opacity: 0.8;
111
+ }
112
+ }
113
+ }
114
+
115
+ .callout-label {
116
+ margin-right: 0.25em;
117
+ }
118
+
119
+ // Variant rules differ only by token prefix.
120
+ @each $variant in (info, success, warning, danger) {
121
+ .callout-#{$variant} {
122
+ background: var(--callout-#{$variant}-surface);
123
+ border: var(--callout-#{$variant}-border-width) solid var(--callout-#{$variant}-border);
124
+ border-left-width: var(--callout-#{$variant}-accent-width);
125
+ border-radius: var(--callout-#{$variant}-radius);
126
+ @include themed-padding(--callout-#{$variant}-padding, $h: 1.33);
127
+
128
+ .callout-label {
129
+ color: var(--callout-#{$variant}-label);
130
+ font-family: var(--callout-#{$variant}-label-font-family);
131
+ font-size: var(--callout-#{$variant}-label-font-size);
132
+ font-weight: var(--callout-#{$variant}-label-font-weight);
133
+ line-height: var(--callout-#{$variant}-label-line-height);
134
+ }
135
+
136
+ .callout-message {
137
+ color: var(--callout-#{$variant}-text);
138
+ font-family: var(--callout-#{$variant}-text-font-family);
139
+ font-size: var(--callout-#{$variant}-text-font-size);
140
+ font-weight: var(--callout-#{$variant}-text-font-weight);
141
+ line-height: var(--callout-#{$variant}-text-line-height);
142
+ }
143
+ }
144
+ }
145
+ </style>
@@ -3,10 +3,12 @@
3
3
  export let iconColor: string = 'var(--text-secondary)';
4
4
  export let title: string = '';
5
5
  export let size: 'default' | 'compact' = 'default';
6
+ let className: string = '';
7
+ export { className as class };
6
8
  </script>
7
9
 
8
10
  <div
9
- class="card"
11
+ class="card {className}"
10
12
  class:compact={size === 'compact'}
11
13
  style="--card-color: {iconColor};"
12
14
  >
@@ -26,58 +28,154 @@
26
28
  </div>
27
29
 
28
30
  <style>
31
+ :global(:root) {
32
+ /* Default */
33
+ --card-default-surface: var(--surface-neutral-high);
34
+ --card-default-border: var(--border-neutral);
35
+ --card-default-border-width: var(--border-width-1);
36
+ --card-default-radius: var(--radius-lg);
37
+ --card-default-header-padding: var(--space-16);
38
+ --card-default-body-padding: var(--space-16);
39
+ --card-default-shadow: var(--shadow-sm);
40
+ --card-default-blur: var(--blur-none);
41
+ --card-default-header-surface: var(--color-transparent);
42
+
43
+ --card-default-title: var(--text-primary);
44
+ --card-default-title-font-family: var(--font-sans);
45
+ --card-default-title-font-size: var(--font-size-lg);
46
+ --card-default-title-font-weight: var(--font-weight-normal);
47
+ --card-default-title-line-height: var(--line-height-snug);
48
+
49
+ --card-default-icon-size: var(--icon-size-lg);
50
+
51
+ --card-default-body: var(--text-secondary);
52
+ --card-default-body-font-family: var(--font-sans);
53
+ --card-default-body-font-size: var(--font-size-md);
54
+ --card-default-body-font-weight: var(--font-weight-normal);
55
+ --card-default-body-line-height: var(--line-height-normal);
56
+
57
+ /* Hover */
58
+ --card-hover-surface: var(--surface-neutral-high);
59
+ --card-hover-border: var(--border-neutral-strong);
60
+ --card-hover-border-width: var(--border-width-1);
61
+ --card-hover-radius: var(--radius-lg);
62
+ --card-hover-header-padding: var(--space-16);
63
+ --card-hover-body-padding: var(--space-16);
64
+ --card-hover-shadow: var(--shadow-md);
65
+ --card-hover-blur: var(--blur-none);
66
+ --card-hover-header-surface: var(--color-transparent);
67
+
68
+ --card-hover-title: var(--text-primary);
69
+ --card-hover-title-font-family: var(--font-sans);
70
+ --card-hover-title-font-size: var(--font-size-lg);
71
+ --card-hover-title-font-weight: var(--font-weight-normal);
72
+ --card-hover-title-line-height: var(--line-height-snug);
73
+
74
+ --card-hover-icon-size: var(--icon-size-lg);
75
+
76
+ --card-hover-body: var(--text-secondary);
77
+ --card-hover-body-font-family: var(--font-sans);
78
+ --card-hover-body-font-size: var(--font-size-md);
79
+ --card-hover-body-font-weight: var(--font-weight-normal);
80
+ --card-hover-body-line-height: var(--line-height-normal);
81
+ }
82
+
29
83
  .card {
30
- background: var(--surface-neutral-high);
31
- border: 1px solid var(--border-neutral-default);
32
- border-radius: var(--radius-lg);
33
- padding: var(--space-16);
34
- transition: all var(--transition-fast);
84
+ background: var(--card-default-surface);
85
+ border: var(--card-default-border-width) solid var(--card-default-border);
86
+ border-radius: var(--card-default-radius);
87
+ box-shadow: var(--card-default-shadow);
88
+ backdrop-filter: blur(var(--card-default-blur));
89
+ transition: all var(--duration-150);
35
90
  display: flex;
36
91
  flex-direction: column;
37
- gap: var(--space-12);
38
- }
39
-
40
- .card:hover {
41
- border-color: var(--card-color, var(--border-neutral-strong));
42
- box-shadow: var(--shadow-md);
92
+ overflow: hidden;
43
93
  }
44
94
 
45
- .card.compact {
46
- padding: var(--space-8) var(--space-12);
47
- gap: var(--space-8);
95
+ .card:not(.no-hover):hover,
96
+ .card.force-hover {
97
+ background: var(--card-hover-surface);
98
+ border: var(--card-hover-border-width) solid var(--card-hover-border);
99
+ border-radius: var(--card-hover-radius);
100
+ box-shadow: var(--card-hover-shadow);
101
+ backdrop-filter: blur(var(--card-hover-blur));
48
102
  }
49
103
 
50
104
  .card-header {
51
105
  display: flex;
52
106
  align-items: center;
53
107
  gap: var(--space-8);
108
+ padding: var(--card-default-header-padding);
109
+ background: var(--card-default-header-surface);
110
+ }
111
+
112
+ .card:not(.no-hover):hover .card-header,
113
+ .card.force-hover .card-header {
114
+ padding: var(--card-hover-header-padding);
115
+ background: var(--card-hover-header-surface);
116
+ }
117
+
118
+ .card.compact .card-header,
119
+ .card.compact .card-body {
120
+ padding: var(--space-8) var(--space-12);
54
121
  }
55
122
 
56
123
  .card-icon {
57
- font-size: var(--font-lg);
58
- color: var(--card-color, var(--text-secondary));
124
+ font-size: var(--card-default-icon-size);
125
+ color: var(--card-color, var(--card-default-title));
126
+ }
127
+
128
+ .card:not(.no-hover):hover .card-icon,
129
+ .card.force-hover .card-icon {
130
+ font-size: var(--card-hover-icon-size);
131
+ color: var(--card-color, var(--card-hover-title));
59
132
  }
60
133
 
61
134
  .card.compact .card-icon {
62
- font-size: var(--font-md);
135
+ font-size: var(--icon-size-md);
63
136
  }
64
137
 
65
138
  .card-title {
66
- font-size: var(--font-lg);
67
- font-weight: var(--font-weight-semibold);
68
- color: var(--text-primary);
139
+ color: var(--card-default-title);
140
+ font-family: var(--card-default-title-font-family);
141
+ font-size: var(--card-default-title-font-size);
142
+ font-weight: var(--card-default-title-font-weight);
143
+ line-height: var(--card-default-title-line-height);
144
+ }
145
+
146
+ .card:not(.no-hover):hover .card-title,
147
+ .card.force-hover .card-title {
148
+ color: var(--card-hover-title);
149
+ font-family: var(--card-hover-title-font-family);
150
+ font-size: var(--card-hover-title-font-size);
151
+ font-weight: var(--card-hover-title-font-weight);
152
+ line-height: var(--card-hover-title-line-height);
69
153
  }
70
154
 
71
155
  .card.compact .card-title {
72
- font-size: var(--font-md);
156
+ font-size: var(--font-size-md);
73
157
  }
74
158
 
75
159
  .card-body {
76
- color: var(--text-secondary);
77
- font-size: var(--font-md);
160
+ color: var(--card-default-body);
161
+ font-family: var(--card-default-body-font-family);
162
+ font-size: var(--card-default-body-font-size);
163
+ font-weight: var(--card-default-body-font-weight);
164
+ line-height: var(--card-default-body-line-height);
165
+ padding: var(--card-default-body-padding);
166
+ }
167
+
168
+ .card:not(.no-hover):hover .card-body,
169
+ .card.force-hover .card-body {
170
+ color: var(--card-hover-body);
171
+ font-family: var(--card-hover-body-font-family);
172
+ font-size: var(--card-hover-body-font-size);
173
+ font-weight: var(--card-hover-body-font-weight);
174
+ line-height: var(--card-hover-body-line-height);
175
+ padding: var(--card-hover-body-padding);
78
176
  }
79
177
 
80
178
  .card.compact .card-body {
81
- font-size: var(--font-sm);
179
+ font-size: var(--font-size-sm);
82
180
  }
83
181
  </style>
@@ -1,11 +1,13 @@
1
1
  <script lang="ts">
2
2
  import { createEventDispatcher } from 'svelte';
3
3
 
4
- // Props
5
4
  export let label: string;
6
5
  export let expanded: boolean = false;
7
6
  export let href: string | undefined = undefined;
8
7
  export let active: boolean = false;
8
+ export let variant: 'chromeless' | 'divider' | 'container' = 'container';
9
+ let className: string = '';
10
+ export { className as class };
9
11
 
10
12
  const dispatch = createEventDispatcher<{
11
13
  toggle: void;
@@ -19,49 +21,165 @@
19
21
  }
20
22
  </script>
21
23
 
22
- {#if href}
23
- <a {href} class="section-header" class:expanded class:active on:click={handleHeaderClick}>
24
- <div class="section-toggle">
25
- <i class="fas fa-chevron-right toggle-icon"></i>
26
- <span class="section-label">{label}</span>
24
+ <section class="es-root variant-{variant} {className}">
25
+ {#if href}
26
+ <a {href} class="section-header" class:expanded class:active on:click={handleHeaderClick}>
27
+ <div class="section-toggle">
28
+ <i class="fas fa-chevron-right toggle-icon"></i>
29
+ <span class="section-label">{label}</span>
30
+ </div>
31
+ <slot name="summary" />
32
+ </a>
33
+ {:else}
34
+ <!-- svelte-ignore a11y-click-events-have-key-events a11y-no-noninteractive-element-interactions -->
35
+ <div class="section-header" class:expanded on:click={() => dispatch('toggle')}>
36
+ <div class="section-toggle">
37
+ <i class="fas fa-chevron-right toggle-icon"></i>
38
+ <span class="section-label">{label}</span>
39
+ </div>
40
+ <slot name="summary" />
27
41
  </div>
28
- <slot name="summary" />
29
- </a>
30
- {:else}
31
- <!-- svelte-ignore a11y-click-events-have-key-events a11y-no-noninteractive-element-interactions -->
32
- <div class="section-header" class:expanded on:click={() => dispatch('toggle')}>
33
- <div class="section-toggle">
34
- <i class="fas fa-chevron-right toggle-icon"></i>
35
- <span class="section-label">{label}</span>
42
+ {/if}
43
+ {#if expanded && $$slots.default}
44
+ <div class="section-content">
45
+ <slot />
36
46
  </div>
37
- <slot name="summary" />
38
- </div>
39
- {/if}
47
+ {/if}
48
+ </section>
40
49
 
41
50
  <style lang="scss">
51
+ @use '../styles/padding' as *;
52
+
53
+ :global(:root) {
54
+ /* Chromeless — default */
55
+ --collapsiblesection-chromeless-default-surface: var(--color-transparent);
56
+ --collapsiblesection-chromeless-default-padding: var(--space-4);
57
+ --collapsiblesection-chromeless-default-label: var(--text-primary);
58
+ --collapsiblesection-chromeless-default-label-font-family: var(--font-sans);
59
+ --collapsiblesection-chromeless-default-label-font-size: var(--font-size-md);
60
+ --collapsiblesection-chromeless-default-label-font-weight: var(--font-weight-normal);
61
+ --collapsiblesection-chromeless-default-label-line-height: var(--line-height-normal);
62
+ --collapsiblesection-chromeless-default-icon: var(--text-muted);
63
+ --collapsiblesection-chromeless-default-icon-size: var(--icon-size-xs);
64
+ /* Chromeless — hover */
65
+ --collapsiblesection-chromeless-hover-surface: var(--color-transparent);
66
+ --collapsiblesection-chromeless-hover-padding: var(--space-4);
67
+ --collapsiblesection-chromeless-hover-label: var(--text-primary);
68
+ --collapsiblesection-chromeless-hover-label-font-family: var(--font-sans);
69
+ --collapsiblesection-chromeless-hover-label-font-size: var(--font-size-md);
70
+ --collapsiblesection-chromeless-hover-label-font-weight: var(--font-weight-normal);
71
+ --collapsiblesection-chromeless-hover-label-line-height: var(--line-height-normal);
72
+ --collapsiblesection-chromeless-hover-icon: var(--text-primary);
73
+ --collapsiblesection-chromeless-hover-icon-size: var(--icon-size-xs);
74
+ /* Chromeless — active */
75
+ --collapsiblesection-chromeless-active-surface: var(--color-transparent);
76
+ --collapsiblesection-chromeless-active-padding: var(--space-4);
77
+ --collapsiblesection-chromeless-active-label: var(--text-primary);
78
+ --collapsiblesection-chromeless-active-label-font-family: var(--font-sans);
79
+ --collapsiblesection-chromeless-active-label-font-size: var(--font-size-md);
80
+ --collapsiblesection-chromeless-active-label-font-weight: var(--font-weight-normal);
81
+ --collapsiblesection-chromeless-active-label-line-height: var(--line-height-normal);
82
+ --collapsiblesection-chromeless-active-icon: var(--text-muted);
83
+ --collapsiblesection-chromeless-active-icon-size: var(--icon-size-xs);
84
+ /* Chromeless — expanded */
85
+ --collapsiblesection-chromeless-expanded-padding: var(--space-4);
86
+
87
+ /* Divider — default */
88
+ --collapsiblesection-divider-default-surface: var(--color-transparent);
89
+ --collapsiblesection-divider-default-border: var(--border-neutral-faint);
90
+ --collapsiblesection-divider-default-border-width: var(--border-width-1);
91
+ --collapsiblesection-divider-default-padding: var(--space-4);
92
+ --collapsiblesection-divider-default-label: var(--text-primary);
93
+ --collapsiblesection-divider-default-label-font-family: var(--font-sans);
94
+ --collapsiblesection-divider-default-label-font-size: var(--font-size-md);
95
+ --collapsiblesection-divider-default-label-font-weight: var(--font-weight-normal);
96
+ --collapsiblesection-divider-default-label-line-height: var(--line-height-normal);
97
+ --collapsiblesection-divider-default-icon: var(--text-muted);
98
+ --collapsiblesection-divider-default-icon-size: var(--icon-size-xs);
99
+ /* Divider — hover */
100
+ --collapsiblesection-divider-hover-surface: var(--color-transparent);
101
+ --collapsiblesection-divider-hover-border: var(--border-neutral);
102
+ --collapsiblesection-divider-hover-border-width: var(--border-width-1);
103
+ --collapsiblesection-divider-hover-padding: var(--space-4);
104
+ --collapsiblesection-divider-hover-label: var(--text-primary);
105
+ --collapsiblesection-divider-hover-label-font-family: var(--font-sans);
106
+ --collapsiblesection-divider-hover-label-font-size: var(--font-size-md);
107
+ --collapsiblesection-divider-hover-label-font-weight: var(--font-weight-normal);
108
+ --collapsiblesection-divider-hover-label-line-height: var(--line-height-normal);
109
+ --collapsiblesection-divider-hover-icon: var(--text-primary);
110
+ --collapsiblesection-divider-hover-icon-size: var(--icon-size-xs);
111
+ /* Divider — active */
112
+ --collapsiblesection-divider-active-surface: var(--color-transparent);
113
+ --collapsiblesection-divider-active-border: var(--color-brand-400);
114
+ --collapsiblesection-divider-active-border-width: var(--border-width-1);
115
+ --collapsiblesection-divider-active-padding: var(--space-4);
116
+ --collapsiblesection-divider-active-label: var(--text-primary);
117
+ --collapsiblesection-divider-active-label-font-family: var(--font-sans);
118
+ --collapsiblesection-divider-active-label-font-size: var(--font-size-md);
119
+ --collapsiblesection-divider-active-label-font-weight: var(--font-weight-normal);
120
+ --collapsiblesection-divider-active-label-line-height: var(--line-height-normal);
121
+ --collapsiblesection-divider-active-icon: var(--text-muted);
122
+ --collapsiblesection-divider-active-icon-size: var(--icon-size-xs);
123
+ /* Divider — expanded */
124
+ --collapsiblesection-divider-expanded-padding: var(--space-4);
125
+
126
+ /* Container — frame (always-on outer chrome) */
127
+ --collapsiblesection-container-frame-surface: var(--surface-canvas);
128
+ --collapsiblesection-container-frame-border: var(--color-transparent);
129
+ --collapsiblesection-container-frame-border-width: var(--border-width-3);
130
+ --collapsiblesection-container-frame-radius: var(--radius-none);
131
+ /* Container — default header strip */
132
+ --collapsiblesection-container-default-surface: var(--surface-canvas);
133
+ --collapsiblesection-container-default-padding: var(--space-4);
134
+ --collapsiblesection-container-default-label: var(--text-primary);
135
+ --collapsiblesection-container-default-label-font-family: var(--font-sans);
136
+ --collapsiblesection-container-default-label-font-size: var(--font-size-md);
137
+ --collapsiblesection-container-default-label-font-weight: var(--font-weight-normal);
138
+ --collapsiblesection-container-default-label-line-height: var(--line-height-normal);
139
+ --collapsiblesection-container-default-icon: var(--text-muted);
140
+ --collapsiblesection-container-default-icon-size: var(--icon-size-xs);
141
+ /* Container — hover header strip */
142
+ --collapsiblesection-container-hover-surface: var(--surface-canvas);
143
+ --collapsiblesection-container-hover-padding: var(--space-4);
144
+ --collapsiblesection-container-hover-label: var(--text-primary);
145
+ --collapsiblesection-container-hover-label-font-family: var(--font-sans);
146
+ --collapsiblesection-container-hover-label-font-size: var(--font-size-md);
147
+ --collapsiblesection-container-hover-label-font-weight: var(--font-weight-normal);
148
+ --collapsiblesection-container-hover-label-line-height: var(--line-height-normal);
149
+ --collapsiblesection-container-hover-icon: var(--text-muted);
150
+ --collapsiblesection-container-hover-icon-size: var(--icon-size-xs);
151
+ /* Container — active header strip */
152
+ --collapsiblesection-container-active-surface: var(--surface-canvas-low);
153
+ --collapsiblesection-container-active-padding: var(--space-4);
154
+ --collapsiblesection-container-active-label: var(--text-primary);
155
+ --collapsiblesection-container-active-label-font-family: var(--font-sans);
156
+ --collapsiblesection-container-active-label-font-size: var(--font-size-md);
157
+ --collapsiblesection-container-active-label-font-weight: var(--font-weight-normal);
158
+ --collapsiblesection-container-active-label-line-height: var(--line-height-normal);
159
+ --collapsiblesection-container-active-icon: var(--text-muted);
160
+ --collapsiblesection-container-active-icon-size: var(--icon-size-xs);
161
+ /* Container — expanded content area */
162
+ --collapsiblesection-container-expanded-surface: var(--surface-canvas-low);
163
+ --collapsiblesection-container-expanded-padding: var(--space-4);
164
+ }
165
+
166
+ .es-root {
167
+ display: flex;
168
+ flex-direction: column;
169
+ }
170
+
42
171
  .section-header {
43
172
  display: flex;
44
173
  align-items: center;
45
174
  gap: var(--space-12);
46
- padding: var(--space-4) var(--space-8);
47
- border-left: 3px solid transparent;
48
175
  cursor: pointer;
49
176
  text-decoration: none;
50
177
  color: inherit;
51
- transition: all var(--transition-fast);
52
-
53
- &:hover {
54
- background: var(--surface-bg);
55
- }
178
+ transition: all var(--duration-150);
56
179
 
57
180
  &.expanded .toggle-icon {
58
181
  transform: rotate(90deg);
59
182
  }
60
-
61
- &.active {
62
- background: var(--surface-bg-low);
63
- border-left-color: var(--color-primary-400);
64
- }
65
183
  }
66
184
 
67
185
  .section-toggle {
@@ -69,14 +187,74 @@
69
187
  align-items: center;
70
188
  gap: var(--space-8);
71
189
  flex-shrink: 0;
72
- color: var(--text-primary);
73
- font-size: var(--font-md);
74
- font-weight: var(--font-weight-semibold);
190
+ }
191
+
192
+ @mixin header-paint($variant, $state) {
193
+ background: var(--collapsiblesection-#{$variant}-#{$state}-surface);
194
+ @include themed-padding(--collapsiblesection-#{$variant}-#{$state}-padding, $h: 2);
195
+
196
+ .section-label {
197
+ color: var(--collapsiblesection-#{$variant}-#{$state}-label);
198
+ font-family: var(--collapsiblesection-#{$variant}-#{$state}-label-font-family);
199
+ font-size: var(--collapsiblesection-#{$variant}-#{$state}-label-font-size);
200
+ font-weight: var(--collapsiblesection-#{$variant}-#{$state}-label-font-weight);
201
+ line-height: var(--collapsiblesection-#{$variant}-#{$state}-label-line-height);
202
+ }
75
203
 
76
204
  .toggle-icon {
77
- font-size: var(--font-xs);
78
- color: var(--text-muted);
79
- transition: transform 0.15s ease;
205
+ color: var(--collapsiblesection-#{$variant}-#{$state}-icon);
206
+ font-size: var(--collapsiblesection-#{$variant}-#{$state}-icon-size);
207
+ transition: transform var(--duration-150);
208
+ }
209
+ }
210
+
211
+ @mixin divider-bottom($state) {
212
+ border-bottom: var(--collapsiblesection-divider-#{$state}-border-width) solid var(--collapsiblesection-divider-#{$state}-border);
213
+ }
214
+
215
+ .es-root.variant-chromeless {
216
+ > .section-header {
217
+ @include header-paint(chromeless, default);
218
+ &:hover, &.force-hover { @include header-paint(chromeless, hover); }
219
+ &.active { @include header-paint(chromeless, active); }
220
+ }
221
+ > .section-content {
222
+ @include themed-padding(--collapsiblesection-chromeless-expanded-padding, $h: 2);
223
+ }
224
+ }
225
+
226
+ .es-root.variant-divider {
227
+ > .section-header {
228
+ @include header-paint(divider, default);
229
+ @include divider-bottom(default);
230
+ &:hover, &.force-hover {
231
+ @include header-paint(divider, hover);
232
+ @include divider-bottom(hover);
233
+ }
234
+ &.active {
235
+ @include header-paint(divider, active);
236
+ @include divider-bottom(active);
237
+ }
238
+ }
239
+ > .section-content {
240
+ @include themed-padding(--collapsiblesection-divider-expanded-padding, $h: 2);
241
+ }
242
+ }
243
+
244
+ .es-root.variant-container {
245
+ background: var(--collapsiblesection-container-frame-surface);
246
+ border: var(--collapsiblesection-container-frame-border-width) solid var(--collapsiblesection-container-frame-border);
247
+ border-radius: var(--collapsiblesection-container-frame-radius);
248
+ overflow: hidden;
249
+
250
+ > .section-header {
251
+ @include header-paint(container, default);
252
+ &:hover, &.force-hover { @include header-paint(container, hover); }
253
+ &.active { @include header-paint(container, active); }
254
+ }
255
+ > .section-content {
256
+ background: var(--collapsiblesection-container-expanded-surface);
257
+ @include themed-padding(--collapsiblesection-container-expanded-padding, $h: 2);
80
258
  }
81
259
  }
82
260
  </style>