@vanduo-oss/framework 1.3.1 → 1.3.3

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 CHANGED
@@ -1,4 +1,4 @@
1
- # Vanduo Framework v1.3.1
1
+ # Vanduo Framework v1.3.3
2
2
 
3
3
  <p align="center">
4
4
  <img src="vanduo-banner.svg" alt="Vanduo Framework Banner" width="100%">
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## Overview
21
21
 
22
- A lightweight, pure HTML/CSS/JS framework with **45+ components** for designing beautiful interfaces. Zero runtime dependencies, no mandatory build tools, just clean and simple code.
22
+ A lightweight, pure HTML/CSS/JS framework with **46+ components** for designing beautiful interfaces. Zero runtime dependencies, no mandatory build tools, just clean and simple code.
23
23
 
24
24
  [**Browse Full Documentation →**](https://vanduo.dev/#docs)
25
25
 
@@ -38,22 +38,30 @@ A lightweight, pure HTML/CSS/JS framework with **45+ components** for designing
38
38
 
39
39
  ---
40
40
 
41
- ## What's New in v1.3.1
41
+ ## What's New in v1.3.3
42
42
 
43
- v1.3.1 is a security and correctness release (12 issues fixed, 0 breaking changes):
43
+ v1.3.3 is a maintenance release with no breaking changes:
44
44
 
45
- - **XSS fix in Suggest.** `renderItems()` now escapes user/server data before `innerHTML` highlight injection.
46
- - **Select component repairs.** Fixed 3 broken `querySelector` selectors (keyboard nav + programmatic updates); `generateId()` now assigns `element.id` so ARIA `aria-labelledby` resolves correctly.
47
- - **Typeahead isolation.** `_typeaheadBuffer` / `_typeaheadTimer` moved to per-instance state in Dropdown and Select — typing in one instance no longer corrupts another.
48
- - **Navbar scroll-lock fix.** CSS class `body-navbar-open` replaces inline `overflow:hidden`, preventing conflicts with modal scroll locks.
49
- - **Validate hardening.** 100-char limit on user regex patterns (ReDoS prevention); `CSS.escape()` applied to `match` rule param (selector injection fix).
50
- - **Release artifacts and docs are aligned for v1.3.1.** Package metadata, generated bundles, `llms.txt`, and release-facing README examples now point at the current version.
45
+ - **Theme default primary alignment.** `ThemeCustomizer` and `ThemeSwitcher` normalize stale `black`/`amber` primary pairs against `localStorage` and `prefers-color-scheme`, so light, dark, and system modes stay consistent with `data-primary` after reloads and OS theme changes.
46
+ - **Documentation site.** Theme customizer demo storage keys align with framework (`vanduo-radius`, `vanduo-font-preference`); changelog and CDN pins updated to v1.3.3.
51
47
 
52
- The framework still ships **45+ components**, including the v1.2.7 additions below.
48
+ ---
49
+
50
+ ## What's New in v1.3.2
51
+
52
+ v1.3.2 is a component release centered on audio playback, with no breaking changes:
53
+
54
+ - **New Music Player component.** Ships a zero-dependency HTML5 audio player with play/pause, previous/next, volume, track title, and optional progress, shuffle, and playlist controls.
55
+ - **Framework-friendly API.** Accepts a plain JavaScript tracks array (`[{ name, url }]`), exposes custom events, and supports programmatic control through `window.VanduoMusicPlayer`.
56
+ - **Responsive player layout.** Control wrapping and volume sizing were tuned so the component stays usable across compact, inline, and mobile layouts.
57
+ - **Release coverage and artifacts updated.** Package metadata, generated bundles, `llms.txt`, and release-facing README examples now point at v1.3.2.
58
+
59
+ The framework now ships **46+ components**, including the new Music Player and the additions below.
53
60
 
54
61
  | Component | Vanduo Name | Type |
55
62
  |---|---|---|
56
63
  | Carousel | Flow | CSS + JS |
64
+ | Music Player | Music Player | CSS + JS |
57
65
  | Popover | Bubble | CSS + JS |
58
66
  | Scrollspy | Waypoint | CSS + JS |
59
67
  | Offcanvas | — (enhanced Sidenav) | CSS + JS |
@@ -90,8 +98,8 @@ The quickest way to get started — no install, no build step. Add two lines to
90
98
 
91
99
  **Pin to a specific version** for production:
92
100
  ```html
93
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.1/dist/vanduo.min.css">
94
- <script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.1/dist/vanduo.min.js"></script>
101
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.3/dist/vanduo.min.css">
102
+ <script src="https://cdn.jsdelivr.net/gh/vanduo-oss/framework@v1.3.3/dist/vanduo.min.js"></script>
95
103
  <script>Vanduo.init();</script>
96
104
  ```
97
105
 
@@ -154,7 +162,7 @@ This project includes an [`llms.txt`](llms.txt) file — a structured markdown s
154
162
  Use the hardened upload script to attach only approved bundle artifacts from `dist/`:
155
163
 
156
164
  ```bash
157
- pnpm run release:assets -- v1.3.1
165
+ pnpm run release:assets -- v1.3.3
158
166
  ```
159
167
 
160
168
  Notes:
@@ -187,6 +187,8 @@
187
187
  border: 1px solid var(--draggable-border-color);
188
188
  border-radius: var(--btn-border-radius);
189
189
  cursor: grab;
190
+ user-select: none;
191
+ touch-action: none;
190
192
  transition: var(--draggable-transition);
191
193
  }
192
194
 
@@ -224,7 +226,7 @@
224
226
  pointer-events: none;
225
227
  z-index: 9999;
226
228
  opacity: 0.9;
227
- transform: scale(0.8);
229
+ transform: none;
228
230
  transition: opacity 0.2s ease;
229
231
  }
230
232
 
@@ -0,0 +1,578 @@
1
+ /**
2
+ * Vanduo Framework - Music Player
3
+ * Audio playback component with transport controls, volume, and optional
4
+ * shuffle, progress bar, and playlist features.
5
+ */
6
+
7
+ :root {
8
+ /* Sizing (Fibonacci pairs) */
9
+ --music-player-padding-x: 1.3125rem; /* 21px */
10
+ --music-player-padding-y: 0.8125rem; /* 13px */
11
+ --music-player-padding-x-sm: 0.8125rem; /* 13px */
12
+ --music-player-padding-y-sm: 0.5rem; /* 8px */
13
+ --music-player-padding-x-lg: 2.125rem; /* 34px */
14
+ --music-player-padding-y-lg: 1.3125rem; /* 21px */
15
+ --music-player-gap: 0.8125rem; /* 13px */
16
+ --music-player-btn-size: 2.125rem; /* 34px */
17
+ --music-player-btn-size-sm: 1.625rem; /* 26px */
18
+ --music-player-btn-size-lg: 2.625rem; /* 42px */
19
+ --music-player-icon-size: 1.125rem;
20
+ --music-player-volume-width: clamp(3.25rem, 16vw, 4.5rem);
21
+ --music-player-volume-width-sm: 3rem;
22
+ --music-player-volume-width-lg: 5.5rem;
23
+ --music-player-border-radius: var(--border-radius, 0.5rem);
24
+ --music-player-border-width: 1px;
25
+
26
+ /* Colors */
27
+ --music-player-bg: var(--bg-primary);
28
+ --music-player-bg-secondary: var(--bg-secondary);
29
+ --music-player-border: var(--border-color);
30
+ --music-player-text: var(--text-primary);
31
+ --music-player-text-muted: var(--text-muted);
32
+ --music-player-accent: var(--color-primary);
33
+ --music-player-btn-hover-bg: var(--bg-secondary);
34
+ --music-player-btn-active-bg: var(--color-primary-alpha-10, rgba(var(--color-primary-rgb, 59,130,246), 0.1));
35
+ --music-player-track-bg: var(--border-color);
36
+ --music-player-track-fill: var(--color-primary);
37
+ --music-player-playlist-hover: var(--bg-secondary);
38
+ --music-player-playlist-active-bg: var(--color-primary-alpha-10, rgba(var(--color-primary-rgb, 59,130,246), 0.1));
39
+ --music-player-playlist-active-text: var(--color-primary);
40
+
41
+ /* Transitions */
42
+ --music-player-transition: 0.15s ease;
43
+ }
44
+
45
+ /* Dark Theme */
46
+ [data-theme="dark"] {
47
+ --music-player-bg: var(--bg-primary);
48
+ --music-player-bg-secondary: var(--color-gray-800);
49
+ --music-player-btn-hover-bg: var(--color-gray-700);
50
+ --music-player-playlist-hover: var(--color-gray-700);
51
+ }
52
+
53
+ @media (prefers-color-scheme: dark) {
54
+ :root:not([data-theme]) {
55
+ --music-player-bg: var(--bg-primary);
56
+ --music-player-bg-secondary: var(--color-gray-800);
57
+ --music-player-btn-hover-bg: var(--color-gray-700);
58
+ --music-player-playlist-hover: var(--color-gray-700);
59
+ }
60
+ }
61
+
62
+ /* ============================================================
63
+ Base Container
64
+ ============================================================ */
65
+
66
+ .vd-music-player {
67
+ display: flex;
68
+ flex-direction: column;
69
+ gap: 0;
70
+ background-color: var(--music-player-bg);
71
+ border: var(--music-player-border-width) solid var(--music-player-border);
72
+ border-radius: var(--music-player-border-radius);
73
+ padding: var(--music-player-padding-y) var(--music-player-padding-x);
74
+ min-width: 16rem;
75
+ max-width: 28rem;
76
+ width: 100%;
77
+ box-sizing: border-box;
78
+ }
79
+
80
+ /* ============================================================
81
+ Now Playing — track info bar
82
+ ============================================================ */
83
+
84
+ .vd-music-player-info {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 0.625rem;
88
+ min-height: 1.5rem;
89
+ margin-bottom: 0.625rem;
90
+ }
91
+
92
+ .vd-music-player-icon {
93
+ flex-shrink: 0;
94
+ color: var(--music-player-accent);
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ width: 1rem;
99
+ height: 1rem;
100
+ }
101
+
102
+ .vd-music-player-track-name {
103
+ font-size: var(--font-size-sm, 0.875rem);
104
+ color: var(--music-player-text);
105
+ flex: 1;
106
+ overflow: hidden;
107
+ white-space: nowrap;
108
+ text-overflow: ellipsis;
109
+ min-width: 0;
110
+ }
111
+
112
+ .vd-music-player-track-name.is-idle {
113
+ color: var(--music-player-text-muted);
114
+ font-style: italic;
115
+ }
116
+
117
+ /* ============================================================
118
+ Controls Row
119
+ ============================================================ */
120
+
121
+ .vd-music-player-controls {
122
+ display: flex;
123
+ align-items: center;
124
+ flex-wrap: wrap;
125
+ gap: 0.375rem;
126
+ }
127
+
128
+ .vd-music-player-btn {
129
+ display: inline-flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ width: var(--music-player-btn-size);
133
+ height: var(--music-player-btn-size);
134
+ padding: 0;
135
+ background: transparent;
136
+ border: none;
137
+ border-radius: var(--music-player-border-radius);
138
+ color: var(--music-player-text);
139
+ cursor: pointer;
140
+ transition:
141
+ background-color var(--music-player-transition),
142
+ color var(--music-player-transition);
143
+ flex-shrink: 0;
144
+ }
145
+
146
+ .vd-music-player-btn:hover:not(:disabled) {
147
+ background-color: var(--music-player-btn-hover-bg);
148
+ color: var(--music-player-accent);
149
+ }
150
+
151
+ .vd-music-player-btn:focus-visible {
152
+ outline: 2px solid var(--music-player-accent);
153
+ outline-offset: 1px;
154
+ }
155
+
156
+ .vd-music-player-btn:disabled {
157
+ opacity: 0.38;
158
+ cursor: not-allowed;
159
+ }
160
+
161
+ .vd-music-player-btn.is-active {
162
+ color: var(--music-player-accent);
163
+ background-color: var(--music-player-btn-active-bg);
164
+ }
165
+
166
+ /* Play/Pause is slightly larger */
167
+ .vd-music-player-btn-play {
168
+ width: calc(var(--music-player-btn-size) + 0.25rem);
169
+ height: calc(var(--music-player-btn-size) + 0.25rem);
170
+ }
171
+
172
+ .vd-music-player-btn svg,
173
+ .vd-music-player-btn i {
174
+ width: var(--music-player-icon-size);
175
+ height: var(--music-player-icon-size);
176
+ font-size: var(--music-player-icon-size);
177
+ pointer-events: none;
178
+ }
179
+
180
+ /* Spacer to push volume to the right */
181
+ .vd-music-player-spacer {
182
+ flex: 1 1 1.5rem;
183
+ min-width: 0;
184
+ }
185
+
186
+ /* ============================================================
187
+ Volume
188
+ ============================================================ */
189
+
190
+ .vd-music-player-volume {
191
+ display: flex;
192
+ align-items: center;
193
+ gap: 0.3125rem;
194
+ flex: 0 1 auto;
195
+ min-width: 0;
196
+ max-width: 100%;
197
+ }
198
+
199
+ .vd-music-player-volume-icon {
200
+ flex-shrink: 0;
201
+ color: var(--music-player-text-muted);
202
+ display: flex;
203
+ align-items: center;
204
+ width: 1rem;
205
+ height: 1rem;
206
+ font-size: 1rem;
207
+ }
208
+
209
+ .vd-music-player-volume-slider {
210
+ -webkit-appearance: none;
211
+ appearance: none;
212
+ width: var(--music-player-volume-width);
213
+ height: 4px;
214
+ border-radius: 9999px;
215
+ background: var(--music-player-track-bg);
216
+ cursor: pointer;
217
+ outline: none;
218
+ min-width: 3.25rem;
219
+ max-width: 100%;
220
+ flex: 0 1 var(--music-player-volume-width);
221
+ }
222
+
223
+ .vd-music-player-volume-slider:focus-visible {
224
+ outline: 2px solid var(--music-player-accent);
225
+ outline-offset: 2px;
226
+ }
227
+
228
+ /* WebKit thumb */
229
+ .vd-music-player-volume-slider::-webkit-slider-thumb {
230
+ -webkit-appearance: none;
231
+ appearance: none;
232
+ width: 0.75rem;
233
+ height: 0.75rem;
234
+ border-radius: 50%;
235
+ background: var(--music-player-accent);
236
+ cursor: pointer;
237
+ transition: transform var(--music-player-transition);
238
+ }
239
+
240
+ .vd-music-player-volume-slider::-webkit-slider-thumb:hover {
241
+ transform: scale(1.2);
242
+ }
243
+
244
+ /* Firefox thumb */
245
+ .vd-music-player-volume-slider::-moz-range-thumb {
246
+ width: 0.75rem;
247
+ height: 0.75rem;
248
+ border-radius: 50%;
249
+ background: var(--music-player-accent);
250
+ cursor: pointer;
251
+ border: none;
252
+ transition: transform var(--music-player-transition);
253
+ }
254
+
255
+ .vd-music-player-volume-slider::-moz-range-thumb:hover {
256
+ transform: scale(1.2);
257
+ }
258
+
259
+ /* Firefox track fill */
260
+ .vd-music-player-volume-slider::-moz-range-progress {
261
+ background: var(--music-player-track-fill);
262
+ border-radius: 9999px;
263
+ }
264
+
265
+ /* ============================================================
266
+ Progress Bar
267
+ ============================================================ */
268
+
269
+ .vd-music-player-progress {
270
+ display: none;
271
+ align-items: center;
272
+ gap: 0.5rem;
273
+ margin-top: 0.625rem;
274
+ }
275
+
276
+ .vd-music-player.has-progress .vd-music-player-progress {
277
+ display: flex;
278
+ }
279
+
280
+ .vd-music-player-progress-bar {
281
+ -webkit-appearance: none;
282
+ appearance: none;
283
+ flex: 1;
284
+ height: 4px;
285
+ border-radius: 9999px;
286
+ background: var(--music-player-track-bg);
287
+ cursor: pointer;
288
+ outline: none;
289
+ }
290
+
291
+ .vd-music-player-progress-bar:focus-visible {
292
+ outline: 2px solid var(--music-player-accent);
293
+ outline-offset: 2px;
294
+ }
295
+
296
+ .vd-music-player-progress-bar::-webkit-slider-thumb {
297
+ -webkit-appearance: none;
298
+ appearance: none;
299
+ width: 0.75rem;
300
+ height: 0.75rem;
301
+ border-radius: 50%;
302
+ background: var(--music-player-accent);
303
+ cursor: pointer;
304
+ transition: transform var(--music-player-transition);
305
+ }
306
+
307
+ .vd-music-player-progress-bar::-webkit-slider-thumb:hover {
308
+ transform: scale(1.2);
309
+ }
310
+
311
+ .vd-music-player-progress-bar::-moz-range-thumb {
312
+ width: 0.75rem;
313
+ height: 0.75rem;
314
+ border-radius: 50%;
315
+ background: var(--music-player-accent);
316
+ border: none;
317
+ cursor: pointer;
318
+ transition: transform var(--music-player-transition);
319
+ }
320
+
321
+ .vd-music-player-progress-bar::-moz-range-progress {
322
+ background: var(--music-player-track-fill);
323
+ border-radius: 9999px;
324
+ }
325
+
326
+ .vd-music-player-time {
327
+ font-size: 0.6875rem;
328
+ color: var(--music-player-text-muted);
329
+ white-space: nowrap;
330
+ flex-shrink: 0;
331
+ font-variant-numeric: tabular-nums;
332
+ min-width: 2.5rem;
333
+ text-align: right;
334
+ }
335
+
336
+ .vd-music-player-time:first-child {
337
+ text-align: left;
338
+ }
339
+
340
+ /* ============================================================
341
+ Playlist
342
+ ============================================================ */
343
+
344
+ .vd-music-player-playlist {
345
+ display: none;
346
+ flex-direction: column;
347
+ margin-top: 0.625rem;
348
+ border-top: var(--music-player-border-width) solid var(--music-player-border);
349
+ padding-top: 0.5rem;
350
+ max-height: 12rem;
351
+ overflow-y: auto;
352
+ scrollbar-width: thin;
353
+ }
354
+
355
+ .vd-music-player.has-playlist .vd-music-player-playlist.is-open {
356
+ display: flex;
357
+ }
358
+
359
+ .vd-music-player-playlist-item {
360
+ display: flex;
361
+ align-items: center;
362
+ gap: 0.5rem;
363
+ padding: 0.375rem 0.5rem;
364
+ border-radius: calc(var(--music-player-border-radius) * 0.5);
365
+ cursor: pointer;
366
+ font-size: var(--font-size-sm, 0.875rem);
367
+ color: var(--music-player-text);
368
+ background: transparent;
369
+ border: none;
370
+ text-align: left;
371
+ width: 100%;
372
+ transition:
373
+ background-color var(--music-player-transition),
374
+ color var(--music-player-transition);
375
+ }
376
+
377
+ .vd-music-player-playlist-item:hover {
378
+ background-color: var(--music-player-playlist-hover);
379
+ }
380
+
381
+ .vd-music-player-playlist-item:focus-visible {
382
+ outline: 2px solid var(--music-player-accent);
383
+ outline-offset: 1px;
384
+ }
385
+
386
+ .vd-music-player-playlist-item.is-active {
387
+ background-color: var(--music-player-playlist-active-bg);
388
+ color: var(--music-player-playlist-active-text);
389
+ font-weight: var(--font-weight-medium, 500);
390
+ }
391
+
392
+ .vd-music-player-playlist-num {
393
+ flex-shrink: 0;
394
+ width: 1.25rem;
395
+ font-size: 0.6875rem;
396
+ color: var(--music-player-text-muted);
397
+ text-align: right;
398
+ font-variant-numeric: tabular-nums;
399
+ }
400
+
401
+ .vd-music-player-playlist-item.is-active .vd-music-player-playlist-num {
402
+ color: var(--music-player-accent);
403
+ }
404
+
405
+ .vd-music-player-playlist-name {
406
+ flex: 1;
407
+ overflow: hidden;
408
+ white-space: nowrap;
409
+ text-overflow: ellipsis;
410
+ min-width: 0;
411
+ }
412
+
413
+ /* ============================================================
414
+ Variants — Compact (floating minimal bar)
415
+ ============================================================ */
416
+
417
+ .vd-music-player-compact {
418
+ flex-direction: row;
419
+ align-items: center;
420
+ padding: 0.5rem 0.8125rem;
421
+ min-width: auto;
422
+ max-width: none;
423
+ width: auto;
424
+ gap: 0.5rem;
425
+ }
426
+
427
+ .vd-music-player-compact .vd-music-player-info {
428
+ display: none;
429
+ }
430
+
431
+ .vd-music-player-compact .vd-music-player-controls {
432
+ gap: 0.125rem;
433
+ }
434
+
435
+ /* ============================================================
436
+ Variants — Inline (full-width bar)
437
+ ============================================================ */
438
+
439
+ .vd-music-player-inline {
440
+ flex-direction: row;
441
+ align-items: center;
442
+ flex-wrap: wrap;
443
+ padding: 0.625rem var(--music-player-padding-x);
444
+ min-width: 0;
445
+ max-width: none;
446
+ gap: 0.625rem;
447
+ }
448
+
449
+ .vd-music-player-inline .vd-music-player-info {
450
+ flex: 1;
451
+ min-width: 8rem;
452
+ margin-bottom: 0;
453
+ }
454
+
455
+ .vd-music-player-inline .vd-music-player-controls {
456
+ flex: 1 1 auto;
457
+ justify-content: flex-end;
458
+ min-width: 0;
459
+ }
460
+
461
+ .vd-music-player-inline .vd-music-player-volume {
462
+ flex: 0 1 auto;
463
+ }
464
+
465
+ .vd-music-player-inline .vd-music-player-volume-slider {
466
+ width: clamp(4rem, 18vw, 5.5rem);
467
+ flex-basis: clamp(4rem, 18vw, 5.5rem);
468
+ }
469
+
470
+ .vd-music-player-inline .vd-music-player-progress {
471
+ flex-basis: 100%;
472
+ margin-top: 0.375rem;
473
+ }
474
+
475
+ /* ============================================================
476
+ Sizes
477
+ ============================================================ */
478
+
479
+ .vd-music-player-sm {
480
+ padding: var(--music-player-padding-y-sm) var(--music-player-padding-x-sm);
481
+ font-size: var(--font-size-sm, 0.875rem);
482
+ }
483
+
484
+ .vd-music-player-sm .vd-music-player-btn {
485
+ width: var(--music-player-btn-size-sm);
486
+ height: var(--music-player-btn-size-sm);
487
+ }
488
+
489
+ .vd-music-player-sm .vd-music-player-btn-play {
490
+ width: calc(var(--music-player-btn-size-sm) + 0.125rem);
491
+ height: calc(var(--music-player-btn-size-sm) + 0.125rem);
492
+ }
493
+
494
+ .vd-music-player-sm .vd-music-player-btn svg,
495
+ .vd-music-player-sm .vd-music-player-btn i {
496
+ font-size: 0.9375rem;
497
+ width: 0.9375rem;
498
+ height: 0.9375rem;
499
+ }
500
+
501
+ .vd-music-player-sm .vd-music-player-volume-slider {
502
+ width: var(--music-player-volume-width-sm);
503
+ min-width: var(--music-player-volume-width-sm);
504
+ flex-basis: var(--music-player-volume-width-sm);
505
+ }
506
+
507
+ .vd-music-player-lg {
508
+ padding: var(--music-player-padding-y-lg) var(--music-player-padding-x-lg);
509
+ }
510
+
511
+ .vd-music-player-lg .vd-music-player-btn {
512
+ width: var(--music-player-btn-size-lg);
513
+ height: var(--music-player-btn-size-lg);
514
+ }
515
+
516
+ .vd-music-player-lg .vd-music-player-btn-play {
517
+ width: calc(var(--music-player-btn-size-lg) + 0.25rem);
518
+ height: calc(var(--music-player-btn-size-lg) + 0.25rem);
519
+ }
520
+
521
+ .vd-music-player-lg .vd-music-player-btn svg,
522
+ .vd-music-player-lg .vd-music-player-btn i {
523
+ font-size: 1.25rem;
524
+ width: 1.25rem;
525
+ height: 1.25rem;
526
+ }
527
+
528
+ .vd-music-player-lg .vd-music-player-volume-slider {
529
+ width: var(--music-player-volume-width-lg);
530
+ min-width: 4rem;
531
+ flex-basis: var(--music-player-volume-width-lg);
532
+ }
533
+
534
+ /* ============================================================
535
+ Neutral color variant — use gray instead of primary
536
+ ============================================================ */
537
+
538
+ .vd-music-player-neutral {
539
+ --music-player-accent: var(--text-primary);
540
+ --music-player-track-fill: var(--text-primary);
541
+ --music-player-playlist-active-text: var(--text-primary);
542
+ --music-player-playlist-active-bg: var(--bg-secondary);
543
+ --music-player-btn-active-bg: var(--bg-secondary);
544
+ }
545
+
546
+ /* ============================================================
547
+ Reduced Motion
548
+ ============================================================ */
549
+
550
+ @media (prefers-reduced-motion: reduce) {
551
+ .vd-music-player-btn,
552
+ .vd-music-player-volume-slider::-webkit-slider-thumb,
553
+ .vd-music-player-volume-slider::-moz-range-thumb,
554
+ .vd-music-player-progress-bar::-webkit-slider-thumb,
555
+ .vd-music-player-progress-bar::-moz-range-thumb,
556
+ .vd-music-player-playlist-item {
557
+ transition: none;
558
+ }
559
+ }
560
+
561
+ @media (max-width: 640px) {
562
+ .vd-music-player {
563
+ min-width: 0;
564
+ max-width: none;
565
+ }
566
+
567
+ .vd-music-player-controls {
568
+ row-gap: 0.5rem;
569
+ }
570
+
571
+ .vd-music-player-spacer {
572
+ display: none;
573
+ }
574
+
575
+ .vd-music-player-volume {
576
+ margin-left: auto;
577
+ }
578
+ }
package/css/vanduo.css CHANGED
@@ -95,6 +95,7 @@
95
95
  @import url('components/transfer.css');
96
96
  @import url('components/tree.css');
97
97
  @import url('components/spotlight.css');
98
+ @import url('components/music-player.css');
98
99
 
99
100
  /* Print Styles */
100
101
  @import url('utilities/print.css');
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.3.1",
3
- "builtAt": "2026-03-20T21:48:40.922Z",
4
- "commit": "7e73bb8",
2
+ "version": "1.3.3",
3
+ "builtAt": "2026-04-10T21:45:12.664Z",
4
+ "commit": "281f4f6",
5
5
  "mode": "development+production"
6
6
  }