@motion-proto/live-tokens 0.1.1 → 0.3.1
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 +160 -21
- package/dist-plugin/index.cjs +823 -336
- package/dist-plugin/index.d.cts +9 -7
- package/dist-plugin/index.d.ts +9 -7
- package/dist-plugin/index.js +822 -335
- package/package.json +46 -20
- package/src/assets/newspaper.webp +0 -0
- package/src/assets/offering.webp +0 -0
- package/src/component-editor/BadgeEditor.svelte +170 -0
- package/src/component-editor/CalloutEditor.svelte +103 -0
- package/src/component-editor/CardEditor.svelte +184 -0
- package/src/component-editor/CollapsibleSectionEditor.svelte +167 -0
- package/src/component-editor/CornerBadgeEditor.svelte +207 -0
- package/src/component-editor/DialogEditor.svelte +172 -0
- package/src/component-editor/ImageEditor.svelte +72 -0
- package/src/component-editor/InlineEditActionsEditor.svelte +83 -0
- package/src/component-editor/NotificationEditor.svelte +160 -0
- package/src/component-editor/ProgressBarEditor.svelte +124 -0
- package/src/component-editor/RadioButtonEditor.svelte +140 -0
- package/src/component-editor/SectionDividerEditor.svelte +263 -0
- package/src/component-editor/SegmentedControlEditor.svelte +154 -0
- package/src/component-editor/StandardButtonsEditor.svelte +178 -0
- package/src/component-editor/TabBarEditor.svelte +137 -0
- package/src/component-editor/TableEditor.svelte +128 -0
- package/src/component-editor/TooltipEditor.svelte +122 -0
- package/src/component-editor/editorTokens.test.ts +93 -0
- package/src/component-editor/groupKeySlots.test.ts +67 -0
- package/src/component-editor/groupKeySnapshot.test.ts +52 -0
- package/src/component-editor/index.ts +5 -0
- package/src/component-editor/registry.ts +246 -0
- package/src/component-editor/scaffolding/AngleDial.svelte +185 -0
- package/src/component-editor/scaffolding/ComponentEditorBase.svelte +96 -0
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +682 -0
- package/src/component-editor/scaffolding/ComponentFileMenu.svelte +312 -0
- package/src/component-editor/scaffolding/ComponentsTab.svelte +69 -0
- package/src/component-editor/scaffolding/CopyFromMenu.svelte +246 -0
- package/src/component-editor/scaffolding/DemoHeader.svelte +21 -0
- package/src/component-editor/scaffolding/DividerEditor.svelte +81 -0
- package/src/component-editor/scaffolding/FieldsetWrapper.svelte +46 -0
- package/src/component-editor/scaffolding/GradientCard.svelte +291 -0
- package/src/component-editor/scaffolding/LinkageChart.svelte +297 -0
- package/src/component-editor/scaffolding/LinkedBlock.svelte +418 -0
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +57 -0
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +177 -0
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +25 -0
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +56 -0
- package/src/component-editor/scaffolding/StateBlock.svelte +115 -0
- package/src/component-editor/scaffolding/TokenLayout.svelte +511 -0
- package/src/component-editor/scaffolding/TypeEditor.svelte +82 -0
- package/src/component-editor/scaffolding/VariantGroup.svelte +277 -0
- package/src/component-editor/scaffolding/buildTypeGroupTokens.ts +97 -0
- package/src/component-editor/scaffolding/componentSectionType.ts +8 -0
- package/src/component-editor/scaffolding/componentSources.ts +9 -0
- package/src/component-editor/scaffolding/defaultSections.ts +16 -0
- package/src/component-editor/scaffolding/editorContext.ts +44 -0
- package/src/component-editor/scaffolding/linkedBlock.ts +226 -0
- package/src/component-editor/scaffolding/siblings.ts +33 -0
- package/src/component-editor/scaffolding/types.ts +39 -0
- package/src/components/Badge.svelte +231 -42
- package/src/components/Button.svelte +324 -124
- package/src/components/Callout.svelte +145 -0
- package/src/components/Card.svelte +123 -25
- package/src/components/CollapsibleSection.svelte +213 -35
- package/src/components/CornerBadge.svelte +224 -0
- package/src/components/Dialog.svelte +137 -114
- package/src/components/Image.svelte +43 -0
- package/src/components/InlineEditActions.svelte +74 -14
- package/src/components/Notification.svelte +184 -163
- package/src/components/ProgressBar.svelte +216 -22
- package/src/components/RadioButton.svelte +110 -40
- package/src/components/SectionDivider.svelte +428 -74
- package/src/components/SegmentedControl.svelte +203 -0
- package/src/components/TabBar.svelte +146 -21
- package/src/components/Table.svelte +102 -0
- package/src/components/Tooltip.svelte +45 -19
- package/src/components/types.ts +51 -0
- package/src/data/google-fonts.json +75 -0
- package/src/lib/ColumnsOverlay.svelte +20 -7
- package/src/lib/LiveEditorOverlay.svelte +257 -78
- package/src/lib/columnsOverlay.ts +21 -17
- package/src/lib/componentConfig.test.ts +204 -0
- package/src/lib/componentConfigKeys.ts +19 -0
- package/src/lib/componentConfigService.ts +88 -0
- package/src/lib/copyPopover.ts +30 -0
- package/src/lib/cssVarSync.ts +59 -7
- package/src/lib/editorConfigStore.ts +0 -10
- package/src/lib/editorCore.ts +402 -0
- package/src/lib/editorKeybindings.ts +52 -0
- package/src/lib/editorPersistence.ts +106 -0
- package/src/lib/editorRenderer.ts +74 -0
- package/src/lib/editorStore.test.ts +328 -0
- package/src/lib/editorStore.ts +412 -0
- package/src/lib/editorTypes.ts +100 -0
- package/src/lib/editorViewStore.ts +55 -0
- package/src/lib/files/versionedFileResource.ts +140 -0
- package/src/lib/fontLoader.ts +130 -0
- package/src/lib/fontMigration.ts +140 -0
- package/src/lib/fontParse.ts +168 -0
- package/src/lib/index.ts +48 -30
- package/src/lib/lazyConfig.test.ts +54 -0
- package/src/lib/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +64 -0
- package/src/lib/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +71 -0
- package/src/lib/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +43 -0
- package/src/lib/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +68 -0
- package/src/lib/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +35 -0
- package/src/lib/migrations/2026-05-10-sectiondivider-gradient-stops.ts +50 -0
- package/src/lib/migrations/2026-05-13-primary-to-brand.ts +90 -0
- package/src/lib/migrations/index.ts +93 -0
- package/src/lib/migrations/migrations.test.ts +341 -0
- package/src/lib/navLinkTypes.ts +1 -0
- package/src/lib/overlayState.ts +3 -0
- package/src/lib/paletteDerivation.ts +300 -0
- package/src/lib/parentRouteStore.ts +42 -0
- package/src/lib/parsers/globalRootBlock.ts +32 -0
- package/src/lib/presetService.ts +94 -0
- package/src/lib/router.ts +42 -10
- package/src/lib/scrollSection.ts +45 -0
- package/src/lib/slices/columns.ts +59 -0
- package/src/lib/slices/components.ts +362 -0
- package/src/lib/slices/domainVars.ts +15 -0
- package/src/lib/slices/fonts.ts +30 -0
- package/src/lib/slices/gradients.ts +153 -0
- package/src/lib/slices/overlays.ts +132 -0
- package/src/lib/slices/palettes.ts +26 -0
- package/src/lib/slices/shadows.ts +123 -0
- package/src/lib/storage.ts +88 -0
- package/src/lib/themeInit.ts +74 -0
- package/src/lib/themeService.ts +101 -0
- package/src/lib/themeTypes.ts +146 -0
- package/src/lib/tokenRegistry.ts +148 -0
- package/src/pages/ComponentEditorPage.svelte +384 -0
- package/src/pages/ComponentEditorPage.svelte.d.ts +2 -0
- package/src/pages/Editor.svelte +98 -0
- package/src/pages/Editor.svelte.d.ts +2 -0
- package/src/pages/EditorShell.svelte +348 -0
- package/src/styles/_padding.scss +34 -0
- package/src/styles/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
- package/src/styles/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Manrope/Manrope-latin.woff2 +0 -0
- package/src/styles/fonts.css +22 -10
- package/src/styles/form-controls.css +14 -16
- package/src/styles/tokens.css +1322 -0
- package/src/styles/ui-editor.css +126 -0
- package/src/{showcase → ui}/BezierCurveEditor.svelte +14 -14
- package/src/{showcase → ui}/ColorEditPanel.svelte +42 -36
- package/src/ui/EditorViewSwitcher.svelte +180 -0
- package/src/ui/FontStackEditor.svelte +360 -0
- package/src/ui/GradientEditor.svelte +461 -0
- package/src/ui/GradientStopPicker.svelte +74 -0
- package/src/ui/PaletteEditor.svelte +1590 -0
- package/src/ui/PaletteEditor.test.ts +108 -0
- package/src/ui/PresetFileManager.svelte +567 -0
- package/src/ui/ProjectFontsSection.svelte +645 -0
- package/src/{showcase → ui}/SurfacesTab.svelte +39 -39
- package/src/{showcase → ui}/TextTab.svelte +27 -27
- package/src/{showcase/TokenFileManager.svelte → ui/ThemeFileManager.svelte} +196 -112
- package/src/ui/Toggle.svelte +108 -0
- package/src/ui/UICopyPopover.svelte +78 -0
- package/src/{showcase/EditorDialog.svelte → ui/UIDialog.svelte} +66 -25
- package/src/ui/UIFontFamilySelector.svelte +309 -0
- package/src/ui/UIFontSizeSelector.svelte +165 -0
- package/src/ui/UIFontWeightSelector.svelte +52 -0
- package/src/ui/UILineHeightSelector.svelte +47 -0
- package/src/ui/UILinkToggle.svelte +60 -0
- package/src/ui/UIOptionItem.svelte +74 -0
- package/src/ui/UIOptionList.svelte +27 -0
- package/src/ui/UIPaddingSelector.svelte +661 -0
- package/src/ui/UIPaletteSelector.svelte +1084 -0
- package/src/ui/UIRadio.svelte +72 -0
- package/src/ui/UIRadioGroup.svelte +59 -0
- package/src/ui/UIRelinkConfirmPopover.svelte +235 -0
- package/src/ui/UITokenSelector.svelte +509 -0
- package/src/ui/UIVariantSelector.svelte +145 -0
- package/src/ui/VariablesTab.svelte +252 -0
- package/src/ui/index.ts +31 -0
- package/src/ui/keepInViewport.ts +84 -0
- package/src/ui/palette/GradientStopEditor.svelte +482 -0
- package/src/ui/palette/OverridesPanel.svelte +526 -0
- package/src/ui/palette/PaletteBase.svelte +165 -0
- package/src/ui/palette/ScaleCurveEditor.svelte +38 -0
- package/src/ui/palette/paletteEditorState.ts +89 -0
- package/src/ui/sections/ColumnsSection.svelte +273 -0
- package/src/ui/sections/GradientsSection.svelte +147 -0
- package/src/ui/sections/OverlaysSection.svelte +670 -0
- package/src/ui/sections/ShadowsSection.svelte +1250 -0
- package/src/ui/sections/TokenScaleTable.svelte +332 -0
- package/src/ui/sections/tokenScales.ts +81 -0
- package/src/ui/variantScales.ts +108 -0
- package/src/components/DetailNav.svelte +0 -78
- package/src/components/Toggle.svelte +0 -86
- package/src/lib/tokenInit.ts +0 -29
- package/src/lib/tokenService.ts +0 -144
- package/src/lib/tokenTypes.ts +0 -45
- package/src/pages/Admin.svelte +0 -100
- package/src/pages/ShowcasePage.svelte +0 -144
- package/src/showcase/BackupBrowser.svelte +0 -617
- package/src/showcase/ComponentsTab.svelte +0 -105
- package/src/showcase/PaletteEditor.svelte +0 -2579
- package/src/showcase/PaletteSelector.svelte +0 -627
- package/src/showcase/TokenMap.svelte +0 -54
- package/src/showcase/VariablesTab.svelte +0 -2655
- package/src/showcase/VisualsTab.svelte +0 -231
- package/src/showcase/demos/BadgeDemo.svelte +0 -56
- package/src/showcase/demos/CardDemo.svelte +0 -50
- package/src/showcase/demos/ChoiceButtonsDemo.svelte +0 -192
- package/src/showcase/demos/CollapsibleSectionDemo.svelte +0 -54
- package/src/showcase/demos/DialogDemo.svelte +0 -42
- package/src/showcase/demos/InlineEditActionsDemo.svelte +0 -25
- package/src/showcase/demos/NotificationDemo.svelte +0 -147
- package/src/showcase/demos/ProgressBarDemo.svelte +0 -54
- package/src/showcase/demos/RadioButtonDemo.svelte +0 -56
- package/src/showcase/demos/SectionDividerDemo.svelte +0 -77
- package/src/showcase/demos/StandardButtonsDemo.svelte +0 -455
- package/src/showcase/demos/TabBarDemo.svelte +0 -58
- package/src/showcase/demos/TooltipDemo.svelte +0 -52
- package/src/showcase/editor.css +0 -93
- package/src/showcase/index.ts +0 -17
- package/src/styles/fonts/Domine/Domine-VariableFont_wght.ttf +0 -0
- package/src/styles/fonts/Domine/OFL.txt +0 -97
- package/src/styles/fonts/Domine/README.txt +0 -66
- /package/src/{showcase → ui}/curveEngine.ts +0 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Parameterised token-display table.
|
|
4
|
+
*
|
|
5
|
+
* Replaces the seven hand-listed scales (spacing, border-width, radius,
|
|
6
|
+
* font-size, font-weight, line-height, icon-size) in VariablesTab with one
|
|
7
|
+
* component. Each variant renders the same `(token-variable, token-value)`
|
|
8
|
+
* pair plus a kind-specific preview swatch.
|
|
9
|
+
*
|
|
10
|
+
* Values are read live via getComputedStyle (passed in by the parent through
|
|
11
|
+
* `tokens`), so tokens.css remains the single source of truth.
|
|
12
|
+
*/
|
|
13
|
+
import { createEventDispatcher } from 'svelte';
|
|
14
|
+
import { editorState } from '../../lib/editorStore';
|
|
15
|
+
|
|
16
|
+
interface TokenItem {
|
|
17
|
+
variable: string;
|
|
18
|
+
value: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Visual layout variant. Each variant matches one of the seven scales the
|
|
22
|
+
* parent renders; the markup differs only in the preview swatch. */
|
|
23
|
+
type ScaleKind =
|
|
24
|
+
| 'spacing' // horizontal bar sized by width: var(--xx)
|
|
25
|
+
| 'border' // horizontal bar sized by height: var(--xx)
|
|
26
|
+
| 'radius' // square box with border-radius: var(--xx)
|
|
27
|
+
| 'font-size' // "Ag" text sized by font-size: var(--xx)
|
|
28
|
+
| 'font-weight' // "Ag" text weighted by font-weight: var(--xx)
|
|
29
|
+
| 'line-height' // no preview, table-only rows
|
|
30
|
+
| 'icon-size'; // star icon sized by font-size: var(--xx)
|
|
31
|
+
|
|
32
|
+
export let kind: ScaleKind;
|
|
33
|
+
/** Var names to resolve via getComputedStyle. Mutually exclusive with `tokens`. */
|
|
34
|
+
export let vars: readonly string[] | undefined = undefined;
|
|
35
|
+
/** Pre-built token list. Use when values are static (e.g. duration/z-index/opacity
|
|
36
|
+
* literals) and don't need live CSS resolution. Mutually exclusive with `vars`. */
|
|
37
|
+
export let tokens: TokenItem[] | undefined = undefined;
|
|
38
|
+
/** Bumped by the parent when the live CSS values may have changed (breakpoint
|
|
39
|
+
* flip). Triggers re-resolution when reading via `vars`. */
|
|
40
|
+
export let liveVersion: number = 0;
|
|
41
|
+
/** When provided, the parent owns the copy-flash UI (pass copiedVar through). */
|
|
42
|
+
export let copiedVar: string | null = null;
|
|
43
|
+
|
|
44
|
+
const dispatch = createEventDispatcher<{ copy: string }>();
|
|
45
|
+
function copy(v: string) { dispatch('copy', v); }
|
|
46
|
+
|
|
47
|
+
function readVar(name: string): string {
|
|
48
|
+
if (typeof document === 'undefined') return '';
|
|
49
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function formatValueHint(raw: string): string {
|
|
53
|
+
if (!raw) return '';
|
|
54
|
+
if (raw === '9999px') return '9999px (pill)';
|
|
55
|
+
const rem = raw.match(/^(-?[\d.]+)rem$/);
|
|
56
|
+
if (rem) {
|
|
57
|
+
const px = Math.round(parseFloat(rem[1]) * 16 * 100) / 100;
|
|
58
|
+
return `${raw} (${px}px)`;
|
|
59
|
+
}
|
|
60
|
+
return raw;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Re-read whenever liveVersion bumps OR the editor mutates any CSS var
|
|
64
|
+
// (editor edits fan out via cssVarSync to :root). Depending on $editorState
|
|
65
|
+
// keeps the display in sync with user edits for free.
|
|
66
|
+
let resolved: TokenItem[] = [];
|
|
67
|
+
$: {
|
|
68
|
+
liveVersion;
|
|
69
|
+
$editorState;
|
|
70
|
+
if (tokens) {
|
|
71
|
+
resolved = tokens;
|
|
72
|
+
} else if (vars) {
|
|
73
|
+
resolved = vars.map((variable) => ({ variable, value: formatValueHint(readVar(variable)) }));
|
|
74
|
+
} else {
|
|
75
|
+
resolved = [];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
{#if kind === 'spacing'}
|
|
81
|
+
<div class="spacing-grid">
|
|
82
|
+
{#each resolved as token}
|
|
83
|
+
<div class="spacing-item">
|
|
84
|
+
<div class="spacing-bar" style="width: var({token.variable}); min-width: 2px;"></div>
|
|
85
|
+
<div class="token-info">
|
|
86
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
87
|
+
<span class="token-value">{token.value}</span>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
{/each}
|
|
91
|
+
</div>
|
|
92
|
+
{:else if kind === 'border'}
|
|
93
|
+
<div class="spacing-grid">
|
|
94
|
+
{#each resolved as token}
|
|
95
|
+
<div class="spacing-item">
|
|
96
|
+
<div class="border-width-bar" style="height: var({token.variable});"></div>
|
|
97
|
+
<div class="token-info">
|
|
98
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
99
|
+
<span class="token-value">{token.value}</span>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
{/each}
|
|
103
|
+
</div>
|
|
104
|
+
{:else if kind === 'radius'}
|
|
105
|
+
<div class="radius-grid">
|
|
106
|
+
{#each resolved as token}
|
|
107
|
+
<div class="radius-item">
|
|
108
|
+
<div class="radius-box" style="border-radius: var({token.variable});"></div>
|
|
109
|
+
<div class="token-info">
|
|
110
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
111
|
+
<span class="token-value">{token.value}</span>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
{/each}
|
|
115
|
+
</div>
|
|
116
|
+
{:else if kind === 'font-size'}
|
|
117
|
+
<div class="font-size-demos">
|
|
118
|
+
{#each resolved as token}
|
|
119
|
+
<div class="font-size-item">
|
|
120
|
+
<span class="font-size-preview" style="font-size: var({token.variable});">Ag</span>
|
|
121
|
+
<div class="token-info">
|
|
122
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
123
|
+
<span class="token-value">{token.value}</span>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
{/each}
|
|
127
|
+
</div>
|
|
128
|
+
{:else if kind === 'font-weight'}
|
|
129
|
+
<div class="font-weight-demos">
|
|
130
|
+
{#each resolved as token}
|
|
131
|
+
<div class="font-weight-item">
|
|
132
|
+
<span class="font-weight-preview" style="font-weight: var({token.variable});">Ag</span>
|
|
133
|
+
<div class="token-info">
|
|
134
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
135
|
+
<span class="token-value">{token.value}</span>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
{/each}
|
|
139
|
+
</div>
|
|
140
|
+
{:else if kind === 'line-height'}
|
|
141
|
+
<div class="token-table">
|
|
142
|
+
{#each resolved as token}
|
|
143
|
+
<div class="token-row">
|
|
144
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
145
|
+
<span class="token-value">{token.value}</span>
|
|
146
|
+
</div>
|
|
147
|
+
{/each}
|
|
148
|
+
</div>
|
|
149
|
+
{:else if kind === 'icon-size'}
|
|
150
|
+
<div class="font-size-demos">
|
|
151
|
+
{#each resolved as token}
|
|
152
|
+
<div class="font-size-item">
|
|
153
|
+
<span class="icon-size-preview" style="font-size: var({token.variable});">
|
|
154
|
+
<i class="fas fa-star"></i>
|
|
155
|
+
</span>
|
|
156
|
+
<div class="token-info">
|
|
157
|
+
<button class="token-variable copyable" class:copied={copiedVar === token.variable} on:click={() => copy(token.variable)}>{copiedVar === token.variable ? 'copied!' : token.variable}</button>
|
|
158
|
+
<span class="token-value">{token.value}</span>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
{/each}
|
|
162
|
+
</div>
|
|
163
|
+
{/if}
|
|
164
|
+
|
|
165
|
+
<style>
|
|
166
|
+
.token-info {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
gap: var(--ui-space-2);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.token-variable {
|
|
173
|
+
font-size: var(--ui-font-size-md);
|
|
174
|
+
color: var(--ui-text-tertiary);
|
|
175
|
+
font-family: var(--ui-font-mono);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.token-variable.copyable {
|
|
179
|
+
all: unset;
|
|
180
|
+
font-size: var(--ui-font-size-md);
|
|
181
|
+
color: var(--ui-text-tertiary);
|
|
182
|
+
font-family: var(--ui-font-mono);
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
transition: color var(--ui-transition-fast);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.token-variable.copyable:hover {
|
|
188
|
+
color: var(--ui-text-accent);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.token-variable.copyable.copied {
|
|
192
|
+
color: var(--ui-text-success);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.token-value {
|
|
196
|
+
font-size: var(--ui-font-size-md);
|
|
197
|
+
color: var(--ui-text-muted);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Spacing & Borders */
|
|
201
|
+
.spacing-grid {
|
|
202
|
+
display: flex;
|
|
203
|
+
flex-direction: column;
|
|
204
|
+
gap: var(--ui-space-6);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.spacing-item {
|
|
208
|
+
display: flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
gap: var(--ui-space-12);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.spacing-bar {
|
|
214
|
+
height: 1.25rem;
|
|
215
|
+
background: var(--ui-text-accent);
|
|
216
|
+
border-radius: var(--ui-radius-sm);
|
|
217
|
+
flex-shrink: 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.border-width-bar {
|
|
221
|
+
width: 4rem;
|
|
222
|
+
background: var(--ui-text-accent);
|
|
223
|
+
flex-shrink: 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.spacing-item .token-info {
|
|
227
|
+
flex-direction: row;
|
|
228
|
+
gap: var(--ui-space-8);
|
|
229
|
+
align-items: baseline;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Border Radius */
|
|
233
|
+
.radius-grid {
|
|
234
|
+
display: grid;
|
|
235
|
+
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
|
|
236
|
+
gap: var(--ui-space-16);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.radius-item {
|
|
240
|
+
display: flex;
|
|
241
|
+
flex-direction: column;
|
|
242
|
+
align-items: center;
|
|
243
|
+
gap: var(--ui-space-8);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.radius-box {
|
|
247
|
+
width: 3.5rem;
|
|
248
|
+
height: 3.5rem;
|
|
249
|
+
background: none;
|
|
250
|
+
border: 2px solid var(--ui-border-medium);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Font sizes / icon sizes */
|
|
254
|
+
.font-size-demos {
|
|
255
|
+
display: flex;
|
|
256
|
+
flex-direction: column;
|
|
257
|
+
gap: var(--ui-space-4);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.font-size-item {
|
|
261
|
+
display: flex;
|
|
262
|
+
align-items: baseline;
|
|
263
|
+
gap: var(--ui-space-12);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.font-size-preview {
|
|
267
|
+
color: var(--ui-text-primary);
|
|
268
|
+
font-family: var(--ui-font-sans);
|
|
269
|
+
line-height: 1;
|
|
270
|
+
min-width: 3rem;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.icon-size-preview {
|
|
274
|
+
color: var(--ui-text-primary);
|
|
275
|
+
line-height: 1;
|
|
276
|
+
min-width: 3rem;
|
|
277
|
+
display: inline-flex;
|
|
278
|
+
align-items: center;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.font-size-item .token-info {
|
|
282
|
+
flex-direction: row;
|
|
283
|
+
gap: var(--ui-space-8);
|
|
284
|
+
align-items: baseline;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* Font weights */
|
|
288
|
+
.font-weight-demos {
|
|
289
|
+
display: flex;
|
|
290
|
+
flex-direction: column;
|
|
291
|
+
gap: var(--ui-space-4);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.font-weight-item {
|
|
295
|
+
display: flex;
|
|
296
|
+
align-items: baseline;
|
|
297
|
+
gap: var(--ui-space-12);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.font-weight-preview {
|
|
301
|
+
font-size: var(--ui-font-size-xl);
|
|
302
|
+
font-family: var(--ui-font-sans);
|
|
303
|
+
color: var(--ui-text-primary);
|
|
304
|
+
line-height: 1;
|
|
305
|
+
min-width: 2rem;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.font-weight-item .token-info {
|
|
309
|
+
flex-direction: row;
|
|
310
|
+
gap: var(--ui-space-8);
|
|
311
|
+
align-items: baseline;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* Token Table (line heights, durations, z-indexes, opacity) */
|
|
315
|
+
.token-table {
|
|
316
|
+
display: flex;
|
|
317
|
+
flex-direction: column;
|
|
318
|
+
gap: var(--ui-space-4);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.token-row {
|
|
322
|
+
display: flex;
|
|
323
|
+
align-items: baseline;
|
|
324
|
+
gap: var(--ui-space-12);
|
|
325
|
+
padding: var(--ui-space-4) 0;
|
|
326
|
+
border-bottom: 1px solid var(--ui-border-faint);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.token-row:last-child {
|
|
330
|
+
border-bottom: none;
|
|
331
|
+
}
|
|
332
|
+
</style>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable-name lists and static utility-token data for the scales rendered
|
|
3
|
+
* in VariablesTab. Pulled out so the parent stays focused on layout +
|
|
4
|
+
* orchestration. Values are resolved live via getComputedStyle inside
|
|
5
|
+
* TokenScaleTable, so tokens.css remains the single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const SPACING_VARS = [
|
|
9
|
+
'--space-2', '--space-4', '--space-6', '--space-8', '--space-10',
|
|
10
|
+
'--space-12', '--space-16', '--space-20', '--space-24', '--space-32',
|
|
11
|
+
'--space-48',
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export const BORDER_WIDTH_VARS = [
|
|
15
|
+
'--border-width-0', '--border-width-1', '--border-width-2', '--border-width-3',
|
|
16
|
+
'--border-width-4', '--border-width-5', '--border-width-6', '--border-width-8',
|
|
17
|
+
'--border-width-10', '--border-width-12', '--border-width-16', '--border-width-20',
|
|
18
|
+
'--border-width-24',
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
export const RADIUS_VARS = [
|
|
22
|
+
'--radius-none', '--radius-sm', '--radius-md', '--radius-lg', '--radius-xl',
|
|
23
|
+
'--radius-2xl', '--radius-3xl', '--radius-4xl', '--radius-full',
|
|
24
|
+
] as const;
|
|
25
|
+
|
|
26
|
+
export const FONT_SIZE_VARS = [
|
|
27
|
+
'--font-size-xs', '--font-size-sm', '--font-size-md', '--font-size-lg',
|
|
28
|
+
'--font-size-xl', '--font-size-2xl', '--font-size-3xl', '--font-size-4xl',
|
|
29
|
+
'--font-size-5xl', '--font-size-6xl',
|
|
30
|
+
] as const;
|
|
31
|
+
|
|
32
|
+
export const ICON_SIZE_VARS = [
|
|
33
|
+
'--icon-size-xs', '--icon-size-sm', '--icon-size-md', '--icon-size-lg',
|
|
34
|
+
'--icon-size-xl', '--icon-size-2xl', '--icon-size-3xl', '--icon-size-4xl',
|
|
35
|
+
'--icon-size-5xl', '--icon-size-6xl',
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
export const FONT_WEIGHT_VARS = [
|
|
39
|
+
'--font-weight-thin', '--font-weight-extralight', '--font-weight-light',
|
|
40
|
+
'--font-weight-normal', '--font-weight-medium', '--font-weight-semibold',
|
|
41
|
+
'--font-weight-bold', '--font-weight-extrabold', '--font-weight-black',
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
export const LINE_HEIGHT_VARS = [
|
|
45
|
+
'--line-height-tight', '--line-height-snug', '--line-height-normal',
|
|
46
|
+
'--line-height-relaxed', '--line-height-loose',
|
|
47
|
+
] as const;
|
|
48
|
+
|
|
49
|
+
export interface TokenItem {
|
|
50
|
+
variable: string;
|
|
51
|
+
value: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Static utility tokens — values are baked at the JS layer (not resolved
|
|
55
|
+
* from CSS) because they're meaningful labels, not the result of computed
|
|
56
|
+
* CSS lookups. */
|
|
57
|
+
export const DURATION_TOKENS: TokenItem[] = [
|
|
58
|
+
{ variable: '--duration-75', value: '75ms' },
|
|
59
|
+
{ variable: '--duration-150', value: '150ms' },
|
|
60
|
+
{ variable: '--duration-200', value: '200ms' },
|
|
61
|
+
{ variable: '--duration-300', value: '300ms' },
|
|
62
|
+
{ variable: '--duration-500', value: '500ms' },
|
|
63
|
+
{ variable: '--duration-750', value: '750ms' },
|
|
64
|
+
{ variable: '--duration-1000', value: '1000ms' },
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
export const Z_INDEX_TOKENS: TokenItem[] = [
|
|
68
|
+
{ variable: '--z-base', value: '0' },
|
|
69
|
+
{ variable: '--z-dropdown', value: '100' },
|
|
70
|
+
{ variable: '--z-sticky', value: '200' },
|
|
71
|
+
{ variable: '--z-overlay', value: '1000' },
|
|
72
|
+
{ variable: '--z-modal', value: '1100' },
|
|
73
|
+
{ variable: '--z-popover', value: '1200' },
|
|
74
|
+
{ variable: '--z-tooltip', value: '1300' },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
export const OPACITY_TOKENS: TokenItem[] = [
|
|
78
|
+
{ variable: '--opacity-disabled', value: '0.6' },
|
|
79
|
+
{ variable: '--opacity-hover', value: '0.8' },
|
|
80
|
+
{ variable: '--opacity-muted', value: '0.5' },
|
|
81
|
+
];
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared scale definitions consumed by `UIVariantSelector`. Each entry pairs
|
|
3
|
+
* a CSS-var prefix with the option list that drives its dropdown. Spread the
|
|
4
|
+
* entry into the selector at the call site:
|
|
5
|
+
*
|
|
6
|
+
* <UIVariantSelector {variable} {component} {canBeLinked} {...BLUR} on:change />
|
|
7
|
+
*
|
|
8
|
+
* Replaces the per-scale wrappers (UIBlurSelector / UIRadiusSelector / etc.)
|
|
9
|
+
* that were 35–50 lines of identical glue around the same data.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface VariantScaleOption {
|
|
13
|
+
key: string;
|
|
14
|
+
label: string;
|
|
15
|
+
/** Resolved value shown in the option's `meta` column. Omit for label-only scales. */
|
|
16
|
+
value?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface VariantScaleEntry {
|
|
20
|
+
varPrefix: string;
|
|
21
|
+
options: ReadonlyArray<VariantScaleOption>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const BLUR: VariantScaleEntry = {
|
|
25
|
+
varPrefix: '--blur-',
|
|
26
|
+
options: [
|
|
27
|
+
{ key: 'none', label: 'None', value: '0' },
|
|
28
|
+
{ key: 'sm', label: 'Small', value: '4px' },
|
|
29
|
+
{ key: 'md', label: 'Medium', value: '8px' },
|
|
30
|
+
{ key: 'lg', label: 'Large', value: '16px' },
|
|
31
|
+
{ key: 'xl', label: 'X-Large', value: '24px' },
|
|
32
|
+
{ key: '2xl', label: '2X-Large', value: '32px' },
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const BORDER_WIDTH: VariantScaleEntry = {
|
|
37
|
+
varPrefix: '--border-width-',
|
|
38
|
+
options: [
|
|
39
|
+
{ key: '0', label: '0', value: '0' },
|
|
40
|
+
{ key: '1', label: '1', value: '1px' },
|
|
41
|
+
{ key: '2', label: '2', value: '2px' },
|
|
42
|
+
{ key: '3', label: '3', value: '3px' },
|
|
43
|
+
{ key: '4', label: '4', value: '4px' },
|
|
44
|
+
{ key: '5', label: '5', value: '5px' },
|
|
45
|
+
{ key: '6', label: '6', value: '6px' },
|
|
46
|
+
{ key: '8', label: '8', value: '8px' },
|
|
47
|
+
{ key: '10', label: '10', value: '10px' },
|
|
48
|
+
{ key: '12', label: '12', value: '12px' },
|
|
49
|
+
{ key: '16', label: '16', value: '16px' },
|
|
50
|
+
{ key: '20', label: '20', value: '20px' },
|
|
51
|
+
{ key: '24', label: '24', value: '24px' },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const DOT_SIZE: VariantScaleEntry = {
|
|
56
|
+
varPrefix: '--dot-size-',
|
|
57
|
+
options: [
|
|
58
|
+
{ key: '0', label: 'None', value: '0%' },
|
|
59
|
+
{ key: '25', label: '25%', value: '25%' },
|
|
60
|
+
{ key: '50', label: '50%', value: '50%' },
|
|
61
|
+
{ key: '75', label: '75%', value: '75%' },
|
|
62
|
+
{ key: '100', label: '100%', value: '100%' },
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const RADIUS: VariantScaleEntry = {
|
|
67
|
+
varPrefix: '--radius-',
|
|
68
|
+
options: [
|
|
69
|
+
{ key: 'none', label: 'None', value: '0' },
|
|
70
|
+
{ key: 'sm', label: 'Small', value: '0.125rem' },
|
|
71
|
+
{ key: 'md', label: 'Medium', value: '0.25rem' },
|
|
72
|
+
{ key: 'lg', label: 'Large', value: '0.375rem' },
|
|
73
|
+
{ key: 'xl', label: 'X-Large', value: '0.5rem' },
|
|
74
|
+
{ key: '2xl', label: '2X-Large', value: '0.625rem' },
|
|
75
|
+
{ key: '3xl', label: '3X-Large', value: '0.75rem' },
|
|
76
|
+
{ key: '4xl', label: '4X-Large', value: '1.25rem' },
|
|
77
|
+
{ key: 'full', label: 'Full', value: '9999px' },
|
|
78
|
+
],
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const SHADOW: VariantScaleEntry = {
|
|
82
|
+
varPrefix: '--shadow-',
|
|
83
|
+
options: [
|
|
84
|
+
{ key: 'none', label: 'None' },
|
|
85
|
+
{ key: 'sm', label: 'Small' },
|
|
86
|
+
{ key: 'md', label: 'Medium' },
|
|
87
|
+
{ key: 'lg', label: 'Large' },
|
|
88
|
+
{ key: 'xl', label: 'X-Large' },
|
|
89
|
+
{ key: '2xl', label: '2X-Large' },
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Used by `*-divider-height` / `*-track-height` variables; values come from the `--space-*` scale,
|
|
94
|
+
* not a dedicated `--divider-height-*` scale. The label-set differs from BORDER_WIDTH so a divider
|
|
95
|
+
* can pick from larger heights (up to 100%). */
|
|
96
|
+
export const DIVIDER_HEIGHT: VariantScaleEntry = {
|
|
97
|
+
varPrefix: '--space-',
|
|
98
|
+
options: [
|
|
99
|
+
{ key: '0', label: 'None', value: '0px' },
|
|
100
|
+
{ key: '8', label: 'XS', value: '0.5rem' },
|
|
101
|
+
{ key: '10', label: 'Small', value: '0.625rem' },
|
|
102
|
+
{ key: '12', label: 'Medium', value: '0.75rem' },
|
|
103
|
+
{ key: '16', label: 'Large', value: '1rem' },
|
|
104
|
+
{ key: '20', label: 'XL', value: '1.25rem' },
|
|
105
|
+
{ key: '24', label: '2XL', value: '1.5rem' },
|
|
106
|
+
{ key: 'full', label: 'Full', value: '100%' },
|
|
107
|
+
],
|
|
108
|
+
};
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
export let backHref: string = '/';
|
|
3
|
-
export let backLabel: string = 'All Modules';
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<nav class="detail-nav">
|
|
7
|
-
<div class="nav-left">
|
|
8
|
-
<a href={backHref} class="back-link">
|
|
9
|
-
<i class="fa-solid fa-arrow-left"></i>
|
|
10
|
-
<span>{backLabel}</span>
|
|
11
|
-
</a>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
{#if $$slots.default}
|
|
15
|
-
<div class="nav-right">
|
|
16
|
-
<slot />
|
|
17
|
-
</div>
|
|
18
|
-
{/if}
|
|
19
|
-
</nav>
|
|
20
|
-
|
|
21
|
-
<style lang="scss">
|
|
22
|
-
.detail-nav {
|
|
23
|
-
display: flex;
|
|
24
|
-
align-items: center;
|
|
25
|
-
justify-content: space-between;
|
|
26
|
-
gap: 12px;
|
|
27
|
-
margin-bottom: 24px;
|
|
28
|
-
flex-wrap: wrap;
|
|
29
|
-
position: sticky;
|
|
30
|
-
top: 96px;
|
|
31
|
-
z-index: 50;
|
|
32
|
-
background: var(--empty);
|
|
33
|
-
padding: 12px 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.nav-left {
|
|
37
|
-
flex-shrink: 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.back-link {
|
|
41
|
-
display: inline-flex;
|
|
42
|
-
align-items: center;
|
|
43
|
-
gap: 8px;
|
|
44
|
-
font-family: var(--font-sans);
|
|
45
|
-
font-size: var(--font-lg);
|
|
46
|
-
font-weight: var(--font-weight-semibold);
|
|
47
|
-
color: var(--text-primary);
|
|
48
|
-
text-decoration: none;
|
|
49
|
-
transition: color var(--transition-fast);
|
|
50
|
-
letter-spacing: 0.02em;
|
|
51
|
-
|
|
52
|
-
&:hover {
|
|
53
|
-
color: var(--text-primary-color);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
:global(i) {
|
|
57
|
-
font-size: 11px;
|
|
58
|
-
transition: transform var(--transition-fast);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
&:hover :global(i) {
|
|
62
|
-
transform: translateX(-3px);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.nav-right {
|
|
67
|
-
display: flex;
|
|
68
|
-
align-items: center;
|
|
69
|
-
gap: 6px;
|
|
70
|
-
flex-shrink: 0;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@media (max-width: 600px) {
|
|
74
|
-
.detail-nav {
|
|
75
|
-
top: 48px;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
</style>
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
export let checked: boolean = false;
|
|
3
|
-
export let disabled: boolean = false;
|
|
4
|
-
export let label: string = '';
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<label class="toggle" class:disabled>
|
|
8
|
-
<button
|
|
9
|
-
type="button"
|
|
10
|
-
role="switch"
|
|
11
|
-
aria-checked={checked}
|
|
12
|
-
{disabled}
|
|
13
|
-
class="toggle-track"
|
|
14
|
-
class:on={checked}
|
|
15
|
-
on:click={() => { if (!disabled) checked = !checked; }}
|
|
16
|
-
>
|
|
17
|
-
<span class="toggle-thumb" />
|
|
18
|
-
</button>
|
|
19
|
-
{#if label}
|
|
20
|
-
<span class="toggle-label">{label}</span>
|
|
21
|
-
{/if}
|
|
22
|
-
</label>
|
|
23
|
-
|
|
24
|
-
<style lang="scss">
|
|
25
|
-
.toggle {
|
|
26
|
-
display: inline-flex;
|
|
27
|
-
align-items: center;
|
|
28
|
-
gap: var(--space-8);
|
|
29
|
-
cursor: pointer;
|
|
30
|
-
user-select: none;
|
|
31
|
-
|
|
32
|
-
&.disabled {
|
|
33
|
-
opacity: var(--opacity-disabled);
|
|
34
|
-
cursor: not-allowed;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.toggle-track {
|
|
39
|
-
position: relative;
|
|
40
|
-
width: 2.25rem;
|
|
41
|
-
height: 1.25rem;
|
|
42
|
-
border-radius: 0.625rem;
|
|
43
|
-
border: 1px solid var(--ui-border-default);
|
|
44
|
-
background: var(--ui-surface-low);
|
|
45
|
-
padding: 0;
|
|
46
|
-
cursor: inherit;
|
|
47
|
-
transition: background var(--transition-fast), border-color var(--transition-fast);
|
|
48
|
-
flex-shrink: 0;
|
|
49
|
-
|
|
50
|
-
&.on {
|
|
51
|
-
background: var(--ui-toggle);
|
|
52
|
-
border-color: var(--ui-border-medium);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
&:hover:not(:disabled) {
|
|
56
|
-
border-color: var(--ui-border-medium);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
&:focus-visible {
|
|
60
|
-
outline: 2px solid var(--border-primary);
|
|
61
|
-
outline-offset: 2px;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.toggle-thumb {
|
|
66
|
-
position: absolute;
|
|
67
|
-
top: 2px;
|
|
68
|
-
left: 2px;
|
|
69
|
-
width: 0.875rem;
|
|
70
|
-
height: 0.875rem;
|
|
71
|
-
border-radius: 50%;
|
|
72
|
-
background: var(--ui-text-secondary);
|
|
73
|
-
transition: transform var(--transition-fast), background var(--transition-fast);
|
|
74
|
-
|
|
75
|
-
.on & {
|
|
76
|
-
transform: translateX(1rem);
|
|
77
|
-
background: var(--text-primary);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.toggle-label {
|
|
82
|
-
font-size: var(--font-md);
|
|
83
|
-
color: var(--ui-text-secondary);
|
|
84
|
-
line-height: 1;
|
|
85
|
-
}
|
|
86
|
-
</style>
|