@motion-proto/live-tokens 0.8.0 → 0.10.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/.claude/skills/live-tokens-add-component/SKILL.md +488 -0
- package/README.md +84 -29
- package/dist-plugin/index.cjs +177 -125
- package/dist-plugin/index.d.cts +3 -2
- package/dist-plugin/index.d.ts +3 -2
- package/dist-plugin/index.js +177 -125
- package/package.json +8 -2
- package/src/editor/component-editor/BadgeEditor.svelte +44 -42
- package/src/editor/component-editor/ButtonEditor.svelte +224 -0
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +1 -7
- package/src/editor/component-editor/CornerBadgeEditor.svelte +44 -34
- package/src/editor/component-editor/ImageLightboxEditor.svelte +58 -0
- package/src/editor/component-editor/InputEditor.svelte +272 -0
- package/src/editor/component-editor/NotificationEditor.svelte +44 -65
- package/src/editor/component-editor/ProgressBarEditor.svelte +71 -87
- package/src/editor/component-editor/SegmentedControlEditor.svelte +98 -37
- package/src/editor/component-editor/SideNavigationEditor.svelte +342 -0
- package/src/editor/component-editor/index.ts +16 -1
- package/src/editor/component-editor/registry.ts +138 -28
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +3 -2
- package/src/editor/component-editor/scaffolding/ComponentsTab.svelte +2 -2
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +9 -10
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +60 -36
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +38 -1
- package/src/editor/component-editor/scaffolding/buildTypeGroupTokens.ts +1 -1
- package/src/editor/component-editor/scaffolding/componentSources.ts +3 -3
- package/src/editor/component-editor/scaffolding/defaultSections.ts +15 -10
- package/src/editor/component-editor/scaffolding/siblings.ts +2 -2
- package/src/editor/component-editor/scaffolding/types.ts +2 -1
- package/src/editor/core/components/componentConfigKeys.ts +14 -3
- package/src/editor/core/components/componentConfigService.ts +7 -6
- package/src/editor/core/manifests/manifestService.ts +5 -4
- package/src/editor/core/storage/apiBase.ts +15 -0
- package/src/editor/core/storage/files/versionedFileResourceClient.ts +1 -1
- package/src/editor/core/themes/migrations/2026-05-24-collapsiblesection-drop-active-state.ts +28 -0
- package/src/editor/core/themes/migrations/2026-05-24-progressbar-collapse-variants.ts +41 -0
- package/src/editor/core/themes/migrations/2026-05-24-promote-state-shared-tokens.ts +59 -0
- package/src/editor/core/themes/migrations/2026-05-24-segmentedcontrol-divider-inset.ts +29 -0
- package/src/editor/core/themes/migrations/2026-05-25-cornerbadge-flatten-variants.ts +46 -0
- package/src/editor/core/themes/migrations/index.ts +10 -0
- package/src/editor/core/themes/slices/components.ts +9 -0
- package/src/editor/core/themes/themeInit.ts +3 -2
- package/src/editor/core/themes/themeService.ts +3 -2
- package/src/editor/index.ts +10 -1
- package/src/editor/pages/ComponentEditorPage.svelte +53 -3
- package/src/editor/pages/EditorShell.svelte +53 -3
- package/src/editor/ui/UIEasingSelector.svelte +240 -0
- package/src/editor/ui/variantScales.ts +34 -0
- package/src/system/components/Button.svelte +34 -85
- package/src/system/components/CollapsibleSection.svelte +1 -48
- package/src/system/components/CornerBadge.svelte +72 -138
- package/src/system/components/Dialog.svelte +24 -4
- package/src/system/components/ImageLightbox.svelte +578 -0
- package/src/system/components/Input.svelte +387 -0
- package/src/system/components/ProgressBar.svelte +62 -258
- package/src/system/components/SectionDivider.svelte +117 -43
- package/src/system/components/SegmentedControl.svelte +81 -15
- package/src/system/components/SideNavigation.svelte +777 -0
- package/src/system/styles/tokens.css +43 -0
- package/src/system/styles/tokens.generated.css +4 -183
- package/src/editor/component-editor/StandardButtonsEditor.svelte +0 -190
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher } from 'svelte';
|
|
3
|
+
import CollapsibleSection from './CollapsibleSection.svelte';
|
|
4
|
+
|
|
5
|
+
export type SideNavItem = {
|
|
6
|
+
/** Full path. Matches `currentPath` exactly when this item is active. */
|
|
7
|
+
path: string;
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type SideNavSection = {
|
|
12
|
+
/** Unique key for expand-state tracking. Also the section's own page path
|
|
13
|
+
when `hasIndexPage` is true. */
|
|
14
|
+
path: string;
|
|
15
|
+
title: string;
|
|
16
|
+
items: SideNavItem[];
|
|
17
|
+
/** When true, the section header is a link to `hrefFor(section.path)`.
|
|
18
|
+
Defaults to false — the header acts as a toggle only. */
|
|
19
|
+
hasIndexPage?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type SideNavFooter = {
|
|
23
|
+
path: string;
|
|
24
|
+
title: string;
|
|
25
|
+
icon?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
sections?: SideNavSection[];
|
|
30
|
+
footer?: SideNavFooter | undefined;
|
|
31
|
+
titleLabel?: string;
|
|
32
|
+
titleHref?: string;
|
|
33
|
+
currentPath?: string;
|
|
34
|
+
open?: boolean;
|
|
35
|
+
/** Builds the href for a section/item/footer path. Default returns `#${path}`. */
|
|
36
|
+
hrefFor?: (path: string) => string;
|
|
37
|
+
/** Force-hover one part for editor previews. */
|
|
38
|
+
forceHoverPart?: 'title' | 'toggle' | 'item' | 'footer' | 'section' | null;
|
|
39
|
+
/** Force-active one part for editor previews. */
|
|
40
|
+
forceActivePart?: 'title' | 'item' | 'footer' | 'section' | null;
|
|
41
|
+
class?: string;
|
|
42
|
+
/** Toggle callback. Preferred over `on:toggle` from 0.5.0 onward. */
|
|
43
|
+
ontoggle?: () => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let {
|
|
47
|
+
sections = [],
|
|
48
|
+
footer = undefined,
|
|
49
|
+
titleLabel = '',
|
|
50
|
+
titleHref = '#',
|
|
51
|
+
currentPath = '',
|
|
52
|
+
open = true,
|
|
53
|
+
hrefFor,
|
|
54
|
+
forceHoverPart = null,
|
|
55
|
+
forceActivePart = null,
|
|
56
|
+
class: className = '',
|
|
57
|
+
ontoggle,
|
|
58
|
+
}: Props = $props();
|
|
59
|
+
|
|
60
|
+
// Dual-fire bridge — see Button.svelte for the deprecation timeline.
|
|
61
|
+
const dispatch = createEventDispatcher<{ toggle: void }>();
|
|
62
|
+
|
|
63
|
+
let expandedSections: Record<string, boolean> = $state({});
|
|
64
|
+
|
|
65
|
+
// Auto-expand sections that match the current path or contain an active item.
|
|
66
|
+
$effect(() => {
|
|
67
|
+
for (const section of sections) {
|
|
68
|
+
const containsActive = section.items.some((i) => i.path === currentPath);
|
|
69
|
+
if (currentPath === section.path || containsActive) {
|
|
70
|
+
expandedSections[section.path] = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
function toggleSection(path: string) {
|
|
76
|
+
expandedSections[path] = !expandedSections[path];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function fireToggle() {
|
|
80
|
+
ontoggle?.();
|
|
81
|
+
dispatch('toggle');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buildHref(path: string): string {
|
|
85
|
+
return hrefFor ? hrefFor(path) : `#${path}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sectionHref(section: SideNavSection): string | undefined {
|
|
89
|
+
return section.hasIndexPage ? buildHref(section.path) : undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// The first section's first / second items are the canonical preview targets
|
|
93
|
+
// when the editor force-activates or force-hovers an item, so token edits
|
|
94
|
+
// always have a row to paint against.
|
|
95
|
+
let activeItemKey = $derived(() => {
|
|
96
|
+
if (forceActivePart !== 'item') return null;
|
|
97
|
+
const s = sections[0];
|
|
98
|
+
if (!s || s.items.length === 0) return null;
|
|
99
|
+
return s.items[0].path;
|
|
100
|
+
});
|
|
101
|
+
let hoverItemKey = $derived(() => {
|
|
102
|
+
if (forceHoverPart !== 'item') return null;
|
|
103
|
+
const s = sections[0];
|
|
104
|
+
if (!s || s.items.length === 0) return null;
|
|
105
|
+
return (s.items[1] ?? s.items[0]).path;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
let titleActive = $derived(forceActivePart === 'title' || currentPath === '');
|
|
109
|
+
|
|
110
|
+
// When the editor force-activates the "section" part, pick the first section
|
|
111
|
+
// that's a valid route (hasIndexPage) so the active styling has somewhere
|
|
112
|
+
// to land in the preview.
|
|
113
|
+
let activeSectionKey = $derived(() => {
|
|
114
|
+
if (forceActivePart !== 'section') return null;
|
|
115
|
+
const s = sections.find((sec) => sec.hasIndexPage) ?? sections[0];
|
|
116
|
+
return s?.path ?? null;
|
|
117
|
+
});
|
|
118
|
+
let hoverSectionKey = $derived(() => {
|
|
119
|
+
if (forceHoverPart !== 'section') return null;
|
|
120
|
+
const s = sections.find((sec) => sec.hasIndexPage) ?? sections[0];
|
|
121
|
+
return s?.path ?? null;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
function isSectionActive(section: SideNavSection): boolean {
|
|
125
|
+
if (!section.hasIndexPage) return false;
|
|
126
|
+
if (activeSectionKey() === section.path) return true;
|
|
127
|
+
return currentPath === section.path;
|
|
128
|
+
}
|
|
129
|
+
function isSectionHover(section: SideNavSection): boolean {
|
|
130
|
+
return hoverSectionKey() === section.path;
|
|
131
|
+
}
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<aside
|
|
135
|
+
class="sidenavigation {className}"
|
|
136
|
+
class:collapsed={!open}
|
|
137
|
+
class:force-title-hover={forceHoverPart === 'title'}
|
|
138
|
+
class:force-toggle-hover={forceHoverPart === 'toggle'}
|
|
139
|
+
class:force-footer-hover={forceHoverPart === 'footer'}
|
|
140
|
+
class:force-footer-active={forceActivePart === 'footer'}
|
|
141
|
+
>
|
|
142
|
+
<!-- Toggle is a single persistent element. Its `left` position is
|
|
143
|
+
calc'd from the panel-width tokens so it transitions smoothly
|
|
144
|
+
between right-of-title (open) and centre-of-rail (closed) using
|
|
145
|
+
the same duration/easing tokens as the rail width. -->
|
|
146
|
+
<button
|
|
147
|
+
type="button"
|
|
148
|
+
class="sn-toggle"
|
|
149
|
+
onclick={fireToggle}
|
|
150
|
+
aria-label={open ? 'Collapse sidebar' : 'Expand sidebar'}
|
|
151
|
+
aria-expanded={open}
|
|
152
|
+
>
|
|
153
|
+
<i class="fa-solid fa-angles-right" aria-hidden="true"></i>
|
|
154
|
+
</button>
|
|
155
|
+
|
|
156
|
+
{#if open}
|
|
157
|
+
<!-- Open layout. Title bar reserves space for the persistent toggle on
|
|
158
|
+
the right; the menu is locked at the open-width so it can't reflow
|
|
159
|
+
while the rail expands around it. -->
|
|
160
|
+
<header class="sn-title" class:active={titleActive}>
|
|
161
|
+
<a href={titleHref} class="sn-title-label">{titleLabel}</a>
|
|
162
|
+
</header>
|
|
163
|
+
|
|
164
|
+
<div class="sn-menu">
|
|
165
|
+
{#each sections as section (section.path)}
|
|
166
|
+
<div class="sn-section">
|
|
167
|
+
<div
|
|
168
|
+
class="sn-section-header"
|
|
169
|
+
class:active={isSectionActive(section)}
|
|
170
|
+
class:force-hover={isSectionHover(section)}
|
|
171
|
+
>
|
|
172
|
+
<CollapsibleSection
|
|
173
|
+
variant="chromeless"
|
|
174
|
+
label={section.title}
|
|
175
|
+
href={sectionHref(section)}
|
|
176
|
+
expanded={expandedSections[section.path] || false}
|
|
177
|
+
ontoggle={() => toggleSection(section.path)}
|
|
178
|
+
/>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
{#if expandedSections[section.path]}
|
|
182
|
+
<div class="sn-items">
|
|
183
|
+
{#each section.items as item (item.path)}
|
|
184
|
+
<a
|
|
185
|
+
href={buildHref(item.path)}
|
|
186
|
+
class="sn-item"
|
|
187
|
+
class:active={item.path === currentPath || item.path === activeItemKey()}
|
|
188
|
+
class:force-hover={item.path === hoverItemKey()}
|
|
189
|
+
>
|
|
190
|
+
{item.title}
|
|
191
|
+
</a>
|
|
192
|
+
{/each}
|
|
193
|
+
</div>
|
|
194
|
+
{/if}
|
|
195
|
+
</div>
|
|
196
|
+
{/each}
|
|
197
|
+
|
|
198
|
+
{#if footer}
|
|
199
|
+
<a
|
|
200
|
+
href={buildHref(footer.path)}
|
|
201
|
+
class="sn-footer"
|
|
202
|
+
class:active={currentPath === footer.path}
|
|
203
|
+
>
|
|
204
|
+
{#if footer.icon}<i class={footer.icon} aria-hidden="true"></i>{/if}
|
|
205
|
+
<span>{footer.title}</span>
|
|
206
|
+
</a>
|
|
207
|
+
{/if}
|
|
208
|
+
</div>
|
|
209
|
+
{/if}
|
|
210
|
+
</aside>
|
|
211
|
+
|
|
212
|
+
<style lang="scss">
|
|
213
|
+
@use '../styles/padding' as *;
|
|
214
|
+
|
|
215
|
+
:global(:root) {
|
|
216
|
+
/* Panel — outer chrome + layout. No states. */
|
|
217
|
+
--sidenavigation-panel-surface: var(--surface-canvas-lower);
|
|
218
|
+
--sidenavigation-panel-border: var(--border-canvas-faint);
|
|
219
|
+
--sidenavigation-panel-border-width: var(--border-width-1);
|
|
220
|
+
--sidenavigation-panel-padding: var(--space-16);
|
|
221
|
+
--sidenavigation-panel-section-gap: var(--space-4);
|
|
222
|
+
--sidenavigation-panel-item-padding: var(--space-32);
|
|
223
|
+
--sidenavigation-panel-footer-gap: var(--space-16);
|
|
224
|
+
--sidenavigation-panel-open-width: 16rem;
|
|
225
|
+
--sidenavigation-panel-closed-width: 3rem;
|
|
226
|
+
--sidenavigation-open-duration: var(--duration-200);
|
|
227
|
+
--sidenavigation-open-easing: var(--ease-out-quart);
|
|
228
|
+
--sidenavigation-close-duration: var(--duration-150);
|
|
229
|
+
--sidenavigation-close-easing: var(--ease-out-quart);
|
|
230
|
+
|
|
231
|
+
/* Title — default */
|
|
232
|
+
--sidenavigation-title-default-surface: var(--color-transparent);
|
|
233
|
+
--sidenavigation-title-default-border: var(--border-canvas-faint);
|
|
234
|
+
--sidenavigation-title-default-border-width: var(--border-width-1);
|
|
235
|
+
--sidenavigation-title-default-padding: var(--space-12);
|
|
236
|
+
--sidenavigation-title-default-accent: var(--color-transparent);
|
|
237
|
+
--sidenavigation-title-default-accent-width: var(--border-width-3);
|
|
238
|
+
--sidenavigation-title-default-label: var(--text-primary);
|
|
239
|
+
--sidenavigation-title-default-label-font-family: var(--font-display);
|
|
240
|
+
--sidenavigation-title-default-label-font-size: var(--font-size-2xl);
|
|
241
|
+
--sidenavigation-title-default-label-font-weight: var(--font-weight-normal);
|
|
242
|
+
--sidenavigation-title-default-label-line-height: var(--line-height-sm);
|
|
243
|
+
|
|
244
|
+
/* Title — hover */
|
|
245
|
+
--sidenavigation-title-hover-surface: var(--surface-canvas);
|
|
246
|
+
--sidenavigation-title-hover-border: var(--border-canvas-faint);
|
|
247
|
+
--sidenavigation-title-hover-border-width: var(--border-width-1);
|
|
248
|
+
--sidenavigation-title-hover-padding: var(--space-12);
|
|
249
|
+
--sidenavigation-title-hover-accent: var(--color-transparent);
|
|
250
|
+
--sidenavigation-title-hover-accent-width: var(--border-width-3);
|
|
251
|
+
--sidenavigation-title-hover-label: var(--text-primary);
|
|
252
|
+
--sidenavigation-title-hover-label-font-family: var(--font-display);
|
|
253
|
+
--sidenavigation-title-hover-label-font-size: var(--font-size-2xl);
|
|
254
|
+
--sidenavigation-title-hover-label-font-weight: var(--font-weight-normal);
|
|
255
|
+
--sidenavigation-title-hover-label-line-height: var(--line-height-sm);
|
|
256
|
+
|
|
257
|
+
/* Title — active */
|
|
258
|
+
--sidenavigation-title-active-surface: var(--surface-canvas-low);
|
|
259
|
+
--sidenavigation-title-active-border: var(--border-canvas-faint);
|
|
260
|
+
--sidenavigation-title-active-border-width: var(--border-width-1);
|
|
261
|
+
--sidenavigation-title-active-padding: var(--space-12);
|
|
262
|
+
--sidenavigation-title-active-accent: var(--border-brand-medium);
|
|
263
|
+
--sidenavigation-title-active-accent-width: var(--border-width-3);
|
|
264
|
+
--sidenavigation-title-active-label: var(--text-primary);
|
|
265
|
+
--sidenavigation-title-active-label-font-family: var(--font-display);
|
|
266
|
+
--sidenavigation-title-active-label-font-size: var(--font-size-2xl);
|
|
267
|
+
--sidenavigation-title-active-label-font-weight: var(--font-weight-normal);
|
|
268
|
+
--sidenavigation-title-active-label-line-height: var(--line-height-sm);
|
|
269
|
+
|
|
270
|
+
/* Toggle — default */
|
|
271
|
+
--sidenavigation-toggle-default-surface: var(--color-transparent);
|
|
272
|
+
--sidenavigation-toggle-default-border: var(--border-brand-medium);
|
|
273
|
+
--sidenavigation-toggle-default-border-width: var(--border-width-1);
|
|
274
|
+
--sidenavigation-toggle-default-radius: var(--radius-md);
|
|
275
|
+
--sidenavigation-toggle-default-padding: var(--space-8);
|
|
276
|
+
--sidenavigation-toggle-default-icon: var(--text-primary);
|
|
277
|
+
--sidenavigation-toggle-default-icon-size: var(--icon-size-md);
|
|
278
|
+
|
|
279
|
+
/* Toggle — hover */
|
|
280
|
+
--sidenavigation-toggle-hover-surface: var(--surface-brand-lowest);
|
|
281
|
+
--sidenavigation-toggle-hover-border: var(--border-brand);
|
|
282
|
+
--sidenavigation-toggle-hover-border-width: var(--border-width-1);
|
|
283
|
+
--sidenavigation-toggle-hover-radius: var(--radius-md);
|
|
284
|
+
--sidenavigation-toggle-hover-padding: var(--space-8);
|
|
285
|
+
--sidenavigation-toggle-hover-icon: var(--text-brand);
|
|
286
|
+
--sidenavigation-toggle-hover-icon-size: var(--icon-size-md);
|
|
287
|
+
|
|
288
|
+
/* Section header — default. The wrapper paints surface + indicator; the
|
|
289
|
+
text tokens below are forwarded into the inner CollapsibleSection
|
|
290
|
+
(chromeless variant) by shadowing its slots in `.sn-section-header`,
|
|
291
|
+
so section typography can be edited per-state without touching the
|
|
292
|
+
generic chromeless variant used elsewhere. */
|
|
293
|
+
--sidenavigation-section-default-surface: var(--color-transparent);
|
|
294
|
+
--sidenavigation-section-default-accent: var(--color-transparent);
|
|
295
|
+
--sidenavigation-section-default-accent-width: var(--border-width-3);
|
|
296
|
+
--sidenavigation-section-default-text: var(--text-primary);
|
|
297
|
+
--sidenavigation-section-default-text-font-family: var(--font-sans);
|
|
298
|
+
--sidenavigation-section-default-text-font-size: var(--font-size-md);
|
|
299
|
+
--sidenavigation-section-default-text-font-weight: var(--font-weight-normal);
|
|
300
|
+
--sidenavigation-section-default-text-line-height: var(--line-height-md);
|
|
301
|
+
|
|
302
|
+
/* Section header — hover */
|
|
303
|
+
--sidenavigation-section-hover-surface: var(--surface-canvas);
|
|
304
|
+
--sidenavigation-section-hover-accent: var(--color-transparent);
|
|
305
|
+
--sidenavigation-section-hover-accent-width: var(--border-width-3);
|
|
306
|
+
--sidenavigation-section-hover-text: var(--text-primary);
|
|
307
|
+
--sidenavigation-section-hover-text-font-family: var(--font-sans);
|
|
308
|
+
--sidenavigation-section-hover-text-font-size: var(--font-size-md);
|
|
309
|
+
--sidenavigation-section-hover-text-font-weight: var(--font-weight-normal);
|
|
310
|
+
--sidenavigation-section-hover-text-line-height: var(--line-height-md);
|
|
311
|
+
|
|
312
|
+
/* Section header — active (this section's page is the current route) */
|
|
313
|
+
--sidenavigation-section-active-surface: var(--surface-canvas-low);
|
|
314
|
+
--sidenavigation-section-active-accent: var(--border-brand-medium);
|
|
315
|
+
--sidenavigation-section-active-accent-width: var(--border-width-3);
|
|
316
|
+
--sidenavigation-section-active-text: var(--text-primary);
|
|
317
|
+
--sidenavigation-section-active-text-font-family: var(--font-sans);
|
|
318
|
+
--sidenavigation-section-active-text-font-size: var(--font-size-md);
|
|
319
|
+
--sidenavigation-section-active-text-font-weight: var(--font-weight-normal);
|
|
320
|
+
--sidenavigation-section-active-text-line-height: var(--line-height-md);
|
|
321
|
+
|
|
322
|
+
/* Item — default */
|
|
323
|
+
--sidenavigation-item-default-surface: var(--color-transparent);
|
|
324
|
+
--sidenavigation-item-default-padding: var(--space-6);
|
|
325
|
+
--sidenavigation-item-default-accent: var(--color-transparent);
|
|
326
|
+
--sidenavigation-item-default-accent-width: var(--border-width-3);
|
|
327
|
+
--sidenavigation-item-default-text: var(--text-tertiary);
|
|
328
|
+
--sidenavigation-item-default-text-font-family: var(--font-sans);
|
|
329
|
+
--sidenavigation-item-default-text-font-size: var(--font-size-sm);
|
|
330
|
+
--sidenavigation-item-default-text-font-weight: var(--font-weight-light);
|
|
331
|
+
--sidenavigation-item-default-text-line-height: var(--line-height-md);
|
|
332
|
+
|
|
333
|
+
/* Item — hover */
|
|
334
|
+
--sidenavigation-item-hover-surface: var(--surface-canvas);
|
|
335
|
+
--sidenavigation-item-hover-padding: var(--space-6);
|
|
336
|
+
--sidenavigation-item-hover-accent: var(--color-transparent);
|
|
337
|
+
--sidenavigation-item-hover-accent-width: var(--border-width-3);
|
|
338
|
+
--sidenavigation-item-hover-text: var(--text-secondary);
|
|
339
|
+
--sidenavigation-item-hover-text-font-family: var(--font-sans);
|
|
340
|
+
--sidenavigation-item-hover-text-font-size: var(--font-size-sm);
|
|
341
|
+
--sidenavigation-item-hover-text-font-weight: var(--font-weight-light);
|
|
342
|
+
--sidenavigation-item-hover-text-line-height: var(--line-height-md);
|
|
343
|
+
|
|
344
|
+
/* Item — active */
|
|
345
|
+
--sidenavigation-item-active-surface: var(--surface-canvas-low);
|
|
346
|
+
--sidenavigation-item-active-padding: var(--space-6);
|
|
347
|
+
--sidenavigation-item-active-accent: var(--border-brand-medium);
|
|
348
|
+
--sidenavigation-item-active-accent-width: var(--border-width-3);
|
|
349
|
+
--sidenavigation-item-active-text: var(--text-primary);
|
|
350
|
+
--sidenavigation-item-active-text-font-family: var(--font-sans);
|
|
351
|
+
--sidenavigation-item-active-text-font-size: var(--font-size-sm);
|
|
352
|
+
--sidenavigation-item-active-text-font-weight: var(--font-weight-normal);
|
|
353
|
+
--sidenavigation-item-active-text-line-height: var(--line-height-md);
|
|
354
|
+
|
|
355
|
+
/* Footer — default */
|
|
356
|
+
--sidenavigation-footer-default-surface: var(--color-transparent);
|
|
357
|
+
--sidenavigation-footer-default-padding: var(--space-8);
|
|
358
|
+
--sidenavigation-footer-default-gap: var(--space-8);
|
|
359
|
+
--sidenavigation-footer-default-accent: var(--color-transparent);
|
|
360
|
+
--sidenavigation-footer-default-accent-width: var(--border-width-3);
|
|
361
|
+
--sidenavigation-footer-default-icon: var(--text-muted);
|
|
362
|
+
--sidenavigation-footer-default-icon-size: var(--icon-size-xs);
|
|
363
|
+
--sidenavigation-footer-default-text: var(--text-tertiary);
|
|
364
|
+
--sidenavigation-footer-default-text-font-family: var(--font-sans);
|
|
365
|
+
--sidenavigation-footer-default-text-font-size: var(--font-size-sm);
|
|
366
|
+
--sidenavigation-footer-default-text-font-weight: var(--font-weight-light);
|
|
367
|
+
--sidenavigation-footer-default-text-line-height: var(--line-height-md);
|
|
368
|
+
|
|
369
|
+
/* Footer — hover */
|
|
370
|
+
--sidenavigation-footer-hover-surface: var(--surface-canvas);
|
|
371
|
+
--sidenavigation-footer-hover-padding: var(--space-8);
|
|
372
|
+
--sidenavigation-footer-hover-gap: var(--space-8);
|
|
373
|
+
--sidenavigation-footer-hover-accent: var(--color-transparent);
|
|
374
|
+
--sidenavigation-footer-hover-accent-width: var(--border-width-3);
|
|
375
|
+
--sidenavigation-footer-hover-icon: var(--text-secondary);
|
|
376
|
+
--sidenavigation-footer-hover-icon-size: var(--icon-size-xs);
|
|
377
|
+
--sidenavigation-footer-hover-text: var(--text-secondary);
|
|
378
|
+
--sidenavigation-footer-hover-text-font-family: var(--font-sans);
|
|
379
|
+
--sidenavigation-footer-hover-text-font-size: var(--font-size-sm);
|
|
380
|
+
--sidenavigation-footer-hover-text-font-weight: var(--font-weight-light);
|
|
381
|
+
--sidenavigation-footer-hover-text-line-height: var(--line-height-md);
|
|
382
|
+
|
|
383
|
+
/* Footer — active */
|
|
384
|
+
--sidenavigation-footer-active-surface: var(--surface-canvas-low);
|
|
385
|
+
--sidenavigation-footer-active-padding: var(--space-8);
|
|
386
|
+
--sidenavigation-footer-active-gap: var(--space-8);
|
|
387
|
+
--sidenavigation-footer-active-accent: var(--border-brand-medium);
|
|
388
|
+
--sidenavigation-footer-active-accent-width: var(--border-width-3);
|
|
389
|
+
--sidenavigation-footer-active-icon: var(--text-primary);
|
|
390
|
+
--sidenavigation-footer-active-icon-size: var(--icon-size-xs);
|
|
391
|
+
--sidenavigation-footer-active-text: var(--text-primary);
|
|
392
|
+
--sidenavigation-footer-active-text-font-family: var(--font-sans);
|
|
393
|
+
--sidenavigation-footer-active-text-font-size: var(--font-size-sm);
|
|
394
|
+
--sidenavigation-footer-active-text-font-weight: var(--font-weight-normal);
|
|
395
|
+
--sidenavigation-footer-active-text-line-height: var(--line-height-md);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.sidenavigation {
|
|
399
|
+
display: flex;
|
|
400
|
+
flex-direction: column;
|
|
401
|
+
overflow: hidden;
|
|
402
|
+
background: var(--sidenavigation-panel-surface);
|
|
403
|
+
border-right: var(--sidenavigation-panel-border-width) solid var(--sidenavigation-panel-border);
|
|
404
|
+
@include themed-padding(--sidenavigation-panel-padding, $h: 0);
|
|
405
|
+
scrollbar-width: thin;
|
|
406
|
+
width: var(--sidenavigation-panel-open-width);
|
|
407
|
+
/* Opening uses the open-* timing tokens; the .collapsed rule below
|
|
408
|
+
overrides with the close-* tokens for the reverse direction. */
|
|
409
|
+
transition: width var(--sidenavigation-open-duration) var(--sidenavigation-open-easing);
|
|
410
|
+
}
|
|
411
|
+
.sidenavigation.collapsed {
|
|
412
|
+
width: var(--sidenavigation-panel-closed-width);
|
|
413
|
+
transition: width var(--sidenavigation-close-duration) var(--sidenavigation-close-easing);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* The .sidenavigation needs to be the positioning context for the
|
|
417
|
+
absolutely-anchored toggle. Set on the outer aside so the toggle's
|
|
418
|
+
`left` calc is relative to the rail's left edge. */
|
|
419
|
+
.sidenavigation {
|
|
420
|
+
position: relative;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/* Per-state token rebinds — layout-affecting properties are written exactly
|
|
424
|
+
once on the element, then state rules rebind only the `--_*` values they
|
|
425
|
+
need. Matches the TabBar pattern: paint-only repaint, no reshape. */
|
|
426
|
+
.sn-title {
|
|
427
|
+
--_surface: var(--sidenavigation-title-default-surface);
|
|
428
|
+
--_border: var(--sidenavigation-title-default-border);
|
|
429
|
+
--_border-width: var(--sidenavigation-title-default-border-width);
|
|
430
|
+
--_padding: var(--sidenavigation-title-default-padding);
|
|
431
|
+
--_indicator: var(--sidenavigation-title-default-accent);
|
|
432
|
+
--_indicator-width: var(--sidenavigation-title-default-accent-width);
|
|
433
|
+
--_label: var(--sidenavigation-title-default-label);
|
|
434
|
+
--_label-family: var(--sidenavigation-title-default-label-font-family);
|
|
435
|
+
--_label-size: var(--sidenavigation-title-default-label-font-size);
|
|
436
|
+
--_label-weight: var(--sidenavigation-title-default-label-font-weight);
|
|
437
|
+
--_label-line-height: var(--sidenavigation-title-default-label-line-height);
|
|
438
|
+
|
|
439
|
+
/* Positioning context for the absolutely-anchored toggle button. */
|
|
440
|
+
position: relative;
|
|
441
|
+
flex: 0 0 auto;
|
|
442
|
+
/* Lock to the open-width so the title doesn't reflow during the rail
|
|
443
|
+
expansion (3rem → 16rem on open). border-box keeps the outer width
|
|
444
|
+
equal to the token value (otherwise padding + border would push the
|
|
445
|
+
toggle past the rail's right edge). */
|
|
446
|
+
box-sizing: border-box;
|
|
447
|
+
width: var(--sidenavigation-panel-open-width);
|
|
448
|
+
display: flex;
|
|
449
|
+
align-items: center;
|
|
450
|
+
gap: var(--space-12);
|
|
451
|
+
background: var(--_surface);
|
|
452
|
+
border-bottom: var(--_border-width) solid var(--_border);
|
|
453
|
+
border-left: var(--_indicator-width) solid var(--_indicator);
|
|
454
|
+
@include themed-padding(--_padding);
|
|
455
|
+
/* Right padding clears the absolutely-positioned toggle inside this
|
|
456
|
+
header (toggle width ~36px + 8px breathing room). */
|
|
457
|
+
padding-right: calc(var(--space-12) + 44px);
|
|
458
|
+
transition: background var(--duration-150), border-color var(--duration-150);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.sn-title:hover:not(.active),
|
|
462
|
+
.sidenavigation.force-title-hover .sn-title:not(.active) {
|
|
463
|
+
--_surface: var(--sidenavigation-title-hover-surface);
|
|
464
|
+
--_border: var(--sidenavigation-title-hover-border);
|
|
465
|
+
--_border-width: var(--sidenavigation-title-hover-border-width);
|
|
466
|
+
--_padding: var(--sidenavigation-title-hover-padding);
|
|
467
|
+
--_indicator: var(--sidenavigation-title-hover-accent);
|
|
468
|
+
--_indicator-width: var(--sidenavigation-title-hover-accent-width);
|
|
469
|
+
--_label: var(--sidenavigation-title-hover-label);
|
|
470
|
+
--_label-family: var(--sidenavigation-title-hover-label-font-family);
|
|
471
|
+
--_label-size: var(--sidenavigation-title-hover-label-font-size);
|
|
472
|
+
--_label-weight: var(--sidenavigation-title-hover-label-font-weight);
|
|
473
|
+
--_label-line-height: var(--sidenavigation-title-hover-label-line-height);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.sn-title.active {
|
|
477
|
+
--_surface: var(--sidenavigation-title-active-surface);
|
|
478
|
+
--_border: var(--sidenavigation-title-active-border);
|
|
479
|
+
--_border-width: var(--sidenavigation-title-active-border-width);
|
|
480
|
+
--_padding: var(--sidenavigation-title-active-padding);
|
|
481
|
+
--_indicator: var(--sidenavigation-title-active-accent);
|
|
482
|
+
--_indicator-width: var(--sidenavigation-title-active-accent-width);
|
|
483
|
+
--_label: var(--sidenavigation-title-active-label);
|
|
484
|
+
--_label-family: var(--sidenavigation-title-active-label-font-family);
|
|
485
|
+
--_label-size: var(--sidenavigation-title-active-label-font-size);
|
|
486
|
+
--_label-weight: var(--sidenavigation-title-active-label-font-weight);
|
|
487
|
+
--_label-line-height: var(--sidenavigation-title-active-label-line-height);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.sn-title-label {
|
|
491
|
+
color: var(--_label);
|
|
492
|
+
font-family: var(--_label-family);
|
|
493
|
+
font-size: var(--_label-size);
|
|
494
|
+
font-weight: var(--_label-weight);
|
|
495
|
+
line-height: var(--_label-line-height);
|
|
496
|
+
text-decoration: none;
|
|
497
|
+
flex: 1 1 auto;
|
|
498
|
+
min-width: 0;
|
|
499
|
+
white-space: nowrap;
|
|
500
|
+
overflow: hidden;
|
|
501
|
+
text-overflow: clip;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.sn-toggle {
|
|
505
|
+
--_surface: var(--sidenavigation-toggle-default-surface);
|
|
506
|
+
--_border: var(--sidenavigation-toggle-default-border);
|
|
507
|
+
--_border-width: var(--sidenavigation-toggle-default-border-width);
|
|
508
|
+
--_radius: var(--sidenavigation-toggle-default-radius);
|
|
509
|
+
--_padding: var(--sidenavigation-toggle-default-padding);
|
|
510
|
+
--_icon: var(--sidenavigation-toggle-default-icon);
|
|
511
|
+
--_icon-size: var(--sidenavigation-toggle-default-icon-size);
|
|
512
|
+
|
|
513
|
+
/* Persistent element anchored to the panel (not the title). Open-state
|
|
514
|
+
`left` puts it near the right edge of the open-width title; collapsed
|
|
515
|
+
`left` centres it in the closed-width rail. Both calc'd from the
|
|
516
|
+
same width tokens so they stay in sync if the consumer overrides. */
|
|
517
|
+
position: absolute;
|
|
518
|
+
/* Toggle's outer width is derived from its constituent tokens — icon
|
|
519
|
+
+ padding (both sides) + border (both sides). Stays accurate when a
|
|
520
|
+
consumer customizes any of those without re-hardcoding here. */
|
|
521
|
+
--_toggle-width: calc(
|
|
522
|
+
var(--sidenavigation-toggle-default-icon-size)
|
|
523
|
+
+ 2 * var(--sidenavigation-toggle-default-padding)
|
|
524
|
+
+ 2 * var(--sidenavigation-toggle-default-border-width)
|
|
525
|
+
);
|
|
526
|
+
top: var(--space-12);
|
|
527
|
+
left: calc(var(--sidenavigation-panel-open-width) - var(--_toggle-width) - var(--space-8));
|
|
528
|
+
z-index: 1;
|
|
529
|
+
transition:
|
|
530
|
+
left var(--sidenavigation-open-duration) var(--sidenavigation-open-easing),
|
|
531
|
+
background var(--duration-150),
|
|
532
|
+
border-color var(--duration-150),
|
|
533
|
+
color var(--duration-150);
|
|
534
|
+
|
|
535
|
+
display: inline-flex;
|
|
536
|
+
align-items: center;
|
|
537
|
+
justify-content: center;
|
|
538
|
+
flex-shrink: 0;
|
|
539
|
+
background: var(--_surface);
|
|
540
|
+
border: var(--_border-width) solid var(--_border);
|
|
541
|
+
border-radius: var(--_radius);
|
|
542
|
+
color: var(--_icon);
|
|
543
|
+
@include themed-padding(--_padding);
|
|
544
|
+
cursor: pointer;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.sn-toggle i {
|
|
548
|
+
font-size: var(--_icon-size);
|
|
549
|
+
line-height: 1;
|
|
550
|
+
/* Icon points right by default (expand). Open state flips it to point
|
|
551
|
+
left (collapse). Rotation tweens with the position so the affordance
|
|
552
|
+
morphs smoothly between the two states. */
|
|
553
|
+
transition: transform var(--sidenavigation-open-duration) var(--sidenavigation-open-easing);
|
|
554
|
+
}
|
|
555
|
+
.sidenavigation:not(.collapsed) .sn-toggle i {
|
|
556
|
+
transform: rotate(180deg);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/* Collapsed: centre the toggle in the rail, and swap to close-* timing
|
|
560
|
+
tokens so the leftward slide matches the rail's shrink. */
|
|
561
|
+
.sidenavigation.collapsed .sn-toggle {
|
|
562
|
+
left: calc((var(--sidenavigation-panel-closed-width) - var(--_toggle-width)) / 2);
|
|
563
|
+
transition:
|
|
564
|
+
left var(--sidenavigation-close-duration) var(--sidenavigation-close-easing),
|
|
565
|
+
background var(--duration-150),
|
|
566
|
+
border-color var(--duration-150),
|
|
567
|
+
color var(--duration-150);
|
|
568
|
+
}
|
|
569
|
+
.sidenavigation.collapsed .sn-toggle i {
|
|
570
|
+
transition: transform var(--sidenavigation-close-duration) var(--sidenavigation-close-easing);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.sn-toggle:hover,
|
|
574
|
+
.sidenavigation.force-toggle-hover .sn-toggle {
|
|
575
|
+
--_surface: var(--sidenavigation-toggle-hover-surface);
|
|
576
|
+
--_border: var(--sidenavigation-toggle-hover-border);
|
|
577
|
+
--_border-width: var(--sidenavigation-toggle-hover-border-width);
|
|
578
|
+
--_radius: var(--sidenavigation-toggle-hover-radius);
|
|
579
|
+
--_padding: var(--sidenavigation-toggle-hover-padding);
|
|
580
|
+
--_icon: var(--sidenavigation-toggle-hover-icon);
|
|
581
|
+
--_icon-size: var(--sidenavigation-toggle-hover-icon-size);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/* Menu wraps everything below the title header. Scroll lives here so the
|
|
585
|
+
title (with its toggle) stays pinned while a tall menu list scrolls.
|
|
586
|
+
Locked to the open-width (matching .sn-title) so the menu's intrinsic
|
|
587
|
+
layout doesn't shift as the rail expands on open — items can't wrap
|
|
588
|
+
and re-flow if their container width never changes. The rail's
|
|
589
|
+
`overflow: hidden` clips them on the right until the rail catches up. */
|
|
590
|
+
.sn-menu {
|
|
591
|
+
flex: 1 1 auto;
|
|
592
|
+
box-sizing: border-box;
|
|
593
|
+
width: var(--sidenavigation-panel-open-width);
|
|
594
|
+
overflow-y: auto;
|
|
595
|
+
overflow-x: hidden;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.sn-section {
|
|
599
|
+
margin-top: var(--sidenavigation-panel-section-gap);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/* Section header wrapper. Paints background + left indicator around the
|
|
603
|
+
CollapsibleSection so a section that's also a route can show an active
|
|
604
|
+
state matching the panel's item/footer treatment. Section text tokens
|
|
605
|
+
are forwarded into the inner CollapsibleSection by shadowing its
|
|
606
|
+
chromeless slots — section typography can then be edited per-state
|
|
607
|
+
without touching the generic chromeless variant. */
|
|
608
|
+
.sn-section-header {
|
|
609
|
+
--_surface: var(--sidenavigation-section-default-surface);
|
|
610
|
+
--_indicator: var(--sidenavigation-section-default-accent);
|
|
611
|
+
--_indicator-width: var(--sidenavigation-section-default-accent-width);
|
|
612
|
+
|
|
613
|
+
--collapsiblesection-chromeless-default-label: var(--sidenavigation-section-default-text);
|
|
614
|
+
--collapsiblesection-chromeless-default-label-font-family: var(--sidenavigation-section-default-text-font-family);
|
|
615
|
+
--collapsiblesection-chromeless-default-label-font-size: var(--sidenavigation-section-default-text-font-size);
|
|
616
|
+
--collapsiblesection-chromeless-default-label-font-weight: var(--sidenavigation-section-default-text-font-weight);
|
|
617
|
+
--collapsiblesection-chromeless-default-label-line-height: var(--sidenavigation-section-default-text-line-height);
|
|
618
|
+
--collapsiblesection-chromeless-hover-label: var(--sidenavigation-section-hover-text);
|
|
619
|
+
--collapsiblesection-chromeless-hover-label-font-family: var(--sidenavigation-section-hover-text-font-family);
|
|
620
|
+
--collapsiblesection-chromeless-hover-label-font-size: var(--sidenavigation-section-hover-text-font-size);
|
|
621
|
+
--collapsiblesection-chromeless-hover-label-font-weight: var(--sidenavigation-section-hover-text-font-weight);
|
|
622
|
+
--collapsiblesection-chromeless-hover-label-line-height: var(--sidenavigation-section-hover-text-line-height);
|
|
623
|
+
|
|
624
|
+
background: var(--_surface);
|
|
625
|
+
border-left: var(--_indicator-width) solid var(--_indicator);
|
|
626
|
+
transition: background var(--duration-150), border-color var(--duration-150);
|
|
627
|
+
}
|
|
628
|
+
.sn-section-header:hover:not(.active),
|
|
629
|
+
.sn-section-header.force-hover:not(.active) {
|
|
630
|
+
--_surface: var(--sidenavigation-section-hover-surface);
|
|
631
|
+
--_indicator: var(--sidenavigation-section-hover-accent);
|
|
632
|
+
--_indicator-width: var(--sidenavigation-section-hover-accent-width);
|
|
633
|
+
}
|
|
634
|
+
.sn-section-header.active {
|
|
635
|
+
--_surface: var(--sidenavigation-section-active-surface);
|
|
636
|
+
--_indicator: var(--sidenavigation-section-active-accent);
|
|
637
|
+
--_indicator-width: var(--sidenavigation-section-active-accent-width);
|
|
638
|
+
|
|
639
|
+
/* Inner CollapsibleSection has no "active" state — shadow both the
|
|
640
|
+
default-slot and hover-slot with the active text values so the section
|
|
641
|
+
header keeps painting active typography whether or not it's hovered. */
|
|
642
|
+
--collapsiblesection-chromeless-default-label: var(--sidenavigation-section-active-text);
|
|
643
|
+
--collapsiblesection-chromeless-default-label-font-family: var(--sidenavigation-section-active-text-font-family);
|
|
644
|
+
--collapsiblesection-chromeless-default-label-font-size: var(--sidenavigation-section-active-text-font-size);
|
|
645
|
+
--collapsiblesection-chromeless-default-label-font-weight: var(--sidenavigation-section-active-text-font-weight);
|
|
646
|
+
--collapsiblesection-chromeless-default-label-line-height: var(--sidenavigation-section-active-text-line-height);
|
|
647
|
+
--collapsiblesection-chromeless-hover-label: var(--sidenavigation-section-active-text);
|
|
648
|
+
--collapsiblesection-chromeless-hover-label-font-family: var(--sidenavigation-section-active-text-font-family);
|
|
649
|
+
--collapsiblesection-chromeless-hover-label-font-size: var(--sidenavigation-section-active-text-font-size);
|
|
650
|
+
--collapsiblesection-chromeless-hover-label-font-weight: var(--sidenavigation-section-active-text-font-weight);
|
|
651
|
+
--collapsiblesection-chromeless-hover-label-line-height: var(--sidenavigation-section-active-text-line-height);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.sn-items {
|
|
655
|
+
display: flex;
|
|
656
|
+
flex-direction: column;
|
|
657
|
+
padding: var(--space-4) 0;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
.sn-item {
|
|
661
|
+
--_surface: var(--sidenavigation-item-default-surface);
|
|
662
|
+
--_padding: var(--sidenavigation-item-default-padding);
|
|
663
|
+
--_indicator: var(--sidenavigation-item-default-accent);
|
|
664
|
+
--_indicator-width: var(--sidenavigation-item-default-accent-width);
|
|
665
|
+
--_text: var(--sidenavigation-item-default-text);
|
|
666
|
+
--_text-family: var(--sidenavigation-item-default-text-font-family);
|
|
667
|
+
--_text-size: var(--sidenavigation-item-default-text-font-size);
|
|
668
|
+
--_text-weight: var(--sidenavigation-item-default-text-font-weight);
|
|
669
|
+
--_text-line-height: var(--sidenavigation-item-default-text-line-height);
|
|
670
|
+
|
|
671
|
+
display: block;
|
|
672
|
+
background: var(--_surface);
|
|
673
|
+
border-left: var(--_indicator-width) solid var(--_indicator);
|
|
674
|
+
@include themed-padding(--_padding);
|
|
675
|
+
padding-left: var(--sidenavigation-panel-item-padding);
|
|
676
|
+
color: var(--_text);
|
|
677
|
+
font-family: var(--_text-family);
|
|
678
|
+
font-size: var(--_text-size);
|
|
679
|
+
font-weight: var(--_text-weight);
|
|
680
|
+
line-height: var(--_text-line-height);
|
|
681
|
+
text-decoration: none;
|
|
682
|
+
transition: background var(--duration-150), color var(--duration-150);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.sn-item:hover:not(.active),
|
|
686
|
+
.sn-item.force-hover:not(.active) {
|
|
687
|
+
--_surface: var(--sidenavigation-item-hover-surface);
|
|
688
|
+
--_padding: var(--sidenavigation-item-hover-padding);
|
|
689
|
+
--_indicator: var(--sidenavigation-item-hover-accent);
|
|
690
|
+
--_indicator-width: var(--sidenavigation-item-hover-accent-width);
|
|
691
|
+
--_text: var(--sidenavigation-item-hover-text);
|
|
692
|
+
--_text-family: var(--sidenavigation-item-hover-text-font-family);
|
|
693
|
+
--_text-size: var(--sidenavigation-item-hover-text-font-size);
|
|
694
|
+
--_text-weight: var(--sidenavigation-item-hover-text-font-weight);
|
|
695
|
+
--_text-line-height: var(--sidenavigation-item-hover-text-line-height);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.sn-item.active {
|
|
699
|
+
--_surface: var(--sidenavigation-item-active-surface);
|
|
700
|
+
--_padding: var(--sidenavigation-item-active-padding);
|
|
701
|
+
--_indicator: var(--sidenavigation-item-active-accent);
|
|
702
|
+
--_indicator-width: var(--sidenavigation-item-active-accent-width);
|
|
703
|
+
--_text: var(--sidenavigation-item-active-text);
|
|
704
|
+
--_text-family: var(--sidenavigation-item-active-text-font-family);
|
|
705
|
+
--_text-size: var(--sidenavigation-item-active-text-font-size);
|
|
706
|
+
--_text-weight: var(--sidenavigation-item-active-text-font-weight);
|
|
707
|
+
--_text-line-height: var(--sidenavigation-item-active-text-line-height);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.sn-footer {
|
|
711
|
+
--_surface: var(--sidenavigation-footer-default-surface);
|
|
712
|
+
--_padding: var(--sidenavigation-footer-default-padding);
|
|
713
|
+
--_gap: var(--sidenavigation-footer-default-gap);
|
|
714
|
+
--_indicator: var(--sidenavigation-footer-default-accent);
|
|
715
|
+
--_indicator-width: var(--sidenavigation-footer-default-accent-width);
|
|
716
|
+
--_icon: var(--sidenavigation-footer-default-icon);
|
|
717
|
+
--_icon-size: var(--sidenavigation-footer-default-icon-size);
|
|
718
|
+
--_text: var(--sidenavigation-footer-default-text);
|
|
719
|
+
--_text-family: var(--sidenavigation-footer-default-text-font-family);
|
|
720
|
+
--_text-size: var(--sidenavigation-footer-default-text-font-size);
|
|
721
|
+
--_text-weight: var(--sidenavigation-footer-default-text-font-weight);
|
|
722
|
+
--_text-line-height: var(--sidenavigation-footer-default-text-line-height);
|
|
723
|
+
|
|
724
|
+
display: flex;
|
|
725
|
+
align-items: center;
|
|
726
|
+
gap: var(--_gap);
|
|
727
|
+
margin-top: var(--sidenavigation-panel-footer-gap);
|
|
728
|
+
background: var(--_surface);
|
|
729
|
+
border-left: var(--_indicator-width) solid var(--_indicator);
|
|
730
|
+
@include themed-padding(--_padding);
|
|
731
|
+
color: var(--_text);
|
|
732
|
+
font-family: var(--_text-family);
|
|
733
|
+
font-size: var(--_text-size);
|
|
734
|
+
font-weight: var(--_text-weight);
|
|
735
|
+
line-height: var(--_text-line-height);
|
|
736
|
+
text-decoration: none;
|
|
737
|
+
transition: background var(--duration-150), color var(--duration-150);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.sn-footer i {
|
|
741
|
+
color: var(--_icon);
|
|
742
|
+
font-size: var(--_icon-size);
|
|
743
|
+
line-height: 1;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.sn-footer:hover:not(.active),
|
|
747
|
+
.sidenavigation.force-footer-hover .sn-footer:not(.active) {
|
|
748
|
+
--_surface: var(--sidenavigation-footer-hover-surface);
|
|
749
|
+
--_padding: var(--sidenavigation-footer-hover-padding);
|
|
750
|
+
--_gap: var(--sidenavigation-footer-hover-gap);
|
|
751
|
+
--_indicator: var(--sidenavigation-footer-hover-accent);
|
|
752
|
+
--_indicator-width: var(--sidenavigation-footer-hover-accent-width);
|
|
753
|
+
--_icon: var(--sidenavigation-footer-hover-icon);
|
|
754
|
+
--_icon-size: var(--sidenavigation-footer-hover-icon-size);
|
|
755
|
+
--_text: var(--sidenavigation-footer-hover-text);
|
|
756
|
+
--_text-family: var(--sidenavigation-footer-hover-text-font-family);
|
|
757
|
+
--_text-size: var(--sidenavigation-footer-hover-text-font-size);
|
|
758
|
+
--_text-weight: var(--sidenavigation-footer-hover-text-font-weight);
|
|
759
|
+
--_text-line-height: var(--sidenavigation-footer-hover-text-line-height);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
.sn-footer.active,
|
|
763
|
+
.sidenavigation.force-footer-active .sn-footer {
|
|
764
|
+
--_surface: var(--sidenavigation-footer-active-surface);
|
|
765
|
+
--_padding: var(--sidenavigation-footer-active-padding);
|
|
766
|
+
--_gap: var(--sidenavigation-footer-active-gap);
|
|
767
|
+
--_indicator: var(--sidenavigation-footer-active-accent);
|
|
768
|
+
--_indicator-width: var(--sidenavigation-footer-active-accent-width);
|
|
769
|
+
--_icon: var(--sidenavigation-footer-active-icon);
|
|
770
|
+
--_icon-size: var(--sidenavigation-footer-active-icon-size);
|
|
771
|
+
--_text: var(--sidenavigation-footer-active-text);
|
|
772
|
+
--_text-family: var(--sidenavigation-footer-active-text-font-family);
|
|
773
|
+
--_text-size: var(--sidenavigation-footer-active-text-font-size);
|
|
774
|
+
--_text-weight: var(--sidenavigation-footer-active-text-font-weight);
|
|
775
|
+
--_text-line-height: var(--sidenavigation-footer-active-text-line-height);
|
|
776
|
+
}
|
|
777
|
+
</style>
|