@vanduo-oss/framework 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -4
- package/css/components/cards.css +8 -0
- package/css/components/dropdown.css +8 -0
- package/css/components/fab.css +14 -0
- package/css/components/modals.css +13 -0
- package/css/components/navbar.css +30 -0
- package/css/components/toast.css +8 -0
- package/css/components/tooltips.css +29 -0
- package/css/core/tokens.css +37 -0
- package/css/core/vd-aliases.css +13 -0
- package/css/effects/glass.css +154 -0
- package/css/vanduo.css +1 -0
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +96 -3
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +4 -4
- package/dist/vanduo.cjs.min.js.map +4 -4
- package/dist/vanduo.css +261 -1
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +96 -3
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +4 -4
- package/dist/vanduo.esm.min.js.map +4 -4
- package/dist/vanduo.js +96 -3
- package/dist/vanduo.js.map +3 -3
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +4 -4
- package/dist/vanduo.min.js.map +4 -4
- package/js/components/glass.js +87 -0
- package/js/components/navbar.js +44 -3
- package/js/index.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Vanduo Framework v1.3.
|
|
1
|
+
# Vanduo Framework v1.3.4
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<img src="vanduo-banner.svg" alt="Vanduo Framework Banner" width="100%">
|
|
@@ -38,6 +38,16 @@ A lightweight, pure HTML/CSS/JS framework with **46+ components** for designing
|
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
+
## What's New in v1.3.4
|
|
42
|
+
|
|
43
|
+
v1.3.4 introduces the Glass Effects system — no breaking changes:
|
|
44
|
+
|
|
45
|
+
- **New `effects/glass.css` module.** Core `.vd-glass` class with `backdrop-filter` blur, translucent background, specular highlight, and noise texture. Size variants (`vd-glass-sm / md / lg / xl`), modifiers (`vd-glass-tinted`, `vd-glass-floating`, `vd-glass-contrast`), and full `prefers-reduced-transparency` / `@supports not (backdrop-filter)` fallbacks.
|
|
46
|
+
- **Glass design tokens.** `--vd-glass-blur`, `--vd-glass-saturate`, `--vd-glass-bg-opacity`, `--vd-glass-bg-light/dark`, `--vd-glass-border-light/dark`, `--vd-glass-shadow`, `--vd-glass-highlight-alpha`, `--vd-glass-noise-opacity` — all with automatic dark-mode overrides and `--vd-glass-*` aliases.
|
|
47
|
+
- **Component glass variants.** Opt-in `.vd-*-glass` modifier added to Navbar, Modal, Dropdown, Tooltip, Toast, Card, and FAB.
|
|
48
|
+
- **Scroll-activated glass.** `initScrollWatcher()` in `navbar.js` activates `.vd-navbar-glass` transparently at rest and frosted on scroll (configurable via `data-scroll-threshold`). Generic `data-glass-scroll` + `data-glass-sentinel` attribute API (new `glass.js`, `IntersectionObserver`) brings the same pattern to any element via `.is-glass-active`.
|
|
49
|
+
- **vd-hex selection fix.** `VdHexGrid` re-syncs `selectedHex` references after grid regeneration, preventing stale coordinates during rotation.
|
|
50
|
+
|
|
41
51
|
## What's New in v1.3.3
|
|
42
52
|
|
|
43
53
|
v1.3.3 is a maintenance release with no breaking changes:
|
|
@@ -98,8 +108,8 @@ The quickest way to get started — no install, no build step. Add two lines to
|
|
|
98
108
|
|
|
99
109
|
**Pin to a specific version** for production:
|
|
100
110
|
```html
|
|
101
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.
|
|
102
|
-
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.
|
|
111
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.4/dist/vanduo.min.css">
|
|
112
|
+
<script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.4/dist/vanduo.min.js"></script>
|
|
103
113
|
<script>Vanduo.init();</script>
|
|
104
114
|
```
|
|
105
115
|
|
|
@@ -162,7 +172,7 @@ This project includes an [`llms.txt`](llms.txt) file — a structured markdown s
|
|
|
162
172
|
Use the hardened upload script to attach only approved bundle artifacts from `dist/`:
|
|
163
173
|
|
|
164
174
|
```bash
|
|
165
|
-
pnpm run release:assets -- v1.3.
|
|
175
|
+
pnpm run release:assets -- v1.3.4
|
|
166
176
|
```
|
|
167
177
|
|
|
168
178
|
Notes:
|
package/css/components/cards.css
CHANGED
|
@@ -63,6 +63,14 @@
|
|
|
63
63
|
box-shadow: var(--card-shadow);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
.vd-card-glass {
|
|
67
|
+
background: var(--vd-glass-bg-light);
|
|
68
|
+
border-color: var(--vd-glass-border-light);
|
|
69
|
+
box-shadow: var(--vd-glass-shadow);
|
|
70
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
71
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
/* Card Variants - Elevated (default) */
|
|
67
75
|
.vd-card-elevated,
|
|
68
76
|
.vd-card {
|
|
@@ -96,6 +96,14 @@
|
|
|
96
96
|
transform var(--transition-duration-base) var(--transition-ease);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
.vd-dropdown-glass .vd-dropdown-menu {
|
|
100
|
+
background: var(--vd-glass-bg-light);
|
|
101
|
+
border-color: var(--vd-glass-border-light);
|
|
102
|
+
box-shadow: var(--vd-glass-shadow);
|
|
103
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
104
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
.vd-dropdown-menu.is-open {
|
|
100
108
|
display: block;
|
|
101
109
|
opacity: 1;
|
package/css/components/fab.css
CHANGED
|
@@ -56,12 +56,26 @@
|
|
|
56
56
|
transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
.vd-fab-glass {
|
|
60
|
+
background: var(--vd-glass-bg-light);
|
|
61
|
+
color: var(--text-primary);
|
|
62
|
+
border: 1px solid var(--vd-glass-border-light);
|
|
63
|
+
box-shadow: var(--vd-glass-shadow);
|
|
64
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
65
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
.vd-fab:hover {
|
|
60
69
|
background: var(--fab-hover-bg);
|
|
61
70
|
box-shadow: var(--fab-hover-shadow);
|
|
62
71
|
transform: scale(1.05);
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
.vd-fab-glass:hover {
|
|
75
|
+
background: var(--vd-glass-bg-light);
|
|
76
|
+
box-shadow: var(--vd-glass-float-shadow, var(--vd-glass-shadow));
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
.vd-fab:active {
|
|
66
80
|
transform: scale(0.95);
|
|
67
81
|
}
|
|
@@ -55,6 +55,11 @@
|
|
|
55
55
|
pointer-events: none;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
.vd-modal-backdrop.vd-modal-glass-backdrop {
|
|
59
|
+
backdrop-filter: blur(calc(var(--vd-glass-blur) * 0.5));
|
|
60
|
+
-webkit-backdrop-filter: blur(calc(var(--vd-glass-blur) * 0.5));
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
.vd-modal-backdrop.is-visible {
|
|
59
64
|
opacity: 1;
|
|
60
65
|
pointer-events: all;
|
|
@@ -114,6 +119,14 @@
|
|
|
114
119
|
outline: 0;
|
|
115
120
|
}
|
|
116
121
|
|
|
122
|
+
.vd-modal-glass .vd-modal-content {
|
|
123
|
+
background: var(--vd-glass-bg-light);
|
|
124
|
+
border-color: var(--vd-glass-border-light);
|
|
125
|
+
box-shadow: var(--vd-glass-shadow);
|
|
126
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
127
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
128
|
+
}
|
|
129
|
+
|
|
117
130
|
/* Modal Header */
|
|
118
131
|
.vd-modal-header {
|
|
119
132
|
display: flex;
|
|
@@ -59,6 +59,29 @@
|
|
|
59
59
|
min-height: var(--navbar-height);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/* Navbar Variant - Glass */
|
|
63
|
+
.vd-navbar-glass {
|
|
64
|
+
background: var(--vd-glass-bg-light);
|
|
65
|
+
border-bottom: 1px solid var(--vd-glass-border-light);
|
|
66
|
+
box-shadow: var(--vd-glass-shadow);
|
|
67
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
68
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
69
|
+
transition:
|
|
70
|
+
background var(--vd-transition-normal, 0.25s ease),
|
|
71
|
+
border-color var(--vd-transition-normal, 0.25s ease),
|
|
72
|
+
box-shadow var(--vd-transition-normal, 0.25s ease),
|
|
73
|
+
backdrop-filter var(--vd-transition-normal, 0.25s ease);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Scroll-activated: transparent at rest, frosted glass once scrolled */
|
|
77
|
+
.vd-navbar-glass:not(.vd-navbar-scrolled) {
|
|
78
|
+
background: transparent;
|
|
79
|
+
border-bottom-color: transparent;
|
|
80
|
+
box-shadow: none;
|
|
81
|
+
backdrop-filter: none;
|
|
82
|
+
-webkit-backdrop-filter: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
62
85
|
/* Navbar Container - matches .vd-container-responsive breakpoints for alignment with page content */
|
|
63
86
|
.vd-navbar-container {
|
|
64
87
|
display: flex;
|
|
@@ -459,6 +482,13 @@
|
|
|
459
482
|
z-index: 1000;
|
|
460
483
|
overflow-y: auto;
|
|
461
484
|
}
|
|
485
|
+
|
|
486
|
+
.vd-navbar-glass .vd-navbar-menu {
|
|
487
|
+
background: var(--vd-glass-bg-light);
|
|
488
|
+
border-left: 1px solid var(--vd-glass-border-light);
|
|
489
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
490
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
491
|
+
}
|
|
462
492
|
|
|
463
493
|
.vd-navbar-menu.is-open {
|
|
464
494
|
right: 0;
|
package/css/components/toast.css
CHANGED
|
@@ -101,6 +101,14 @@
|
|
|
101
101
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
.vd-toast-glass {
|
|
105
|
+
background: var(--vd-glass-bg-light);
|
|
106
|
+
border-color: var(--vd-glass-border-light);
|
|
107
|
+
box-shadow: var(--vd-glass-shadow);
|
|
108
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
109
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
110
|
+
}
|
|
111
|
+
|
|
104
112
|
/* Toast Visible State */
|
|
105
113
|
.vd-toast.is-visible {
|
|
106
114
|
opacity: 1;
|
|
@@ -78,6 +78,15 @@
|
|
|
78
78
|
transition: opacity var(--transition-duration-base) var(--transition-ease);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
.vd-tooltip-glass {
|
|
82
|
+
background: var(--vd-glass-bg-light);
|
|
83
|
+
border: 1px solid var(--vd-glass-border-light);
|
|
84
|
+
box-shadow: var(--vd-glass-shadow);
|
|
85
|
+
color: var(--text-primary);
|
|
86
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
87
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
.vd-tooltip.is-visible {
|
|
82
91
|
opacity: 1;
|
|
83
92
|
}
|
|
@@ -151,6 +160,26 @@
|
|
|
151
160
|
border-color: transparent var(--tooltip-bg) transparent transparent;
|
|
152
161
|
}
|
|
153
162
|
|
|
163
|
+
.vd-tooltip-glass.vd-tooltip-top::before,
|
|
164
|
+
.vd-tooltip-glass[data-placement="top"]::before {
|
|
165
|
+
border-color: var(--vd-glass-bg-light) transparent transparent;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.vd-tooltip-glass.vd-tooltip-bottom::before,
|
|
169
|
+
.vd-tooltip-glass[data-placement="bottom"]::before {
|
|
170
|
+
border-color: transparent transparent var(--vd-glass-bg-light);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.vd-tooltip-glass.vd-tooltip-left::before,
|
|
174
|
+
.vd-tooltip-glass[data-placement="left"]::before {
|
|
175
|
+
border-color: transparent transparent transparent var(--vd-glass-bg-light);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.vd-tooltip-glass.vd-tooltip-right::before,
|
|
179
|
+
.vd-tooltip-glass[data-placement="right"]::before {
|
|
180
|
+
border-color: transparent var(--vd-glass-bg-light) transparent transparent;
|
|
181
|
+
}
|
|
182
|
+
|
|
154
183
|
/* Tooltip Variants - Light */
|
|
155
184
|
.vd-tooltip-light {
|
|
156
185
|
background-color: var(--tooltip-bg-light);
|
package/css/core/tokens.css
CHANGED
|
@@ -142,6 +142,33 @@
|
|
|
142
142
|
--vd-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
|
143
143
|
--vd-shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);
|
|
144
144
|
|
|
145
|
+
/* ============================================
|
|
146
|
+
* GLASS TOKENS
|
|
147
|
+
* ============================================ */
|
|
148
|
+
--glass-blur: 12px;
|
|
149
|
+
--glass-saturate: 1.8;
|
|
150
|
+
--glass-bg-opacity: 0.65;
|
|
151
|
+
--glass-bg-light: rgba(255, 255, 255, var(--glass-bg-opacity));
|
|
152
|
+
--glass-bg-dark: rgba(30, 30, 30, var(--glass-bg-opacity));
|
|
153
|
+
--glass-border-alpha: 0.18;
|
|
154
|
+
--glass-border-light: rgba(255, 255, 255, var(--glass-border-alpha));
|
|
155
|
+
--glass-border-dark: rgba(255, 255, 255, 0.08);
|
|
156
|
+
--glass-highlight-alpha: 0.25;
|
|
157
|
+
--glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
|
158
|
+
--glass-noise-opacity: 0.03;
|
|
159
|
+
|
|
160
|
+
--vd-glass-blur: var(--glass-blur);
|
|
161
|
+
--vd-glass-saturate: var(--glass-saturate);
|
|
162
|
+
--vd-glass-bg-opacity: var(--glass-bg-opacity);
|
|
163
|
+
--vd-glass-bg-light: var(--glass-bg-light);
|
|
164
|
+
--vd-glass-bg-dark: var(--glass-bg-dark);
|
|
165
|
+
--vd-glass-border-alpha: var(--glass-border-alpha);
|
|
166
|
+
--vd-glass-border-light: var(--glass-border-light);
|
|
167
|
+
--vd-glass-border-dark: var(--glass-border-dark);
|
|
168
|
+
--vd-glass-highlight-alpha: var(--glass-highlight-alpha);
|
|
169
|
+
--vd-glass-shadow: var(--glass-shadow);
|
|
170
|
+
--vd-glass-noise-opacity: var(--glass-noise-opacity);
|
|
171
|
+
|
|
145
172
|
/* ============================================
|
|
146
173
|
* TRANSITION TOKENS
|
|
147
174
|
* ============================================ */
|
|
@@ -190,6 +217,11 @@
|
|
|
190
217
|
--vd-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
191
218
|
--vd-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
|
|
192
219
|
--vd-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);
|
|
220
|
+
|
|
221
|
+
--glass-bg-light: var(--glass-bg-dark);
|
|
222
|
+
--glass-border-light: var(--glass-border-dark);
|
|
223
|
+
--glass-shadow: 0 12px 36px rgba(0, 0, 0, 0.45);
|
|
224
|
+
--glass-highlight-alpha: 0.16;
|
|
193
225
|
}
|
|
194
226
|
|
|
195
227
|
/* Dark mode via prefers-color-scheme */
|
|
@@ -209,5 +241,10 @@
|
|
|
209
241
|
--vd-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
210
242
|
--vd-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
|
|
211
243
|
--vd-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);
|
|
244
|
+
|
|
245
|
+
--glass-bg-light: var(--glass-bg-dark);
|
|
246
|
+
--glass-border-light: var(--glass-border-dark);
|
|
247
|
+
--glass-shadow: 0 12px 36px rgba(0, 0, 0, 0.45);
|
|
248
|
+
--glass-highlight-alpha: 0.16;
|
|
212
249
|
}
|
|
213
250
|
}
|
package/css/core/vd-aliases.css
CHANGED
|
@@ -33,6 +33,19 @@
|
|
|
33
33
|
--vd-shadow-md: var(--shadow-md);
|
|
34
34
|
--vd-shadow-lg: var(--shadow-lg);
|
|
35
35
|
|
|
36
|
+
/* Glass */
|
|
37
|
+
--vd-glass-blur: var(--glass-blur, 12px);
|
|
38
|
+
--vd-glass-saturate: var(--glass-saturate, 1.8);
|
|
39
|
+
--vd-glass-bg-opacity: var(--glass-bg-opacity, 0.65);
|
|
40
|
+
--vd-glass-bg-light: var(--glass-bg-light, rgba(255, 255, 255, var(--vd-glass-bg-opacity)));
|
|
41
|
+
--vd-glass-bg-dark: var(--glass-bg-dark, rgba(30, 30, 30, var(--vd-glass-bg-opacity)));
|
|
42
|
+
--vd-glass-border-alpha: var(--glass-border-alpha, 0.18);
|
|
43
|
+
--vd-glass-border-light: var(--glass-border-light, rgba(255, 255, 255, var(--vd-glass-border-alpha)));
|
|
44
|
+
--vd-glass-border-dark: var(--glass-border-dark, rgba(255, 255, 255, 0.08));
|
|
45
|
+
--vd-glass-highlight-alpha: var(--glass-highlight-alpha, 0.25);
|
|
46
|
+
--vd-glass-shadow: var(--glass-shadow, 0 8px 32px rgba(0, 0, 0, 0.12));
|
|
47
|
+
--vd-glass-noise-opacity: var(--glass-noise-opacity, 0.03);
|
|
48
|
+
|
|
36
49
|
/* Typography */
|
|
37
50
|
--vd-font-family-base: var(--font-family-sans);
|
|
38
51
|
--vd-font-family-mono: var(--font-family-mono);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanduo Framework - Glass Effects
|
|
3
|
+
* Frosted glass utility surfaces and modifiers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
--vd-glass-float-shadow: 0 14px 42px rgba(0, 0, 0, 0.2);
|
|
8
|
+
--vd-glass-float-translate-y: -2px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.vd-glass,
|
|
12
|
+
.vd-glass-md {
|
|
13
|
+
position: relative;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
background: var(--vd-glass-bg-light);
|
|
16
|
+
border: 1px solid var(--vd-glass-border-light);
|
|
17
|
+
box-shadow: var(--vd-glass-shadow);
|
|
18
|
+
backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
19
|
+
-webkit-backdrop-filter: blur(var(--vd-glass-blur)) saturate(var(--vd-glass-saturate));
|
|
20
|
+
isolation: isolate;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.vd-glass::before,
|
|
24
|
+
.vd-glass-md::before {
|
|
25
|
+
content: "";
|
|
26
|
+
position: absolute;
|
|
27
|
+
inset: 0;
|
|
28
|
+
background: linear-gradient(
|
|
29
|
+
to bottom,
|
|
30
|
+
rgba(255, 255, 255, var(--vd-glass-highlight-alpha)) 0%,
|
|
31
|
+
rgba(255, 255, 255, 0) 45%
|
|
32
|
+
);
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
z-index: 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.vd-glass::after,
|
|
38
|
+
.vd-glass-md::after {
|
|
39
|
+
content: "";
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140' viewBox='0 0 140 140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.15' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.25'/%3E%3C/svg%3E");
|
|
43
|
+
opacity: var(--vd-glass-noise-opacity);
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
z-index: 2;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.vd-glass > *,
|
|
49
|
+
.vd-glass-md > * {
|
|
50
|
+
position: relative;
|
|
51
|
+
z-index: 3;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.vd-glass-sm {
|
|
55
|
+
--vd-glass-blur: 6px;
|
|
56
|
+
--vd-glass-saturate: 1.4;
|
|
57
|
+
--vd-glass-bg-opacity: 0.55;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.vd-glass-lg {
|
|
61
|
+
--vd-glass-blur: 20px;
|
|
62
|
+
--vd-glass-saturate: 2;
|
|
63
|
+
--vd-glass-bg-opacity: 0.72;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.vd-glass-xl {
|
|
67
|
+
--vd-glass-blur: 28px;
|
|
68
|
+
--vd-glass-saturate: 2.2;
|
|
69
|
+
--vd-glass-bg-opacity: 0.78;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.vd-glass-tinted {
|
|
73
|
+
background: linear-gradient(
|
|
74
|
+
135deg,
|
|
75
|
+
var(--vd-glass-tint, var(--vd-color-primary-alpha-10)) 0%,
|
|
76
|
+
transparent 70%
|
|
77
|
+
),
|
|
78
|
+
var(--vd-glass-bg-light);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.vd-glass-floating {
|
|
82
|
+
transition: transform var(--vd-transition-normal), box-shadow var(--vd-transition-normal);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.vd-glass-floating:hover,
|
|
86
|
+
.vd-glass-floating:focus-within {
|
|
87
|
+
transform: translateY(var(--vd-glass-float-translate-y));
|
|
88
|
+
box-shadow: var(--vd-glass-float-shadow);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.vd-glass-contrast {
|
|
92
|
+
--vd-glass-bg-opacity: 0.82;
|
|
93
|
+
--vd-glass-border-alpha: 0.26;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Scroll-activated glass: inactive until .is-glass-active is set by glass.js */
|
|
97
|
+
[data-glass-scroll] {
|
|
98
|
+
transition:
|
|
99
|
+
background var(--vd-transition-normal, 0.25s ease),
|
|
100
|
+
border-color var(--vd-transition-normal, 0.25s ease),
|
|
101
|
+
box-shadow var(--vd-transition-normal, 0.25s ease),
|
|
102
|
+
backdrop-filter var(--vd-transition-normal, 0.25s ease);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[data-glass-scroll]:not(.is-glass-active) {
|
|
106
|
+
background: transparent !important;
|
|
107
|
+
border-color: transparent !important;
|
|
108
|
+
box-shadow: none !important;
|
|
109
|
+
backdrop-filter: none !important;
|
|
110
|
+
-webkit-backdrop-filter: none !important;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
[data-glass-scroll]:not(.is-glass-active)::before,
|
|
114
|
+
[data-glass-scroll]:not(.is-glass-active)::after {
|
|
115
|
+
opacity: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
119
|
+
.vd-glass,
|
|
120
|
+
.vd-glass-md {
|
|
121
|
+
background: var(--vd-bg-primary);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
126
|
+
.vd-glass,
|
|
127
|
+
.vd-glass-sm,
|
|
128
|
+
.vd-glass-md,
|
|
129
|
+
.vd-glass-lg,
|
|
130
|
+
.vd-glass-xl {
|
|
131
|
+
backdrop-filter: none;
|
|
132
|
+
-webkit-backdrop-filter: none;
|
|
133
|
+
background: var(--vd-bg-primary);
|
|
134
|
+
border-color: var(--vd-border-color);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.vd-glass::before,
|
|
138
|
+
.vd-glass::after,
|
|
139
|
+
.vd-glass-md::before,
|
|
140
|
+
.vd-glass-md::after {
|
|
141
|
+
display: none;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@media (prefers-reduced-motion: reduce) {
|
|
146
|
+
.vd-glass-floating {
|
|
147
|
+
transition: none;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.vd-glass-floating:hover,
|
|
151
|
+
.vd-glass-floating:focus-within {
|
|
152
|
+
transform: none;
|
|
153
|
+
}
|
|
154
|
+
}
|
package/css/vanduo.css
CHANGED
package/dist/build-info.json
CHANGED
package/dist/vanduo.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Vanduo v1.3.
|
|
1
|
+
/*! Vanduo v1.3.4 | Built: 2026-04-14T21:21:55.517Z | git:73e3db5 | development */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -132,7 +132,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
132
132
|
// js/vanduo.js
|
|
133
133
|
(function() {
|
|
134
134
|
"use strict";
|
|
135
|
-
const VANDUO_VERSION = true ? "1.3.
|
|
135
|
+
const VANDUO_VERSION = true ? "1.3.4" : "0.0.0-dev";
|
|
136
136
|
const Vanduo2 = {
|
|
137
137
|
version: VANDUO_VERSION,
|
|
138
138
|
components: {},
|
|
@@ -2182,6 +2182,31 @@ module.exports = __toCommonJS(index_exports);
|
|
|
2182
2182
|
this.initNavbar(navbar);
|
|
2183
2183
|
});
|
|
2184
2184
|
},
|
|
2185
|
+
/**
|
|
2186
|
+
* Initialize scroll-aware glass/transparent behaviour for a navbar.
|
|
2187
|
+
* Adds/removes `.vd-navbar-scrolled` when the page scrolls past a threshold.
|
|
2188
|
+
* Threshold: `data-scroll-threshold` attribute (px) or the navbar's own height.
|
|
2189
|
+
* @param {HTMLElement} navbar - Navbar element
|
|
2190
|
+
* @returns {Function|null} Cleanup function, or null if not applicable
|
|
2191
|
+
*/
|
|
2192
|
+
initScrollWatcher: function(navbar) {
|
|
2193
|
+
const isGlass = navbar.classList.contains("vd-navbar-glass");
|
|
2194
|
+
const isTransparent = navbar.classList.contains("vd-navbar-transparent");
|
|
2195
|
+
if (!isGlass && !isTransparent) {
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
const getThreshold = () => {
|
|
2199
|
+
const attr = parseInt(navbar.dataset.scrollThreshold, 10);
|
|
2200
|
+
return isNaN(attr) ? navbar.offsetHeight || 60 : attr;
|
|
2201
|
+
};
|
|
2202
|
+
const onScroll = () => {
|
|
2203
|
+
const scrolled = window.scrollY > getThreshold();
|
|
2204
|
+
navbar.classList.toggle("vd-navbar-scrolled", scrolled);
|
|
2205
|
+
};
|
|
2206
|
+
onScroll();
|
|
2207
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
2208
|
+
return () => window.removeEventListener("scroll", onScroll);
|
|
2209
|
+
},
|
|
2185
2210
|
/**
|
|
2186
2211
|
* Initialize a single navbar
|
|
2187
2212
|
* @param {HTMLElement} navbar - Navbar element
|
|
@@ -2190,10 +2215,17 @@ module.exports = __toCommonJS(index_exports);
|
|
|
2190
2215
|
const toggle = navbar.querySelector(".vd-navbar-toggle, .vd-navbar-burger");
|
|
2191
2216
|
const menu = navbar.querySelector(".vd-navbar-menu");
|
|
2192
2217
|
const overlay = navbar.querySelector(".vd-navbar-overlay") || this.createOverlay(navbar);
|
|
2218
|
+
const cleanupFunctions = [];
|
|
2219
|
+
const scrollWatcherCleanup = this.initScrollWatcher(navbar);
|
|
2220
|
+
if (scrollWatcherCleanup) {
|
|
2221
|
+
cleanupFunctions.push(scrollWatcherCleanup);
|
|
2222
|
+
}
|
|
2193
2223
|
if (!toggle || !menu) {
|
|
2224
|
+
if (cleanupFunctions.length) {
|
|
2225
|
+
this.instances.set(navbar, { toggle: null, menu: null, overlay: null, cleanup: cleanupFunctions });
|
|
2226
|
+
}
|
|
2194
2227
|
return;
|
|
2195
2228
|
}
|
|
2196
|
-
const cleanupFunctions = [];
|
|
2197
2229
|
const toggleClickHandler = (e) => {
|
|
2198
2230
|
e.preventDefault();
|
|
2199
2231
|
e.stopPropagation();
|
|
@@ -6504,6 +6536,67 @@ module.exports = __toCommonJS(index_exports);
|
|
|
6504
6536
|
window.VanduoLazyLoad = VanduoLazyLoad;
|
|
6505
6537
|
})();
|
|
6506
6538
|
|
|
6539
|
+
// js/components/glass.js
|
|
6540
|
+
(function() {
|
|
6541
|
+
"use strict";
|
|
6542
|
+
const GlassScroll = {
|
|
6543
|
+
/** @type {Map<Element, IntersectionObserver>} */
|
|
6544
|
+
observers: /* @__PURE__ */ new Map(),
|
|
6545
|
+
init: function() {
|
|
6546
|
+
document.querySelectorAll("[data-glass-scroll]").forEach((el) => {
|
|
6547
|
+
if (this.observers.has(el)) return;
|
|
6548
|
+
this.initElement(el);
|
|
6549
|
+
});
|
|
6550
|
+
},
|
|
6551
|
+
/**
|
|
6552
|
+
* Wire up a single scroll-activated glass element.
|
|
6553
|
+
* @param {HTMLElement} el
|
|
6554
|
+
*/
|
|
6555
|
+
initElement: function(el) {
|
|
6556
|
+
const sentinelSelector = el.dataset.glassSentinel;
|
|
6557
|
+
let sentinel;
|
|
6558
|
+
if (sentinelSelector) {
|
|
6559
|
+
sentinel = document.querySelector(sentinelSelector);
|
|
6560
|
+
}
|
|
6561
|
+
if (!sentinel) {
|
|
6562
|
+
sentinel = el.previousElementSibling;
|
|
6563
|
+
}
|
|
6564
|
+
if (!sentinel) {
|
|
6565
|
+
el.classList.add("is-glass-active");
|
|
6566
|
+
return;
|
|
6567
|
+
}
|
|
6568
|
+
const observer = new IntersectionObserver(
|
|
6569
|
+
(entries) => {
|
|
6570
|
+
entries.forEach((entry) => {
|
|
6571
|
+
el.classList.toggle("is-glass-active", !entry.isIntersecting);
|
|
6572
|
+
});
|
|
6573
|
+
},
|
|
6574
|
+
{ threshold: 0, rootMargin: "0px" }
|
|
6575
|
+
);
|
|
6576
|
+
observer.observe(sentinel);
|
|
6577
|
+
this.observers.set(el, observer);
|
|
6578
|
+
},
|
|
6579
|
+
/**
|
|
6580
|
+
* Disconnect and remove a single element's observer.
|
|
6581
|
+
* @param {HTMLElement} el
|
|
6582
|
+
*/
|
|
6583
|
+
destroy: function(el) {
|
|
6584
|
+
const observer = this.observers.get(el);
|
|
6585
|
+
if (observer) {
|
|
6586
|
+
observer.disconnect();
|
|
6587
|
+
this.observers.delete(el);
|
|
6588
|
+
}
|
|
6589
|
+
},
|
|
6590
|
+
destroyAll: function() {
|
|
6591
|
+
this.observers.forEach((observer, el) => this.destroy(el));
|
|
6592
|
+
}
|
|
6593
|
+
};
|
|
6594
|
+
if (typeof window.Vanduo !== "undefined") {
|
|
6595
|
+
window.Vanduo.register("glassScroll", GlassScroll);
|
|
6596
|
+
}
|
|
6597
|
+
window.VanduoGlassScroll = GlassScroll;
|
|
6598
|
+
})();
|
|
6599
|
+
|
|
6507
6600
|
// js/components/flow.js
|
|
6508
6601
|
(function() {
|
|
6509
6602
|
"use strict";
|