@nkanish/liquidglass-ui 0.1.0 → 0.2.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/dist/index.js CHANGED
@@ -1,6 +1,13 @@
1
1
  // src/components/GlassProvider.tsx
2
2
  import { createContext, useContext, useState, useEffect } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
+ var DEFAULT_REFRACTION = {
5
+ enabled: true,
6
+ depth: 8,
7
+ dome: 4,
8
+ shine: 0.3,
9
+ lightAngle: 225
10
+ };
4
11
  var GlassContext = createContext(null);
5
12
  function getSystemTheme() {
6
13
  if (typeof window === "undefined") return "light";
@@ -22,6 +29,10 @@ function GlassProvider({
22
29
  return theme;
23
30
  });
24
31
  const [config, setConfigState] = useState(initialConfig);
32
+ const refraction = {
33
+ ...DEFAULT_REFRACTION,
34
+ ...config.refraction
35
+ };
25
36
  const setTheme = (newTheme) => {
26
37
  setThemeState(newTheme);
27
38
  if (typeof window !== "undefined") {
@@ -69,7 +80,8 @@ function GlassProvider({
69
80
  resolvedTheme,
70
81
  setTheme,
71
82
  config,
72
- setConfig
83
+ setConfig,
84
+ refraction
73
85
  },
74
86
  children
75
87
  }
@@ -86,9 +98,16 @@ function useTheme() {
86
98
  const { theme, resolvedTheme, setTheme } = useGlass();
87
99
  return { theme, resolvedTheme, setTheme };
88
100
  }
101
+ function useRefraction() {
102
+ const context = useContext(GlassContext);
103
+ if (!context) {
104
+ return DEFAULT_REFRACTION;
105
+ }
106
+ return context.refraction;
107
+ }
89
108
 
90
109
  // src/components/Glass.tsx
91
- import { forwardRef, useRef } from "react";
110
+ import { forwardRef, useRef as useRef2 } from "react";
92
111
 
93
112
  // src/utils/cn.ts
94
113
  function cn(...inputs) {
@@ -172,34 +191,482 @@ function useReducedMotion() {
172
191
  return reducedMotion;
173
192
  }
174
193
 
175
- // src/core/svg-filters.ts
194
+ // src/hooks/use-glisse-effect.ts
195
+ import { useEffect as useEffect4, useRef, useState as useState4, useCallback as useCallback2 } from "react";
176
196
  var SVG_NS = "http://www.w3.org/2000/svg";
197
+ var DEFAULT_LIGHT = {
198
+ angle: 225,
199
+ glow: 0.4,
200
+ spread: 0.5,
201
+ glowPower: 2,
202
+ edge: 0.5,
203
+ edgeWidth: 1.5,
204
+ edgePower: 1
205
+ };
206
+ var DEFAULT_LENS = {
207
+ depth: 8,
208
+ dome: 4,
209
+ splay: 0.85,
210
+ relative: false
211
+ };
212
+ var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
213
+ var erf = (x) => Math.tanh(1.7724538509 * x);
214
+ function distance(x, y, halfWidth, halfHeight, radius) {
215
+ const qx = Math.abs(x) - halfWidth + radius;
216
+ const qy = Math.abs(y) - halfHeight + radius;
217
+ return Math.hypot(Math.max(qx, 0), Math.max(qy, 0)) + Math.min(Math.max(qx, qy), 0) - radius;
218
+ }
219
+ function arc(sag, half) {
220
+ const r = (half * half + sag * sag) / (2 * sag);
221
+ let sum = 0;
222
+ for (let i = 0; i <= 200; i++) {
223
+ const x = i / 200 * half;
224
+ const s = x / Math.sqrt(r * r - x * x);
225
+ sum += i === 0 || i === 200 ? s / 2 : s;
226
+ }
227
+ const mean = sum / 200;
228
+ return { radius: r, scale: mean > 0 ? 0.5 / mean : 1 };
229
+ }
230
+ function slopeAt(x, curve) {
231
+ const inside = Math.min(x, 0.999 * curve.radius);
232
+ return inside / Math.sqrt(curve.radius * curve.radius - inside * inside) * curve.scale;
233
+ }
234
+ function grey(data, i, value, alpha = 255) {
235
+ data[i] = data[i + 1] = data[i + 2] = value;
236
+ data[i + 3] = alpha;
237
+ }
238
+ function lensMap(shape, options, light, density) {
239
+ const { width, height } = shape;
240
+ const halfWidth = width / 2;
241
+ const halfHeight = height / 2;
242
+ const radius = clamp(shape.radius, 0, Math.min(halfWidth, halfHeight));
243
+ const columns = Math.max(1, Math.round(width * density));
244
+ const rows = Math.max(1, Math.round(height * density));
245
+ const pullAcross = new Uint8ClampedArray(columns * rows * 4);
246
+ const pullDown = new Uint8ClampedArray(columns * rows * 4);
247
+ const caught = new Uint8ClampedArray(columns * rows * 4);
248
+ const share = options.relative ? Math.min(width, height) : 1;
249
+ const depth = options.depth * share;
250
+ const dome = options.dome * share;
251
+ const { splay } = options;
252
+ const innerWidth = Math.max(0, halfWidth - depth);
253
+ const innerHeight = Math.max(0, halfHeight - depth);
254
+ const innerRadius = clamp(radius, 0, Math.min(innerWidth, innerHeight));
255
+ const ramp = depth > 0 ? 1 / (depth * Math.SQRT2) : 1e6;
256
+ const sag = Math.max(0.01, Math.min(dome, Math.min(halfWidth, halfHeight) - 1));
257
+ const across = dome > 0 ? arc(sag, halfWidth) : null;
258
+ const down = dome > 0 ? arc(sag, halfHeight) : null;
259
+ const reach = 0.5 * Math.min(halfWidth, halfHeight);
260
+ const cos = Math.cos(light.angle * Math.PI / 180);
261
+ const sin = Math.sin(light.angle * Math.PI / 180);
262
+ const glowStart = (1 - light.spread) * Math.SQRT2;
263
+ const glowRange = light.spread * Math.SQRT2;
264
+ for (let row = 0; row < rows; row++) {
265
+ for (let column = 0; column < columns; column++) {
266
+ const i = (row * columns + column) * 4;
267
+ const x = (column + 0.5) / columns * width - halfWidth;
268
+ const y = (row + 0.5) / rows * height - halfHeight;
269
+ const edge = distance(x, y, halfWidth, halfHeight, radius);
270
+ if (edge >= 0) {
271
+ grey(pullAcross, i, 128);
272
+ grey(pullDown, i, 128);
273
+ grey(caught, i, 128, 0);
274
+ continue;
275
+ }
276
+ const ax = Math.abs(x);
277
+ const ay = Math.abs(y);
278
+ let dx = across ? Math.sign(x) * slopeAt(ax, across) : clamp(x / halfWidth, -1, 1);
279
+ let dy = down ? Math.sign(y) * slopeAt(ay, down) : clamp(y / halfHeight, -1, 1);
280
+ if (splay < 1 && reach > 0) {
281
+ const keepX = Math.max(0, 1 - (halfHeight - ay) / reach) * (1 - splay);
282
+ const keepY = Math.max(0, 1 - (halfWidth - ax) / reach) * (1 - splay);
283
+ if (keepX > 1e-3 || keepY > 1e-3) {
284
+ const before = Math.hypot(dx, dy);
285
+ dx *= 1 - keepX;
286
+ dy *= 1 - keepY;
287
+ const after = Math.hypot(dx, dy);
288
+ if (after > 1e-3) {
289
+ dx *= before / after;
290
+ dy *= before / after;
291
+ }
292
+ }
293
+ }
294
+ const falloff = 0.5 * (1 + erf(distance(x, y, innerWidth, innerHeight, innerRadius) * ramp));
295
+ grey(pullAcross, i, Math.round((0.5 - 0.5 * dx * falloff) * 255));
296
+ grey(pullDown, i, Math.round((0.5 - 0.5 * dy * falloff) * 255));
297
+ const facing = Math.abs(clamp(x / halfWidth, -1, 1) * cos + clamp(y / halfHeight, -1, 1) * sin);
298
+ const glow = glowRange > 1e-3 ? light.glow * Math.pow(clamp((facing - glowStart) / glowRange, 0, 1), light.glowPower) * falloff : 0;
299
+ const rim = light.edge * Math.max(0, 1 + edge / light.edgeWidth) * Math.pow(facing, light.edgePower);
300
+ const amount = Math.min(1, glow + rim);
301
+ const bends = Math.min(1, falloff * 20, -edge);
302
+ grey(caught, i, Math.round(127 * amount + 128), Math.round(255 * bends));
303
+ }
304
+ }
305
+ return { columns, rows, across: pullAcross, down: pullDown, light: caught };
306
+ }
307
+ var encodedCache = /* @__PURE__ */ new Map();
308
+ function encode(key, draw) {
309
+ const cached = encodedCache.get(key);
310
+ if (cached) return cached;
311
+ const map = draw();
312
+ const canvas = document.createElement("canvas");
313
+ canvas.width = map.columns;
314
+ canvas.height = map.rows;
315
+ const context = canvas.getContext("2d");
316
+ if (!context) return null;
317
+ const image = context.createImageData(map.columns, map.rows);
318
+ const png = (data) => {
319
+ image.data.set(data);
320
+ context.putImageData(image, 0, 0);
321
+ return canvas.toDataURL();
322
+ };
323
+ const result = {
324
+ across: png(map.across),
325
+ down: png(map.down),
326
+ light: png(map.light)
327
+ };
328
+ encodedCache.set(key, result);
329
+ return result;
330
+ }
331
+ function svg(tag, attrs = {}) {
332
+ const el = document.createElementNS(SVG_NS, tag);
333
+ for (const [key, value] of Object.entries(attrs)) {
334
+ el.setAttribute(key, String(value));
335
+ }
336
+ return el;
337
+ }
338
+ var CHANNELS = [
339
+ "1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
340
+ "0 0 0 0 0 0 1 0 0 0 0 0 0 0 0",
341
+ "0 0 0 0 0 0 0 0 0 0 0 0 1 0 0"
342
+ ];
343
+ function isWebKit() {
344
+ if (typeof navigator === "undefined") return false;
345
+ return /AppleWebKit\//.test(navigator.userAgent) && !/Chrom(?:e|ium)\//.test(navigator.userAgent);
346
+ }
347
+ function supportsDisplacementMap() {
348
+ if (typeof document === "undefined") return false;
349
+ try {
350
+ const el = document.createElementNS(SVG_NS, "feDisplacementMap");
351
+ return !!el && el.namespaceURI === SVG_NS && "scale" in el;
352
+ } catch {
353
+ return false;
354
+ }
355
+ }
356
+ function buildFilter(lenses, box) {
357
+ const unit = box ? "objectBoundingBox" : "userSpaceOnUse";
358
+ const filter = svg("filter", {
359
+ filterUnits: unit,
360
+ primitiveUnits: unit,
361
+ "color-interpolation-filters": "sRGB"
362
+ });
363
+ if (box) {
364
+ filter.setAttribute("x", "0");
365
+ filter.setAttribute("y", "0");
366
+ filter.setAttribute("width", "1");
367
+ filter.setAttribute("height", "1");
368
+ }
369
+ const single = lenses.length === 1;
370
+ lenses.forEach(({ maps, shine }, k) => {
371
+ const merged = (name) => single ? name : `${name}-${k}`;
372
+ const image = (href, result) => svg("feImage", { href, preserveAspectRatio: "none", result });
373
+ filter.append(
374
+ image(maps.across, `across-${k}`),
375
+ image(maps.down, `down-${k}`),
376
+ image(maps.light, merged("raw")),
377
+ svg("feFlood", { "flood-color": "rgb(128, 128, 128)", result: `neutral-${k}` })
378
+ );
379
+ for (const pull of ["across", "down"]) {
380
+ const half = svg("feComponentTransfer", {
381
+ in: `${pull}-grey-${k}`,
382
+ result: `${pull}-pull-${k}`
383
+ });
384
+ half.append(svg("feFuncA", { type: "linear", slope: 0, intercept: 0.5 }));
385
+ filter.append(
386
+ svg("feComposite", {
387
+ in: `${pull}-${k}`,
388
+ in2: `neutral-${k}`,
389
+ operator: "over",
390
+ result: `${pull}-grey-${k}`
391
+ }),
392
+ half
393
+ );
394
+ }
395
+ CHANNELS.forEach((_, i) => {
396
+ filter.append(
397
+ svg("feDisplacementMap", {
398
+ in: "SourceGraphic",
399
+ in2: `across-pull-${k}`,
400
+ xChannelSelector: "R",
401
+ yChannelSelector: "A",
402
+ result: `across-${k}-${i}`
403
+ }),
404
+ svg("feDisplacementMap", {
405
+ in: `across-${k}-${i}`,
406
+ in2: `down-pull-${k}`,
407
+ xChannelSelector: "A",
408
+ yChannelSelector: "R",
409
+ result: `ray-${k}-${i}`
410
+ })
411
+ );
412
+ });
413
+ CHANNELS.forEach((channel, i) => {
414
+ filter.append(
415
+ svg("feColorMatrix", {
416
+ in: `ray-${k}-${i}`,
417
+ type: "matrix",
418
+ values: `${channel} 0 0 0 0.3333 0`,
419
+ result: `light-${k}-${i}`
420
+ })
421
+ );
422
+ });
423
+ filter.append(
424
+ svg("feComposite", {
425
+ in: `light-${k}-0`,
426
+ in2: `light-${k}-1`,
427
+ operator: "arithmetic",
428
+ k2: 1,
429
+ k3: 1,
430
+ result: `light-${k}-01`
431
+ }),
432
+ svg("feComposite", {
433
+ in: `light-${k}-01`,
434
+ in2: `light-${k}-2`,
435
+ operator: "arithmetic",
436
+ k2: 1,
437
+ k3: 1,
438
+ result: `spread-${k}`
439
+ }),
440
+ svg("feColorMatrix", {
441
+ in: `spread-${k}`,
442
+ type: "matrix",
443
+ values: "3 0 0 0 0 0 3 0 0 0 0 0 3 0 0 0 0 0 1 0",
444
+ result: `bent-${k}`
445
+ })
446
+ );
447
+ const bent = `bent-${k}`;
448
+ let lit = bent;
449
+ if (shine > 0) {
450
+ const white = `0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 ${-128 / 255}`;
451
+ filter.append(
452
+ svg("feColorMatrix", {
453
+ in: merged("raw"),
454
+ type: "matrix",
455
+ values: white,
456
+ result: `glint-${k}`
457
+ }),
458
+ svg("feComposite", {
459
+ in: `glint-${k}`,
460
+ in2: bent,
461
+ operator: "arithmetic",
462
+ k2: shine,
463
+ k3: 1,
464
+ result: `lit-${k}`
465
+ })
466
+ );
467
+ lit = `lit-${k}`;
468
+ } else if (shine < 0) {
469
+ const row = `0 0 ${shine} 0 ${1 - 128 * shine / 255}`;
470
+ filter.append(
471
+ svg("feColorMatrix", {
472
+ in: merged("raw"),
473
+ type: "matrix",
474
+ values: `${row} ${row} ${row} 0 0 0 0 1`,
475
+ result: `shade-${k}`
476
+ }),
477
+ svg("feComposite", {
478
+ in: `shade-${k}`,
479
+ in2: bent,
480
+ operator: "arithmetic",
481
+ k1: 1,
482
+ result: `lit-${k}`
483
+ })
484
+ );
485
+ lit = `lit-${k}`;
486
+ }
487
+ filter.append(
488
+ svg("feComposite", {
489
+ in: lit,
490
+ in2: merged("raw"),
491
+ operator: "in",
492
+ result: merged("inside")
493
+ })
494
+ );
495
+ });
496
+ filter.append(
497
+ svg("feComposite", {
498
+ in: "SourceGraphic",
499
+ in2: "raw",
500
+ operator: "out",
501
+ result: "outside"
502
+ }),
503
+ svg("feComposite", {
504
+ in: "inside",
505
+ in2: "outside",
506
+ operator: "arithmetic",
507
+ k2: 1,
508
+ k3: 1,
509
+ result: "seen"
510
+ })
511
+ );
512
+ return filter;
513
+ }
514
+ var filterIdCounter = 0;
177
515
  var filterContainer = null;
178
- var filterCounter = 0;
179
516
  function getFilterContainer() {
180
- if (filterContainer && document.body.contains(filterContainer)) {
517
+ if (filterContainer && filterContainer.isConnected) {
181
518
  return filterContainer;
182
519
  }
183
- filterContainer = document.createElementNS(SVG_NS, "svg");
184
- filterContainer.setAttribute("aria-hidden", "true");
185
- filterContainer.style.cssText = `
520
+ let container = document.getElementById("lg-glisse-filters");
521
+ if (!container) {
522
+ container = document.createElement("div");
523
+ container.id = "lg-glisse-filters";
524
+ container.innerHTML = '<svg aria-hidden="true" style="position:absolute;width:0;height:0;overflow:hidden;pointer-events:none"><defs></defs></svg>';
525
+ document.body.appendChild(container);
526
+ }
527
+ filterContainer = container;
528
+ return container;
529
+ }
530
+ function useGlisseEffect(ref, options = {}) {
531
+ const {
532
+ enabled = true,
533
+ depth = DEFAULT_LENS.depth,
534
+ dome = DEFAULT_LENS.dome,
535
+ splay = DEFAULT_LENS.splay,
536
+ shine = 0.3,
537
+ density = 0.5,
538
+ lightAngle = DEFAULT_LIGHT.angle
539
+ } = options;
540
+ const [filterUrl, setFilterUrl] = useState4(null);
541
+ const [isReady, setIsReady] = useState4(false);
542
+ const filterRef = useRef(null);
543
+ const currentFilterId = useRef(null);
544
+ const lastDimensions = useRef(null);
545
+ const rafRef = useRef(null);
546
+ const supportsRef = useRef(null);
547
+ const cleanup = useCallback2(() => {
548
+ if (rafRef.current != null) {
549
+ cancelAnimationFrame(rafRef.current);
550
+ rafRef.current = null;
551
+ }
552
+ if (filterRef.current) {
553
+ filterRef.current.remove();
554
+ filterRef.current = null;
555
+ }
556
+ currentFilterId.current = null;
557
+ setFilterUrl(null);
558
+ setIsReady(false);
559
+ }, []);
560
+ const updateFilter = useCallback2((el) => {
561
+ if (!enabled || typeof document === "undefined") {
562
+ cleanup();
563
+ return;
564
+ }
565
+ if (supportsRef.current === null) {
566
+ supportsRef.current = supportsDisplacementMap();
567
+ }
568
+ if (!supportsRef.current) {
569
+ setFilterUrl(null);
570
+ setIsReady(true);
571
+ return;
572
+ }
573
+ const rect = el.getBoundingClientRect();
574
+ const width = Math.max(1, Math.round(rect.width));
575
+ const height = Math.max(1, Math.round(rect.height));
576
+ const computedStyle = getComputedStyle(el);
577
+ const radius = parseFloat(computedStyle.borderRadius) || 0;
578
+ if (lastDimensions.current) {
579
+ const { width: lw, height: lh, radius: lr } = lastDimensions.current;
580
+ if (Math.abs(width - lw) < 2 && Math.abs(height - lh) < 2 && Math.abs(radius - lr) < 1) {
581
+ return;
582
+ }
583
+ }
584
+ lastDimensions.current = { width, height, radius };
585
+ const shape = { width, height, radius };
586
+ const lensOpts = { depth, dome, splay, relative: false };
587
+ const lightOpts = { ...DEFAULT_LIGHT, angle: lightAngle };
588
+ const cacheKey = `${width}:${height}:${radius}:${depth}:${dome}:${splay}:${lightAngle}:${density}`;
589
+ const maps = encode(cacheKey, () => lensMap(shape, lensOpts, lightOpts, density));
590
+ if (!maps) {
591
+ cleanup();
592
+ return;
593
+ }
594
+ const lensConfig = { maps, shine };
595
+ const webKit = isWebKit();
596
+ const filter = buildFilter([lensConfig], webKit);
597
+ const filterId = `lg-glisse-${++filterIdCounter}`;
598
+ filter.id = filterId;
599
+ const container = getFilterContainer();
600
+ const defs = container.querySelector("defs");
601
+ if (filterRef.current) {
602
+ filterRef.current.remove();
603
+ }
604
+ defs.appendChild(filter);
605
+ filterRef.current = filter;
606
+ currentFilterId.current = filterId;
607
+ setFilterUrl(`url(#${filterId})`);
608
+ setIsReady(true);
609
+ }, [enabled, depth, dome, splay, shine, density, lightAngle, cleanup]);
610
+ useEffect4(() => {
611
+ if (!enabled || typeof document === "undefined" || typeof ResizeObserver === "undefined") {
612
+ cleanup();
613
+ return;
614
+ }
615
+ const el = ref.current;
616
+ if (!el) return;
617
+ updateFilter(el);
618
+ const observer = new ResizeObserver(() => {
619
+ if (rafRef.current != null) return;
620
+ rafRef.current = requestAnimationFrame(() => {
621
+ rafRef.current = null;
622
+ if (ref.current) updateFilter(ref.current);
623
+ });
624
+ });
625
+ observer.observe(el);
626
+ return () => {
627
+ observer.disconnect();
628
+ cleanup();
629
+ };
630
+ }, [ref, enabled, updateFilter, cleanup]);
631
+ const rimGradient = `linear-gradient(${lightAngle + 90}deg,
632
+ rgba(255,255,255,0.12) 0%,
633
+ rgba(255,255,255,0.06) 30%,
634
+ transparent 50%,
635
+ rgba(0,0,0,0.04) 100%)`;
636
+ return { filterUrl, rimGradient, isReady };
637
+ }
638
+ function clearGlisseCache() {
639
+ encodedCache.clear();
640
+ }
641
+
642
+ // src/core/svg-filters.ts
643
+ var SVG_NS2 = "http://www.w3.org/2000/svg";
644
+ var filterContainer2 = null;
645
+ var filterCounter = 0;
646
+ function getFilterContainer2() {
647
+ if (filterContainer2 && document.body.contains(filterContainer2)) {
648
+ return filterContainer2;
649
+ }
650
+ filterContainer2 = document.createElementNS(SVG_NS2, "svg");
651
+ filterContainer2.setAttribute("aria-hidden", "true");
652
+ filterContainer2.style.cssText = `
186
653
  position: absolute;
187
654
  width: 0;
188
655
  height: 0;
189
656
  overflow: hidden;
190
657
  pointer-events: none;
191
658
  `;
192
- const defs = document.createElementNS(SVG_NS, "defs");
193
- filterContainer.appendChild(defs);
194
- document.body.appendChild(filterContainer);
195
- return filterContainer;
659
+ const defs = document.createElementNS(SVG_NS2, "defs");
660
+ filterContainer2.appendChild(defs);
661
+ document.body.appendChild(filterContainer2);
662
+ return filterContainer2;
196
663
  }
197
664
  function getDefs() {
198
- const container = getFilterContainer();
665
+ const container = getFilterContainer2();
199
666
  return container.querySelector("defs");
200
667
  }
201
668
  function createSVGElement(tag, attrs = {}) {
202
- const el = document.createElementNS(SVG_NS, tag);
669
+ const el = document.createElementNS(SVG_NS2, tag);
203
670
  for (const [key, value] of Object.entries(attrs)) {
204
671
  el.setAttribute(key, String(value));
205
672
  }
@@ -446,9 +913,9 @@ function createSpecularHighlight(x, y, radius = 200, intensity = 0.08) {
446
913
  )`;
447
914
  }
448
915
  function cleanupFilters() {
449
- if (filterContainer) {
450
- filterContainer.remove();
451
- filterContainer = null;
916
+ if (filterContainer2) {
917
+ filterContainer2.remove();
918
+ filterContainer2 = null;
452
919
  }
453
920
  filterCounter = 0;
454
921
  }
@@ -459,9 +926,15 @@ function supportsBackdropFilter() {
459
926
  return CSS.supports("backdrop-filter", "blur(1px)") || CSS.supports("-webkit-backdrop-filter", "blur(1px)");
460
927
  }
461
928
  function supportsSVGFilters() {
462
- if (typeof document === "undefined") return false;
463
- const svg = document.createElementNS(SVG_NS, "svg");
464
- return "getComputedStyle" in window && svg instanceof SVGElement;
929
+ if (typeof document === "undefined" || typeof window === "undefined") return false;
930
+ try {
931
+ const svg2 = document.createElementNS(SVG_NS2, "svg");
932
+ if (!(svg2 instanceof SVGElement)) return false;
933
+ const displace = document.createElementNS(SVG_NS2, "feDisplacementMap");
934
+ return !!displace && displace.namespaceURI === SVG_NS2 && "scale" in displace;
935
+ } catch {
936
+ return false;
937
+ }
465
938
  }
466
939
 
467
940
  // src/components/Glass.tsx
@@ -476,14 +949,31 @@ var Glass = forwardRef(
476
949
  tint,
477
950
  interactive = false,
478
951
  rimLight = false,
479
- bendStrength = 0.3,
952
+ refraction,
953
+ refractionDepth,
954
+ refractionDome,
955
+ shine,
956
+ lightAngle,
480
957
  children,
481
958
  ...props
482
959
  }, ref) => {
483
- const localRef = useRef(null);
960
+ const localRef = useRef2(null);
484
961
  const combinedRef = ref || localRef;
485
962
  const reducedMotion = useReducedMotion();
486
963
  const pointerPosition = usePointerPosition(combinedRef, { enabled: interactive && !reducedMotion });
964
+ const globalRefraction = useRefraction();
965
+ const shouldRefract = refraction ?? globalRefraction.enabled;
966
+ const depth = refractionDepth ?? globalRefraction.depth;
967
+ const dome = refractionDome ?? globalRefraction.dome;
968
+ const shineValue = shine ?? globalRefraction.shine;
969
+ const angle = lightAngle ?? globalRefraction.lightAngle;
970
+ const { filterUrl, rimGradient: glisseRim, isReady } = useGlisseEffect(combinedRef, {
971
+ enabled: shouldRefract && !reducedMotion,
972
+ depth,
973
+ dome,
974
+ shine: shineValue,
975
+ lightAngle: angle
976
+ });
487
977
  const customStyles = {
488
978
  ...style
489
979
  };
@@ -496,8 +986,13 @@ var Glass = forwardRef(
496
986
  if (tint) {
497
987
  customStyles.backgroundColor = tint;
498
988
  }
499
- if (rimLight) {
500
- customStyles.backgroundImage = createRimLightGradient({ intensity: 0.2 });
989
+ if (shouldRefract && isReady) {
990
+ customStyles.backgroundImage = glisseRim;
991
+ } else if (rimLight) {
992
+ customStyles.backgroundImage = createRimLightGradient({ intensity: 0.15, angle });
993
+ }
994
+ if (shouldRefract && filterUrl && isReady) {
995
+ customStyles.filter = filterUrl;
501
996
  }
502
997
  if (interactive && pointerPosition.isInside) {
503
998
  customStyles["--lg-pointer-x"] = `${pointerPosition.percentX}%`;
@@ -516,6 +1011,7 @@ var Glass = forwardRef(
516
1011
  className: cn(variantClasses[variant], className),
517
1012
  style: customStyles,
518
1013
  "data-hover": interactive && pointerPosition.isInside ? "" : void 0,
1014
+ "data-rim": shouldRefract && isReady ? "" : void 0,
519
1015
  ...props,
520
1016
  children
521
1017
  }
@@ -525,7 +1021,7 @@ var Glass = forwardRef(
525
1021
  Glass.displayName = "Glass";
526
1022
 
527
1023
  // src/components/GlassCard.tsx
528
- import { forwardRef as forwardRef2 } from "react";
1024
+ import { forwardRef as forwardRef2, useRef as useRef3 } from "react";
529
1025
  import { jsx as jsx3 } from "react/jsx-runtime";
530
1026
  var paddingMap = {
531
1027
  none: "0",
@@ -534,11 +1030,11 @@ var paddingMap = {
534
1030
  lg: "24px"
535
1031
  };
536
1032
  var radiusMap = {
537
- sm: "var(--lg-radius-sm)",
538
- md: "var(--lg-radius)",
539
- lg: "var(--lg-radius-lg)",
540
- xl: "var(--lg-radius-xl)",
541
- full: "var(--lg-radius-full)"
1033
+ sm: "8px",
1034
+ md: "12px",
1035
+ lg: "16px",
1036
+ xl: "20px",
1037
+ full: "9999px"
542
1038
  };
543
1039
  var GlassCard = forwardRef2(
544
1040
  ({
@@ -548,14 +1044,25 @@ var GlassCard = forwardRef2(
548
1044
  padding = "md",
549
1045
  radius = "lg",
550
1046
  hoverable = false,
1047
+ disableRefraction = false,
551
1048
  children,
552
1049
  ...props
553
1050
  }, ref) => {
1051
+ const localRef = useRef3(null);
1052
+ const combinedRef = ref || localRef;
1053
+ const reducedMotion = useReducedMotion();
1054
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(combinedRef, {
1055
+ enabled: !disableRefraction && !reducedMotion
1056
+ });
554
1057
  const customStyles = {
555
1058
  padding: paddingMap[padding],
556
1059
  borderRadius: radiusMap[radius],
557
1060
  ...style
558
1061
  };
1062
+ if (isReady && filterUrl) {
1063
+ customStyles.filter = filterUrl;
1064
+ customStyles.backgroundImage = rimGradient;
1065
+ }
559
1066
  const baseClasses = cn(
560
1067
  "lg-glass",
561
1068
  variant === "elevated" && "lg-glass-elevated",
@@ -563,56 +1070,56 @@ var GlassCard = forwardRef2(
563
1070
  hoverable && "transition-transform hover:scale-[1.02] hover:shadow-lg cursor-pointer",
564
1071
  className
565
1072
  );
566
- return /* @__PURE__ */ jsx3("div", { ref, className: baseClasses, style: customStyles, ...props, children });
1073
+ return /* @__PURE__ */ jsx3("div", { ref: combinedRef, className: baseClasses, style: customStyles, ...props, children });
567
1074
  }
568
1075
  );
569
1076
  GlassCard.displayName = "GlassCard";
570
1077
 
571
1078
  // src/components/Button.tsx
572
- import { forwardRef as forwardRef3 } from "react";
1079
+ import { forwardRef as forwardRef3, useRef as useRef5 } from "react";
573
1080
 
574
1081
  // src/hooks/use-pressed-state.ts
575
- import { useState as useState4, useCallback as useCallback2, useRef as useRef2, useEffect as useEffect5 } from "react";
1082
+ import { useState as useState5, useCallback as useCallback3, useRef as useRef4, useEffect as useEffect5 } from "react";
576
1083
  function usePressedState(options = {}) {
577
1084
  const { disabled = false, onPressStart, onPressEnd } = options;
578
- const [isPressed, setIsPressed] = useState4(false);
579
- const pointerIdRef = useRef2(null);
580
- const handlePressStart = useCallback2(() => {
1085
+ const [isPressed, setIsPressed] = useState5(false);
1086
+ const pointerIdRef = useRef4(null);
1087
+ const handlePressStart = useCallback3(() => {
581
1088
  if (disabled) return;
582
1089
  setIsPressed(true);
583
1090
  onPressStart?.();
584
1091
  }, [disabled, onPressStart]);
585
- const handlePressEnd = useCallback2(() => {
1092
+ const handlePressEnd = useCallback3(() => {
586
1093
  setIsPressed(false);
587
1094
  onPressEnd?.();
588
1095
  }, [onPressEnd]);
589
- const onPointerDown = useCallback2((e) => {
1096
+ const onPointerDown = useCallback3((e) => {
590
1097
  if (disabled || pointerIdRef.current !== null) return;
591
1098
  pointerIdRef.current = e.pointerId;
592
1099
  handlePressStart();
593
1100
  e.target.setPointerCapture?.(e.pointerId);
594
1101
  }, [disabled, handlePressStart]);
595
- const onPointerUp = useCallback2((e) => {
1102
+ const onPointerUp = useCallback3((e) => {
596
1103
  if (pointerIdRef.current !== e.pointerId) return;
597
1104
  pointerIdRef.current = null;
598
1105
  handlePressEnd();
599
1106
  }, [handlePressEnd]);
600
- const onPointerCancel = useCallback2((e) => {
1107
+ const onPointerCancel = useCallback3((e) => {
601
1108
  if (pointerIdRef.current !== e.pointerId) return;
602
1109
  pointerIdRef.current = null;
603
1110
  handlePressEnd();
604
1111
  }, [handlePressEnd]);
605
- const onPointerLeave = useCallback2((e) => {
1112
+ const onPointerLeave = useCallback3((e) => {
606
1113
  if (pointerIdRef.current !== e.pointerId) return;
607
1114
  }, []);
608
- const onKeyDown = useCallback2((e) => {
1115
+ const onKeyDown = useCallback3((e) => {
609
1116
  if (disabled) return;
610
1117
  if (e.key === " " || e.key === "Enter") {
611
1118
  e.preventDefault();
612
1119
  handlePressStart();
613
1120
  }
614
1121
  }, [disabled, handlePressStart]);
615
- const onKeyUp = useCallback2((e) => {
1122
+ const onKeyUp = useCallback3((e) => {
616
1123
  if (e.key === " " || e.key === "Enter") {
617
1124
  handlePressEnd();
618
1125
  }
@@ -676,23 +1183,38 @@ var Button = forwardRef3(
676
1183
  loading = false,
677
1184
  fullWidth = false,
678
1185
  disabled,
1186
+ disableRefraction = false,
679
1187
  children,
680
1188
  ...props
681
1189
  }, ref) => {
1190
+ const localRef = useRef5(null);
1191
+ const combinedRef = ref || localRef;
682
1192
  const { isPressed, pressHandlers } = usePressedState({ disabled: disabled || loading });
683
- const sizeConfig15 = sizeStyles[size];
1193
+ const reducedMotion = useReducedMotion();
1194
+ const sizeConfig14 = sizeStyles[size];
1195
+ const shouldRefract = variant === "glass" && !disableRefraction && !reducedMotion;
1196
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(combinedRef, {
1197
+ enabled: shouldRefract,
1198
+ depth: 6,
1199
+ dome: 3,
1200
+ shine: 0.25
1201
+ });
684
1202
  const customStyles = {
685
- height: sizeConfig15.height,
686
- padding: icon && !children ? "0" : sizeConfig15.padding,
687
- fontSize: sizeConfig15.fontSize,
688
- borderRadius: sizeConfig15.borderRadius,
689
- gap: sizeConfig15.gap,
690
- width: icon && !children ? sizeConfig15.height : fullWidth ? "100%" : void 0,
1203
+ height: sizeConfig14.height,
1204
+ padding: icon && !children ? "0" : sizeConfig14.padding,
1205
+ fontSize: sizeConfig14.fontSize,
1206
+ borderRadius: sizeConfig14.borderRadius,
1207
+ gap: sizeConfig14.gap,
1208
+ width: icon && !children ? sizeConfig14.height : fullWidth ? "100%" : void 0,
691
1209
  ...style
692
1210
  };
693
1211
  if (tint && !destructive) {
694
1212
  customStyles["--lg-tint"] = tint;
695
1213
  }
1214
+ if (shouldRefract && isReady && filterUrl) {
1215
+ customStyles.filter = filterUrl;
1216
+ customStyles.backgroundImage = rimGradient;
1217
+ }
696
1218
  const baseClasses = cn(
697
1219
  "lg-glass lg-interactive lg-focus-ring",
698
1220
  "inline-flex items-center justify-center",
@@ -718,7 +1240,7 @@ var Button = forwardRef3(
718
1240
  return /* @__PURE__ */ jsx4(
719
1241
  "button",
720
1242
  {
721
- ref,
1243
+ ref: combinedRef,
722
1244
  className: baseClasses,
723
1245
  style: { ...customStyles, ...variantStyles2 },
724
1246
  disabled: disabled || loading,
@@ -733,8 +1255,8 @@ var Button = forwardRef3(
733
1255
  {
734
1256
  className: "animate-spin",
735
1257
  style: {
736
- width: sizeConfig15.iconSize,
737
- height: sizeConfig15.iconSize,
1258
+ width: sizeConfig14.iconSize,
1259
+ height: sizeConfig14.iconSize,
738
1260
  border: "2px solid currentColor",
739
1261
  borderTopColor: "transparent",
740
1262
  borderRadius: "50%"
@@ -745,7 +1267,7 @@ var Button = forwardRef3(
745
1267
  "span",
746
1268
  {
747
1269
  className: "flex items-center justify-center",
748
- style: { width: sizeConfig15.iconSize, height: sizeConfig15.iconSize },
1270
+ style: { width: sizeConfig14.iconSize, height: sizeConfig14.iconSize },
749
1271
  children: icon
750
1272
  }
751
1273
  ),
@@ -754,7 +1276,7 @@ var Button = forwardRef3(
754
1276
  "span",
755
1277
  {
756
1278
  className: "flex items-center justify-center",
757
- style: { width: sizeConfig15.iconSize, height: sizeConfig15.iconSize },
1279
+ style: { width: sizeConfig14.iconSize, height: sizeConfig14.iconSize },
758
1280
  children: icon
759
1281
  }
760
1282
  )
@@ -787,10 +1309,10 @@ var IconButton = forwardRef4(
787
1309
  ...props
788
1310
  }, ref) => {
789
1311
  const { isPressed, pressHandlers } = usePressedState({ disabled: disabled || loading });
790
- const sizeConfig15 = sizeStyles2[size];
1312
+ const sizeConfig14 = sizeStyles2[size];
791
1313
  const customStyles = {
792
- width: sizeConfig15.size,
793
- height: sizeConfig15.size,
1314
+ width: sizeConfig14.size,
1315
+ height: sizeConfig14.size,
794
1316
  borderRadius: "50%",
795
1317
  ...style
796
1318
  };
@@ -827,8 +1349,8 @@ var IconButton = forwardRef4(
827
1349
  {
828
1350
  className: "animate-spin",
829
1351
  style: {
830
- width: sizeConfig15.iconSize,
831
- height: sizeConfig15.iconSize,
1352
+ width: sizeConfig14.iconSize,
1353
+ height: sizeConfig14.iconSize,
832
1354
  border: "2px solid currentColor",
833
1355
  borderTopColor: "transparent",
834
1356
  borderRadius: "50%"
@@ -838,7 +1360,7 @@ var IconButton = forwardRef4(
838
1360
  "span",
839
1361
  {
840
1362
  className: "flex items-center justify-center",
841
- style: { width: sizeConfig15.iconSize, height: sizeConfig15.iconSize },
1363
+ style: { width: sizeConfig14.iconSize, height: sizeConfig14.iconSize },
842
1364
  children: icon
843
1365
  }
844
1366
  )
@@ -852,13 +1374,13 @@ IconButton.displayName = "IconButton";
852
1374
  import { forwardRef as forwardRef5 } from "react";
853
1375
 
854
1376
  // src/hooks/use-controllable.ts
855
- import { useState as useState5, useCallback as useCallback3 } from "react";
1377
+ import { useState as useState6, useCallback as useCallback4 } from "react";
856
1378
  function useControllable(options) {
857
1379
  const { value: controlledValue, defaultValue, onChange } = options;
858
1380
  const isControlled = controlledValue !== void 0;
859
- const [uncontrolledValue, setUncontrolledValue] = useState5(defaultValue);
1381
+ const [uncontrolledValue, setUncontrolledValue] = useState6(defaultValue);
860
1382
  const value = isControlled ? controlledValue : uncontrolledValue;
861
- const setValue = useCallback3((newValue) => {
1383
+ const setValue = useCallback4((newValue) => {
862
1384
  if (!isControlled) {
863
1385
  setUncontrolledValue(newValue);
864
1386
  }
@@ -869,9 +1391,9 @@ function useControllable(options) {
869
1391
  function useControllableBoolean(options) {
870
1392
  const { checked, defaultChecked = false, onCheckedChange } = options;
871
1393
  const isControlled = checked !== void 0;
872
- const [uncontrolledValue, setUncontrolledValue] = useState5(defaultChecked);
1394
+ const [uncontrolledValue, setUncontrolledValue] = useState6(defaultChecked);
873
1395
  const value = isControlled ? checked : uncontrolledValue;
874
- const setValue = useCallback3((newValue) => {
1396
+ const setValue = useCallback4((newValue) => {
875
1397
  if (!isControlled) {
876
1398
  setUncontrolledValue(newValue);
877
1399
  }
@@ -965,7 +1487,7 @@ var Toggle = forwardRef5(
965
1487
  Toggle.displayName = "Toggle";
966
1488
 
967
1489
  // src/components/Input.tsx
968
- import { forwardRef as forwardRef6, useState as useState6 } from "react";
1490
+ import { forwardRef as forwardRef6, useState as useState7 } from "react";
969
1491
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
970
1492
  var sizeConfig2 = {
971
1493
  sm: { height: 32, padding: "0 10px", fontSize: 13, iconSize: 14, borderRadius: 16 },
@@ -993,7 +1515,7 @@ var Input = forwardRef6(
993
1515
  defaultValue,
994
1516
  onChange: onValueChange
995
1517
  });
996
- const [isFocused, setIsFocused] = useState6(false);
1518
+ const [isFocused, setIsFocused] = useState7(false);
997
1519
  const config = sizeConfig2[size];
998
1520
  const handleChange = (e) => {
999
1521
  setValue(e.target.value);
@@ -1080,7 +1602,7 @@ var Input = forwardRef6(
1080
1602
  Input.displayName = "Input";
1081
1603
 
1082
1604
  // src/components/Textarea.tsx
1083
- import { forwardRef as forwardRef7, useState as useState7 } from "react";
1605
+ import { forwardRef as forwardRef7, useState as useState8 } from "react";
1084
1606
  import { jsx as jsx8 } from "react/jsx-runtime";
1085
1607
  var Textarea = forwardRef7(
1086
1608
  ({
@@ -1100,7 +1622,7 @@ var Textarea = forwardRef7(
1100
1622
  defaultValue,
1101
1623
  onChange: onValueChange
1102
1624
  });
1103
- const [isFocused, setIsFocused] = useState7(false);
1625
+ const [isFocused, setIsFocused] = useState8(false);
1104
1626
  const handleChange = (e) => {
1105
1627
  setValue(e.target.value);
1106
1628
  };
@@ -1177,7 +1699,7 @@ var SearchField = forwardRef8(
1177
1699
  SearchField.displayName = "SearchField";
1178
1700
 
1179
1701
  // src/components/Select.tsx
1180
- import { forwardRef as forwardRef9, useState as useState8, useRef as useRef4, useEffect as useEffect7, useCallback as useCallback4 } from "react";
1702
+ import { forwardRef as forwardRef9, useState as useState9, useRef as useRef7, useEffect as useEffect7, useCallback as useCallback5 } from "react";
1181
1703
  import { createPortal } from "react-dom";
1182
1704
 
1183
1705
  // src/hooks/use-id.ts
@@ -1218,16 +1740,16 @@ var Select = forwardRef9(
1218
1740
  defaultValue,
1219
1741
  onChange: onValueChange
1220
1742
  });
1221
- const [isOpen, setIsOpen] = useState8(false);
1222
- const [focusedIndex, setFocusedIndex] = useState8(-1);
1223
- const triggerRef = useRef4(null);
1224
- const menuRef = useRef4(null);
1743
+ const [isOpen, setIsOpen] = useState9(false);
1744
+ const [focusedIndex, setFocusedIndex] = useState9(-1);
1745
+ const triggerRef = useRef7(null);
1746
+ const menuRef = useRef7(null);
1225
1747
  const reducedMotion = useReducedMotion();
1226
1748
  const id = useId(providedId);
1227
1749
  const menuId = `${id}-menu`;
1228
1750
  const config = sizeConfig3[size];
1229
1751
  const selectedOption = options.find((opt) => opt.value === value);
1230
- const updateMenuPosition = useCallback4(() => {
1752
+ const updateMenuPosition = useCallback5(() => {
1231
1753
  if (!triggerRef.current || !menuRef.current) return;
1232
1754
  const rect = triggerRef.current.getBoundingClientRect();
1233
1755
  menuRef.current.style.top = `${rect.bottom + window.scrollY + 4}px`;
@@ -1628,13 +2150,25 @@ var Radio = forwardRef11(
1628
2150
  Radio.displayName = "Radio";
1629
2151
 
1630
2152
  // src/components/Switch.tsx
1631
- import { forwardRef as forwardRef12, useState as useState9 } from "react";
2153
+ import {
2154
+ forwardRef as forwardRef12,
2155
+ useRef as useRef8,
2156
+ useState as useState10,
2157
+ useImperativeHandle
2158
+ } from "react";
1632
2159
  import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1633
- var sizeConfig6 = {
1634
- sm: { width: 44, height: 24, thumbSize: 20, travel: 20 },
1635
- md: { width: 51, height: 31, thumbSize: 27, travel: 20 },
1636
- lg: { width: 60, height: 36, thumbSize: 32, travel: 24 }
2160
+ var SCALE_BY_SIZE = {
2161
+ sm: 0.3,
2162
+ md: 0.375,
2163
+ lg: 0.5
1637
2164
  };
2165
+ var THUMB_SHADOW = `
2166
+ 0 6px 24px rgba(0,0,0,0.2),
2167
+ inset 0 0 0 1.5px rgba(255,255,255,0.5),
2168
+ inset 0 2px 1px rgba(255,255,255,0.45),
2169
+ inset 2px 7px 24px rgba(0,0,0,0.09),
2170
+ inset -2px -7px 24px rgba(255,255,255,0.16)
2171
+ `;
1638
2172
  var Switch = forwardRef12(
1639
2173
  ({
1640
2174
  className,
@@ -1645,93 +2179,152 @@ var Switch = forwardRef12(
1645
2179
  size = "md",
1646
2180
  disabled,
1647
2181
  ...props
1648
- }, ref) => {
2182
+ }, forwardedRef) => {
1649
2183
  const [checked, setChecked] = useControllableBoolean({
1650
2184
  checked: controlledChecked,
1651
2185
  defaultChecked,
1652
2186
  onCheckedChange
1653
2187
  });
1654
- const [lift, setLift] = useState9(0);
2188
+ const [lift, setLift] = useState10(0);
1655
2189
  const reducedMotion = useReducedMotion();
1656
- const config = sizeConfig6[size];
1657
- const { isPressed, pressHandlers } = usePressedState({
1658
- disabled,
1659
- onPressStart: () => !reducedMotion && setLift(1),
1660
- onPressEnd: () => setLift(0)
2190
+ const rootRef = useRef8(null);
2191
+ const thumbRef = useRef8(null);
2192
+ const gestureRef = useRef8(null);
2193
+ useImperativeHandle(forwardedRef, () => rootRef.current);
2194
+ const scale = SCALE_BY_SIZE[size];
2195
+ const travel = 57.9 * scale;
2196
+ const width = 160 * scale;
2197
+ const height = 67 * scale;
2198
+ const thumbWidth = 146 * scale;
2199
+ const thumbHeight = 92 * scale;
2200
+ const thumbScale = 0.65 + lift * 0.25;
2201
+ const thumbX = checked ? travel : 0;
2202
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(thumbRef, {
2203
+ enabled: !reducedMotion,
2204
+ depth: 2,
2205
+ dome: 6,
2206
+ splay: 0.4,
2207
+ shine: 0.3
1661
2208
  });
1662
2209
  const handleClick = () => {
1663
- if (!disabled) {
2210
+ if (!disabled && !gestureRef.current) {
1664
2211
  setChecked(!checked);
1665
2212
  }
1666
2213
  };
1667
- const customStyles = {
1668
- width: config.width,
1669
- height: config.height,
2214
+ const handlePointerDown = (e) => {
2215
+ if (disabled || e.button !== 0) return;
2216
+ e.preventDefault();
2217
+ gestureRef.current = {
2218
+ id: e.pointerId,
2219
+ x: e.clientX,
2220
+ from: checked ? 1 : 0
2221
+ };
2222
+ rootRef.current?.setPointerCapture(e.pointerId);
2223
+ if (!reducedMotion) setLift(1);
2224
+ };
2225
+ const handlePointerUp = (e) => {
2226
+ if (gestureRef.current?.id !== e.pointerId) return;
2227
+ const gesture = gestureRef.current;
2228
+ gestureRef.current = null;
2229
+ setLift(0);
2230
+ const dx = e.clientX - gesture.x;
2231
+ if (Math.abs(dx) > 4) {
2232
+ const value = gesture.from + dx / travel;
2233
+ setChecked(value > 0.5);
2234
+ } else {
2235
+ setChecked(!checked);
2236
+ }
2237
+ };
2238
+ const handlePointerCancel = () => {
2239
+ gestureRef.current = null;
2240
+ setLift(0);
2241
+ };
2242
+ const rootStyles = {
2243
+ width,
2244
+ height,
1670
2245
  ...style
1671
2246
  };
1672
2247
  const thumbStyles = {
1673
- "--lg-lift": lift,
1674
- width: config.thumbSize + lift * 8,
1675
- height: config.thumbSize + lift * 4,
1676
- transform: `translateX(${checked ? config.travel : 0}px) scale(${1 - lift * 0.05})`,
1677
- transition: reducedMotion ? "none" : "transform 200ms var(--lg-ease-spring), width 150ms var(--lg-ease), height 150ms var(--lg-ease)"
2248
+ position: "absolute",
2249
+ top: "50%",
2250
+ left: -21.95 * scale,
2251
+ width: thumbWidth,
2252
+ height: thumbHeight,
2253
+ transform: `translate(${thumbX}px, -50%) scale(${thumbScale})`,
2254
+ transition: reducedMotion ? "none" : "transform 200ms cubic-bezier(.25,.1,.25,1)",
2255
+ borderRadius: 9999,
2256
+ backdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
2257
+ WebkitBackdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
2258
+ boxShadow: THUMB_SHADOW,
2259
+ pointerEvents: "none",
2260
+ ...isReady && filterUrl ? { filter: filterUrl, backgroundImage: rimGradient } : {}
1678
2261
  };
1679
2262
  return /* @__PURE__ */ jsxs8(
1680
2263
  "button",
1681
2264
  {
1682
- ref,
2265
+ ref: rootRef,
2266
+ type: "button",
1683
2267
  role: "switch",
1684
2268
  "aria-checked": checked,
1685
2269
  className: cn(
1686
- "lg-interactive lg-focus-ring",
1687
- "relative inline-flex items-center",
1688
- "p-0 border-0 rounded-full cursor-pointer",
2270
+ "lg-focus-ring relative inline-flex items-center shrink-0",
2271
+ "p-0 border-0 rounded-full cursor-pointer touch-pan-y",
2272
+ "bg-transparent",
1689
2273
  disabled && "opacity-35 cursor-default",
1690
2274
  className
1691
2275
  ),
1692
- style: customStyles,
2276
+ style: rootStyles,
1693
2277
  disabled,
1694
2278
  onClick: handleClick,
1695
- ...pressHandlers,
2279
+ onPointerDown: handlePointerDown,
2280
+ onPointerUp: handlePointerUp,
2281
+ onPointerCancel: handlePointerCancel,
1696
2282
  ...props,
1697
2283
  children: [
1698
2284
  /* @__PURE__ */ jsx13(
1699
2285
  "span",
1700
2286
  {
1701
- className: "absolute inset-0 rounded-full transition-colors",
1702
- style: {
1703
- backgroundColor: checked ? "var(--lg-on)" : "var(--lg-track)",
1704
- transition: reducedMotion ? "none" : "background-color 200ms var(--lg-ease)"
1705
- }
1706
- }
1707
- ),
1708
- /* @__PURE__ */ jsx13(
1709
- "span",
1710
- {
1711
- className: "absolute rounded-full",
1712
- style: {
1713
- ...thumbStyles,
1714
- left: 2,
1715
- top: "50%",
1716
- marginTop: -(config.thumbSize + lift * 4) / 2,
1717
- backdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
1718
- boxShadow: `
1719
- 0 6px 24px rgb(0 0 0 / 0.2),
1720
- inset 0 0 0 1.5px rgb(255 255 255 / 0.5),
1721
- inset 0 2px 1px rgb(255 255 255 / 0.45)
1722
- `
1723
- },
2287
+ "aria-hidden": true,
2288
+ style: { position: "absolute", inset: "-6px -12px", pointerEvents: "none" },
1724
2289
  children: /* @__PURE__ */ jsx13(
1725
2290
  "span",
1726
2291
  {
1727
- className: "absolute inset-0 rounded-full bg-white",
1728
2292
  style: {
1729
- opacity: 1 - lift * 0.3
1730
- }
2293
+ position: "absolute",
2294
+ inset: "6px 12px",
2295
+ borderRadius: 9999,
2296
+ backgroundColor: "var(--lg-track)"
2297
+ },
2298
+ children: /* @__PURE__ */ jsx13(
2299
+ "span",
2300
+ {
2301
+ style: {
2302
+ position: "absolute",
2303
+ inset: 0,
2304
+ borderRadius: 9999,
2305
+ backgroundColor: "var(--lg-on)",
2306
+ opacity: checked ? 1 : 0,
2307
+ transition: reducedMotion ? "none" : "opacity 200ms cubic-bezier(.25,.1,.25,1)"
2308
+ }
2309
+ }
2310
+ )
1731
2311
  }
1732
2312
  )
1733
2313
  }
1734
- )
2314
+ ),
2315
+ /* @__PURE__ */ jsx13("span", { ref: thumbRef, "aria-hidden": true, style: thumbStyles, children: /* @__PURE__ */ jsx13(
2316
+ "span",
2317
+ {
2318
+ "aria-hidden": true,
2319
+ style: {
2320
+ position: "absolute",
2321
+ inset: 0,
2322
+ borderRadius: "inherit",
2323
+ backgroundColor: "#fff",
2324
+ opacity: 1 - lift * 0.85
2325
+ }
2326
+ }
2327
+ ) })
1735
2328
  ]
1736
2329
  }
1737
2330
  );
@@ -1740,10 +2333,15 @@ var Switch = forwardRef12(
1740
2333
  Switch.displayName = "Switch";
1741
2334
 
1742
2335
  // src/components/Slider.tsx
1743
- import { forwardRef as forwardRef13, useState as useState10, useRef as useRef6, useCallback as useCallback5 } from "react";
2336
+ import {
2337
+ forwardRef as forwardRef13,
2338
+ useState as useState11,
2339
+ useRef as useRef9,
2340
+ useCallback as useCallback6
2341
+ } from "react";
1744
2342
 
1745
2343
  // src/utils/index.ts
1746
- function clamp(value, min, max) {
2344
+ function clamp2(value, min, max) {
1747
2345
  return Math.min(Math.max(value, min), max);
1748
2346
  }
1749
2347
  function lerp(start, end, t) {
@@ -1780,6 +2378,13 @@ function isBrowser() {
1780
2378
 
1781
2379
  // src/components/Slider.tsx
1782
2380
  import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2381
+ var THUMB_SHADOW2 = `
2382
+ 0 6px 24px rgba(0,0,0,0.2),
2383
+ inset 0 0 0 1.5px rgba(255,255,255,0.5),
2384
+ inset 0 2px 1px rgba(255,255,255,0.45),
2385
+ inset 2px 7px 24px rgba(0,0,0,0.09),
2386
+ inset -2px -7px 24px rgba(255,255,255,0.16)
2387
+ `;
1783
2388
  var Slider = forwardRef13(
1784
2389
  ({
1785
2390
  className,
@@ -1800,19 +2405,30 @@ var Slider = forwardRef13(
1800
2405
  defaultValue,
1801
2406
  onChange: onValueChange
1802
2407
  });
1803
- const [lift, setLift] = useState10(0);
1804
- const [isDragging, setIsDragging] = useState10(false);
2408
+ const [lift, setLift] = useState11(0);
2409
+ const [isDragging, setIsDragging] = useState11(false);
1805
2410
  const reducedMotion = useReducedMotion();
1806
- const trackRef = useRef6(null);
2411
+ const thumbRef = useRef9(null);
1807
2412
  const currentValue = value ?? defaultValue;
1808
2413
  const progress = mapRange(currentValue, min, max, 0, 1);
1809
- const handlePointerDown = useCallback5((e) => {
1810
- if (disabled) return;
1811
- setIsDragging(true);
1812
- if (!reducedMotion) setLift(1);
1813
- e.target.setPointerCapture(e.pointerId);
1814
- }, [disabled, reducedMotion]);
1815
- const handlePointerUp = useCallback5(() => {
2414
+ const thumbScale = 0.6 + lift * 0.4;
2415
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(thumbRef, {
2416
+ enabled: !reducedMotion,
2417
+ depth: 2,
2418
+ dome: 6,
2419
+ splay: 0.4,
2420
+ shine: 0.3
2421
+ });
2422
+ const handlePointerDown = useCallback6(
2423
+ (e) => {
2424
+ if (disabled) return;
2425
+ setIsDragging(true);
2426
+ if (!reducedMotion) setLift(1);
2427
+ e.target.setPointerCapture(e.pointerId);
2428
+ },
2429
+ [disabled, reducedMotion]
2430
+ );
2431
+ const handlePointerUp = useCallback6(() => {
1816
2432
  setIsDragging(false);
1817
2433
  setLift(0);
1818
2434
  }, []);
@@ -1820,75 +2436,64 @@ var Slider = forwardRef13(
1820
2436
  setValue(parseFloat(e.target.value));
1821
2437
  };
1822
2438
  const thumbStyles = {
1823
- "--lg-lift": lift,
1824
- "--lg-progress": progress,
1825
- left: `calc(${progress * 100}% - 18px)`,
1826
- width: 36 + lift * 24,
1827
- height: 36 + lift * 4,
1828
- transform: `scale(${0.6 + lift * 0.15})`,
1829
- transition: reducedMotion || isDragging ? "none" : "transform 150ms var(--lg-ease), width 150ms var(--lg-ease), height 150ms var(--lg-ease)"
2439
+ position: "absolute",
2440
+ top: 0,
2441
+ left: `calc((100% - 36px) * ${progress} - 12px)`,
2442
+ width: 60,
2443
+ height: 40,
2444
+ transform: `scale(${thumbScale})`,
2445
+ transformOrigin: "center center",
2446
+ transition: reducedMotion || isDragging ? "none" : "transform 150ms cubic-bezier(.25,.1,.25,1), left 50ms linear",
2447
+ borderRadius: 9999,
2448
+ backdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
2449
+ WebkitBackdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
2450
+ boxShadow: THUMB_SHADOW2,
2451
+ pointerEvents: "none",
2452
+ ...isReady && filterUrl ? { filter: filterUrl, backgroundImage: rimGradient } : {}
1830
2453
  };
1831
2454
  return /* @__PURE__ */ jsxs9(
1832
2455
  "div",
1833
2456
  {
1834
- ref: trackRef,
1835
- className: cn(
1836
- "relative w-full h-10",
1837
- disabled && "opacity-35",
1838
- className
1839
- ),
2457
+ className: cn("relative w-full h-10", disabled && "opacity-35", className),
1840
2458
  style,
1841
2459
  children: [
1842
2460
  /* @__PURE__ */ jsx14(
1843
2461
  "div",
1844
2462
  {
1845
- className: "absolute rounded-full",
2463
+ className: "absolute rounded-[3px] pointer-events-none",
1846
2464
  style: {
1847
2465
  top: 17,
1848
2466
  left: 0,
1849
2467
  right: 0,
1850
2468
  height: 6,
1851
2469
  backgroundColor: "var(--lg-rail)"
1852
- }
1853
- }
1854
- ),
1855
- /* @__PURE__ */ jsx14(
1856
- "div",
1857
- {
1858
- className: "absolute rounded-full",
1859
- style: {
1860
- top: 17,
1861
- left: 0,
1862
- width: `calc(${progress * 100}%)`,
1863
- height: 6,
1864
- backgroundColor: "var(--lg-fill)",
1865
- transition: isDragging ? "none" : "width 50ms linear"
1866
- }
1867
- }
1868
- ),
1869
- /* @__PURE__ */ jsx14(
1870
- "div",
1871
- {
1872
- className: "absolute rounded-full pointer-events-none",
1873
- style: {
1874
- ...thumbStyles,
1875
- top: 2,
1876
- backdropFilter: `blur(${2 * (1 - lift) + 0.5 * lift}px) brightness(${1 + 0.15 * (1 - lift)}) saturate(1.5)`,
1877
- boxShadow: `
1878
- 0 6px 24px rgb(0 0 0 / 0.2),
1879
- inset 0 0 0 1.5px rgb(255 255 255 / 0.5),
1880
- inset 0 2px 1px rgb(255 255 255 / 0.45)
1881
- `
1882
2470
  },
1883
2471
  children: /* @__PURE__ */ jsx14(
1884
2472
  "span",
1885
2473
  {
1886
- className: "absolute inset-0 rounded-full bg-white",
1887
- style: { opacity: 1 - lift * 0.3 }
2474
+ className: "block h-full rounded-[inherit]",
2475
+ style: {
2476
+ width: `calc((100% - 36px) * ${progress} + 18px)`,
2477
+ backgroundColor: "var(--lg-fill)",
2478
+ transition: isDragging ? "none" : "width 50ms linear"
2479
+ }
1888
2480
  }
1889
2481
  )
1890
2482
  }
1891
2483
  ),
2484
+ /* @__PURE__ */ jsx14("div", { ref: thumbRef, "aria-hidden": true, style: thumbStyles, children: /* @__PURE__ */ jsx14(
2485
+ "span",
2486
+ {
2487
+ "aria-hidden": true,
2488
+ style: {
2489
+ position: "absolute",
2490
+ inset: 0,
2491
+ borderRadius: "inherit",
2492
+ backgroundColor: "#fff",
2493
+ opacity: 1 - lift * 0.85
2494
+ }
2495
+ }
2496
+ ) }),
1892
2497
  /* @__PURE__ */ jsx14(
1893
2498
  "input",
1894
2499
  {
@@ -1915,7 +2520,7 @@ var Slider = forwardRef13(
1915
2520
  showValue && /* @__PURE__ */ jsx14(
1916
2521
  "div",
1917
2522
  {
1918
- className: "absolute text-xs font-medium text-center",
2523
+ className: "absolute text-xs font-medium text-center pointer-events-none",
1919
2524
  style: {
1920
2525
  left: `${progress * 100}%`,
1921
2526
  top: -20,
@@ -1933,7 +2538,11 @@ var Slider = forwardRef13(
1933
2538
  Slider.displayName = "Slider";
1934
2539
 
1935
2540
  // src/components/TabBar.tsx
1936
- import { forwardRef as forwardRef14, useState as useState11 } from "react";
2541
+ import {
2542
+ forwardRef as forwardRef14,
2543
+ useState as useState12,
2544
+ useRef as useRef10
2545
+ } from "react";
1937
2546
  import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
1938
2547
  var TabBar = forwardRef14(
1939
2548
  ({
@@ -1953,13 +2562,31 @@ var TabBar = forwardRef14(
1953
2562
  defaultValue: defaultValue ?? items[0]?.value ?? null,
1954
2563
  onChange: onValueChange
1955
2564
  });
1956
- const [lift, setLift] = useState11(0);
2565
+ const [lift, setLift] = useState12(0);
1957
2566
  const reducedMotion = useReducedMotion();
2567
+ const containerRef = useRef10(null);
2568
+ const lensRef = useRef10(null);
1958
2569
  const selectedIndex = items.findIndex((item) => item.value === value);
1959
2570
  const hasIcons = items.some((item) => item.icon);
1960
2571
  const tabWidth = hasIcons ? 72 : 84;
1961
2572
  const tabHeight = hasIcons ? 52 : 32;
1962
2573
  const inset = 4;
2574
+ const lensGrowX = hasIcons ? 24 : 27;
2575
+ const lensGrowY = hasIcons ? 16 : 20;
2576
+ const { filterUrl: containerFilter, rimGradient: containerRim, isReady: containerReady } = useGlisseEffect(containerRef, {
2577
+ enabled: !reducedMotion,
2578
+ depth: 6,
2579
+ dome: 3
2580
+ });
2581
+ const { filterUrl: lensFilter, rimGradient: lensRim, isReady: lensReady } = useGlisseEffect(
2582
+ lensRef,
2583
+ {
2584
+ enabled: !reducedMotion && lift > 0.01,
2585
+ depth: 4,
2586
+ dome: 3,
2587
+ splay: 0.5
2588
+ }
2589
+ );
1963
2590
  const handleSelect = (itemValue) => {
1964
2591
  setValue(itemValue);
1965
2592
  };
@@ -1969,45 +2596,47 @@ var TabBar = forwardRef14(
1969
2596
  const handlePointerUp = () => {
1970
2597
  setLift(0);
1971
2598
  };
2599
+ const setRefs = (node) => {
2600
+ containerRef.current = node;
2601
+ if (typeof ref === "function") ref(node);
2602
+ else if (ref) ref.current = node;
2603
+ };
1972
2604
  const containerStyles = {
1973
2605
  padding: inset,
1974
2606
  borderRadius: tabHeight / 2 + inset,
2607
+ ...containerReady && containerFilter ? { filter: containerFilter, backgroundImage: containerRim } : {},
1975
2608
  ...style
1976
2609
  };
1977
2610
  const lensStyles = {
1978
- "--lg-lift": lift,
1979
2611
  position: "absolute",
1980
- top: inset,
1981
- left: inset,
1982
- width: tabWidth + lift * 27,
1983
- height: tabHeight + lift * 20,
1984
- marginTop: -lift * 10,
1985
- marginLeft: -lift * 13.5,
1986
- borderRadius: (tabHeight + lift * 20) / 2,
1987
- transform: `translateX(${selectedIndex * tabWidth}px) scale(${1 + lift * 0.05})`,
1988
- transition: reducedMotion ? "none" : "transform 200ms var(--lg-ease-spring), width 150ms var(--lg-ease), height 150ms var(--lg-ease), margin 150ms var(--lg-ease)",
1989
- background: "var(--lg-selection)",
1990
- boxShadow: lift > 0.5 ? `0 ${7 / (1 + lift * 0.5)}px ${11 / (1 + lift * 0.5)}px var(--lg-lens-drop)` : "none"
2612
+ top: inset - lift * lensGrowY / 2,
2613
+ left: inset - lift * lensGrowX / 2,
2614
+ width: tabWidth + lift * lensGrowX,
2615
+ height: tabHeight + lift * lensGrowY,
2616
+ borderRadius: (tabHeight + lift * lensGrowY) / 2,
2617
+ transform: `translateX(${Math.max(0, selectedIndex) * tabWidth}px)`,
2618
+ transition: reducedMotion ? "none" : "transform 200ms cubic-bezier(.25,.1,.25,1), width 150ms cubic-bezier(.25,.1,.25,1), height 150ms cubic-bezier(.25,.1,.25,1), top 150ms, left 150ms, background-color 140ms",
2619
+ backgroundColor: lift > 0.5 ? "var(--lg-lens)" : "var(--lg-selection)",
2620
+ boxShadow: lift > 0.5 ? `0 ${7 / (1 + lift * 0.5)}px ${11 / (1 + lift * 0.5)}px var(--lg-lens-drop)` : "none",
2621
+ pointerEvents: "none",
2622
+ zIndex: lift > 0.5 ? 2 : 0,
2623
+ ...lensReady && lensFilter ? { filter: lensFilter, backgroundImage: lensRim } : {}
1991
2624
  };
1992
2625
  return /* @__PURE__ */ jsxs10(
1993
2626
  "nav",
1994
2627
  {
1995
- ref,
2628
+ ref: setRefs,
1996
2629
  role: "tablist",
1997
2630
  "aria-label": ariaLabel,
1998
- className: cn(
1999
- "lg-glass lg-interactive",
2000
- "relative inline-flex",
2001
- className
2002
- ),
2631
+ className: cn("lg-glass lg-interactive", "relative inline-flex", className),
2003
2632
  style: containerStyles,
2004
2633
  onPointerDown: handlePointerDown,
2005
2634
  onPointerUp: handlePointerUp,
2006
2635
  onPointerCancel: handlePointerUp,
2007
2636
  ...props,
2008
2637
  children: [
2009
- selectedIndex >= 0 && /* @__PURE__ */ jsx15("div", { className: "lg-glass", style: lensStyles }),
2010
- /* @__PURE__ */ jsx15("div", { className: "relative flex z-10", children: items.map((item) => {
2638
+ selectedIndex >= 0 && /* @__PURE__ */ jsx15("div", { ref: lensRef, "aria-hidden": true, style: lensStyles }),
2639
+ /* @__PURE__ */ jsx15("div", { className: "relative flex z-[1]", children: items.map((item) => {
2011
2640
  const isSelected = item.value === value;
2012
2641
  const TabElement = item.href && LinkComponent ? LinkComponent : "button";
2013
2642
  return /* @__PURE__ */ jsxs10(
@@ -2016,6 +2645,7 @@ var TabBar = forwardRef14(
2016
2645
  role: "tab",
2017
2646
  "aria-selected": isSelected,
2018
2647
  href: item.href,
2648
+ type: TabElement === "button" ? "button" : void 0,
2019
2649
  onClick: () => handleSelect(item.value),
2020
2650
  className: cn(
2021
2651
  "flex flex-col items-center justify-center",
@@ -2044,9 +2674,9 @@ var TabBar = forwardRef14(
2044
2674
  TabBar.displayName = "TabBar";
2045
2675
 
2046
2676
  // src/components/SegmentedControl.tsx
2047
- import { forwardRef as forwardRef15, useState as useState12 } from "react";
2677
+ import { forwardRef as forwardRef15, useState as useState13 } from "react";
2048
2678
  import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
2049
- var sizeConfig7 = {
2679
+ var sizeConfig6 = {
2050
2680
  sm: { height: 28, padding: 2, fontSize: 12, segmentWidth: 72 },
2051
2681
  md: { height: 32, padding: 2, fontSize: 13, segmentWidth: 84 },
2052
2682
  lg: { height: 40, padding: 3, fontSize: 14, segmentWidth: 100 }
@@ -2068,9 +2698,9 @@ var SegmentedControl = forwardRef15(
2068
2698
  defaultValue: defaultValue ?? items[0]?.value ?? null,
2069
2699
  onChange: onValueChange
2070
2700
  });
2071
- const [lift, setLift] = useState12(0);
2701
+ const [lift, setLift] = useState13(0);
2072
2702
  const reducedMotion = useReducedMotion();
2073
- const config = sizeConfig7[size];
2703
+ const config = sizeConfig6[size];
2074
2704
  const selectedIndex = items.findIndex((item) => item.value === value);
2075
2705
  const handleSelect = (itemValue, disabled) => {
2076
2706
  if (disabled) return;
@@ -2337,7 +2967,7 @@ var NavbarLink = forwardRef17(
2337
2967
  NavbarLink.displayName = "NavbarLink";
2338
2968
 
2339
2969
  // src/components/Sidebar.tsx
2340
- import { forwardRef as forwardRef18, createContext as createContext4, useContext as useContext4, useState as useState14, useCallback as useCallback7 } from "react";
2970
+ import { forwardRef as forwardRef18, createContext as createContext4, useContext as useContext4, useState as useState15, useCallback as useCallback8 } from "react";
2341
2971
  import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
2342
2972
  var SidebarContext = createContext4(null);
2343
2973
  function useSidebar() {
@@ -2348,8 +2978,8 @@ function useSidebar() {
2348
2978
  return context;
2349
2979
  }
2350
2980
  function SidebarProvider({ children, defaultCollapsed = false }) {
2351
- const [isCollapsed, setCollapsed] = useState14(defaultCollapsed);
2352
- const toggleCollapsed = useCallback7(() => {
2981
+ const [isCollapsed, setCollapsed] = useState15(defaultCollapsed);
2982
+ const toggleCollapsed = useCallback8(() => {
2353
2983
  setCollapsed((prev) => !prev);
2354
2984
  }, []);
2355
2985
  return /* @__PURE__ */ jsx19(SidebarContext.Provider, { value: { isCollapsed, toggleCollapsed, setCollapsed }, children });
@@ -2456,7 +3086,7 @@ var SidebarGroup = forwardRef18(
2456
3086
  SidebarGroup.displayName = "SidebarGroup";
2457
3087
 
2458
3088
  // src/components/Dock.tsx
2459
- import { forwardRef as forwardRef19, useState as useState15, useRef as useRef8 } from "react";
3089
+ import { forwardRef as forwardRef19, useState as useState16, useRef as useRef12 } from "react";
2460
3090
  import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
2461
3091
  var Dock = forwardRef19(
2462
3092
  ({
@@ -2464,12 +3094,12 @@ var Dock = forwardRef19(
2464
3094
  style,
2465
3095
  items,
2466
3096
  magnification = 1.5,
2467
- distance = 100,
3097
+ distance: distance2 = 100,
2468
3098
  direction = "bottom",
2469
3099
  ...props
2470
3100
  }, ref) => {
2471
- const [mouseX, setMouseX] = useState15(null);
2472
- const containerRef = useRef8(null);
3101
+ const [mouseX, setMouseX] = useState16(null);
3102
+ const containerRef = useRef12(null);
2473
3103
  const reducedMotion = useReducedMotion();
2474
3104
  const handleMouseMove = (e) => {
2475
3105
  if (reducedMotion) return;
@@ -2489,8 +3119,8 @@ var Dock = forwardRef19(
2489
3119
  const startX = (containerRef.current?.offsetWidth || 0) / 2 - totalWidth / 2;
2490
3120
  const iconCenter = startX + index * (iconSize + gap) + iconSize / 2;
2491
3121
  const distanceFromMouse = Math.abs(mouseX - iconCenter);
2492
- if (distanceFromMouse > distance) return 1;
2493
- const scale = 1 + (magnification - 1) * (1 - distanceFromMouse / distance);
3122
+ if (distanceFromMouse > distance2) return 1;
3123
+ const scale = 1 + (magnification - 1) * (1 - distanceFromMouse / distance2);
2494
3124
  return scale;
2495
3125
  };
2496
3126
  const isHorizontal = direction === "bottom";
@@ -2565,10 +3195,10 @@ var Dock = forwardRef19(
2565
3195
  Dock.displayName = "Dock";
2566
3196
 
2567
3197
  // src/components/Modal.tsx
2568
- import { forwardRef as forwardRef20, useEffect as useEffect8, useCallback as useCallback8, useRef as useRef9 } from "react";
3198
+ import { forwardRef as forwardRef20, useEffect as useEffect8, useCallback as useCallback9, useRef as useRef13 } from "react";
2569
3199
  import { createPortal as createPortal2 } from "react-dom";
2570
3200
  import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
2571
- var sizeConfig8 = {
3201
+ var sizeConfig7 = {
2572
3202
  sm: { maxWidth: 400 },
2573
3203
  md: { maxWidth: 500 },
2574
3204
  lg: { maxWidth: 640 },
@@ -2588,12 +3218,17 @@ var Modal = forwardRef20(
2588
3218
  closeOnOverlayClick = true,
2589
3219
  closeOnEscape = true,
2590
3220
  showCloseButton = true,
3221
+ disableRefraction = false,
2591
3222
  ...props
2592
3223
  }, ref) => {
2593
3224
  const reducedMotion = useReducedMotion();
2594
- const modalRef = useRef9(null);
2595
- const config = sizeConfig8[size];
2596
- const handleClose = useCallback8(() => {
3225
+ const localRef = useRef13(null);
3226
+ const combinedRef = ref || localRef;
3227
+ const config = sizeConfig7[size];
3228
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(combinedRef, {
3229
+ enabled: open && !disableRefraction && !reducedMotion
3230
+ });
3231
+ const handleClose = useCallback9(() => {
2597
3232
  onOpenChange(false);
2598
3233
  }, [onOpenChange]);
2599
3234
  const handleOverlayClick = (e) => {
@@ -2601,7 +3236,7 @@ var Modal = forwardRef20(
2601
3236
  handleClose();
2602
3237
  }
2603
3238
  };
2604
- const handleKeyDown = useCallback8((e) => {
3239
+ const handleKeyDown = useCallback9((e) => {
2605
3240
  if (closeOnEscape && e.key === "Escape") {
2606
3241
  handleClose();
2607
3242
  }
@@ -2610,14 +3245,23 @@ var Modal = forwardRef20(
2610
3245
  if (open) {
2611
3246
  document.addEventListener("keydown", handleKeyDown);
2612
3247
  document.body.style.overflow = "hidden";
2613
- modalRef.current?.focus();
3248
+ combinedRef.current?.focus();
2614
3249
  }
2615
3250
  return () => {
2616
3251
  document.removeEventListener("keydown", handleKeyDown);
2617
3252
  document.body.style.overflow = "";
2618
3253
  };
2619
- }, [open, handleKeyDown]);
3254
+ }, [open, handleKeyDown, combinedRef]);
2620
3255
  if (!open) return null;
3256
+ const modalStyles = {
3257
+ maxWidth: config.maxWidth,
3258
+ borderRadius: 24,
3259
+ ...style
3260
+ };
3261
+ if (isReady && filterUrl) {
3262
+ modalStyles.filter = filterUrl;
3263
+ modalStyles.backgroundImage = rimGradient;
3264
+ }
2621
3265
  const modalContent = /* @__PURE__ */ jsx21(
2622
3266
  "div",
2623
3267
  {
@@ -2634,7 +3278,7 @@ var Modal = forwardRef20(
2634
3278
  children: /* @__PURE__ */ jsxs15(
2635
3279
  "div",
2636
3280
  {
2637
- ref: ref || modalRef,
3281
+ ref: combinedRef,
2638
3282
  tabIndex: -1,
2639
3283
  className: cn(
2640
3284
  "lg-glass lg-glass-elevated lg-text",
@@ -2642,11 +3286,7 @@ var Modal = forwardRef20(
2642
3286
  !reducedMotion && "animate-[lg-scale-in_200ms_var(--lg-ease-spring)]",
2643
3287
  className
2644
3288
  ),
2645
- style: {
2646
- maxWidth: config.maxWidth,
2647
- borderRadius: 24,
2648
- ...style
2649
- },
3289
+ style: modalStyles,
2650
3290
  ...props,
2651
3291
  children: [
2652
3292
  showCloseButton && /* @__PURE__ */ jsx21(
@@ -2713,10 +3353,10 @@ var ModalFooter = forwardRef20(
2713
3353
  ModalFooter.displayName = "ModalFooter";
2714
3354
 
2715
3355
  // src/components/Sheet.tsx
2716
- import { forwardRef as forwardRef21, useEffect as useEffect9, useCallback as useCallback9, useRef as useRef10 } from "react";
3356
+ import { forwardRef as forwardRef21, useEffect as useEffect9, useCallback as useCallback10, useRef as useRef14 } from "react";
2717
3357
  import { createPortal as createPortal3 } from "react-dom";
2718
3358
  import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2719
- var sizeConfig9 = {
3359
+ var sizeConfig8 = {
2720
3360
  sm: { width: 320, height: 300 },
2721
3361
  md: { width: 400, height: 400 },
2722
3362
  lg: { width: 500, height: 500 },
@@ -2732,12 +3372,17 @@ var Sheet = forwardRef21(
2732
3372
  side = "bottom",
2733
3373
  size = "md",
2734
3374
  showHandle = true,
3375
+ disableRefraction = false,
2735
3376
  ...props
2736
3377
  }, ref) => {
2737
3378
  const reducedMotion = useReducedMotion();
2738
- const sheetRef = useRef10(null);
2739
- const config = sizeConfig9[size];
2740
- const handleClose = useCallback9(() => {
3379
+ const localRef = useRef14(null);
3380
+ const combinedRef = ref || localRef;
3381
+ const config = sizeConfig8[size];
3382
+ const { filterUrl, rimGradient, isReady } = useGlisseEffect(combinedRef, {
3383
+ enabled: open && !disableRefraction && !reducedMotion
3384
+ });
3385
+ const handleClose = useCallback10(() => {
2741
3386
  onOpenChange(false);
2742
3387
  }, [onOpenChange]);
2743
3388
  const handleOverlayClick = (e) => {
@@ -2745,7 +3390,7 @@ var Sheet = forwardRef21(
2745
3390
  handleClose();
2746
3391
  }
2747
3392
  };
2748
- const handleKeyDown = useCallback9((e) => {
3393
+ const handleKeyDown = useCallback10((e) => {
2749
3394
  if (e.key === "Escape") {
2750
3395
  handleClose();
2751
3396
  }
@@ -2761,7 +3406,6 @@ var Sheet = forwardRef21(
2761
3406
  };
2762
3407
  }, [open, handleKeyDown]);
2763
3408
  if (!open) return null;
2764
- const isHorizontal = side === "left" || side === "right";
2765
3409
  const sheetStyles = {
2766
3410
  position: "fixed",
2767
3411
  zIndex: 50,
@@ -2803,6 +3447,10 @@ var Sheet = forwardRef21(
2803
3447
  },
2804
3448
  ...style
2805
3449
  };
3450
+ if (isReady && filterUrl) {
3451
+ sheetStyles.filter = filterUrl;
3452
+ sheetStyles.backgroundImage = rimGradient;
3453
+ }
2806
3454
  const animationClass = reducedMotion ? "" : {
2807
3455
  bottom: "animate-[lg-slide-up_300ms_var(--lg-ease-spring)]",
2808
3456
  top: "animate-[lg-slide-down_300ms_var(--lg-ease-spring)]",
@@ -2823,7 +3471,7 @@ var Sheet = forwardRef21(
2823
3471
  children: /* @__PURE__ */ jsxs16(
2824
3472
  "div",
2825
3473
  {
2826
- ref: ref || sheetRef,
3474
+ ref: combinedRef,
2827
3475
  className: cn(
2828
3476
  "lg-glass lg-glass-elevated lg-text",
2829
3477
  "overflow-auto",
@@ -2851,7 +3499,7 @@ var Sheet = forwardRef21(
2851
3499
  Sheet.displayName = "Sheet";
2852
3500
 
2853
3501
  // src/components/Menu.tsx
2854
- import { forwardRef as forwardRef22, useState as useState16, useRef as useRef11, useEffect as useEffect10 } from "react";
3502
+ import { forwardRef as forwardRef22, useState as useState17, useRef as useRef15, useEffect as useEffect10 } from "react";
2855
3503
  import { createPortal as createPortal4 } from "react-dom";
2856
3504
  import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
2857
3505
  var Menu = forwardRef22(
@@ -2863,10 +3511,10 @@ var Menu = forwardRef22(
2863
3511
  "aria-label": ariaLabel,
2864
3512
  ...props
2865
3513
  }, ref) => {
2866
- const [isOpen, setIsOpen] = useState16(false);
2867
- const [position, setPosition] = useState16({ top: 0, left: 0 });
2868
- const triggerRef = useRef11(null);
2869
- const menuRef = useRef11(null);
3514
+ const [isOpen, setIsOpen] = useState17(false);
3515
+ const [position, setPosition] = useState17({ top: 0, left: 0 });
3516
+ const triggerRef = useRef15(null);
3517
+ const menuRef = useRef15(null);
2870
3518
  const reducedMotion = useReducedMotion();
2871
3519
  const updatePosition = () => {
2872
3520
  if (!triggerRef.current || !menuRef.current) return;
@@ -2985,7 +3633,7 @@ var Menu = forwardRef22(
2985
3633
  Menu.displayName = "Menu";
2986
3634
 
2987
3635
  // src/components/Tooltip.tsx
2988
- import { useState as useState17, useRef as useRef12, useEffect as useEffect11, cloneElement, isValidElement } from "react";
3636
+ import { useState as useState18, useRef as useRef16, useEffect as useEffect11, cloneElement, isValidElement } from "react";
2989
3637
  import { createPortal as createPortal5 } from "react-dom";
2990
3638
  import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
2991
3639
  function Tooltip({
@@ -2996,11 +3644,11 @@ function Tooltip({
2996
3644
  delay = 200,
2997
3645
  disabled = false
2998
3646
  }) {
2999
- const [isOpen, setIsOpen] = useState17(false);
3000
- const [position, setPosition] = useState17({ top: 0, left: 0 });
3001
- const triggerRef = useRef12(null);
3002
- const tooltipRef = useRef12(null);
3003
- const timeoutRef = useRef12();
3647
+ const [isOpen, setIsOpen] = useState18(false);
3648
+ const [position, setPosition] = useState18({ top: 0, left: 0 });
3649
+ const triggerRef = useRef16(null);
3650
+ const tooltipRef = useRef16(null);
3651
+ const timeoutRef = useRef16();
3004
3652
  const reducedMotion = useReducedMotion();
3005
3653
  const updatePosition = () => {
3006
3654
  if (!triggerRef.current || !tooltipRef.current) return;
@@ -3095,7 +3743,7 @@ function Tooltip({
3095
3743
  }
3096
3744
 
3097
3745
  // src/components/Toast.tsx
3098
- import { forwardRef as forwardRef24, useState as useState18, useEffect as useEffect12, createContext as createContext5, useContext as useContext5, useCallback as useCallback10 } from "react";
3746
+ import { forwardRef as forwardRef24, useState as useState19, useEffect as useEffect12, createContext as createContext5, useContext as useContext5, useCallback as useCallback11 } from "react";
3099
3747
  import { createPortal as createPortal6 } from "react-dom";
3100
3748
  import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
3101
3749
  var variantIcons = {
@@ -3135,7 +3783,7 @@ var Toast = forwardRef24(
3135
3783
  ...props
3136
3784
  }, ref) => {
3137
3785
  const reducedMotion = useReducedMotion();
3138
- const [isLeaving, setIsLeaving] = useState18(false);
3786
+ const [isLeaving, setIsLeaving] = useState19(false);
3139
3787
  useEffect12(() => {
3140
3788
  if (duration > 0) {
3141
3789
  const timer = setTimeout(() => {
@@ -3198,16 +3846,16 @@ Toast.displayName = "Toast";
3198
3846
  var ToastContext = createContext5(null);
3199
3847
  var toastId = 0;
3200
3848
  function ToastProvider({ children }) {
3201
- const [toasts, setToasts] = useState18([]);
3202
- const toast = useCallback10((props) => {
3849
+ const [toasts, setToasts] = useState19([]);
3850
+ const toast = useCallback11((props) => {
3203
3851
  const id = `toast-${++toastId}`;
3204
3852
  setToasts((prev) => [...prev, { ...props, id }]);
3205
3853
  return id;
3206
3854
  }, []);
3207
- const dismiss = useCallback10((id) => {
3855
+ const dismiss = useCallback11((id) => {
3208
3856
  setToasts((prev) => prev.filter((t) => t.id !== id));
3209
3857
  }, []);
3210
- const dismissAll = useCallback10(() => {
3858
+ const dismissAll = useCallback11(() => {
3211
3859
  setToasts([]);
3212
3860
  }, []);
3213
3861
  return /* @__PURE__ */ jsxs19(ToastContext.Provider, { value: { toasts, toast, dismiss, dismissAll }, children: [
@@ -3353,7 +4001,7 @@ var Progress = forwardRef26(
3353
4001
  indeterminate = false,
3354
4002
  ...props
3355
4003
  }, ref) => {
3356
- const percentage = clamp(value / max * 100, 0, 100);
4004
+ const percentage = clamp2(value / max * 100, 0, 100);
3357
4005
  const fillColor = color || "var(--lg-fill)";
3358
4006
  if (variant === "circular") {
3359
4007
  const config2 = circularSizeConfig[size];
@@ -3589,7 +4237,7 @@ var variantStyles = {
3589
4237
  border: "1px solid var(--lg-edge-strong)"
3590
4238
  }
3591
4239
  };
3592
- var sizeConfig10 = {
4240
+ var sizeConfig9 = {
3593
4241
  sm: { height: 18, padding: "0 6px", fontSize: 10, dotSize: 6 },
3594
4242
  md: { height: 22, padding: "0 8px", fontSize: 11, dotSize: 8 },
3595
4243
  lg: { height: 26, padding: "0 10px", fontSize: 12, dotSize: 10 }
@@ -3605,7 +4253,7 @@ var Badge = forwardRef28(
3605
4253
  children,
3606
4254
  ...props
3607
4255
  }, ref) => {
3608
- const config = sizeConfig10[size];
4256
+ const config = sizeConfig9[size];
3609
4257
  const variantStyle = variantStyles[variant];
3610
4258
  if (dot) {
3611
4259
  return /* @__PURE__ */ jsx29(
@@ -3653,9 +4301,9 @@ var Badge = forwardRef28(
3653
4301
  Badge.displayName = "Badge";
3654
4302
 
3655
4303
  // src/components/Avatar.tsx
3656
- import { forwardRef as forwardRef29, useState as useState19 } from "react";
4304
+ import { forwardRef as forwardRef29, useState as useState20 } from "react";
3657
4305
  import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
3658
- var sizeConfig11 = {
4306
+ var sizeConfig10 = {
3659
4307
  xs: { size: 24, fontSize: 10, statusSize: 6 },
3660
4308
  sm: { size: 32, fontSize: 12, statusSize: 8 },
3661
4309
  md: { size: 40, fontSize: 14, statusSize: 10 },
@@ -3683,8 +4331,8 @@ var Avatar = forwardRef29(
3683
4331
  status,
3684
4332
  ...props
3685
4333
  }, ref) => {
3686
- const [imageError, setImageError] = useState19(false);
3687
- const config = sizeConfig11[size];
4334
+ const [imageError, setImageError] = useState20(false);
4335
+ const config = sizeConfig10[size];
3688
4336
  const showFallback = !src || imageError;
3689
4337
  const avatarStyles = {
3690
4338
  width: config.size,
@@ -3741,7 +4389,7 @@ Avatar.displayName = "Avatar";
3741
4389
  // src/components/Chip.tsx
3742
4390
  import { forwardRef as forwardRef30 } from "react";
3743
4391
  import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
3744
- var sizeConfig12 = {
4392
+ var sizeConfig11 = {
3745
4393
  sm: { height: 24, padding: "0 8px", fontSize: 11, iconSize: 14 },
3746
4394
  md: { height: 32, padding: "0 12px", fontSize: 13, iconSize: 16 },
3747
4395
  lg: { height: 40, padding: "0 16px", fontSize: 14, iconSize: 18 }
@@ -3761,7 +4409,7 @@ var Chip = forwardRef30(
3761
4409
  children,
3762
4410
  ...props
3763
4411
  }, ref) => {
3764
- const config = sizeConfig12[size];
4412
+ const config = sizeConfig11[size];
3765
4413
  const isClickable = !!onClick;
3766
4414
  const chipStyles = {
3767
4415
  height: config.height,
@@ -3838,7 +4486,7 @@ var Chip = forwardRef30(
3838
4486
  Chip.displayName = "Chip";
3839
4487
 
3840
4488
  // src/components/Accordion.tsx
3841
- import { forwardRef as forwardRef31, createContext as createContext6, useContext as useContext6, useState as useState20, useCallback as useCallback11 } from "react";
4489
+ import { forwardRef as forwardRef31, createContext as createContext6, useContext as useContext6, useState as useState21, useCallback as useCallback12 } from "react";
3842
4490
  import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
3843
4491
  var AccordionContext = createContext6(null);
3844
4492
  var Accordion = forwardRef31(
@@ -3850,13 +4498,13 @@ var Accordion = forwardRef31(
3850
4498
  children,
3851
4499
  ...props
3852
4500
  }, ref) => {
3853
- const [expandedItems, setExpandedItems] = useState20(() => {
4501
+ const [expandedItems, setExpandedItems] = useState21(() => {
3854
4502
  if (defaultValue) {
3855
4503
  return Array.isArray(defaultValue) ? defaultValue : [defaultValue];
3856
4504
  }
3857
4505
  return [];
3858
4506
  });
3859
- const toggleItem = useCallback11((value) => {
4507
+ const toggleItem = useCallback12((value) => {
3860
4508
  setExpandedItems((prev) => {
3861
4509
  const isExpanded = prev.includes(value);
3862
4510
  if (type === "single") {
@@ -4069,10 +4717,10 @@ var Skeleton = forwardRef33(
4069
4717
  Skeleton.displayName = "Skeleton";
4070
4718
 
4071
4719
  // src/components/Drawer.tsx
4072
- import { forwardRef as forwardRef34, useEffect as useEffect13, useCallback as useCallback12, useRef as useRef13 } from "react";
4720
+ import { forwardRef as forwardRef34, useEffect as useEffect13, useCallback as useCallback13, useRef as useRef17 } from "react";
4073
4721
  import { createPortal as createPortal7 } from "react-dom";
4074
4722
  import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
4075
- var sizeConfig13 = {
4723
+ var sizeConfig12 = {
4076
4724
  sm: 280,
4077
4725
  md: 320,
4078
4726
  lg: 400,
@@ -4095,11 +4743,11 @@ var Drawer = forwardRef34(
4095
4743
  ...props
4096
4744
  }, ref) => {
4097
4745
  const reducedMotion = useReducedMotion();
4098
- const drawerRef = useRef13(null);
4746
+ const drawerRef = useRef17(null);
4099
4747
  const titleId = useId();
4100
4748
  const descId = useId();
4101
- const width = sizeConfig13[size];
4102
- const handleClose = useCallback12(() => {
4749
+ const width = sizeConfig12[size];
4750
+ const handleClose = useCallback13(() => {
4103
4751
  onOpenChange(false);
4104
4752
  }, [onOpenChange]);
4105
4753
  const handleOverlayClick = (e) => {
@@ -4107,7 +4755,7 @@ var Drawer = forwardRef34(
4107
4755
  handleClose();
4108
4756
  }
4109
4757
  };
4110
- const handleKeyDown = useCallback12((e) => {
4758
+ const handleKeyDown = useCallback13((e) => {
4111
4759
  if (closeOnEscape && e.key === "Escape") {
4112
4760
  handleClose();
4113
4761
  }
@@ -4209,7 +4857,7 @@ var Drawer = forwardRef34(
4209
4857
  Drawer.displayName = "Drawer";
4210
4858
 
4211
4859
  // src/components/Popover.tsx
4212
- import { useState as useState21, useRef as useRef14, useEffect as useEffect14, useCallback as useCallback13, cloneElement as cloneElement2, isValidElement as isValidElement2 } from "react";
4860
+ import { useState as useState22, useRef as useRef18, useEffect as useEffect14, useCallback as useCallback14, cloneElement as cloneElement2, isValidElement as isValidElement2 } from "react";
4213
4861
  import { createPortal as createPortal8 } from "react-dom";
4214
4862
  import { Fragment as Fragment5, jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
4215
4863
  function Popover({
@@ -4225,15 +4873,15 @@ function Popover({
4225
4873
  closeOnEscape = true,
4226
4874
  trigger = "click"
4227
4875
  }) {
4228
- const [internalOpen, setInternalOpen] = useState21(defaultOpen);
4876
+ const [internalOpen, setInternalOpen] = useState22(defaultOpen);
4229
4877
  const open = controlledOpen !== void 0 ? controlledOpen : internalOpen;
4230
4878
  const setOpen = controlledOpen !== void 0 ? onOpenChange : setInternalOpen;
4231
- const [position, setPosition] = useState21({ top: 0, left: 0 });
4232
- const triggerRef = useRef14(null);
4233
- const popoverRef = useRef14(null);
4879
+ const [position, setPosition] = useState22({ top: 0, left: 0 });
4880
+ const triggerRef = useRef18(null);
4881
+ const popoverRef = useRef18(null);
4234
4882
  const reducedMotion = useReducedMotion();
4235
4883
  const popoverId = useId();
4236
- const updatePosition = useCallback13(() => {
4884
+ const updatePosition = useCallback14(() => {
4237
4885
  if (!triggerRef.current || !popoverRef.current) return;
4238
4886
  const triggerRect = triggerRef.current.getBoundingClientRect();
4239
4887
  const popoverRect = popoverRef.current.getBoundingClientRect();
@@ -4367,7 +5015,7 @@ function Popover({
4367
5015
  }
4368
5016
 
4369
5017
  // src/components/ContextMenu.tsx
4370
- import { useState as useState22, useRef as useRef15, useEffect as useEffect15, useCallback as useCallback14, cloneElement as cloneElement3, isValidElement as isValidElement3 } from "react";
5018
+ import { useState as useState23, useRef as useRef19, useEffect as useEffect15, useCallback as useCallback15, cloneElement as cloneElement3, isValidElement as isValidElement3 } from "react";
4371
5019
  import { createPortal as createPortal9 } from "react-dom";
4372
5020
  import { Fragment as Fragment6, jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
4373
5021
  function ContextMenu({
@@ -4376,14 +5024,14 @@ function ContextMenu({
4376
5024
  disabled = false,
4377
5025
  onOpenChange
4378
5026
  }) {
4379
- const [open, setOpen] = useState22(false);
4380
- const [position, setPosition] = useState22({ x: 0, y: 0 });
4381
- const [focusedIndex, setFocusedIndex] = useState22(-1);
4382
- const menuRef = useRef15(null);
4383
- const triggerRef = useRef15(null);
5027
+ const [open, setOpen] = useState23(false);
5028
+ const [position, setPosition] = useState23({ x: 0, y: 0 });
5029
+ const [focusedIndex, setFocusedIndex] = useState23(-1);
5030
+ const menuRef = useRef19(null);
5031
+ const triggerRef = useRef19(null);
4384
5032
  const reducedMotion = useReducedMotion();
4385
5033
  const menuId = useId();
4386
- const handleOpenChange = useCallback14((isOpen) => {
5034
+ const handleOpenChange = useCallback15((isOpen) => {
4387
5035
  setOpen(isOpen);
4388
5036
  onOpenChange?.(isOpen);
4389
5037
  if (!isOpen) {
@@ -4411,7 +5059,7 @@ function ContextMenu({
4411
5059
  item.onSelect?.();
4412
5060
  handleOpenChange(false);
4413
5061
  };
4414
- const handleKeyDown = useCallback14((e) => {
5062
+ const handleKeyDown = useCallback15((e) => {
4415
5063
  if (!open) return;
4416
5064
  const selectableItems = items.filter((item) => item !== "separator" && !item.disabled);
4417
5065
  switch (e.key) {
@@ -4539,7 +5187,7 @@ function ContextMenu({
4539
5187
  }
4540
5188
 
4541
5189
  // src/components/CommandPalette.tsx
4542
- import { useState as useState23, useRef as useRef16, useEffect as useEffect16, useCallback as useCallback15, useMemo } from "react";
5190
+ import { useState as useState24, useRef as useRef20, useEffect as useEffect16, useCallback as useCallback16, useMemo } from "react";
4543
5191
  import { createPortal as createPortal10 } from "react-dom";
4544
5192
  import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
4545
5193
  function CommandPalette({
@@ -4550,10 +5198,10 @@ function CommandPalette({
4550
5198
  emptyMessage = "No results found.",
4551
5199
  groups = {}
4552
5200
  }) {
4553
- const [query, setQuery] = useState23("");
4554
- const [selectedIndex, setSelectedIndex] = useState23(0);
4555
- const inputRef = useRef16(null);
4556
- const listRef = useRef16(null);
5201
+ const [query, setQuery] = useState24("");
5202
+ const [selectedIndex, setSelectedIndex] = useState24(0);
5203
+ const inputRef = useRef20(null);
5204
+ const listRef = useRef20(null);
4557
5205
  const reducedMotion = useReducedMotion();
4558
5206
  const dialogId = useId();
4559
5207
  const listboxId = useId();
@@ -4580,16 +5228,16 @@ function CommandPalette({
4580
5228
  const flattenedItems = useMemo(() => {
4581
5229
  return Object.values(groupedItems).flat();
4582
5230
  }, [groupedItems]);
4583
- const handleClose = useCallback15(() => {
5231
+ const handleClose = useCallback16(() => {
4584
5232
  onOpenChange(false);
4585
5233
  setQuery("");
4586
5234
  setSelectedIndex(0);
4587
5235
  }, [onOpenChange]);
4588
- const handleSelect = useCallback15((item) => {
5236
+ const handleSelect = useCallback16((item) => {
4589
5237
  item.onSelect();
4590
5238
  handleClose();
4591
5239
  }, [handleClose]);
4592
- const handleKeyDown = useCallback15((e) => {
5240
+ const handleKeyDown = useCallback16((e) => {
4593
5241
  switch (e.key) {
4594
5242
  case "ArrowDown":
4595
5243
  e.preventDefault();
@@ -4643,7 +5291,8 @@ function CommandPalette({
4643
5291
  "div",
4644
5292
  {
4645
5293
  className: cn(
4646
- "fixed inset-0 z-50 flex items-start justify-center pt-[15vh]",
5294
+ "fixed inset-0 z-50 flex items-stretch sm:items-start justify-center",
5295
+ "p-0 sm:p-4 sm:pt-[12vh]",
4647
5296
  "bg-black/40 backdrop-blur-sm",
4648
5297
  !reducedMotion && "animate-[lg-fade-in_150ms_ease-out]"
4649
5298
  ),
@@ -4656,13 +5305,14 @@ function CommandPalette({
4656
5305
  "aria-labelledby": dialogId,
4657
5306
  className: cn(
4658
5307
  "lg-glass lg-glass-elevated lg-text",
4659
- "w-full max-w-[540px] overflow-hidden",
5308
+ "w-full sm:max-w-[540px] overflow-hidden",
5309
+ "h-full sm:h-auto max-h-full sm:max-h-[min(80vh,640px)]",
5310
+ "flex flex-col rounded-none sm:rounded-2xl",
4660
5311
  !reducedMotion && "animate-[lg-scale-in_150ms_var(--lg-ease-spring)]"
4661
5312
  ),
4662
- style: { borderRadius: 16 },
4663
5313
  children: [
4664
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-[var(--lg-separator)]", children: [
4665
- /* @__PURE__ */ jsxs30("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "var(--lg-muted)", strokeWidth: "2", children: [
5314
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-3 px-3 sm:px-4 min-h-[56px] border-b border-[var(--lg-separator)] shrink-0", children: [
5315
+ /* @__PURE__ */ jsxs30("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "var(--lg-muted)", strokeWidth: "2", "aria-hidden": true, children: [
4666
5316
  /* @__PURE__ */ jsx38("circle", { cx: "11", cy: "11", r: "8" }),
4667
5317
  /* @__PURE__ */ jsx38("path", { d: "m21 21-4.35-4.35" })
4668
5318
  ] }),
@@ -4670,7 +5320,11 @@ function CommandPalette({
4670
5320
  "input",
4671
5321
  {
4672
5322
  ref: inputRef,
4673
- type: "text",
5323
+ type: "search",
5324
+ enterKeyHint: "search",
5325
+ autoComplete: "off",
5326
+ autoCorrect: "off",
5327
+ spellCheck: false,
4674
5328
  value: query,
4675
5329
  onChange: (e) => setQuery(e.target.value),
4676
5330
  onKeyDown: handleKeyDown,
@@ -4680,13 +5334,29 @@ function CommandPalette({
4680
5334
  "aria-controls": listboxId,
4681
5335
  "aria-activedescendant": flattenedItems[selectedIndex]?.id,
4682
5336
  className: cn(
4683
- "flex-1 bg-transparent border-0 outline-none",
5337
+ "flex-1 min-w-0 bg-transparent border-0 outline-none",
4684
5338
  "text-base placeholder:text-[var(--lg-muted)]"
4685
5339
  ),
4686
- style: { color: "var(--lg-foreground)" }
5340
+ style: { color: "var(--lg-foreground)", fontSize: 16 }
4687
5341
  }
4688
5342
  ),
4689
- /* @__PURE__ */ jsx38("kbd", { className: "px-2 py-0.5 text-xs rounded bg-[var(--lg-glass)] text-[var(--lg-muted)]", children: "ESC" })
5343
+ /* @__PURE__ */ jsx38(
5344
+ "button",
5345
+ {
5346
+ type: "button",
5347
+ onClick: handleClose,
5348
+ className: "inline-flex items-center justify-center rounded-lg text-[var(--lg-muted)] border-0 bg-transparent cursor-pointer",
5349
+ style: { minWidth: 44, minHeight: 44 },
5350
+ "aria-label": "Close search",
5351
+ children: /* @__PURE__ */ jsx38(
5352
+ "kbd",
5353
+ {
5354
+ className: "px-2 py-1 text-xs rounded bg-[var(--lg-glass)] text-[var(--lg-muted)] pointer-events-none",
5355
+ children: "ESC"
5356
+ }
5357
+ )
5358
+ }
5359
+ )
4690
5360
  ] }),
4691
5361
  /* @__PURE__ */ jsx38(
4692
5362
  "div",
@@ -4694,7 +5364,8 @@ function CommandPalette({
4694
5364
  ref: listRef,
4695
5365
  role: "listbox",
4696
5366
  id: listboxId,
4697
- className: "max-h-[300px] overflow-auto p-2",
5367
+ className: "flex-1 overflow-auto overscroll-contain p-2 min-h-0",
5368
+ style: { maxHeight: "min(70dvh, 480px)" },
4698
5369
  children: flattenedItems.length === 0 ? /* @__PURE__ */ jsx38("div", { className: "px-4 py-8 text-center text-sm text-[var(--lg-muted)]", children: emptyMessage }) : Object.entries(groupedItems).map(([group, groupItems]) => /* @__PURE__ */ jsxs30("div", { children: [
4699
5370
  group !== "_default" && groups[group] && /* @__PURE__ */ jsx38("div", { className: "px-3 py-2 text-xs font-medium text-[var(--lg-muted)] uppercase tracking-wider", children: groups[group] }),
4700
5371
  groupItems.map((item) => {
@@ -4709,18 +5380,19 @@ function CommandPalette({
4709
5380
  onClick: () => handleSelect(item),
4710
5381
  onMouseEnter: () => setSelectedIndex(flattenedItems.indexOf(item)),
4711
5382
  className: cn(
4712
- "w-full flex items-center gap-3 px-3 py-2.5 rounded-lg",
5383
+ "w-full flex items-center gap-3 px-3 rounded-lg",
4713
5384
  "border-0 bg-transparent text-left cursor-pointer",
4714
5385
  "transition-colors",
4715
5386
  isSelected && "bg-[var(--lg-highlight)]"
4716
5387
  ),
5388
+ style: { minHeight: 44 },
4717
5389
  children: [
4718
5390
  item.icon && /* @__PURE__ */ jsx38("span", { className: "flex-shrink-0 w-5 h-5 text-[var(--lg-muted)]", children: item.icon }),
4719
5391
  /* @__PURE__ */ jsxs30("div", { className: "flex-1 min-w-0", children: [
4720
5392
  /* @__PURE__ */ jsx38("div", { className: "text-sm font-medium", style: { color: "var(--lg-foreground)" }, children: item.label }),
4721
5393
  item.description && /* @__PURE__ */ jsx38("div", { className: "text-xs text-[var(--lg-muted)] truncate", children: item.description })
4722
5394
  ] }),
4723
- item.shortcut && /* @__PURE__ */ jsx38("kbd", { className: "px-2 py-0.5 text-xs rounded bg-[var(--lg-glass)] text-[var(--lg-muted)]", children: item.shortcut })
5395
+ item.shortcut && /* @__PURE__ */ jsx38("kbd", { className: "hidden sm:inline px-2 py-0.5 text-xs rounded bg-[var(--lg-glass)] text-[var(--lg-muted)]", children: item.shortcut })
4724
5396
  ]
4725
5397
  },
4726
5398
  item.id
@@ -4738,7 +5410,7 @@ function CommandPalette({
4738
5410
  }
4739
5411
 
4740
5412
  // src/components/Carousel.tsx
4741
- import { forwardRef as forwardRef38, useState as useState24, useRef as useRef17, useEffect as useEffect17, useCallback as useCallback16, Children } from "react";
5413
+ import { forwardRef as forwardRef38, useState as useState25, useRef as useRef21, useEffect as useEffect17, useCallback as useCallback17, Children } from "react";
4742
5414
  import { Fragment as Fragment7, jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
4743
5415
  var Carousel = forwardRef38(
4744
5416
  ({
@@ -4754,15 +5426,15 @@ var Carousel = forwardRef38(
4754
5426
  gap = 16,
4755
5427
  ...props
4756
5428
  }, ref) => {
4757
- const [currentIndex, setCurrentIndex] = useState24(0);
4758
- const [isHovered, setIsHovered] = useState24(false);
4759
- const containerRef = useRef17(null);
5429
+ const [currentIndex, setCurrentIndex] = useState25(0);
5430
+ const [isHovered, setIsHovered] = useState25(false);
5431
+ const containerRef = useRef21(null);
4760
5432
  const reducedMotion = useReducedMotion();
4761
5433
  const carouselId = useId();
4762
5434
  const slides = Children.toArray(children);
4763
5435
  const totalSlides = slides.length;
4764
5436
  const maxIndex = Math.max(0, totalSlides - slidesToShow);
4765
- const goToSlide = useCallback16((index) => {
5437
+ const goToSlide = useCallback17((index) => {
4766
5438
  if (loop) {
4767
5439
  if (index < 0) index = maxIndex;
4768
5440
  if (index > maxIndex) index = 0;
@@ -4771,10 +5443,10 @@ var Carousel = forwardRef38(
4771
5443
  }
4772
5444
  setCurrentIndex(index);
4773
5445
  }, [loop, maxIndex]);
4774
- const goToPrevious = useCallback16(() => {
5446
+ const goToPrevious = useCallback17(() => {
4775
5447
  goToSlide(currentIndex - 1);
4776
5448
  }, [currentIndex, goToSlide]);
4777
- const goToNext = useCallback16(() => {
5449
+ const goToNext = useCallback17(() => {
4778
5450
  goToSlide(currentIndex + 1);
4779
5451
  }, [currentIndex, goToSlide]);
4780
5452
  useEffect17(() => {
@@ -4920,9 +5592,9 @@ var Carousel = forwardRef38(
4920
5592
  Carousel.displayName = "Carousel";
4921
5593
 
4922
5594
  // src/components/FloatingActionButton.tsx
4923
- import { forwardRef as forwardRef39, useState as useState25 } from "react";
5595
+ import { forwardRef as forwardRef39, useState as useState26 } from "react";
4924
5596
  import { jsx as jsx40, jsxs as jsxs32 } from "react/jsx-runtime";
4925
- var sizeConfig14 = {
5597
+ var sizeConfig13 = {
4926
5598
  sm: { size: 40, iconSize: 20 },
4927
5599
  md: { size: 56, iconSize: 24 },
4928
5600
  lg: { size: 72, iconSize: 32 }
@@ -4947,10 +5619,10 @@ var FloatingActionButton = forwardRef39(
4947
5619
  disabled,
4948
5620
  ...props
4949
5621
  }, ref) => {
4950
- const [isHovered, setIsHovered] = useState25(false);
5622
+ const [isHovered, setIsHovered] = useState26(false);
4951
5623
  const { isPressed, pressHandlers } = usePressedState({ disabled });
4952
5624
  const reducedMotion = useReducedMotion();
4953
- const config = sizeConfig14[size];
5625
+ const config = sizeConfig13[size];
4954
5626
  const fabStyles = {
4955
5627
  position: "fixed",
4956
5628
  zIndex: 40,
@@ -5009,7 +5681,7 @@ var FloatingActionButton = forwardRef39(
5009
5681
  FloatingActionButton.displayName = "FloatingActionButton";
5010
5682
 
5011
5683
  // src/components/DatePicker.tsx
5012
- import { forwardRef as forwardRef40, useState as useState26, useRef as useRef18, useEffect as useEffect18, useCallback as useCallback17, useMemo as useMemo2 } from "react";
5684
+ import { forwardRef as forwardRef40, useState as useState27, useRef as useRef22, useEffect as useEffect18, useCallback as useCallback18, useMemo as useMemo2 } from "react";
5013
5685
  import { createPortal as createPortal11 } from "react-dom";
5014
5686
  import { jsx as jsx41, jsxs as jsxs33 } from "react/jsx-runtime";
5015
5687
  var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
@@ -5044,17 +5716,17 @@ var DatePicker = forwardRef40(
5044
5716
  formatDate = (date) => date.toLocaleDateString(locale, { year: "numeric", month: "long", day: "numeric" }),
5045
5717
  ...props
5046
5718
  }, ref) => {
5047
- const [internalValue, setInternalValue] = useState26(defaultValue || null);
5719
+ const [internalValue, setInternalValue] = useState27(defaultValue || null);
5048
5720
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
5049
- const [isOpen, setIsOpen] = useState26(false);
5050
- const [viewDate, setViewDate] = useState26(() => value || /* @__PURE__ */ new Date());
5051
- const [focusedDate, setFocusedDate] = useState26(null);
5052
- const triggerRef = useRef18(null);
5053
- const calendarRef = useRef18(null);
5721
+ const [isOpen, setIsOpen] = useState27(false);
5722
+ const [viewDate, setViewDate] = useState27(() => value || /* @__PURE__ */ new Date());
5723
+ const [focusedDate, setFocusedDate] = useState27(null);
5724
+ const triggerRef = useRef22(null);
5725
+ const calendarRef = useRef22(null);
5054
5726
  const reducedMotion = useReducedMotion();
5055
5727
  const inputId = useId();
5056
5728
  const calendarId = useId();
5057
- const setValue = useCallback17((date) => {
5729
+ const setValue = useCallback18((date) => {
5058
5730
  if (controlledValue === void 0) {
5059
5731
  setInternalValue(date);
5060
5732
  }
@@ -5305,14 +5977,14 @@ var DatePicker = forwardRef40(
5305
5977
  DatePicker.displayName = "DatePicker";
5306
5978
 
5307
5979
  // src/hooks/use-reduced-transparency.ts
5308
- import { useState as useState27, useEffect as useEffect19 } from "react";
5980
+ import { useState as useState28, useEffect as useEffect19 } from "react";
5309
5981
  var QUERY2 = "(prefers-reduced-transparency: reduce)";
5310
5982
  function getInitialState2() {
5311
5983
  if (typeof window === "undefined") return false;
5312
5984
  return window.matchMedia(QUERY2).matches;
5313
5985
  }
5314
5986
  function useReducedTransparency() {
5315
- const [reducedTransparency, setReducedTransparency] = useState27(getInitialState2);
5987
+ const [reducedTransparency, setReducedTransparency] = useState28(getInitialState2);
5316
5988
  useEffect19(() => {
5317
5989
  const mediaQuery = window.matchMedia(QUERY2);
5318
5990
  const handler = (event) => {
@@ -5328,9 +6000,9 @@ function useReducedTransparency() {
5328
6000
  }
5329
6001
 
5330
6002
  // src/hooks/use-mounted.ts
5331
- import { useState as useState28, useEffect as useEffect20 } from "react";
6003
+ import { useState as useState29, useEffect as useEffect20 } from "react";
5332
6004
  function useMounted() {
5333
- const [mounted, setMounted] = useState28(false);
6005
+ const [mounted, setMounted] = useState29(false);
5334
6006
  useEffect20(() => {
5335
6007
  setMounted(true);
5336
6008
  }, []);
@@ -5394,8 +6066,9 @@ export {
5394
6066
  ToastProvider,
5395
6067
  Toggle,
5396
6068
  Tooltip,
5397
- clamp,
6069
+ clamp2 as clamp,
5398
6070
  cleanupFilters,
6071
+ clearGlisseCache,
5399
6072
  cn,
5400
6073
  createLensFilter,
5401
6074
  createRefractionFilter,
@@ -5412,12 +6085,14 @@ export {
5412
6085
  throttle,
5413
6086
  useControllable,
5414
6087
  useGlass,
6088
+ useGlisseEffect,
5415
6089
  useId,
5416
6090
  useMounted,
5417
6091
  usePointerPosition,
5418
6092
  usePressedState,
5419
6093
  useReducedMotion,
5420
6094
  useReducedTransparency,
6095
+ useRefraction,
5421
6096
  useSidebar,
5422
6097
  useTheme,
5423
6098
  useToast