@motion-proto/live-tokens 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -13
- package/dist-plugin/index.cjs +854 -226
- package/dist-plugin/index.d.cts +2 -1
- package/dist-plugin/index.d.ts +2 -1
- package/dist-plugin/index.js +852 -225
- package/package.json +26 -40
- package/src/{styles → app}/site.css +1 -1
- package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
- package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
- package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
- package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
- package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
- package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
- package/src/editor/component-editor/ImageEditor.svelte +30 -0
- package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
- package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
- package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
- package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
- package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
- package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
- package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
- package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
- package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
- package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
- package/src/editor/component-editor/editors.d.ts +10 -0
- package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
- package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
- package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
- package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
- package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
- package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
- package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
- package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
- package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
- package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
- package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
- package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
- package/src/editor/core/flashStatus.ts +30 -0
- package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
- package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
- package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
- package/src/editor/core/manifests/manifestService.ts +171 -0
- package/src/editor/core/palettes/familySwap.ts +99 -0
- package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
- package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
- package/src/editor/core/productionPulse.ts +37 -0
- package/src/{lib → editor/core/routing}/router.ts +1 -1
- package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
- package/src/{lib → editor/core/store}/editorCore.ts +24 -8
- package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
- package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
- package/src/{lib → editor/core/store}/editorStore.ts +222 -28
- package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
- package/src/editor/core/store/gradientSource.ts +192 -0
- package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
- package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
- package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
- package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
- package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
- package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
- package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
- package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
- package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
- package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
- package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
- package/src/{lib → editor/core/themes}/themeService.ts +6 -6
- package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
- package/src/editor/index.ts +69 -0
- package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
- package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
- package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
- package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
- package/src/{pages → editor/pages}/Editor.svelte +4 -4
- package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
- package/src/{styles → editor/styles}/ui-editor.css +43 -22
- package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
- package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
- package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
- package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
- package/src/editor/ui/FileLoadList.svelte +367 -0
- package/src/editor/ui/FilePill.svelte +80 -0
- package/src/editor/ui/FontStackEditor.svelte +499 -0
- package/src/editor/ui/GradientEditor.svelte +690 -0
- package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
- package/src/editor/ui/ManifestFileManager.svelte +438 -0
- package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
- package/src/editor/ui/ProjectFontsSection.svelte +638 -0
- package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
- package/src/{ui → editor/ui}/TextTab.svelte +3 -3
- package/src/editor/ui/ThemeFileManager.svelte +783 -0
- package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
- package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
- package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
- package/src/editor/ui/UIInfoPopover.svelte +243 -0
- package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
- package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
- package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
- package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
- package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
- package/src/editor/ui/UIPillButton.svelte +168 -0
- package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
- package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
- package/src/editor/ui/UISegmentedControl.svelte +114 -0
- package/src/editor/ui/UISquareButton.svelte +172 -0
- package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
- package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
- package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
- package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
- package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
- package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
- package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
- package/src/editor/ui/palette/paletteMath.ts +275 -0
- package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
- package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
- package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
- package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
- package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
- package/src/{components → system/components}/Badge.svelte +0 -36
- package/src/{components → system/components}/Button.svelte +2 -2
- package/src/{components → system/components}/Card.svelte +34 -60
- package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
- package/src/{components → system/components}/CornerBadge.svelte +8 -24
- package/src/{components → system/components}/Dialog.svelte +1 -1
- package/src/system/components/FloatingTokenTags.css +275 -0
- package/src/system/components/FloatingTokenTags.svelte +543 -0
- package/src/{components → system/components}/InlineEditActions.svelte +6 -4
- package/src/system/components/MenuSelect.svelte +229 -0
- package/src/{components → system/components}/Notification.svelte +8 -1
- package/src/{components → system/components}/ProgressBar.svelte +29 -11
- package/src/system/components/SectionDivider.svelte +560 -0
- package/src/{components → system/components}/SegmentedControl.svelte +49 -43
- package/src/{components → system/components}/TabBar.svelte +81 -65
- package/src/{components → system/components}/Table.svelte +17 -3
- package/src/{components → system/components}/Tooltip.svelte +6 -4
- package/src/system/styles/CONVENTIONS.md +178 -0
- package/src/system/styles/fonts.css +20 -0
- package/src/system/styles/tokens.css +601 -0
- package/src/system/styles/tokens.generated.css +544 -0
- package/src/component-editor/ImageEditor.svelte +0 -74
- package/src/component-editor/SectionDividerEditor.svelte +0 -265
- package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
- package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
- package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
- package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
- package/src/components/SectionDivider.svelte +0 -483
- package/src/data/google-fonts.json +0 -75
- package/src/lib/index.ts +0 -68
- package/src/lib/presetService.ts +0 -214
- package/src/lib/productionPulse.ts +0 -32
- package/src/styles/fonts.css +0 -30
- package/src/styles/tokens.css +0 -1324
- package/src/ui/FontStackEditor.svelte +0 -361
- package/src/ui/GradientEditor.svelte +0 -470
- package/src/ui/PresetFileManager.svelte +0 -1116
- package/src/ui/ProjectFontsSection.svelte +0 -645
- package/src/ui/ThemeFileManager.svelte +0 -1020
- package/src/ui/UnsavedComponentsDialog.svelte +0 -315
- /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
- /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
- /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
- /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
- /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
- /package/src/{lib → editor/core/storage}/storage.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
- /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
- /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
- /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
- /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
- /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
- /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
- /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
- /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
- /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
- /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
- /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
- /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
- /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
- /package/src/{ui → editor/ui}/index.ts +0 -0
- /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
- /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
- /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
- /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
- /package/src/{ui → editor/ui}/variantScales.ts +0 -0
- /package/src/{assets → system/assets}/newspaper.webp +0 -0
- /package/src/{assets → system/assets}/offering.webp +0 -0
- /package/src/{components → system/components}/Callout.svelte +0 -0
- /package/src/{components → system/components}/Image.svelte +0 -0
- /package/src/{components → system/components}/RadioButton.svelte +0 -0
- /package/src/{components → system/components}/types.ts +0 -0
- /package/src/{styles → system/styles}/_padding.scss +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
|
@@ -126,7 +126,22 @@
|
|
|
126
126
|
border-radius: var(--segmentedcontrol-bar-radius);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
/* Font + color properties are declared once on `.segment` and rebound per
|
|
130
|
+
state via the `--_*` custom properties below. State classes only change
|
|
131
|
+
the bindings; the actual `font-*` declarations never move. When two
|
|
132
|
+
states resolve to the same final value the computed font is identical
|
|
133
|
+
and the browser has no reason to re-shape — which is what kept the
|
|
134
|
+
selected segment shifting by a whole pixel even after the border was
|
|
135
|
+
swapped for an outline. */
|
|
129
136
|
.segment {
|
|
137
|
+
--_text-color: var(--segmentedcontrol-option-text);
|
|
138
|
+
--_text-family: var(--segmentedcontrol-option-text-font-family);
|
|
139
|
+
--_text-size: var(--segmentedcontrol-option-text-font-size);
|
|
140
|
+
--_text-weight: var(--segmentedcontrol-option-text-font-weight);
|
|
141
|
+
--_text-line-height: var(--segmentedcontrol-option-text-line-height);
|
|
142
|
+
--_icon-color: var(--segmentedcontrol-option-icon);
|
|
143
|
+
--_icon-size: var(--segmentedcontrol-option-icon-size);
|
|
144
|
+
|
|
130
145
|
display: inline-flex;
|
|
131
146
|
align-items: center;
|
|
132
147
|
gap: var(--space-8);
|
|
@@ -134,19 +149,19 @@
|
|
|
134
149
|
background: transparent;
|
|
135
150
|
border: 0;
|
|
136
151
|
border-radius: var(--segmentedcontrol-selected-radius);
|
|
137
|
-
color: var(--
|
|
138
|
-
font-family: var(--
|
|
139
|
-
font-size: var(--
|
|
140
|
-
font-weight: var(--
|
|
141
|
-
line-height: var(--
|
|
152
|
+
color: var(--_text-color);
|
|
153
|
+
font-family: var(--_text-family);
|
|
154
|
+
font-size: var(--_text-size);
|
|
155
|
+
font-weight: var(--_text-weight);
|
|
156
|
+
line-height: var(--_text-line-height);
|
|
142
157
|
cursor: pointer;
|
|
143
158
|
transition: background var(--duration-150), color var(--duration-150);
|
|
144
159
|
position: relative;
|
|
145
160
|
}
|
|
146
161
|
|
|
147
162
|
.segment i {
|
|
148
|
-
font-size: var(--
|
|
149
|
-
color: var(--
|
|
163
|
+
font-size: var(--_icon-size);
|
|
164
|
+
color: var(--_icon-color);
|
|
150
165
|
transition: color var(--duration-150);
|
|
151
166
|
}
|
|
152
167
|
|
|
@@ -166,52 +181,43 @@
|
|
|
166
181
|
|
|
167
182
|
.segment:hover:not(:disabled):not(.selected),
|
|
168
183
|
.segment.force-hover:not(:disabled):not(.selected) {
|
|
184
|
+
--_text-color: var(--segmentedcontrol-option-hover-text);
|
|
185
|
+
--_text-family: var(--segmentedcontrol-option-hover-text-font-family);
|
|
186
|
+
--_text-size: var(--segmentedcontrol-option-hover-text-font-size);
|
|
187
|
+
--_text-weight: var(--segmentedcontrol-option-hover-text-font-weight);
|
|
188
|
+
--_text-line-height: var(--segmentedcontrol-option-hover-text-line-height);
|
|
189
|
+
--_icon-color: var(--segmentedcontrol-option-hover-icon);
|
|
190
|
+
--_icon-size: var(--segmentedcontrol-option-hover-icon-size);
|
|
169
191
|
background: var(--segmentedcontrol-option-hover-surface);
|
|
170
|
-
color: var(--segmentedcontrol-option-hover-text);
|
|
171
|
-
font-family: var(--segmentedcontrol-option-hover-text-font-family);
|
|
172
|
-
font-size: var(--segmentedcontrol-option-hover-text-font-size);
|
|
173
|
-
font-weight: var(--segmentedcontrol-option-hover-text-font-weight);
|
|
174
|
-
line-height: var(--segmentedcontrol-option-hover-text-line-height);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.segment:hover:not(:disabled):not(.selected) i,
|
|
178
|
-
.segment.force-hover:not(:disabled):not(.selected) i {
|
|
179
|
-
color: var(--segmentedcontrol-option-hover-icon);
|
|
180
|
-
font-size: var(--segmentedcontrol-option-hover-icon-size);
|
|
181
192
|
}
|
|
182
193
|
|
|
194
|
+
/* Outline (not border) so the selection ring sits outside the box model.
|
|
195
|
+
A real border would force a padding compensation calc, and the resulting
|
|
196
|
+
sub-pixel flex layout would shift the selected segment by a whole pixel
|
|
197
|
+
against its neighbors. Outline is paint-only and leaves geometry alone. */
|
|
183
198
|
.segment.selected {
|
|
199
|
+
--_text-color: var(--segmentedcontrol-selected-text);
|
|
200
|
+
--_text-family: var(--segmentedcontrol-selected-text-font-family);
|
|
201
|
+
--_text-size: var(--segmentedcontrol-selected-text-font-size);
|
|
202
|
+
--_text-weight: var(--segmentedcontrol-selected-text-font-weight);
|
|
203
|
+
--_text-line-height: var(--segmentedcontrol-selected-text-line-height);
|
|
204
|
+
--_icon-color: var(--segmentedcontrol-selected-icon);
|
|
205
|
+
--_icon-size: var(--segmentedcontrol-selected-icon-size);
|
|
184
206
|
background: var(--segmentedcontrol-selected-surface);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
color: var(--segmentedcontrol-selected-text);
|
|
188
|
-
font-family: var(--segmentedcontrol-selected-text-font-family);
|
|
189
|
-
font-size: var(--segmentedcontrol-selected-text-font-size);
|
|
190
|
-
font-weight: var(--segmentedcontrol-selected-text-font-weight);
|
|
191
|
-
line-height: var(--segmentedcontrol-selected-text-line-height);
|
|
192
|
-
/* Account for border so the pill doesn't shift adjacent segments */
|
|
193
|
-
padding: calc(var(--space-6) - var(--segmentedcontrol-selected-border-width))
|
|
194
|
-
calc(var(--space-16) - var(--segmentedcontrol-selected-border-width));
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.segment.selected i {
|
|
198
|
-
color: var(--segmentedcontrol-selected-icon);
|
|
199
|
-
font-size: var(--segmentedcontrol-selected-icon-size);
|
|
207
|
+
outline: var(--segmentedcontrol-selected-border-width) solid var(--segmentedcontrol-selected-border);
|
|
208
|
+
outline-offset: calc(var(--segmentedcontrol-selected-border-width) * -1);
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
.segment:disabled {
|
|
212
|
+
--_text-color: var(--segmentedcontrol-disabled-text);
|
|
213
|
+
--_text-family: var(--segmentedcontrol-disabled-text-font-family);
|
|
214
|
+
--_text-size: var(--segmentedcontrol-disabled-text-font-size);
|
|
215
|
+
--_text-weight: var(--segmentedcontrol-disabled-text-font-weight);
|
|
216
|
+
--_text-line-height: var(--segmentedcontrol-disabled-text-line-height);
|
|
217
|
+
--_icon-color: var(--segmentedcontrol-disabled-icon);
|
|
218
|
+
--_icon-size: var(--segmentedcontrol-disabled-icon-size);
|
|
203
219
|
background: var(--segmentedcontrol-disabled-surface);
|
|
204
|
-
color: var(--segmentedcontrol-disabled-text);
|
|
205
|
-
font-family: var(--segmentedcontrol-disabled-text-font-family);
|
|
206
|
-
font-size: var(--segmentedcontrol-disabled-text-font-size);
|
|
207
|
-
font-weight: var(--segmentedcontrol-disabled-text-font-weight);
|
|
208
|
-
line-height: var(--segmentedcontrol-disabled-text-line-height);
|
|
209
220
|
opacity: 0.4;
|
|
210
221
|
cursor: not-allowed;
|
|
211
222
|
}
|
|
212
|
-
|
|
213
|
-
.segment:disabled i {
|
|
214
|
-
color: var(--segmentedcontrol-disabled-icon);
|
|
215
|
-
font-size: var(--segmentedcontrol-disabled-icon-size);
|
|
216
|
-
}
|
|
217
223
|
</style>
|
|
@@ -140,91 +140,107 @@
|
|
|
140
140
|
margin-bottom: var(--tabbar-bar-bottom-margin);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/* Per-state tokens are bound to `--_*` custom properties below. The actual
|
|
144
|
+
layout-affecting declarations (padding, border, border-radius, font-*)
|
|
145
|
+
are written exactly once on `.tab`, so a hover/active state change can
|
|
146
|
+
only repaint, not relayout. When two states resolve to the same value,
|
|
147
|
+
the computed property is identical and no reshape is triggered. The
|
|
148
|
+
`transition: all` of the old rule has also been narrowed to paint-only
|
|
149
|
+
properties — otherwise it would try to animate layout changes between
|
|
150
|
+
states that happen to differ in tokens. */
|
|
143
151
|
.tab {
|
|
152
|
+
--_text-color: var(--tabbar-default-text);
|
|
153
|
+
--_text-family: var(--tabbar-default-text-font-family);
|
|
154
|
+
--_text-size: var(--tabbar-default-text-font-size);
|
|
155
|
+
--_text-weight: var(--tabbar-default-text-font-weight);
|
|
156
|
+
--_text-line-height: var(--tabbar-default-text-line-height);
|
|
157
|
+
--_icon-size: var(--tabbar-default-icon-size);
|
|
158
|
+
--_surface: var(--tabbar-default-surface);
|
|
159
|
+
--_indicator-color: var(--tabbar-default-border);
|
|
160
|
+
--_padding: var(--tabbar-default-padding);
|
|
161
|
+
--_border-color: var(--tabbar-default-tab-border-color);
|
|
162
|
+
--_border-width: var(--tabbar-default-tab-border-width);
|
|
163
|
+
--_top-radius: var(--tabbar-default-tab-top-radius);
|
|
164
|
+
--_bottom-radius: var(--tabbar-default-tab-bottom-radius);
|
|
165
|
+
|
|
144
166
|
display: inline-flex;
|
|
145
167
|
align-items: center;
|
|
146
168
|
gap: var(--space-6);
|
|
147
|
-
|
|
148
|
-
background: var(--
|
|
149
|
-
border: var(--
|
|
150
|
-
/*
|
|
151
|
-
|
|
152
|
-
border-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
font-
|
|
156
|
-
font-
|
|
157
|
-
|
|
169
|
+
padding: var(--_padding) calc(var(--_padding) * 2);
|
|
170
|
+
background: var(--_surface);
|
|
171
|
+
border: var(--_border-width) solid var(--_border-color);
|
|
172
|
+
/* Indicator accent owns the bottom edge. Thickness is constant across
|
|
173
|
+
states (--tabbar-bar-indicator-thickness), only color rebinds. */
|
|
174
|
+
border-bottom: var(--tabbar-bar-indicator-thickness) solid var(--_indicator-color);
|
|
175
|
+
border-radius: var(--_top-radius) var(--_top-radius) var(--_bottom-radius) var(--_bottom-radius);
|
|
176
|
+
color: var(--_text-color);
|
|
177
|
+
font-family: var(--_text-family);
|
|
178
|
+
font-size: var(--_text-size);
|
|
179
|
+
font-weight: var(--_text-weight);
|
|
180
|
+
line-height: var(--_text-line-height);
|
|
158
181
|
cursor: pointer;
|
|
159
|
-
transition:
|
|
182
|
+
transition:
|
|
183
|
+
background var(--duration-150),
|
|
184
|
+
color var(--duration-150),
|
|
185
|
+
border-color var(--duration-150);
|
|
160
186
|
position: relative;
|
|
161
187
|
}
|
|
162
188
|
|
|
189
|
+
.tab i {
|
|
190
|
+
font-size: var(--_icon-size);
|
|
191
|
+
}
|
|
192
|
+
|
|
163
193
|
.tab:hover:not(:disabled):not(.active),
|
|
164
194
|
.tab-bar.force-hover .tab:not(:disabled):not(.active) {
|
|
165
|
-
color: var(--tabbar-hover-text);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
195
|
+
--_text-color: var(--tabbar-hover-text);
|
|
196
|
+
--_text-family: var(--tabbar-hover-text-font-family);
|
|
197
|
+
--_text-size: var(--tabbar-hover-text-font-size);
|
|
198
|
+
--_text-weight: var(--tabbar-hover-text-font-weight);
|
|
199
|
+
--_text-line-height: var(--tabbar-hover-text-line-height);
|
|
200
|
+
--_icon-size: var(--tabbar-hover-icon-size);
|
|
201
|
+
--_surface: var(--tabbar-hover-surface);
|
|
202
|
+
--_indicator-color: var(--tabbar-hover-border);
|
|
203
|
+
--_padding: var(--tabbar-hover-padding);
|
|
204
|
+
--_border-color: var(--tabbar-hover-tab-border-color);
|
|
205
|
+
--_border-width: var(--tabbar-hover-tab-border-width);
|
|
206
|
+
--_top-radius: var(--tabbar-hover-tab-top-radius);
|
|
207
|
+
--_bottom-radius: var(--tabbar-hover-tab-bottom-radius);
|
|
177
208
|
}
|
|
178
209
|
|
|
179
210
|
.tab.active {
|
|
180
|
-
color: var(--tabbar-active-text);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
211
|
+
--_text-color: var(--tabbar-active-text);
|
|
212
|
+
--_text-family: var(--tabbar-active-text-font-family);
|
|
213
|
+
--_text-size: var(--tabbar-active-text-font-size);
|
|
214
|
+
--_text-weight: var(--tabbar-active-text-font-weight);
|
|
215
|
+
--_text-line-height: var(--tabbar-active-text-line-height);
|
|
216
|
+
--_icon-size: var(--tabbar-active-icon-size);
|
|
217
|
+
--_surface: var(--tabbar-active-surface);
|
|
218
|
+
--_indicator-color: var(--tabbar-active-border);
|
|
219
|
+
--_padding: var(--tabbar-active-padding);
|
|
220
|
+
--_border-color: var(--tabbar-active-tab-border-color);
|
|
221
|
+
--_border-width: var(--tabbar-active-tab-border-width);
|
|
222
|
+
--_top-radius: var(--tabbar-active-tab-top-radius);
|
|
223
|
+
--_bottom-radius: var(--tabbar-active-tab-bottom-radius);
|
|
192
224
|
}
|
|
193
225
|
|
|
194
226
|
.tab:disabled {
|
|
195
|
-
color: var(--tabbar-disabled-text);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
227
|
+
--_text-color: var(--tabbar-disabled-text);
|
|
228
|
+
--_text-family: var(--tabbar-disabled-text-font-family);
|
|
229
|
+
--_text-size: var(--tabbar-disabled-text-font-size);
|
|
230
|
+
--_text-weight: var(--tabbar-disabled-text-font-weight);
|
|
231
|
+
--_text-line-height: var(--tabbar-disabled-text-line-height);
|
|
232
|
+
--_icon-size: var(--tabbar-disabled-icon-size);
|
|
233
|
+
--_surface: var(--tabbar-disabled-surface);
|
|
234
|
+
--_indicator-color: var(--tabbar-disabled-border);
|
|
235
|
+
--_padding: var(--tabbar-disabled-padding);
|
|
236
|
+
--_border-color: var(--tabbar-disabled-tab-border-color);
|
|
237
|
+
--_border-width: var(--tabbar-disabled-tab-border-width);
|
|
238
|
+
--_top-radius: var(--tabbar-disabled-tab-top-radius);
|
|
239
|
+
--_bottom-radius: var(--tabbar-disabled-tab-bottom-radius);
|
|
207
240
|
cursor: not-allowed;
|
|
208
241
|
}
|
|
209
242
|
|
|
210
243
|
.tab.icon-only {
|
|
211
244
|
padding: var(--space-8) var(--space-12);
|
|
212
245
|
}
|
|
213
|
-
|
|
214
|
-
.tab:hover:not(:disabled):not(.active) i,
|
|
215
|
-
.tab-bar.force-hover .tab:not(:disabled):not(.active) i {
|
|
216
|
-
font-size: var(--tabbar-hover-icon-size);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.tab.active i {
|
|
220
|
-
font-size: var(--tabbar-active-icon-size);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
.tab:disabled i {
|
|
224
|
-
font-size: var(--tabbar-disabled-icon-size);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.tab i {
|
|
228
|
-
font-size: var(--tabbar-default-icon-size);
|
|
229
|
-
}
|
|
230
246
|
</style>
|
|
@@ -11,9 +11,12 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
13
|
<style lang="scss">
|
|
14
|
+
@use '../styles/padding' as *;
|
|
15
|
+
|
|
14
16
|
:global(:root) {
|
|
15
17
|
/* Wrapper */
|
|
16
18
|
--table-default-radius: var(--radius-md);
|
|
19
|
+
--table-default-surface: var(--color-transparent);
|
|
17
20
|
--table-default-border: var(--border-canvas-subtle);
|
|
18
21
|
--table-default-border-width: var(--border-width-1);
|
|
19
22
|
--table-default-shadow: var(--shadow-md);
|
|
@@ -38,9 +41,10 @@
|
|
|
38
41
|
--table-default-cell-padding: var(--space-8);
|
|
39
42
|
|
|
40
43
|
/* Row */
|
|
44
|
+
--table-default-row-surface: var(--color-transparent);
|
|
41
45
|
--table-default-row-divider: var(--border-canvas-faint);
|
|
42
46
|
--table-default-row-divider-width: var(--border-width-1);
|
|
43
|
-
--table-default-row-stripe-surface: var(--
|
|
47
|
+
--table-default-row-stripe-surface: var(--color-transparent);
|
|
44
48
|
|
|
45
49
|
/* Column */
|
|
46
50
|
--table-default-column-divider: var(--border-canvas-faint);
|
|
@@ -51,6 +55,7 @@
|
|
|
51
55
|
overflow-x: auto;
|
|
52
56
|
margin: var(--space-12) 0;
|
|
53
57
|
-webkit-overflow-scrolling: touch;
|
|
58
|
+
background: var(--table-default-surface);
|
|
54
59
|
border: var(--table-default-border-width) solid var(--table-default-border);
|
|
55
60
|
border-radius: var(--table-default-radius);
|
|
56
61
|
box-shadow: var(--table-default-shadow);
|
|
@@ -70,7 +75,7 @@
|
|
|
70
75
|
font-size: var(--table-default-header-font-size);
|
|
71
76
|
font-weight: var(--table-default-header-font-weight);
|
|
72
77
|
line-height: var(--table-default-header-line-height);
|
|
73
|
-
padding
|
|
78
|
+
@include themed-padding(--table-default-header-padding);
|
|
74
79
|
text-align: left;
|
|
75
80
|
border-bottom: var(--table-default-header-border-width) solid var(--table-default-header-border);
|
|
76
81
|
border-right: var(--table-default-column-divider-width) solid var(--table-default-column-divider);
|
|
@@ -78,6 +83,7 @@
|
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
.table-wrapper :global(td) {
|
|
86
|
+
background: var(--table-default-row-surface);
|
|
81
87
|
color: var(--table-default-cell-text);
|
|
82
88
|
font-family: var(--table-default-cell-font-family);
|
|
83
89
|
font-size: var(--table-default-cell-font-size);
|
|
@@ -97,8 +103,16 @@
|
|
|
97
103
|
border-right: none;
|
|
98
104
|
}
|
|
99
105
|
|
|
106
|
+
/* Stripe is layered over the base row surface as a background-image, so a
|
|
107
|
+
translucent stripe color blends with the base instead of replacing it.
|
|
108
|
+
An opaque stripe still covers the base (visually identical to the old
|
|
109
|
+
replacement behavior); a fully transparent stripe leaves the base
|
|
110
|
+
untouched, which is the default out of the box. */
|
|
100
111
|
.table-wrapper :global(tr:nth-child(even) td) {
|
|
101
|
-
background:
|
|
112
|
+
background-image: linear-gradient(
|
|
113
|
+
var(--table-default-row-stripe-surface),
|
|
114
|
+
var(--table-default-row-stripe-surface)
|
|
115
|
+
);
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
.table-wrapper :global(tr:last-child td) {
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
{/if}
|
|
24
24
|
</div>
|
|
25
25
|
|
|
26
|
-
<style>
|
|
26
|
+
<style lang="scss">
|
|
27
|
+
@use '../styles/padding' as *;
|
|
28
|
+
|
|
27
29
|
:global(:root) {
|
|
28
30
|
--tooltip-surface: var(--surface-neutral-highest);
|
|
29
31
|
--tooltip-text: var(--text-primary);
|
|
@@ -50,7 +52,7 @@
|
|
|
50
52
|
transform: translateX(-50%);
|
|
51
53
|
background: var(--tooltip-surface);
|
|
52
54
|
color: var(--tooltip-text);
|
|
53
|
-
|
|
55
|
+
@include themed-padding(--tooltip-padding, $h: 2);
|
|
54
56
|
border: var(--tooltip-border-width) solid var(--tooltip-border);
|
|
55
57
|
border-radius: var(--tooltip-radius);
|
|
56
58
|
font-family: var(--tooltip-text-font-family);
|
|
@@ -68,7 +70,7 @@
|
|
|
68
70
|
.tooltip::after {
|
|
69
71
|
content: '';
|
|
70
72
|
position: absolute;
|
|
71
|
-
bottom: calc(-4px - var(--tooltip-border-width)
|
|
73
|
+
bottom: calc(-4px - var(--tooltip-border-width));
|
|
72
74
|
left: 50%;
|
|
73
75
|
width: 8px;
|
|
74
76
|
height: 8px;
|
|
@@ -86,7 +88,7 @@
|
|
|
86
88
|
|
|
87
89
|
.tooltip.bottom::after {
|
|
88
90
|
bottom: auto;
|
|
89
|
-
top: calc(-4px - var(--tooltip-border-width)
|
|
91
|
+
top: calc(-4px - var(--tooltip-border-width));
|
|
90
92
|
border-right: none;
|
|
91
93
|
border-bottom: none;
|
|
92
94
|
border-left: var(--tooltip-border-width) solid var(--tooltip-border);
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Token naming conventions
|
|
2
|
+
|
|
3
|
+
This project uses a **two-layer token system**. Read this before adding or renaming a CSS custom property.
|
|
4
|
+
|
|
5
|
+
## Files in this directory
|
|
6
|
+
|
|
7
|
+
Each file plays a distinct role. Don't merge them without understanding why they were split.
|
|
8
|
+
|
|
9
|
+
| File | Scope | Tokens used | Loaded by | Notes |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| `tokens.css` | Themed pages | Defines `--color-*`, `--surface-*`, `--text-*`, `--space-*`, … | `main.ts` | **Runtime-edited.** The token editor rewrites this file via the `themeFileApi` Vite plugin. Starter content; consumers replace at will. |
|
|
12
|
+
| `ui-editor.css` | Editor chrome only | Defines `--ui-*` (opaque grayscale, system fonts) | JS-imported by `Editor.svelte` and `ComponentEditorPage.svelte` | Deliberately isolated from the theme system so editor surfaces stay neutral while live theme edits flow through the components being edited. Never load globally. |
|
|
13
|
+
| `ui-form-controls.css` | Editor chrome only | Consumes `--ui-*` only | JS-imported by `Editor.svelte` and `ComponentEditorPage.svelte` | `.ui-form-select` / `.ui-form-input` / `.ui-form-field-*` classes. Used by `ProjectFontsSection`, `FontStackEditor`, `DialogEditor`, `NotificationEditor`. Theme-immune — must not reference `--font-*`, `--surface-*`, etc. |
|
|
14
|
+
| `site.css` | Themed pages | Consumes theme tokens | Page-imported by `Home.svelte` | Consumer-facing starter typography for the landing page (unscoped `h1`, `p`, `a`, …). Never load on editor pages. Replaceable starter content — users edit or replace this file to style their own site. Components that take slot content (Card body, CollapsibleSection content) defend their typography aliases against these global rules via `:global(p) { font: inherit; color: inherit; }`. The demo page no longer imports it; the demo uses scoped classes and component-owned slot typography instead. |
|
|
15
|
+
| `fonts.css` + `fonts/` | Themed pages only | n/a (`@font-face` only) | `main.ts` | Build-special-cased: copied directly to `dist/` without processing so Vite doesn't inline woff2 files as base64. Starter content; editor's font invariant means these never affect chrome. |
|
|
16
|
+
|
|
17
|
+
### Publishing layout
|
|
18
|
+
|
|
19
|
+
The library publishes a small set of subpaths:
|
|
20
|
+
|
|
21
|
+
- `./styles/ui-editor.css` — read-only window onto the editor's `--ui-*` token contract (for theming inspection or debugging). Consumers don't *need* to import this; the editor pages auto-load it.
|
|
22
|
+
- `./starter/tokens.css`, `./starter/site.css`, `./starter/fonts.css` — replaceable starter content. Consumers can import as-is for a working default, or copy + edit.
|
|
23
|
+
|
|
24
|
+
`ui-form-controls.css` is editor-internal and not exported — the editor pages script-import it themselves.
|
|
25
|
+
|
|
26
|
+
### Editor font invariant
|
|
27
|
+
|
|
28
|
+
Editor chrome uses **only** the `--ui-*` font namespace (`--ui-font-sans`, `--ui-font-mono`, `--ui-font-size-*`, etc.), which `ui-editor.css` defines as a pure system stack. No editor-namespace rule may reference `var(--font-sans)`, `var(--font-serif)`, `var(--font-display)`, or `var(--font-mono)` — those are the consumer's theme fonts and must not bleed into chrome. This invariant is what closes the "editor adopts consumer brand fonts" leak.
|
|
29
|
+
|
|
30
|
+
### When to put a rule where
|
|
31
|
+
|
|
32
|
+
- It defines a `--color-*` / `--surface-*` / `--space-*` / etc. → `tokens.css`.
|
|
33
|
+
- It defines a `--ui-*` token → `ui-editor.css`.
|
|
34
|
+
- It styles a bare element selector (`h1`, `p`, `blockquote`) on themed pages → `site.css`.
|
|
35
|
+
- It styles editor chrome → put it in the component's own `<style>` block using `--ui-*` tokens; don't add a new global file.
|
|
36
|
+
- It declares an `@font-face` → `fonts.css` (and add the woff2 to `fonts/`).
|
|
37
|
+
|
|
38
|
+
## Layer 1 — theme tokens (`tokens.css`)
|
|
39
|
+
|
|
40
|
+
Theme tokens are the design system's vocabulary. They describe colors, sizes, spacing, shadows, and motion: the things a designer reasons about independent of any one component. Components consume them, and themes in `themes/*.json` recolor or re-scale them.
|
|
41
|
+
|
|
42
|
+
### Category-first naming
|
|
43
|
+
|
|
44
|
+
Every theme token starts with a **category prefix**. The category tells you what *kind* of value lives at that key:
|
|
45
|
+
|
|
46
|
+
| Category | What it holds |
|
|
47
|
+
|----------------|-----------------------------------------------------------------|
|
|
48
|
+
| `--color-*` | Primitive color palette (e.g. `--color-accent-500`) |
|
|
49
|
+
| `--surface-*` | Fill/background colors, with elevation tiers |
|
|
50
|
+
| `--border-*` | Border colors, with emphasis tiers |
|
|
51
|
+
| `--text-*` | Text colors, with hierarchy tiers |
|
|
52
|
+
| `--font-*` | Font families and weights |
|
|
53
|
+
| `--font-size-*`| Font sizes (explicit subcategory to avoid colliding with families) |
|
|
54
|
+
| `--space-*` | Spacing scale, values encoded in the name (`--space-8` = 8px) |
|
|
55
|
+
| `--radius-*` | Border radii (t-shirt scale) |
|
|
56
|
+
| `--shadow-*` | Elevation shadows |
|
|
57
|
+
| `--ring-*` | Focus rings (separate namespace from shadows) |
|
|
58
|
+
| `--border-width-*` | Stroke widths |
|
|
59
|
+
| `--transition-*`, `--opacity-*`, `--z-*` | Animation, opacity, z-index scales |
|
|
60
|
+
| `--overlay-*`, `--hover-*` | Semantic overlay tints |
|
|
61
|
+
| `--gradient-*` | Named gradients |
|
|
62
|
+
| `--columns-*`, `--page-*` | Page-level layout primitives |
|
|
63
|
+
|
|
64
|
+
**Rule: a bare one-word token belongs to *some* category.** If you find yourself writing `--overlay` or `--border`, make sure the category is obvious and it's the canonical default. Otherwise pick a longer name that slots it into its family (e.g. `--border-neutral`).
|
|
65
|
+
|
|
66
|
+
### Families within a category
|
|
67
|
+
|
|
68
|
+
Color categories (`--surface-*`, `--border-*`, `--text-*`) partition into **families**: `neutral`, `canvas`, `primary` (*→ brand, rename pending*), `accent`, `success`, `warning`, `danger`, `info`, `special`, `alternate`. Each family carries its own emphasis/elevation scale suited to its role: 7-step elevation for surfaces, 4-step emphasis for borders, 5-step hierarchy for text. They differ on purpose.
|
|
69
|
+
|
|
70
|
+
### Scales
|
|
71
|
+
|
|
72
|
+
Two shapes appear:
|
|
73
|
+
|
|
74
|
+
- **T-shirt scale** (`-xs / -sm / -md / -lg / -xl / -2xl …`). Used for `--radius-*`, `--font-size-*`, `--shadow-*`, `--ring-focus-*`.
|
|
75
|
+
- **Numeric scale.** `--color-*-100` through `--color-*-950` for palettes; `--space-4 / -8 / -16 / …` (value encoded in the name).
|
|
76
|
+
|
|
77
|
+
Don't invent a third scale shape for a new category.
|
|
78
|
+
|
|
79
|
+
## Layer 2 — component tokens (`component-configs/*/default.json` + component Svelte files)
|
|
80
|
+
|
|
81
|
+
Component tokens *reference* theme tokens. They're how a component names its own slots: "my bar's surface color", "my selected option's border width". The config file records which theme alias is currently assigned to each slot.
|
|
82
|
+
|
|
83
|
+
### The naming scheme
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
--<componentId>-<part>[-<state>][-<element>]-<property>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- **`componentId`.** The literal component ID. No abbreviations. The ID itself has no dashes (it's the file-system-safe form: `segmentedcontrol`, not `segmented-control`).
|
|
90
|
+
- **`part`.** Which part of the component this slot belongs to: `bar`, `divider`, `option`, `selected`, `track`, `save`, `cancel`, etc.
|
|
91
|
+
- **`state`.** Optional. The interaction state if more than default: `hover`, `disabled`, `active`, `focus`. States come **before** the property, never after.
|
|
92
|
+
- **`element`.** Optional. A sub-element within the part: `dot`, `icon`, `label`, `text`.
|
|
93
|
+
- **`property`.** Always last. Either a **theme role** (`surface`, `border`, `text`, `icon`, `label`, `fill`) or a **CSS property name** (`radius`, `border-width`, `font-weight`, `font-family`, `font-size`).
|
|
94
|
+
|
|
95
|
+
### No abbreviations
|
|
96
|
+
|
|
97
|
+
- `bg` → `surface` (matches the theme role name and the theme layer's full-word vocabulary).
|
|
98
|
+
- `fg` → `text`.
|
|
99
|
+
- Component IDs are never abbreviated. Use `--segmentedcontrol-*`, not `--segment-*` or `--sc-*`.
|
|
100
|
+
|
|
101
|
+
### Property suffix vocabulary
|
|
102
|
+
|
|
103
|
+
| Suffix | Meaning |
|
|
104
|
+
|----------------|--------------------------------------------------------------|
|
|
105
|
+
| `-surface` | Fill/background color |
|
|
106
|
+
| `-border` | Border color |
|
|
107
|
+
| `-text` | Text color |
|
|
108
|
+
| `-icon` | Icon color |
|
|
109
|
+
| `-label` | Label text color |
|
|
110
|
+
| `-fill` | Inner fill (distinct from outer surface) |
|
|
111
|
+
| `-radius` | Corner radius |
|
|
112
|
+
| `-border-width`| Stroke thickness |
|
|
113
|
+
| `-font-family` | Font family reference |
|
|
114
|
+
| `-font-weight` | Font weight reference |
|
|
115
|
+
| `-font-size` | Font size reference |
|
|
116
|
+
| `-thickness` | Alternative stroke dimension (used where `-width` would alias another token under name-based fallback grouping) |
|
|
117
|
+
| `-height` | Explicit height when `-width`'s sibling would collide under name-based fallback grouping |
|
|
118
|
+
| `-color` | Generic color when none of the role words fits (rare) |
|
|
119
|
+
|
|
120
|
+
**Why `thickness` and `height` sometimes stand in for `width`:** when an editor declares no explicit `groupKey` for a token, sibling grouping falls back to matching the final `-<property>` segment. If two unrelated slots both end in `-width` and neither has a `groupKey`, they get auto-linked. Either declare a `groupKey` per token in the editor (preferred) or use an alternative property word. The divider in SegmentedControl uses `--segmentedcontrol-divider-thickness` for legacy parity with the fallback rule, but it now also has `groupKey: 'divider-thickness'` declared in the editor. The `groupKey` is the source of truth.
|
|
121
|
+
|
|
122
|
+
### State order matters
|
|
123
|
+
|
|
124
|
+
State comes **before** the property, not after:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
--inlineeditactions-save-hover-surface ✓ state before property; siblings on `-surface`
|
|
128
|
+
--inlineeditactions-save-surface-hover ✗ breaks sibling matching and reads oddly
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Linked siblings (the link toggle)
|
|
132
|
+
|
|
133
|
+
Tokens that share a `groupKey` form a **sibling set**. A property declared `canBeLinked: true` in the editor shows a link toggle that lets the user broadcast one value across every sibling. So in SegmentedControl:
|
|
134
|
+
|
|
135
|
+
- `--segmentedcontrol-bar-border-width` and `--segmentedcontrol-selected-border-width` share `groupKey: 'border-width'`.
|
|
136
|
+
- `--segmentedcontrol-option-text-font-weight`, `--segmentedcontrol-option-disabled-text-font-weight`, and `--segmentedcontrol-selected-text-font-weight` share `groupKey: 'font-weight'`.
|
|
137
|
+
|
|
138
|
+
Editor authors declare `groupKey` per token in the editor's token list (and call `registerComponentSchema(component, tokens)` once at module load). The store consults the schema first; for unmigrated editors with no schema entry, it falls back to matching the last `-<property>` segment. Tokens with neither a `groupKey` nor a colliding name suffix are solo.
|
|
139
|
+
|
|
140
|
+
Linkage is **dev-declared** — the editor schema is the source of truth for which variables share a `groupKey`. Users only choose whether to opt out of an existing link (per-property), never to add or reshape one.
|
|
141
|
+
|
|
142
|
+
The `unlinked` array on a `ComponentSlice` stores the variable names the user has explicitly detached. The remaining declared siblings stay linked to each other; an unlinked variable rejoins via `setComponentAliasLinked` or `relinkComponentProperty`.
|
|
143
|
+
|
|
144
|
+
### Typography slot scoping
|
|
145
|
+
|
|
146
|
+
When a component declares more than one typography slot — e.g. a notification with separate `title` and `text` slots — every typography `groupKey` (`font-family`, `font-size`, `font-weight`, `line-height`) **must** include the slot name as a prefix:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
groupKey: 'title-font-family', 'text-font-family' ✓ one link tree per slot
|
|
150
|
+
groupKey: 'font-family' ✗ silently links title and text together
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
A bare typography `groupKey` like `'font-family'` is fine when the component has only one typography slot (Button has only `text`; RadioButton only `label`; CollapsibleSection only `label`). Add a slot prefix the moment the component grows a second slot.
|
|
154
|
+
|
|
155
|
+
`registerComponentSchema` emits a console warning at runtime if a single `groupKey` covers variables whose name-derived slots differ. Treat that warning as a build-time error.
|
|
156
|
+
|
|
157
|
+
### When the last-dash fallback surprises you
|
|
158
|
+
|
|
159
|
+
For tokens without an explicit `groupKey`, the store derives one by splitting on the last dash:
|
|
160
|
+
|
|
161
|
+
- `--segmentedcontrol-option-text-font-weight` → fallback groupKey `weight`.
|
|
162
|
+
|
|
163
|
+
So the fallback property is always the literal last segment. If you don't want a token to participate in the fallback grouping, declare an explicit `groupKey` (or omit `canBeLinked`).
|
|
164
|
+
|
|
165
|
+
## Checklist for adding a new component token
|
|
166
|
+
|
|
167
|
+
1. Does the value belong at the **theme layer**? (It's a color or scale that multiple components could reuse.) → Add it to `tokens.css` under the correct category, not here.
|
|
168
|
+
2. Pick a **componentId** matching the one used in `component-configs/` and the editor's `const component = '...'` literal.
|
|
169
|
+
3. Build the name as `--<componentId>-<part>[-<state>]-<property>`.
|
|
170
|
+
4. Use **full words**: no `bg`, no shortened component IDs.
|
|
171
|
+
5. Declare the slot in both the component's Svelte `<style>` (`--tok: var(--theme-alias);`) and the config JSON (`"--tok": "--theme-alias"`).
|
|
172
|
+
6. If the slot should link across variants, add `canBeLinked: true` and `groupKey: '<your-key>'` in the editor's token list. Siblings are tokens that share the same `groupKey`. Pick a `groupKey` that names the kind of property (`radius`, `border-width`, `font-weight`, `font-family`, etc.); a unique key isolates a token from any other. For typography on multi-slot components, prefix the slot name (see "Typography slot scoping").
|
|
173
|
+
7. Make sure the editor calls `registerComponentSchema(component, tokens)` once at module load so the store sees the explicit groupKeys.
|
|
174
|
+
|
|
175
|
+
## What's still pending
|
|
176
|
+
|
|
177
|
+
- **`primary` → `brand` rename.** Disambiguates the emphasis-tier, color-family, and component-variant uses of "primary." Tracked in `temp/primary-to-brand-rename.md`.
|
|
178
|
+
- **Theme-layer cleanups** tracked in `temp/theme-token-improvements.md`: font-weight scale normalization, bare-word orphan audit, full `bg` → `canvas` sweep.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* Generated from the production theme by syncFontsToCss. Do not edit. */
|
|
2
|
+
/* Both fonts.css and fonts/ are in dist/, so relative paths work at runtime. */
|
|
3
|
+
|
|
4
|
+
/* Adobe Typekit — fira-code */
|
|
5
|
+
@import url('https://use.typekit.net/jes8oow.css');
|
|
6
|
+
|
|
7
|
+
/* Google Fonts — Arvo */
|
|
8
|
+
@import url('https://fonts.googleapis.com/css2?family=Arvo:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
|
9
|
+
|
|
10
|
+
/* Google Fonts — GFS Didot */
|
|
11
|
+
@import url('https://fonts.googleapis.com/css2?family=GFS+Didot&display=swap');
|
|
12
|
+
|
|
13
|
+
/* Local — Manrope */
|
|
14
|
+
@font-face {
|
|
15
|
+
font-family: "Manrope";
|
|
16
|
+
src: url('/src/system/styles/fonts/Manrope/Manrope-latin.woff2') format('woff2');
|
|
17
|
+
font-weight: 200 800;
|
|
18
|
+
font-style: normal;
|
|
19
|
+
font-display: swap;
|
|
20
|
+
}
|