@leavepulse/ui 0.12.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/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/component-names.d.ts +1 -0
- package/dist/components/LayoutCanvas.vue.d.ts +28 -0
- package/dist/components/LayoutNode.vue.d.ts +40 -0
- package/dist/components/LpAlert.vue.d.ts +44 -0
- package/dist/components/LpAppShell.vue.d.ts +83 -0
- package/dist/components/LpAutocomplete.vue.d.ts +50 -0
- package/dist/components/LpAvatar.vue.d.ts +20 -0
- package/dist/components/LpBadge.vue.d.ts +47 -0
- package/dist/components/LpBreadcrumbs.vue.d.ts +14 -0
- package/dist/components/LpButton.vue.d.ts +113 -0
- package/dist/components/LpCalendar.vue.d.ts +20 -0
- package/dist/components/LpCard.vue.d.ts +29 -0
- package/dist/components/LpCheckbox.vue.d.ts +28 -0
- package/dist/components/LpCodeBlock.vue.d.ts +39 -0
- package/dist/components/LpCommandPalette.vue.d.ts +42 -0
- package/dist/components/LpConfirmDialog.vue.d.ts +32 -0
- package/dist/components/LpContextMenu.vue.d.ts +30 -0
- package/dist/components/LpDatePicker.vue.d.ts +25 -0
- package/dist/components/LpDisclosure.vue.d.ts +37 -0
- package/dist/components/LpDivider.vue.d.ts +17 -0
- package/dist/components/LpDrawer.vue.d.ts +88 -0
- package/dist/components/LpDropdownMenu.vue.d.ts +23 -0
- package/dist/components/LpEmptyState.vue.d.ts +18 -0
- package/dist/components/LpFormField.vue.d.ts +21 -0
- package/dist/components/LpIcon.vue.d.ts +8 -0
- package/dist/components/LpInfraNode.vue.d.ts +21 -0
- package/dist/components/LpInput.vue.d.ts +68 -0
- package/dist/components/LpLaneNode.vue.d.ts +24 -0
- package/dist/components/LpLink.vue.d.ts +27 -0
- package/dist/components/LpLogViewer.vue.d.ts +92 -0
- package/dist/components/LpModal.vue.d.ts +43 -0
- package/dist/components/LpNotificationBell.vue.d.ts +51 -0
- package/dist/components/LpNumberField.vue.d.ts +14 -0
- package/dist/components/LpOtpInput.vue.d.ts +27 -0
- package/dist/components/LpPagination.vue.d.ts +25 -0
- package/dist/components/LpPasswordInput.vue.d.ts +28 -0
- package/dist/components/LpPhoneInput.vue.d.ts +37 -0
- package/dist/components/LpPopover.vue.d.ts +34 -0
- package/dist/components/LpProgress.vue.d.ts +12 -0
- package/dist/components/LpRadio.vue.d.ts +18 -0
- package/dist/components/LpRadioGroup.vue.d.ts +26 -0
- package/dist/components/LpScrollArea.vue.d.ts +24 -0
- package/dist/components/LpSegmented.vue.d.ts +24 -0
- package/dist/components/LpSelect.vue.d.ts +45 -0
- package/dist/components/LpServiceNode.vue.d.ts +14 -0
- package/dist/components/LpSidebar.vue.d.ts +85 -0
- package/dist/components/LpSidebarNav.vue.d.ts +34 -0
- package/dist/components/LpSkeleton.vue.d.ts +6 -0
- package/dist/components/LpSlider.vue.d.ts +23 -0
- package/dist/components/LpStat.vue.d.ts +22 -0
- package/dist/components/LpStepper.vue.d.ts +10 -0
- package/dist/components/LpSwitch.vue.d.ts +11 -0
- package/dist/components/LpTable.vue.d.ts +63 -0
- package/dist/components/LpTableOfContents.vue.d.ts +19 -0
- package/dist/components/LpTabs.vue.d.ts +45 -0
- package/dist/components/LpTextarea.vue.d.ts +17 -0
- package/dist/components/LpThemeSwitcher.vue.d.ts +40 -0
- package/dist/components/LpToaster.vue.d.ts +3 -0
- package/dist/components/LpTooltip.vue.d.ts +19 -0
- package/dist/components/LpTopologyCanvas.vue.d.ts +154 -0
- package/dist/components/LpUptimeBar.vue.d.ts +30 -0
- package/dist/components/codeHighlight.d.ts +8 -0
- package/dist/components/countries-data.d.ts +2 -0
- package/dist/components/countries.d.ts +20 -0
- package/dist/components/dropdown.d.ts +29 -0
- package/dist/components/sidebar.d.ts +18 -0
- package/dist/composables/useInputFilter.d.ts +14 -0
- package/dist/composables/usePillTransition.d.ts +9 -0
- package/dist/composables/useToast.d.ts +39 -0
- package/dist/countries-data-9rgqJWHo.js +203 -0
- package/dist/icons.d.ts +1 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.js +17600 -0
- package/dist/layout/registry.d.ts +26 -0
- package/dist/layout/tree.d.ts +75 -0
- package/dist/layout/useLayout.d.ts +39 -0
- package/dist/theme/config.d.ts +16 -0
- package/dist/theme/define.d.ts +12 -0
- package/dist/theme/presets.d.ts +20 -0
- package/dist/theme/tokens.d.ts +72 -0
- package/dist/theme/useTheme.d.ts +36 -0
- package/package.json +93 -0
- package/src/canvas.css +67 -0
- package/src/component-names.ts +65 -0
- package/src/components/LayoutCanvas.vue +76 -0
- package/src/components/LayoutNode.vue +248 -0
- package/src/components/LpAlert.vue +59 -0
- package/src/components/LpAppShell.vue +210 -0
- package/src/components/LpAutocomplete.vue +244 -0
- package/src/components/LpAvatar.vue +67 -0
- package/src/components/LpBadge.vue +32 -0
- package/src/components/LpBreadcrumbs.vue +35 -0
- package/src/components/LpButton.vue +111 -0
- package/src/components/LpCalendar.vue +134 -0
- package/src/components/LpCard.vue +71 -0
- package/src/components/LpCheckbox.vue +44 -0
- package/src/components/LpCodeBlock.vue +298 -0
- package/src/components/LpCommandPalette.vue +323 -0
- package/src/components/LpConfirmDialog.vue +49 -0
- package/src/components/LpContextMenu.vue +111 -0
- package/src/components/LpDatePicker.vue +117 -0
- package/src/components/LpDisclosure.vue +92 -0
- package/src/components/LpDivider.vue +20 -0
- package/src/components/LpDrawer.vue +402 -0
- package/src/components/LpDropdownMenu.vue +54 -0
- package/src/components/LpEmptyState.vue +21 -0
- package/src/components/LpFormField.vue +31 -0
- package/src/components/LpIcon.vue +49 -0
- package/src/components/LpInfraNode.vue +108 -0
- package/src/components/LpInput.vue +147 -0
- package/src/components/LpLaneNode.vue +48 -0
- package/src/components/LpLink.vue +48 -0
- package/src/components/LpLogViewer.vue +569 -0
- package/src/components/LpModal.vue +123 -0
- package/src/components/LpNotificationBell.vue +238 -0
- package/src/components/LpNumberField.vue +56 -0
- package/src/components/LpOtpInput.vue +81 -0
- package/src/components/LpPagination.vue +165 -0
- package/src/components/LpPasswordInput.vue +50 -0
- package/src/components/LpPhoneInput.vue +241 -0
- package/src/components/LpPopover.vue +42 -0
- package/src/components/LpProgress.vue +30 -0
- package/src/components/LpRadio.vue +28 -0
- package/src/components/LpRadioGroup.vue +43 -0
- package/src/components/LpScrollArea.vue +82 -0
- package/src/components/LpSegmented.vue +83 -0
- package/src/components/LpSelect.vue +0 -0
- package/src/components/LpServiceNode.vue +57 -0
- package/src/components/LpSidebar.vue +200 -0
- package/src/components/LpSidebarNav.vue +118 -0
- package/src/components/LpSkeleton.vue +16 -0
- package/src/components/LpSlider.vue +53 -0
- package/src/components/LpStat.vue +90 -0
- package/src/components/LpStepper.vue +46 -0
- package/src/components/LpSwitch.vue +19 -0
- package/src/components/LpTable.vue +252 -0
- package/src/components/LpTableOfContents.vue +183 -0
- package/src/components/LpTabs.vue +120 -0
- package/src/components/LpTextarea.vue +39 -0
- package/src/components/LpThemeSwitcher.vue +168 -0
- package/src/components/LpToaster.vue +216 -0
- package/src/components/LpTooltip.vue +30 -0
- package/src/components/LpTopologyCanvas.vue +370 -0
- package/src/components/LpUptimeBar.vue +126 -0
- package/src/components/codeHighlight.ts +137 -0
- package/src/components/countries-data.ts +207 -0
- package/src/components/countries.ts +67 -0
- package/src/components/dropdown.ts +64 -0
- package/src/components/sidebar.ts +26 -0
- package/src/composables/useInputFilter.ts +89 -0
- package/src/composables/usePillTransition.ts +19 -0
- package/src/composables/useToast.ts +92 -0
- package/src/icons.ts +11 -0
- package/src/index.css +21 -0
- package/src/index.ts +146 -0
- package/src/layout/registry.ts +44 -0
- package/src/layout/tree.ts +288 -0
- package/src/layout/useLayout.ts +134 -0
- package/src/nuxt.ts +22 -0
- package/src/theme/config.ts +48 -0
- package/src/theme/define.ts +50 -0
- package/src/theme/presets.ts +279 -0
- package/src/theme/tokens.ts +151 -0
- package/src/theme/useTheme.ts +288 -0
- package/src/tokens/scrollbar.css +138 -0
- package/src/tokens/tokens.css +333 -0
- package/src/tokens/utilities.css +23 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Design tokens — the single source of truth for the kit.
|
|
3
|
+
*
|
|
4
|
+
* No `@import "tailwindcss"` here: this file is meant to be pulled in by a
|
|
5
|
+
* consumer that already imports Tailwind (see src/index.css and the package's
|
|
6
|
+
* "./css" export). Importing Tailwind here too would double its rules.
|
|
7
|
+
*
|
|
8
|
+
* Exposed to Tailwind v4 via @theme, so every token becomes BOTH a utility
|
|
9
|
+
* (bg-surface-raised, text-ink, rounded-card, …) AND a live CSS variable that
|
|
10
|
+
* the runtime theme engine can override. Components read only tokens; theming
|
|
11
|
+
* is just rewriting these variables.
|
|
12
|
+
*
|
|
13
|
+
* Three orthogonal axes:
|
|
14
|
+
* color — semantic palette (theme / brand)
|
|
15
|
+
* shape — radii (style)
|
|
16
|
+
* density — spacing unit, control height, font scale (compactness)
|
|
17
|
+
*/
|
|
18
|
+
@theme {
|
|
19
|
+
/* ── color: surfaces ─────────────────────────── */
|
|
20
|
+
--color-surface: #080b0d;
|
|
21
|
+
--color-surface-raised: #12171d;
|
|
22
|
+
--color-surface-soft: #172027;
|
|
23
|
+
/* Derived from the (themed) raised surface so it can never drift per theme.
|
|
24
|
+
A popover/dropdown is just the raised surface with a touch of translucency. */
|
|
25
|
+
--color-surface-overlay: color-mix(in srgb, var(--color-surface-raised) 94%, transparent);
|
|
26
|
+
|
|
27
|
+
/* ── color: text ─────────────────────────────── */
|
|
28
|
+
--color-ink: #eef5f1;
|
|
29
|
+
--color-ink-inverse: #06100b;
|
|
30
|
+
--color-muted: #9aa8a2;
|
|
31
|
+
--color-muted-strong: #c7d2cc;
|
|
32
|
+
|
|
33
|
+
/* ── color: brand + state ────────────────────── */
|
|
34
|
+
--color-brand: #00bcff;
|
|
35
|
+
--color-brand-hover: #19c6ff;
|
|
36
|
+
--color-brand-soft: rgba(0, 188, 255, 0.16);
|
|
37
|
+
--color-action: #39e58c;
|
|
38
|
+
--color-action-hover: #4dffa1;
|
|
39
|
+
--color-accent: #f0b35a;
|
|
40
|
+
--color-danger: #ff6f6f;
|
|
41
|
+
--color-danger-hover: #ff8585;
|
|
42
|
+
--color-danger-soft: rgba(255, 111, 111, 0.14);
|
|
43
|
+
|
|
44
|
+
/* ── color: lines + focus ────────────────────── */
|
|
45
|
+
--color-line: rgba(255, 255, 255, 0.1);
|
|
46
|
+
--color-line-strong: rgba(255, 255, 255, 0.18);
|
|
47
|
+
--color-ring: rgba(0, 188, 255, 0.45);
|
|
48
|
+
|
|
49
|
+
/* ── shape ───────────────────────────────────── */
|
|
50
|
+
--radius-control: 8px;
|
|
51
|
+
--radius-card: 14px;
|
|
52
|
+
--radius-pill: 9999px;
|
|
53
|
+
|
|
54
|
+
/* ── density ─────────────────────────────────── */
|
|
55
|
+
--spacing-unit: 4px; /* base rhythm; scaled per density mode */
|
|
56
|
+
--size-control-sm: 32px;
|
|
57
|
+
--size-control-md: 38px;
|
|
58
|
+
--size-control-lg: 44px;
|
|
59
|
+
|
|
60
|
+
/* ── depth ───────────────────────────────────── */
|
|
61
|
+
--shadow-panel: 0 16px 48px rgba(0, 0, 0, 0.32);
|
|
62
|
+
|
|
63
|
+
/* ── surface / skin ──────────────────────────────
|
|
64
|
+
The skin axis (flat default). applyTheme() overrides these at runtime per
|
|
65
|
+
TokenSet.surface; components paint panels via .lp-skin-panel which reads
|
|
66
|
+
them, so a flat look and a full glass look are the same vars. */
|
|
67
|
+
--surface-border-width: 1px;
|
|
68
|
+
--surface-panel-blur: 0px;
|
|
69
|
+
--surface-panel-saturate: 100%;
|
|
70
|
+
--surface-panel-overlay: none;
|
|
71
|
+
--surface-panel-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
|
|
72
|
+
--surface-panel-inset: 0 0 0 0 transparent;
|
|
73
|
+
|
|
74
|
+
/* ── motion ──────────────────────────────────── */
|
|
75
|
+
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
76
|
+
/* Three-step motion scale, themeable like everything else. fast = state
|
|
77
|
+
feedback (hover/press/focus); medium = transforms & most enter/exit;
|
|
78
|
+
slow = larger reveals (disclosure height, drawer slide).
|
|
79
|
+
|
|
80
|
+
Exposed under BOTH names on purpose: `--duration-*` for the explicit
|
|
81
|
+
`duration-[var(--duration-fast)]` form already used across components, and
|
|
82
|
+
`--transition-duration-*` so Tailwind v4 emits the short `duration-medium`
|
|
83
|
+
utility (v4 reads duration utilities from the --transition-duration-*
|
|
84
|
+
namespace, not --duration-*). They reference one source so values can't drift. */
|
|
85
|
+
--duration-fast: 160ms;
|
|
86
|
+
--duration-medium: 220ms;
|
|
87
|
+
--duration-slow: 320ms;
|
|
88
|
+
--transition-duration-fast: var(--duration-fast);
|
|
89
|
+
--transition-duration-medium: var(--duration-medium);
|
|
90
|
+
--transition-duration-slow: var(--duration-slow);
|
|
91
|
+
|
|
92
|
+
/* ── type ────────────────────────────────────── */
|
|
93
|
+
--font-sans: "Inter", "Segoe UI", system-ui, sans-serif;
|
|
94
|
+
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* NOTE: there are no static [data-theme]/[data-density] rules. Themes are
|
|
99
|
+
* JSON (TokenSet) applied at runtime via useTheme().apply() — see src/theme/.
|
|
100
|
+
* The :root block above is only the bootstrap fallback (the dark default).
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/* ── layering scale ──────────────────────────────
|
|
104
|
+
One ladder so overlays never fight. Toasts sit ABOVE modals on purpose:
|
|
105
|
+
a notification must remain visible even while a dialog is open. */
|
|
106
|
+
@theme {
|
|
107
|
+
--z-dropdown: 50;
|
|
108
|
+
--z-overlay: 100;
|
|
109
|
+
--z-modal: 110;
|
|
110
|
+
--z-popover: 120;
|
|
111
|
+
--z-tooltip: 130;
|
|
112
|
+
--z-toast: 200;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* ── overlay enter/exit animations ───────────────
|
|
116
|
+
reka keeps content mounted while data-state=closed as long as a CSS
|
|
117
|
+
animation is declared for that state (via its Presence wrapper). */
|
|
118
|
+
@keyframes fade-in {
|
|
119
|
+
from {
|
|
120
|
+
opacity: 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
@keyframes fade-out {
|
|
124
|
+
to {
|
|
125
|
+
opacity: 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
@keyframes pop-in {
|
|
129
|
+
from {
|
|
130
|
+
opacity: 0;
|
|
131
|
+
transform: translate(-50%, -50%) scale(0.96);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
@keyframes pop-out {
|
|
135
|
+
to {
|
|
136
|
+
opacity: 0;
|
|
137
|
+
transform: translate(-50%, -50%) scale(0.96);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/*
|
|
141
|
+
* Popover enter/exit. The -in/-out pair drifts DOWN from the trigger (content
|
|
142
|
+
* placed below it). When the popper flips ABOVE the trigger (data-side=top),
|
|
143
|
+
* use the -up pair so the drift direction matches where it actually opens —
|
|
144
|
+
* otherwise an upward menu still slides down-from-above and reads wrong.
|
|
145
|
+
*/
|
|
146
|
+
@keyframes popover-in {
|
|
147
|
+
from {
|
|
148
|
+
opacity: 0;
|
|
149
|
+
transform: translateY(-4px) scale(0.97);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
@keyframes popover-out {
|
|
153
|
+
to {
|
|
154
|
+
opacity: 0;
|
|
155
|
+
transform: translateY(-4px) scale(0.97);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
@keyframes popover-in-up {
|
|
159
|
+
from {
|
|
160
|
+
opacity: 0;
|
|
161
|
+
transform: translateY(4px) scale(0.97);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
@keyframes popover-out-up {
|
|
165
|
+
to {
|
|
166
|
+
opacity: 0;
|
|
167
|
+
transform: translateY(4px) scale(0.97);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/* Option cascade: items slide in top→down on open. */
|
|
171
|
+
@keyframes option-in {
|
|
172
|
+
from {
|
|
173
|
+
opacity: 0;
|
|
174
|
+
transform: translateY(-6px);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/* Cascade upward when the list opens above the trigger (data-side=top), so the
|
|
178
|
+
options drift toward where the list actually is — mirror of option-in. */
|
|
179
|
+
@keyframes option-in-up {
|
|
180
|
+
from {
|
|
181
|
+
opacity: 0;
|
|
182
|
+
transform: translateY(6px);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
@keyframes tab-in {
|
|
186
|
+
from {
|
|
187
|
+
opacity: 0;
|
|
188
|
+
transform: translateY(6px);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
@keyframes toast-in {
|
|
192
|
+
from {
|
|
193
|
+
opacity: 0;
|
|
194
|
+
transform: translateX(16px);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
@keyframes toast-out {
|
|
198
|
+
to {
|
|
199
|
+
opacity: 0;
|
|
200
|
+
transform: translateX(16px);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
@keyframes drawer-in-right {
|
|
204
|
+
from {
|
|
205
|
+
transform: translateX(100%);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
@keyframes drawer-out-right {
|
|
209
|
+
to {
|
|
210
|
+
transform: translateX(100%);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
@keyframes drawer-in-left {
|
|
214
|
+
from {
|
|
215
|
+
transform: translateX(-100%);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
@keyframes drawer-out-left {
|
|
219
|
+
to {
|
|
220
|
+
transform: translateX(-100%);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
@keyframes collapsible-down {
|
|
224
|
+
from {
|
|
225
|
+
height: 0;
|
|
226
|
+
opacity: 0;
|
|
227
|
+
}
|
|
228
|
+
to {
|
|
229
|
+
height: var(--reka-collapsible-content-height);
|
|
230
|
+
opacity: 1;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
@keyframes collapsible-up {
|
|
234
|
+
from {
|
|
235
|
+
height: var(--reka-collapsible-content-height);
|
|
236
|
+
opacity: 1;
|
|
237
|
+
}
|
|
238
|
+
to {
|
|
239
|
+
height: 0;
|
|
240
|
+
opacity: 0;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/* Check/indicator pop: the tick scales + fades in when toggled on. */
|
|
244
|
+
@keyframes indicator-in {
|
|
245
|
+
from {
|
|
246
|
+
opacity: 0;
|
|
247
|
+
transform: scale(0.6);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
@keyframes disclosure-body-in {
|
|
251
|
+
from {
|
|
252
|
+
opacity: 0;
|
|
253
|
+
transform: translateY(-4px);
|
|
254
|
+
}
|
|
255
|
+
to {
|
|
256
|
+
opacity: 1;
|
|
257
|
+
transform: translateY(0);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/*
|
|
262
|
+
* Skin painter. A raised panel opts in with .lp-skin-panel and gets the active
|
|
263
|
+
* skin (flat → glass) purely from the surface tokens: border width, an overlay
|
|
264
|
+
* gradient layer, backdrop blur/saturate, and a layered + inset shadow. Driven
|
|
265
|
+
* by data, so re-skinning needs no per-component CSS.
|
|
266
|
+
*/
|
|
267
|
+
.lp-skin-panel {
|
|
268
|
+
position: relative;
|
|
269
|
+
border-width: var(--surface-border-width);
|
|
270
|
+
box-shadow: var(--surface-panel-inset), var(--surface-panel-shadow);
|
|
271
|
+
backdrop-filter: blur(var(--surface-panel-blur)) saturate(var(--surface-panel-saturate));
|
|
272
|
+
-webkit-backdrop-filter: blur(var(--surface-panel-blur)) saturate(var(--surface-panel-saturate));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* The overlay gradient rides above the base fill but under the content. */
|
|
276
|
+
.lp-skin-panel::before {
|
|
277
|
+
content: "";
|
|
278
|
+
position: absolute;
|
|
279
|
+
inset: 0;
|
|
280
|
+
z-index: 0;
|
|
281
|
+
border-radius: inherit;
|
|
282
|
+
background: var(--surface-panel-overlay);
|
|
283
|
+
pointer-events: none;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.lp-skin-panel > * {
|
|
287
|
+
position: relative;
|
|
288
|
+
z-index: 1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* ── circular theme reveal (View Transitions) ────
|
|
292
|
+
applyThemeWithTransition() snapshots the page, swaps the theme tokens, then
|
|
293
|
+
shrinks a clip-path circle in the OLD snapshot from the toggle's position,
|
|
294
|
+
revealing the new theme through the hole. The browser's default root
|
|
295
|
+
cross-fade would smear that, so we disable it: both snapshots hold full
|
|
296
|
+
opacity and don't blend — only the JS-driven circle animates. The NEW layer
|
|
297
|
+
sits beneath, full-screen and static; the OLD layer is on top and gets
|
|
298
|
+
clipped away. */
|
|
299
|
+
::view-transition-old(root),
|
|
300
|
+
::view-transition-new(root) {
|
|
301
|
+
animation: none;
|
|
302
|
+
mix-blend-mode: normal;
|
|
303
|
+
}
|
|
304
|
+
::view-transition-new(root) {
|
|
305
|
+
z-index: 1;
|
|
306
|
+
}
|
|
307
|
+
::view-transition-old(root) {
|
|
308
|
+
z-index: 2;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* ── reduced motion ──────────────────────────────
|
|
312
|
+
WCAG 2.3.3: honour the OS "reduce motion" preference. Every overlay
|
|
313
|
+
keyframe above (pop/drawer/toast/option/tab/popover/collapsible) and the
|
|
314
|
+
CSS transitions/animate-pulse used across the kit collapse to a near-instant
|
|
315
|
+
state change — content still mounts/unmounts, it just doesn't travel. This is
|
|
316
|
+
the CSS half; motion-v springs (Tabs/Layout) opt out in JS via
|
|
317
|
+
useReducedMotion(). */
|
|
318
|
+
@media (prefers-reduced-motion: reduce) {
|
|
319
|
+
*,
|
|
320
|
+
*::before,
|
|
321
|
+
*::after {
|
|
322
|
+
animation-duration: 0.01ms !important;
|
|
323
|
+
animation-iteration-count: 1 !important;
|
|
324
|
+
transition-duration: 0.01ms !important;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/*
|
|
329
|
+
* NOTE: tokens.css is the EMBEDDABLE layer — tokens + keyframes + z-scale only,
|
|
330
|
+
* no html/body resets and no global scrollbar rules (those would clobber a host
|
|
331
|
+
* app like the launcher). App-level resets live in the consumer (see the
|
|
332
|
+
* preview's preview.css / a host's own base styles).
|
|
333
|
+
*/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Always-on utilities (shipped via the main "@leavepulse/ui" import, unlike the
|
|
3
|
+
* opt-in scrollbar skin). These are scoped CLASSES — they only affect elements
|
|
4
|
+
* that explicitly carry them, so they never clobber a host app's globals.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Hide a native scrollbar while keeping the element scrollable, and crucially
|
|
9
|
+
* keep it OUT of the layout flow so it never reserves viewport width. Used by
|
|
10
|
+
* components whose scroll can't be an LpScrollArea overlay (e.g. the CodeBlock
|
|
11
|
+
* overlay editor, whose transparent textarea + <pre> must scroll natively in
|
|
12
|
+
* sync), and exposed for app-level use to drop native bars site-wide.
|
|
13
|
+
*/
|
|
14
|
+
.lp-scrollbar-none {
|
|
15
|
+
scrollbar-width: none; /* Firefox / standards */
|
|
16
|
+
-ms-overflow-style: none; /* old Edge */
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.lp-scrollbar-none::-webkit-scrollbar {
|
|
20
|
+
display: none; /* Chrome / Safari */
|
|
21
|
+
width: 0;
|
|
22
|
+
height: 0;
|
|
23
|
+
}
|