@shohojdhara/atomix 0.6.4 → 0.6.6

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.
Files changed (83) hide show
  1. package/dist/atomix.css +117 -38
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +1 -1
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/atomix.umd.js +1 -1
  6. package/dist/atomix.umd.js.map +1 -1
  7. package/dist/atomix.umd.min.js +1 -1
  8. package/dist/charts.d.ts +30 -1
  9. package/dist/charts.js +625 -846
  10. package/dist/charts.js.map +1 -1
  11. package/dist/core.d.ts +30 -1
  12. package/dist/core.js +659 -873
  13. package/dist/core.js.map +1 -1
  14. package/dist/forms.d.ts +30 -1
  15. package/dist/forms.js +1171 -1402
  16. package/dist/forms.js.map +1 -1
  17. package/dist/heavy.d.ts +31 -89
  18. package/dist/heavy.js +975 -1195
  19. package/dist/heavy.js.map +1 -1
  20. package/dist/index.d.ts +383 -140
  21. package/dist/index.esm.js +1567 -1679
  22. package/dist/index.esm.js.map +1 -1
  23. package/dist/index.js +1556 -1667
  24. package/dist/index.js.map +1 -1
  25. package/dist/index.min.js +1 -1
  26. package/dist/index.min.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/components/Accordion/Accordion.tsx +2 -5
  29. package/src/components/AtomixGlass/AtomixGlass.test.tsx +14 -16
  30. package/src/components/AtomixGlass/AtomixGlass.tsx +137 -364
  31. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +32 -251
  32. package/src/components/AtomixGlass/GlassFilter.tsx +62 -68
  33. package/src/components/AtomixGlass/README.md +2 -1
  34. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +19 -18
  35. package/src/components/AtomixGlass/glass-border-styles.test.ts +58 -0
  36. package/src/components/AtomixGlass/glass-border-styles.ts +136 -0
  37. package/src/components/AtomixGlass/glass-utils.ts +456 -22
  38. package/src/components/AtomixGlass/shader-utils.ts +19 -77
  39. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +158 -537
  40. package/src/components/AtomixGlass/stories/Border.stories.tsx +149 -0
  41. package/src/components/AtomixGlass/stories/Examples.stories.tsx +229 -89
  42. package/src/components/AtomixGlass/stories/Playground.stories.tsx +29 -340
  43. package/src/components/AtomixGlass/stories/argTypes.ts +30 -13
  44. package/src/components/AtomixGlass/stories/premium-presets.ts +206 -0
  45. package/src/components/AtomixGlass/stories/shared-components.tsx +52 -8
  46. package/src/components/Badge/Badge.tsx +4 -4
  47. package/src/components/Button/Button.tsx +2 -6
  48. package/src/components/Callout/Callout.test.tsx +4 -3
  49. package/src/components/Callout/Callout.tsx +2 -5
  50. package/src/components/Dropdown/Dropdown.tsx +3 -7
  51. package/src/components/Form/Checkbox.tsx +2 -8
  52. package/src/components/Form/Input.tsx +2 -9
  53. package/src/components/Form/Radio.tsx +2 -9
  54. package/src/components/Form/Select.test.tsx +6 -6
  55. package/src/components/Form/Select.tsx +2 -7
  56. package/src/components/Form/Textarea.stories.tsx +5 -5
  57. package/src/components/Form/Textarea.tsx +2 -9
  58. package/src/components/Messages/Messages.tsx +2 -8
  59. package/src/components/Modal/Modal.tsx +4 -5
  60. package/src/components/Navigation/Nav/Nav.tsx +2 -6
  61. package/src/components/Navigation/Navbar/Navbar.tsx +2 -9
  62. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -6
  63. package/src/components/Pagination/Pagination.tsx +2 -10
  64. package/src/components/Popover/Popover.tsx +2 -9
  65. package/src/components/Progress/Progress.tsx +2 -7
  66. package/src/components/Rating/Rating.tsx +2 -10
  67. package/src/components/Spinner/Spinner.tsx +2 -7
  68. package/src/components/Steps/Steps.tsx +2 -10
  69. package/src/components/Tabs/Tabs.tsx +2 -9
  70. package/src/components/Toggle/Toggle.tsx +2 -10
  71. package/src/components/Tooltip/Tooltip.tsx +2 -5
  72. package/src/lib/composables/useAtomixGlass.ts +42 -143
  73. package/src/lib/composables/useAtomixGlassStyles.ts +61 -77
  74. package/src/lib/composables/usePerformanceMonitor.ts +5 -66
  75. package/src/lib/constants/components.ts +363 -46
  76. package/src/lib/types/components.ts +33 -1
  77. package/src/styles/01-settings/_settings.atomix-glass.scss +66 -28
  78. package/src/styles/02-tools/_tools.button.scss +51 -42
  79. package/src/styles/02-tools/_tools.glass.scss +45 -3
  80. package/src/styles/06-components/_components.atomix-glass.scss +116 -79
  81. package/src/components/AtomixGlass/PerformanceDashboard.tsx +0 -171
  82. package/src/components/AtomixGlass/animation-system.ts +0 -578
  83. package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +0 -390
package/dist/forms.js CHANGED
@@ -7,7 +7,65 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
7
7
  */
8
8
  /**
9
9
  * Form-specific constants
10
- */ const FORM_CLASSES_BASE = "c-form", FORM_CLASSES_DISABLED = "c-form--disabled", FORM_GROUP_CLASSES_BASE = "c-form-group", FORM_GROUP_CLASSES_SMALL = "c-form-group--sm", FORM_GROUP_CLASSES_LARGE = "c-form-group--lg", FORM_GROUP_CLASSES_INVALID = "c-form-group--invalid", FORM_GROUP_CLASSES_VALID = "c-form-group--valid", FORM_GROUP_CLASSES_DISABLED = "c-form-group--disabled", INPUT_CLASSES_BASE = "c-input", INPUT_CLASSES_SMALL = "c-input--sm", INPUT_CLASSES_LARGE = "c-input--lg", INPUT_CLASSES_INVALID = "is-invalid", INPUT_CLASSES_VALID = "is-valid", INPUT_CLASSES_DISABLED = "is-disabled", INPUT_CLASSES_FULL_WIDTH = "c-input--full-width", INPUT_CLASSES_PREFIX_ICON = "c-input--prefix-icon", INPUT_CLASSES_SUFFIX_ICON = "c-input--suffix-icon", INPUT_CLASSES_CLEARABLE = "c-input--clearable", INPUT_CLASSES_WITH_COUNTER = "c-input--with-counter", INPUT_CLASSES_PASSWORD_TOGGLE = "c-input--password-toggle", INPUT_ELEMENTS_WRAPPER = "c-input-wrapper", RADIO_CLASSES_BASE = "c-radio", RADIO_CLASSES_INVALID = "is-error", RADIO_CLASSES_VALID = "is-valid", RADIO_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_BASE = "c-select", SELECT_CLASSES_SELECTED = "c-select__selected", SELECT_CLASSES_SELECT_BODY = "c-select__body", SELECT_CLASSES_SELECT_PANEL = "c-select__panel", SELECT_CLASSES_SELECT_ITEMS = "c-select__items", SELECT_CLASSES_SELECT_ITEM = "c-select__item", SELECT_CLASSES_TOGGLE_ICON = "c-select__toggle-icon", SELECT_CLASSES_ICON_CARET = "icon-atomix-caret-down", SELECT_CLASSES_SMALL = "c-select--sm", SELECT_CLASSES_LARGE = "c-select--lg", SELECT_CLASSES_INVALID = "is-invalid", SELECT_CLASSES_VALID = "is-valid", SELECT_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_IS_OPEN = "is-open", TEXTAREA_CLASSES_BASE = "c-input c-input--textarea", TEXTAREA_CLASSES_SMALL = "c-input--sm", TEXTAREA_CLASSES_LARGE = "c-input--lg", TEXTAREA_CLASSES_INVALID = "is-invalid", TEXTAREA_CLASSES_VALID = "is-valid", TEXTAREA_CLASSES_DISABLED = "is-disabled", ATOMIX_GLASS = {
10
+ */ const FORM_CLASSES_BASE = "c-form", FORM_CLASSES_DISABLED = "c-form--disabled", FORM_GROUP_CLASSES_BASE = "c-form-group", FORM_GROUP_CLASSES_SMALL = "c-form-group--sm", FORM_GROUP_CLASSES_LARGE = "c-form-group--lg", FORM_GROUP_CLASSES_INVALID = "c-form-group--invalid", FORM_GROUP_CLASSES_VALID = "c-form-group--valid", FORM_GROUP_CLASSES_DISABLED = "c-form-group--disabled", INPUT_CLASSES_BASE = "c-input", INPUT_CLASSES_SMALL = "c-input--sm", INPUT_CLASSES_LARGE = "c-input--lg", INPUT_CLASSES_INVALID = "is-invalid", INPUT_CLASSES_VALID = "is-valid", INPUT_CLASSES_DISABLED = "is-disabled", INPUT_CLASSES_FULL_WIDTH = "c-input--full-width", INPUT_CLASSES_PREFIX_ICON = "c-input--prefix-icon", INPUT_CLASSES_SUFFIX_ICON = "c-input--suffix-icon", INPUT_CLASSES_CLEARABLE = "c-input--clearable", INPUT_CLASSES_WITH_COUNTER = "c-input--with-counter", INPUT_CLASSES_PASSWORD_TOGGLE = "c-input--password-toggle", INPUT_ELEMENTS_WRAPPER = "c-input-wrapper", RADIO_CLASSES_BASE = "c-radio", RADIO_CLASSES_INVALID = "is-error", RADIO_CLASSES_VALID = "is-valid", RADIO_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_BASE = "c-select", SELECT_CLASSES_SELECTED = "c-select__selected", SELECT_CLASSES_SELECT_BODY = "c-select__body", SELECT_CLASSES_SELECT_PANEL = "c-select__panel", SELECT_CLASSES_SELECT_ITEMS = "c-select__items", SELECT_CLASSES_SELECT_ITEM = "c-select__item", SELECT_CLASSES_TOGGLE_ICON = "c-select__toggle-icon", SELECT_CLASSES_ICON_CARET = "icon-atomix-caret-down", SELECT_CLASSES_SMALL = "c-select--sm", SELECT_CLASSES_LARGE = "c-select--lg", SELECT_CLASSES_INVALID = "is-invalid", SELECT_CLASSES_VALID = "is-valid", SELECT_CLASSES_DISABLED = "is-disabled", SELECT_CLASSES_IS_OPEN = "is-open", TEXTAREA_CLASSES_BASE = "c-input c-input--textarea", TEXTAREA_CLASSES_SMALL = "c-input--sm", TEXTAREA_CLASSES_LARGE = "c-input--lg", TEXTAREA_CLASSES_INVALID = "is-invalid", TEXTAREA_CLASSES_VALID = "is-valid", TEXTAREA_CLASSES_DISABLED = "is-disabled", GLASS_DEFAULTS_INPUT = {
11
+ displacementScale: 18,
12
+ borderRadius: 6,
13
+ elasticity: 0
14
+ }, GLASS_DEFAULTS_TEXTAREA = {
15
+ displacementScale: 18,
16
+ borderRadius: 6,
17
+ elasticity: 0
18
+ }, GLASS_DEFAULTS_SELECT = {
19
+ displacementScale: 18,
20
+ borderRadius: 6,
21
+ elasticity: 0
22
+ }, GLASS_DEFAULTS_CHECKBOX = {
23
+ displacementScale: 14,
24
+ borderRadius: 4,
25
+ elasticity: 0
26
+ }, GLASS_DEFAULTS_RADIO = {
27
+ displacementScale: 14,
28
+ borderRadius: 99,
29
+ elasticity: 0
30
+ }, GLASS_BORDER_GRADIENT = {
31
+ BASE_ANGLE: 135,
32
+ ANGLE_MULTIPLIER: .5,
33
+ VELOCITY_ANGLE_MULTIPLIER: .5,
34
+ CHROMATIC_OFFSET: 1.5,
35
+ STOP_1: {
36
+ MIN: 10,
37
+ BASE: 33,
38
+ get MULTIPLIER() {
39
+ return .009 * this.BASE;
40
+ }
41
+ },
42
+ STOP_2: {
43
+ MAX: 90,
44
+ BASE: 66,
45
+ get MULTIPLIER() {
46
+ return .006 * this.BASE;
47
+ }
48
+ },
49
+ OPACITY: {
50
+ /** Matches $glass-border-1-opacity (0.08) */
51
+ BASE_1: .08,
52
+ get BASE_2() {
53
+ return 3.33 * this.BASE_1;
54
+ },
55
+ get BASE_3() {
56
+ return 2.66 * this.BASE_1;
57
+ },
58
+ get BASE_4() {
59
+ return 5 * this.BASE_1;
60
+ },
61
+ get MULTIPLIER_LOW() {
62
+ return .066 * this.BASE_1;
63
+ },
64
+ get MULTIPLIER_HIGH() {
65
+ return .1 * this.BASE_1;
66
+ }
67
+ }
68
+ }, ATOMIX_GLASS = {
11
69
  BASE_CLASS: "c-atomix-glass",
12
70
  CONTAINER_CLASS: "c-atomix-glass__container",
13
71
  INNER_CLASS: "c-atomix-glass__inner",
@@ -18,6 +76,22 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
18
76
  BORDER_BACKDROP_CLASS: "c-atomix-glass__border-backdrop",
19
77
  BORDER_1_CLASS: "c-atomix-glass__border-1",
20
78
  BORDER_2_CLASS: "c-atomix-glass__border-2",
79
+ /** Centralized liquid glass rim configuration */
80
+ BORDER: {
81
+ WIDTH_CSS_VAR: "--atomix-glass-border-width",
82
+ DEFAULT_WIDTH: "0.5px",
83
+ GRADIENT_CSS_VARS: {
84
+ GRADIENT_1: "--atomix-glass-border-gradient-1",
85
+ GRADIENT_2: "--atomix-glass-border-gradient-2"
86
+ },
87
+ GRADIENT: GLASS_BORDER_GRADIENT,
88
+ OVER_LIGHT: {
89
+ opacity: .7
90
+ },
91
+ DARK: {
92
+ opacity: .35
93
+ }
94
+ },
21
95
  HOVER_1_CLASS: "c-atomix-glass__hover-1",
22
96
  HOVER_2_CLASS: "c-atomix-glass__hover-2",
23
97
  HOVER_3_CLASS: "c-atomix-glass__hover-3",
@@ -46,25 +120,22 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
46
120
  SHADER: "c-atomix-glass--shader"
47
121
  },
48
122
  DEFAULTS: {
49
- DISPLACEMENT_SCALE: 70,
123
+ /** Subtle refraction — Apple UI chrome avoids heavy liquid distortion */
124
+ DISPLACEMENT_SCALE: 28,
50
125
  get BLUR_AMOUNT() {
51
- return .15 * this.DISPLACEMENT_SCALE;
52
- // Dynamically computed based on displacement
53
- },
54
- get SATURATION() {
55
- return 100 + .5 * this.DISPLACEMENT_SCALE;
56
- // Saturate relative to intensity
57
- },
126
+ // Apple Music sidebar / player bar: ~20–40px frost (see $glass-backdrop-filter)
127
+ return Math.max(20, .72 * this.DISPLACEMENT_SCALE);
128
+ },
129
+ /** Fixed 180% matches Apple's saturate(180%) backdrop recipe */
130
+ SATURATION: 180,
58
131
  get ABERRATION_INTENSITY() {
59
- return .03 * this.DISPLACEMENT_SCALE;
60
- // Scale aberration with displacement
61
- },
62
- ELASTICITY: .15,
132
+ return .02 * this.DISPLACEMENT_SCALE;
133
+ },
134
+ ELASTICITY: .05,
63
135
  get CORNER_RADIUS() {
64
136
  return 16;
65
137
  // Use 16 to match SCSS design system (was 20)
66
138
  },
67
- PADDING: "0",
68
139
  MODE: "standard",
69
140
  OVER_LIGHT: !1,
70
141
  ENABLE_OVER_LIGHT_LAYERS: !0,
@@ -80,19 +151,29 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
80
151
  },
81
152
  CONSTANTS: {
82
153
  ACTIVATION_ZONE: 200,
83
- LERP_FACTOR: .08,
154
+ LERP_FACTOR: .05,
155
+ // Lower = more viscous, liquid-smooth tracking (Apple feel)
84
156
  SMOOTHSTEP_POWER: 2.5,
85
157
  MIN_BLUR: .1,
86
158
  MOUSE_INFLUENCE_DIVISOR: 100,
87
159
  EDGE_FADE_PIXELS: 2,
88
- // Elasticity physics constants
89
- ELASTICITY_TRANSLATION_FACTOR: .1,
160
+ // Interaction intensity multipliers shared by the hook and the imperative style updater
161
+ INTERACTION: {
162
+ HOVER_INTENSITY: 1.4,
163
+ ACTIVE_INTENSITY: 1.6
164
+ },
165
+ // Elasticity physics constants — Apple-tuned: soft springs, fast settling, minimal stretch
166
+ ELASTICITY_TRANSLATION_FACTOR: .06,
167
+ // Subtler elastic shift (was 0.1)
90
168
  ELASTICITY_DISTANCE_THRESHOLD: 200,
91
169
  ELASTICITY_COMPRESSION_FACTOR: .3,
92
- ELASTICITY_STIFFNESS: .1,
93
- ELASTICITY_DAMPING: .76,
170
+ ELASTICITY_STIFFNESS: .06,
171
+ // Softer springs = gentler motion (was 0.1)
172
+ ELASTICITY_DAMPING: .88,
173
+ // Fast settling, no wobble (was 0.76)
94
174
  ELASTICITY_VELOCITY_FACTOR: .65,
95
- ELASTICITY_STRETCH_RATIO: .45,
175
+ ELASTICITY_STRETCH_RATIO: .25,
176
+ // Less visible surface tension stretch (was 0.45)
96
177
  ELASTICITY_MAGNIFICATION_BASE: 1.02,
97
178
  // Note: This default must match the SCSS variable --atomix-radius-md
98
179
  // @see src/styles/01-settings/_settings.global.scss
@@ -106,55 +187,16 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
106
187
  },
107
188
  // Gradient calculation constants
108
189
  GRADIENT: {
109
- BASE_ANGLE: 135,
110
- // Base angle for border gradients (degrees)
111
- ANGLE_MULTIPLIER: 1.2,
112
- // Multiplier for mouse influence on angle
113
- VELOCITY_ANGLE_MULTIPLIER: 2.5,
114
- // How much velocity affects gradient rotation
115
- CHROMATIC_OFFSET: 1.5,
116
- // Degree offset for chromatic rim layers
117
- BORDER_STOP_1: {
118
- MIN: 10,
119
- // Minimum percentage for border stop 1
120
- BASE: 33,
121
- // Base percentage for border stop 1
122
- get MULTIPLIER() {
123
- return .009 * this.BASE;
124
- }
125
- },
126
- BORDER_STOP_2: {
127
- MAX: 90,
128
- // Maximum percentage for border stop 2
129
- BASE: 66,
130
- // Base percentage for border stop 2
131
- get MULTIPLIER() {
132
- return .006 * this.BASE;
133
- }
134
- },
135
- BORDER_OPACITY: {
136
- BASE_1: .12,
137
- // Base opacity for border gradient 1
138
- get BASE_2() {
139
- return 3.33 * this.BASE_1;
140
- },
141
- // Base opacity for border gradient 2
142
- get BASE_3() {
143
- return 2.66 * this.BASE_1;
144
- },
145
- // Base opacity for border gradient 3
146
- get BASE_4() {
147
- return 5 * this.BASE_1;
148
- },
149
- // Base opacity for border gradient 4
150
- get MULTIPLIER_LOW() {
151
- return .066 * this.BASE_1;
152
- },
153
- // Low multiplier for mouse influence on opacity
154
- get MULTIPLIER_HIGH() {
155
- return .1 * this.BASE_1;
156
- }
157
- },
190
+ BASE_ANGLE: GLASS_BORDER_GRADIENT.BASE_ANGLE,
191
+ ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.ANGLE_MULTIPLIER,
192
+ VELOCITY_ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.VELOCITY_ANGLE_MULTIPLIER,
193
+ CHROMATIC_OFFSET: GLASS_BORDER_GRADIENT.CHROMATIC_OFFSET,
194
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_1 */
195
+ BORDER_STOP_1: GLASS_BORDER_GRADIENT.STOP_1,
196
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_2 */
197
+ BORDER_STOP_2: GLASS_BORDER_GRADIENT.STOP_2,
198
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.OPACITY */
199
+ BORDER_OPACITY: GLASS_BORDER_GRADIENT.OPACITY,
158
200
  CENTER_POSITION: 50,
159
201
  // Center position percentage (50%)
160
202
  HOVER_POSITION: {
@@ -187,8 +229,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
187
229
  return 2 * this.BLACK_STOP;
188
230
  },
189
231
  // End percentage for black hover 1
190
- WHITE_START: .5,
191
- // Start opacity for white hover 1
232
+ WHITE_START: .35,
233
+ // Gentler hover flash Apple hover is barely visible
192
234
  get WHITE_STOP() {
193
235
  return this.BLACK_END - 10;
194
236
  }
@@ -206,8 +248,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
206
248
  return 2 * this.BLACK_STOP;
207
249
  },
208
250
  // End percentage for black hover 2
209
- WHITE_START: 1,
210
- // Start opacity for white hover 2
251
+ WHITE_START: .7,
252
+ // Gentler hover flash
211
253
  get WHITE_STOP() {
212
254
  return this.BLACK_END;
213
255
  }
@@ -225,8 +267,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
225
267
  return 2 * this.BLACK_STOP;
226
268
  },
227
269
  // End percentage for black hover 3
228
- WHITE_START: 1,
229
- // Start opacity for white hover 3
270
+ WHITE_START: .7,
271
+ // Gentler hover flash
230
272
  get WHITE_STOP() {
231
273
  return this.BLACK_END;
232
274
  }
@@ -236,13 +278,13 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
236
278
  BASE_GRADIENT: {
237
279
  ANGLE: 135,
238
280
  // Gradient angle in degrees
239
- BLACK_START_BASE: .15,
281
+ BLACK_START_BASE: .1,
240
282
  // Base start opacity for black
241
283
  get BLACK_START_MULTIPLIER() {
242
284
  return .02 * this.BLACK_START_BASE;
243
285
  },
244
286
  // Multiplier for mouse X influence on start
245
- BLACK_MID_BASE: .1,
287
+ BLACK_MID_BASE: .07,
246
288
  // Base mid opacity for black
247
289
  get BLACK_MID_MULTIPLIER() {
248
290
  return .02 * this.BLACK_MID_BASE;
@@ -263,7 +305,7 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
263
305
  }
264
306
  },
265
307
  OVERLAY_GRADIENT: {
266
- BLACK_START_BASE: .12,
308
+ BLACK_START_BASE: .08,
267
309
  // Base start opacity for black overlay
268
310
  get BLACK_START_MULTIPLIER() {
269
311
  return .025 * this.BLACK_START_BASE;
@@ -287,14 +329,14 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
287
329
  return .416 * this.BLACK_START_BASE;
288
330
  }
289
331
  },
290
- // Overlay highlight constants
332
+ // Overlay highlight constants — Apple places specular at the top-center
291
333
  OVERLAY_HIGHLIGHT: {
292
- POSITION_X: 20,
293
- // X position percentage
294
- POSITION_Y: 20,
295
- // Y position percentage
296
- WHITE_OPACITY: .4,
297
- // White opacity in gradient
334
+ POSITION_X: 50,
335
+ // Centered horizontal — Apple's top-center specular
336
+ POSITION_Y: 5,
337
+ // Very top — catches light like a curved glass surface
338
+ WHITE_OPACITY: .28,
339
+ // Softer specular visible but not glaring
298
340
  get STOP() {
299
341
  return 150 * this.WHITE_OPACITY;
300
342
  },
@@ -315,6 +357,10 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
315
357
  SATURATION: {
316
358
  HIGH_CONTRAST: 200
317
359
  },
360
+ // Container shadows — hairline inner catch + soft floating lift (Apple player bar)
361
+ CONTAINER_SHADOW: {
362
+ LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0 4px 16px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.08)"
363
+ },
318
364
  // Phase 1: Animation System Constants
319
365
  ANIMATION: {
320
366
  // Breathing effect timing (in milliseconds)
@@ -354,267 +400,638 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
354
400
  }
355
401
  }
356
402
  }
357
- }, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
358
- x: rect.left + rect.width / 2,
359
- y: rect.top + rect.height / 2
360
- } : {
361
- x: 0,
362
- y: 0
363
- }, calculateMouseInfluence = mouseOffset => {
364
- if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
365
- // Bounded calculation — keeps the glass effect subtle and stable
366
- const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$2.MOUSE_INFLUENCE_DIVISOR;
367
- return Math.min(.8, influence);
368
- // Tighter cap to prevent blur/filter blow-out
369
- }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$2.MIN_BLUR : Math.max(CONSTANTS$2.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$2.MAX_SIZE && size.height <= CONSTANTS$2.MAX_SIZE, parseBorderRadiusValue = value => {
370
- if ("number" == typeof value) return Math.max(0, value);
371
- if ("string" != typeof value || !value.trim()) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
372
- const trimmedValue = value.trim();
373
- // Handle px values
374
- if (trimmedValue.endsWith("px")) {
375
- const parsed = parseFloat(trimmedValue);
376
- return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
377
- }
378
- // Handle rem values (assume 16px = 1rem)
379
- if (trimmedValue.endsWith("rem")) {
380
- const parsed = parseFloat(trimmedValue);
381
- return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
382
- }
383
- // Handle em values (assume 16px = 1em for simplicity)
384
- if (trimmedValue.endsWith("em")) {
385
- const parsed = parseFloat(trimmedValue);
386
- return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
387
- }
388
- // Handle percentage (convert to approximate px value, assuming 200px container)
389
- if (trimmedValue.endsWith("%")) {
390
- const parsed = parseFloat(trimmedValue);
391
- return isNaN(parsed) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
392
- }
393
- // Handle unitless numbers
394
- const numValue = parseFloat(trimmedValue);
395
- return isNaN(numValue) ? CONSTANTS$2.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
396
- }, extractBorderRadiusFromElement = element => {
397
- if (!element || !element.props) return null;
398
- // Check inline styles first (highest priority)
399
- if (element.props.style) {
400
- const radiusFromStyle = (style => {
401
- if (!style) return null;
402
- // Check various border-radius properties
403
- const borderRadius = style.borderRadius || style.borderTopLeftRadius || style.borderTopRightRadius || style.borderBottomLeftRadius || style.borderBottomRightRadius;
404
- return void 0 !== borderRadius ? parseBorderRadiusValue(borderRadius) : null;
405
- })(element.props.style);
406
- if (null !== radiusFromStyle && radiusFromStyle > 0) return radiusFromStyle;
407
- }
408
- // If element has children, recursively check them
409
- if (element.props.children) {
410
- const childRadius = extractBorderRadiusFromChildren(element.props.children);
411
- if (childRadius > 0 && childRadius !== CONSTANTS$2.DEFAULT_CORNER_RADIUS) return childRadius;
412
- }
413
- return null;
414
- }, extractBorderRadiusFromChildren = children => {
415
- if (!children) return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
403
+ };
404
+
405
+ /**
406
+ * Form Group-specific constants
407
+ */ var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
408
+
409
+ function getDefaultExportFromCjs(x) {
410
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
411
+ }
412
+
413
+ var fails$8 = function(exec) {
416
414
  try {
417
- const childArray = React.Children.toArray(children);
418
- for (let i = 0; i < childArray.length; i++) {
419
- const child = childArray[i];
420
- if ( React.isValidElement(child)) {
421
- const radius = extractBorderRadiusFromElement(child);
422
- if (null !== radius) return radius;
423
- }
424
- }
415
+ return !!exec();
425
416
  } catch (error) {
426
- // Silently handle errors
417
+ return !0;
427
418
  }
428
- return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
429
- }, smoothstep = t => {
430
- const clamped = Math.max(0, Math.min(1, t));
431
- return clamped * clamped * (3 - 2 * clamped);
432
- }, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
433
- const newVelocity = (velocity + (target - current) * stiffness) * damping;
434
- return {
435
- value: current + newVelocity,
436
- velocity: newVelocity
419
+ }, functionBindNative = !fails$8((function() {
420
+ // eslint-disable-next-line es/no-function-prototype-bind -- safe
421
+ var test = function() {/* empty */}.bind();
422
+ // eslint-disable-next-line no-prototype-builtins -- safe
423
+ return "function" != typeof test || test.hasOwnProperty("prototype");
424
+ })), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
425
+ return function() {
426
+ return call$5.apply(fn, arguments);
437
427
  };
438
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
439
- switch (mode) {
440
- case "standard":
441
- return displacementMap;
428
+ }, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
429
+ return it && it.Math === Math && it;
430
+ }, globalThis_1 =
431
+ // eslint-disable-next-line es/no-global-this -- safe
432
+ check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
433
+ // eslint-disable-next-line no-restricted-globals -- safe
434
+ check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
435
+ // eslint-disable-next-line no-new-func -- fallback
436
+ function() {
437
+ return this;
438
+ }() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
439
+ return call$4.apply(apply$1, arguments);
440
+ }), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
441
+ return stringSlice(toString$3(it), 8, -1);
442
+ }, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
443
+ // Nashorn bug:
444
+ // https://github.com/zloirock/core-js/issues/1128
445
+ // https://github.com/zloirock/core-js/issues/1130
446
+ if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
447
+ }, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
448
+ return "function" == typeof argument || argument === documentAll;
449
+ } : function(argument) {
450
+ return "function" == typeof argument;
451
+ }, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$8((function() {
452
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
453
+ return 7 !== Object.defineProperty({}, 1, {
454
+ get: function() {
455
+ return 7;
456
+ }
457
+ })[1];
458
+ })), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
459
+ return call$3.apply(call$3, arguments);
460
+ }, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
461
+ 1: 2
462
+ }, 1);
442
463
 
443
- case "polar":
444
- return polarDisplacementMap;
464
+ // `Object.prototype.propertyIsEnumerable` method implementation
465
+ // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
466
+ objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
467
+ var descriptor = getOwnPropertyDescriptor$1(this, V);
468
+ return !!descriptor && descriptor.enumerable;
469
+ } : $propertyIsEnumerable;
445
470
 
446
- case "prominent":
447
- return prominentDisplacementMap;
471
+ var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
472
+ return {
473
+ enumerable: !(1 & bitmap),
474
+ configurable: !(2 & bitmap),
475
+ writable: !(4 & bitmap),
476
+ value: value
477
+ };
478
+ }, fails$5 = fails$8, classof$3 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$5((function() {
479
+ // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
480
+ // eslint-disable-next-line no-prototype-builtins -- safe
481
+ return !$Object$3("z").propertyIsEnumerable(0);
482
+ })) ? function(it) {
483
+ return "String" === classof$3(it) ? split(it, "") : $Object$3(it);
484
+ } : $Object$3, isNullOrUndefined$2 = function(it) {
485
+ return null == it;
486
+ }, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$6 = TypeError, requireObjectCoercible$3 = function(it) {
487
+ if (isNullOrUndefined$1(it)) throw new $TypeError$6("Can't call method on " + it);
488
+ return it;
489
+ }, IndexedObject = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
490
+ return IndexedObject(requireObjectCoercible$2(it));
491
+ }, isCallable$7 = isCallable$8, isObject$5 = function(it) {
492
+ return "object" == typeof it ? null !== it : isCallable$7(it);
493
+ }, path$3 = {}, path$2 = path$3, globalThis$a = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
494
+ return isCallable$6(variable) ? variable : void 0;
495
+ }, navigator$1 = globalThis_1.navigator, userAgent$1 = navigator$1 && navigator$1.userAgent, globalThis$8 = globalThis_1, userAgent = userAgent$1 ? String(userAgent$1) : "", process$1 = globalThis$8.process, Deno = globalThis$8.Deno, versions = process$1 && process$1.versions || Deno && Deno.version, v8 = versions && versions.v8;
448
496
 
449
- case "shader":
450
- return shaderMapUrl || displacementMap;
497
+ v8 && (
498
+ // in old Chrome, versions of V8 isn't V8 = Chrome / 10
499
+ // but their correct versions are not interesting for us
500
+ version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
501
+ // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
502
+ // so check `userAgent` even if `.v8` exists, but 0
503
+ !version && userAgent && (!(match = userAgent.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent.match(/Chrome\/(\d+)/)) && (version = +match[1]);
451
504
 
452
- default:
453
- return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
505
+ var V8_VERSION = version, fails$4 = fails$8, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$4((function() {
506
+ var symbol = Symbol("symbol detection");
507
+ // Chrome 38 Symbol has incorrect toString conversion
508
+ // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
509
+ // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
510
+ // of course, fail.
511
+ return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
512
+ // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
513
+ !Symbol.sham && V8_VERSION && V8_VERSION < 41;
514
+ })), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$1 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
515
+ return "symbol" == typeof it;
516
+ } : function(it) {
517
+ var $Symbol = function(namespace, method) {
518
+ return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$a[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$a[namespace] && globalThis$a[namespace][method];
519
+ }("Symbol");
520
+ return isCallable$5($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
521
+ }, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$5 = TypeError, aCallable$2 = function(argument) {
522
+ if (isCallable$4(argument)) return argument;
523
+ throw new $TypeError$5(function(argument) {
524
+ try {
525
+ return $String$2(argument);
526
+ } catch (error) {
527
+ return "Object";
528
+ }
529
+ }(argument) + " is not a function");
530
+ }, aCallable$1 = aCallable$2, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$4 = TypeError, sharedStore = {
531
+ exports: {}
532
+ }, globalThis$6 = globalThis_1, defineProperty = Object.defineProperty, globalThis$5 = globalThis_1, store$1 = sharedStore.exports = globalThis$5["__core-js_shared__"] || function(key, value) {
533
+ try {
534
+ defineProperty(globalThis$6, key, {
535
+ value: value,
536
+ configurable: !0,
537
+ writable: !0
538
+ });
539
+ } catch (error) {
540
+ globalThis$6[key] = value;
454
541
  }
455
- }, sharedShaderCache = new Map, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
456
- style: {
457
- position: "absolute",
458
- width: "100%",
459
- height: "100%",
460
- inset: 0
461
- },
462
- "aria-hidden": "true",
463
- children: jsxs("defs", {
464
- children: [ jsxs("radialGradient", {
465
- id: `${id}-edge-mask`,
466
- cx: "50%",
467
- cy: "50%",
468
- r: "50%",
469
- children: [ jsx("stop", {
470
- offset: "0%",
471
- stopColor: "black",
472
- stopOpacity: "0"
473
- }), jsx("stop", {
474
- offset: `${Math.max(30, 80 - 2 * aberrationIntensity)}%`,
475
- stopColor: "black",
476
- stopOpacity: "0"
477
- }), jsx("stop", {
478
- offset: "100%",
479
- stopColor: "white",
480
- stopOpacity: "1"
481
- }) ]
482
- }), jsxs("filter", {
483
- id: id,
484
- x: "-35%",
485
- y: "-35%",
486
- width: "170%",
487
- height: "170%",
488
- colorInterpolationFilters: "sRGB",
489
- children: [ jsx("feImage", {
490
- id: `${id}-image`,
491
- x: "0",
492
- y: "0",
493
- width: "100%",
494
- height: "100%",
495
- result: "DISPLACEMENT_MAP",
496
- href: getDisplacementMap(mode, "data:image/jpeg;base64,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cUAUAkEkziomgGgkoxZGgxZFQFQlYnQHRdPfj/10KCSCKESCNiVkViPSLpD0h6I0Q0I0A2IoBWBIJIBKBIJoJIJ2R2J0JWBUJ0JUB0XTv479dFZDYiglYigkhEgjZFQjRFQjRFQjQigFYigHYigmgEgmglYlYnQlQlYlQHQlQnQ9P/kf1yVkNiNCNkNiVENiNiViNEViNkVCVgKCViViViSCViSCVgdCViVCViVCdgVCVCdD1D+U/XBWQ2I0I2Q2JUQ2I0JWQ0I2JUQ2JUI2JUI2J0JWJWJWA2R0BWJ0I2JUJ2BUJUJ0P//EABkQAQEBAQEBAAAAAAAAAAAAAAECABEDEP/aAAgBAQABAgB1atWrVq1atWrVq1atWrVq1atWrVq1atWrVq+OrVq1atWrVq1atWrVq1atWrVq1atWrVq1atXxVppppppdWrVq1atWrVq1NNNNNNNNNNNPVWmmmmms6tWrVq1atWpppppppppppppp6q0000uc51atWrVq1ammmmmmmmmmmmmt1Vpppc5znVq1atWrVqaaaaaaaaaaaaaeqtNLnOc51atWrVq1ammmmmmmmmmmmmnqrS5znOc6tWrVq16222mmmmmmlVppp6tKuc5znOrVq1a9TbbbbTTTTTSq000qtLnOc5zq1atWrW0222200000qqqtKqrnOc5zq1atTbbbbbbbbTTTSqqqqqq5znOc6tTTTbbbbbbbbTTTSqqqqrlVznOctNNNtttttttttNNNNKqqqrqznKqrTTTTbbbbbbbbbTTTSqqqqrqznOc5aaaabbbbbbbbbaaaaVVVVVdWc5znVq1NNttttttttttNNKqqqqudWc5znVq16tbbbbbbbbbbTTSqqqq5XVnOc6tWrVrb1tttttttttNNKqqqqrWrK5VWmmm2230bbbbbbaaaXOc5zlVa1KuVVppptttt9G22222mmlzlVznK6tWVVWmmmm2222222222mlznOc5znLWppVVWmmm22222229bTWrOc5znOcq1qaaVpWmm222222229erVqznOc5znKtatStK0rTbTTbbbberXr1as5znOc5aVpppppWlabaabbbb1ta9WrVnOc5znU0rTTTTTTTTTbTTbbbTWvVq1as5znOdTTStNNNNNNNNNtNNtttN6tWvVq1ZznOrU00rTTTTTTTTTTTTTbTWvVq1atWrOc6tTTTStNNNNNNNNNNtNNtNa9WrVq1Z1Z1NNNNNK1q1NNNNNNNNNNNtNatWrVq1atWrU00000rWrVq1atWrVq1alaaa1atWrVq1NNNammmmla1atWrVq1aterVq16tWrVnVqa1NK1qaaaVX/xAAWEAADAAAAAAAAAAAAAAAAAAAhgJD/2gAIAQEAAz8AaExf/8QAGhEBAQEBAQEBAAAAAAAAAAAAAQISEQADEP/aAAgBAgEBAgDx48ePHjx48ePHjx48ePHjx48ePHjx48ePHj86IiIiIiInjx48ePHjx48IiIiIj0oooooooooRERER73ve60UUUUUUVrWiiiiiihERERER73ve97ooooorRWiiiiihKERERER73ve973RRRRWtFFFFFFCIiIiIiPe973ve60UUVrRRRRRRQiIlCIiI973ve973pRRWiiiiiiiiiiiiiiihEe973ve973RRWtFFFFFFFFFFFFFFFFFFa13ve973WitaKKKKKKKKKKKKKKKKKK1rWtd1rutFa1oooooooooooosssooorWta1rWta1rRRRRRRRRRRZZZZZZZZZWta1rWta1rRRRRRRRRZZZZZZZZZZZZe9a1rWta1rWitaKLLLLLLLLLLLLLLLLL3rWta1rWtFbLLLLLLLLLLLLLLLLLLLL3vWta1rWita1ssssssss+hZZZZZZZZe961rWta0Vre97LLLLLLLLLLLPoWWWWWXrWta1oorWta3ssss+hZZZZ9Cyyyyyyyyiita1orWta1ve9llllllllllllllllFFa0VorWta1ve9llllllllllllllllllFFFaK1rWta1rWiyyyyyyyyyyyyiiiiiiitFFa1rWta1oosoosssssoooosoooorRRRWta1rWta0UUUUUWUUUUUUUUUUUVoooorWta1rWtaKKKKKKmiiiiiiiiiiiiiiitd73ve61oSiiipoqaKKKKKKKKKK0UUUVrve973vREREZoSihEooooorRRRRWtd73ve9EREREREoSiiiiitFllllla73ve9ERERERESiiiiiitH0PoWWWWVrXe96IiIiMoiJRRRRRRWjwlFFllllFFd6IiIiIlCUUUUUUUUUePHjx48ePCIiIiIiIiUUUUUUUUUUUePHjx48ePHjx48ePHjx48IiUUUUUUJRRRX//xAAWEQADAAAAAAAAAAAAAAAAAAABYJD/2gAIAQIBAz8AtEV7/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAECEP/aAAgBAwEBAgCtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcrTTTTTTTTTTTTTTTTTTTTTTTTTTTTTXKrTTTTTTTU000000000000000000001FVpppppqampqaaaaaaaaaaaaaaaaaaaa5Vaaaaampqampqammmmmmmmmmmlaaaaaaiq0001NTU1NTU1NTTTTTTTTTTSqqtNNNcqtNNSyzU1LNTU1NTTTTTTTTTSqqq001ytNLLLLNTU1NTU1NTbbbTTTTTSqqq001ytNLLLLLNTU1NTU3NttttNNNNNKqq001KrSyyyyyzU1NTU3Nzc02220000qqqqrSqqyyyyyzU1NTU3Nzc3NttttNNNKqqqqqqssssss1NTU3Nzc3NzbbbbTTTSqqqqqqrLLLLLNTU1Nzc3Nzc22220000qqqqqqqqssss1NTU3Nzc3NzbbbbbTTSqqqqqqqqqqzU1NTc3Nzc3Nzbc22000qqqqqqqqqqqtTU3Nzc3Nzc3NtzbTTSqqqqrKqqqqqtNNzc23Nzc3Nzc3NTU1KqqqrKqqqqqtNNNNttzc3Nzc3NzU1NLLLLLKqqqqqqqq0022223Nzc3NzU1NSyyyyyyqqqqqqqrTTbbbbc3Nzc3NTU1LLLLLLKsqqqqqqrTTTTbbbc3Nzc1NTUsssssssqqqqqqrTTTTTbbbTc3NTU1NTUsssssqqqqqqqq0000222023NTU1NTUsssssqqqqqqqq000000003NTU1NTU1LLLLLNKrTSqqqqtNNNNNNtNNTU1NSzUssss00qq0qqqqrTTTTTTTTTU1NTUs1LLLNNNKrTTTSqqq00000000001NTU1LNTU0000qtNNNKqqqtNNNNNNNNTU1NTUs1NNNNNKss1NNNK00qtK0000001NNTU0s000000qq000001NKrStNNNNK1NNNNStNNNNNKqtNNNNNNNK0000000rU0000rTTTTTSq00000rTTTTTTTTTTTTTTTTStNNNNKr/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=", "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/2wCEAAYEBAQFBAYFBQYJBgUGCQsIBgYICwwKCgsKCgwQDAwMDAwMEAwODxAPDgwTExQUExMcGxsbHB8fHx8fHx8fHx8BBwcHDQwNGBAQGBoVERUaHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH//CABEIAQABAAMBEQACEQEDEQH/xAAxAAADAQEBAAAAAAAAAAAAAAABAgMABAcBAAMBAQEBAAAAAAAAAAAAAAIDBAEABQb/2gAMAwEAAhADEAAAAPG/tfu93bu3bs7d27t3bu2du7d27h3bs3du7d27t3bc3du7d27tvbu3du7d27T3E+2du05u7tm7O2cM7d2zt3Du2YOzbw7N3bcHZt7dm3tvbeO9u7dx3d3Ht3cS05pzd24dOds0Z2HdnDsGdswdg7hw7cHYNzbg3NvbcO9izbx3TvbtPae09pLTmnCObh3ZuHcO4eGcM4ZgzB2DhHYOEbg0QWbcxZtzFmLjvEuO6e07p4jmsWnCOERIiWHcO4NA8M4DwzBmLgjsXRHCNEEI0QQ4sxZjwlxLjvEtPa2keJuJt04bCREsJECw6A3BoHFHhmKIrmLwjQXRGgpCCHEIMcWE8x4S1i4lraR7W02wnIiJsJkTIFg3AWXoHgGqGAcXBTBXhXgXQUgBADAGIMceE8J4T4lrFraTaT6TYbabiZFjAeAissBBegNAcq8UcXBXATBXVpoKQAlqYBg4wzMx4WYx8T1i1yJtN+NsN9NxYwmVmQZlllllaA1V8oYoYoimAnAmrXVoS1MAawwAwcwSzCzCfMzXLWIn035j8b6xwYwMIMKjKzyiCyCuVfKGKAoIpgJgJq0JSEtTWprDQzAzRzBZvFnMfOZORuRvzHw6a1wYwMZbSphUeUQUQXqqxF4gCgCmAnLnykJaGpTUrFhqw0M0S0S3GZrM52E5HTTfm0xlNY4OYGMtrJZlMKSCiVOqrkWKAKACCE+XPVTJSGlGKDFq1YcvNEuFm4zeZmuwqEb6ymspja61wcymutpS0pPJMJIJ1FcqsRYTAJ4ueKkSpkpDSjFK1StVnBnAXCXYzeduuwqEyhMrrKY6nNoDnU5lNZLSlmQYQap1U4ihRYzBcxXLlS1MyVNiUYlWqVyg9ecBeDO5nc7dowqGyhMrzaY6vOoDnU50uZLihmQwIJUaqcRIzUEwXIVy5UtTI0zYhGKRyVckPXnrLxZ+O7naVGlQ2VJtebXH151AdRT2S9kNM7chgnJUaqMRIooJLXIVR5UiREkzaibEq9CuUKFZ6zQLPxn9RpUadWHXW111cfbn0W+inuh7IcZ26dgnJZ9WfESM0hIFRFUuTHUxNEmIm5COQtCQ9WoWaRZ+O/qOKjTqxlibXnWx9efVdFE0Oh7ocZnadgmNZ9WYUSMkrktcRTHkw1EWIkxE3To9CUJFCdSs0C9AvRtHbVrKsZUnW11sotj6roommiHtM8zu0zBMYl1ZxnOM1LipUBTHkwJETni2eTkI+daULSnUrakGox6Oq8qtZVjLG6+vsNFuoqqmqKHRQ8zzM7TNWUhLqzYk4ySuC1RFMMRAp4Mni2eT50fOlKBSnVKNIPTj09V5VayzWWJ99fbKb5RVVNUU0noaahpnCVokMS8suTnGSVxUnnFMMRAp+dk0XTyfNOidKZxUnVKNQPSNKdq8qvZZjbm6/UXym2U2VTVFVJ6XleZX6RolMScsuTmCKFwUqAo5+RzlNBk0HTRfMlMyUoWpGrU1QNUNKetQdXsu1tyffaLjVfKbKqsiqk1LS0NI7SOEhiPllyUwRQuCk84I5+RzlNzslg6aNEs6ZkqnFaNWo1rerKVdag6vO7XdB0X6joyq+U2TXZFVJanloMjzG4RmI+STJzBGdfOpPOE/N0/MU3O2WDpo0yzplSqda0axLVrasa1bWkrvZdrrnR0bT0ZV0DVdNdZ66zVPJSY36NwjPRckeSmCM6udKeYEc3Tcxzc7JOd8saZZVSpVMLEaxJsW9Y0r21JXey7X9DKOnaega+garpstPXSWp5KWjo0ThEeh5I8lKEJ1c6k8oT82Tcxy8zZOd8sKZJ1SpXMts+sSbVvWNa+tUV3t6HP6Do6dq6Br6Mr6EWWmsrLU8lTRUaJwhPQ8keRkXCdfMlHME/Lk3KcvM2TnojhTJKuVLJVsn1qWtU9mVs61RXob0Nf0sp6eq6Mr6Rs6EWWmsrLXSOow06J2gPQ8kWRkXzzK5kp5Qn5cl5Tk5XSc9EcKo5VyzslFswtS1yntGtfXqO9Lel1HSdPTtXSNnSNnQi281lZK3iraKjQv0B7z+SLIyL5plcyE8i5uTpeU5OV0fPTHCqONciWyLbPrkG5VLgrZt6jvS3pdR1HT07X05Z1Bb0ItvNbWOukVbQ06F+8895/JDkI180yuZCONc3JkvIyTmdFzUx89cUrJJ2yLdNrp2vW9wVs69bOmlvS6jpZV1bX1Db0qt6VW3mttHa8NbQ06B7ecY8/pwDGMOaVXIhHGqbk6TkZHyvi5qYueuKNsc7ZFvm1yGvTS8a29es+ml3S+jqOvq2vpXb1Ku6lXXnttHbSGtoKt57z5x7z+nAMIg5pU8k6OJM3IcnI2LkbFzUxc9cMbY53SLfLr0N6CXuGt2dFh9NL+p9PUyrqG3pXb/8QAGxAAAwEBAQEBAAAAAAAAAAAAAAECEQMwECD/2gAIAQEAAQIAMzMzMzM/W7u7u745mZmZnhu7u7u+GZmZmZ4bu7u7vhmZmZmeG7u7u7+l8zMzMzBjGMY/m7u7u6IQhCEISzMzMxjGMYxje7u7u6hCEIQhJLMzMxjGMYxjGN7u7upoQhCEIQlmZmY0xjGMYxje7vzU0IQhCEISzMzMaYxjGMYxtvd3dQhCEIQhCEszMaaYxjGMYxtvd1NNCEIQhCEISzMxppjGMYxjG293U000IQhCJEISzMxppjTVKiihjG93U000IkkkkkQklmZjTTVFFFFFDG2291NNNOSSSSSRCSSWY0001SoooooY223upppoRJJJJJIkklmNNNNUqVFFFFDbbe6mmnJJJJJJJIkklmNNNNUUUUWUMbbb3U005JJJJJJJJSSWY001SpUqLKKKKbbe6mmnJJJJJJJJKSSzGmmqVFFllllFNtvdTTlySSQQSSSSkksxrGqVK1ZZZZRTbb3U05ckkEEEEkkpJLMaxqlSsssssoptt7qacuSSCCCCSSUklmNY1Sssssssoptt7qacuSSCCCCCSUklmNY1StWdCyyyim23uppy5JIIIIIIJUpLMxpqlZZZZ0LLKbbe6mnLkggggggglSkszGqVK1Z0LOh0LKdNvdTly4IIIIIIIJSSWZjVK1a6HQ6HQ6Flum3upy5cuCDmcyCCCUklmY1StWdDodDodCy3Tb3U5cuHBBzOZBBBKlJZmNUrVrodDodCyy3Tb3U5cuCDmczmQQQSpSWYk1StdDodDodDoWWU291OXDgg5nM5nM5kEqUlmY1StdDodTodDoWW6be6nLhwczmczmczmQSpSWZjVK10Op1Oh0OhZbpt7qckOHzOZzOZzOZBClJZiTVKzodTqdDqdDoW6be6nLhwczmczmczmcyFKSzBq10XRdTqdTqdDo7dNvdRJD5vmczkczmf/8QAFhAAAwAAAAAAAAAAAAAAAAAAMXCQ/9oACAEBAAM/AK3FJf/EABsRAAMBAQEBAQAAAAAAAAAAAAABAhEDIBAw/9oACAECAQECAMzM9bu7u7u+szMzMzPw3d3d3fwzMzMzPD8bu7u7vlfczMzMzw/G7u7u75X3MzMzMGMYxj+bu7u7ohCEIXzMzMzMYxjGMYzd3d3U0IQhCEISzMzMaaYxjGMY3u7u6mmhCEIQhLMzMxppjGMYxjbe7u6mhCEIQhCSWZmY0xjGMYxjG93d1NCEIQhCEkszMxpjGMYxjGN7u7qaEIQhCEJJZmY00xjGUMYxjbe7qaaESIRIhCSWZmNNMZRRRRQxjbe7qaaESSSSSIQklmY00xlFFFFDG2293U000SSSSSSISSzMaaaooooooZTbb3U0005JJJJJJEkkszGmqVFFFFFFDbbe6mmmiSSSSSSRJJLMxpqiiiiiiim223upppySSSSSSSISSzGmmqKKKKKKKKbbe6mmnJJJJJJJJKSSzGmmqKKLLKKKdNtvdTTTkkkgkkkklJJZjTVKiiiyyiinTbb3U05cuSSCSCSSUkkljTVKiiiyyyyinTb3U05cuSCCCCSSUklmNNUqVFllllllOm3uppy5JIIIIIJJUpLMaapUqLLLLLLKbbe6mnLkkgggggklSksxpqlSsssssssp0291OXLkggggggklSksxpqlRZZZZ0LLdOm3upy5cEEEEEEEEqUkljTVKiyyzodDoW6dNvdTly4IIIOZBBBKlJJY01Ssss6HQ6HQt26bbepy5cOCCDmcyCCVKSSxqlStWWdDodDoW7dNtvU5cuCCDmczmQQSpSSWNUqVqzodDodDoW7dNtvU5cOHBzOZzOZzIIUqUljVKlas6HQ6HQ6Fu3Tpt6nLhwQczmczmcyCFKSSxplK1Z0Oh0Op0Ojt06bey5cOHBzOZzOZzIUKUkljGUWdDodDodTodHbp0200S4cPmczmczmczmQpSSTGMZZ0Oh0Op1Op0du3TbRJJD5vmczmcjmczmoUpJJjP/8QAFBEBAAAAAAAAAAAAAAAAAAAAoP/aAAgBAgEDPwAAH//EABsRAAMBAQEBAQAAAAAAAAAAAAABAhEDEDAg/9oACAEDAQECAPzmZmZnx3d3d3fjmZmZ8d3d3d+OZmZmfHd3d3fjmZmZmfDd3d3d9Qhe5mZmZ4xjGP3d3d3dEIQhCEZmZmZjGMYxjGbu7u6IQhCEIXmZhmMYxjGMYzd3d3UIQhCEIQlmZhjGMYxjGMfu7uoQhCEIQhLMzMGmMYxjGMZu7uppoQhCEIQklmZjTGMYxjGMbb3d1NCEIQhCEISzMxpjGMYxjGMb3d1NCEIkQhCEkszGmMYyihjGMbb3d1NCESSIkQhJLMxppjGUUUMYxtvd1NNNCJJESIQklmY0xjKKKKKGMbb3dTTTRJJJJJIhJLMxpjGUUUUUUMbb3dTTQiSSSSSRCSWZjTTGUUUUUUMbb3dTTRJJJJJJJIklmY0xjKKKKKKKG293U005JJJJJJJEkksaaaaoooooooobbb3U05JJJJJJJJEkksaaZRRRRRRRRQ223uppySSSSSSSSIQkNNMoooooooooptt7qackkkkkEEkiEksGmqKKLLKLKKKbbe6mnJJJBBBBJJKSSxpplFFFllllFFNtvdTTkkkggggkklJZjTTVFFFlllllFDbe6mnLkggggggkkSzGmUUUUWWWWWUUU291NOSSCCCCCCSRLMaaZRRRZZZZZRRTb3U5ckkEEEEEEkpLMaaaoossssssop0291OXJBBBBBBBBKSzGmMossssssssp0291OXJBBBzOZBBBKlZjTVFFllllllllOm3upy5cEEHM5kEEEqVmNNUUWWWWdCyyynTb1NOXLggg5nMggglSvGmUqLLOhZ0LLLKdNm6nLgggg5nMggglSsxpqlRZZ0Oh0OhZZTpt7qcuHBzOZzOZzOZBKleNNUUWWdDodDodCynQxmy5cEHM5n/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=", "data:image/png;base64,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", shaderMapUrl),
497
- preserveAspectRatio: "xMidYMid slice"
498
- }), jsx("feColorMatrix", {
499
- in: "DISPLACEMENT_MAP",
500
- type: "matrix",
501
- values: "0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0 0 0 1 0",
502
- result: "EDGE_INTENSITY"
503
- }), jsx("feComponentTransfer", {
504
- in: "EDGE_INTENSITY",
505
- result: "EDGE_MASK",
506
- children: jsx("feFuncA", {
507
- type: "discrete",
508
- tableValues: `0 ${.05 * aberrationIntensity} 1`
509
- })
510
- }), jsx("feOffset", {
511
- in: "SourceGraphic",
512
- dx: "0",
513
- dy: "0",
514
- result: "CENTER_ORIGINAL"
515
- }), jsx("feDisplacementMap", {
516
- in: "SourceGraphic",
517
- in2: "DISPLACEMENT_MAP",
518
- scale: displacementScale * ("shader" === mode ? 1 : -1),
519
- xChannelSelector: "R",
520
- yChannelSelector: "B",
521
- result: "RED_DISPLACED"
522
- }), jsx("feColorMatrix", {
523
- in: "RED_DISPLACED",
524
- type: "matrix",
525
- values: "1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
526
- result: "RED_CHANNEL"
527
- }), jsx("feDisplacementMap", {
528
- in: "SourceGraphic",
529
- in2: "DISPLACEMENT_MAP",
530
- scale: displacementScale * (("shader" === mode ? 1 : -1) - .02 * aberrationIntensity),
531
- xChannelSelector: "R",
532
- yChannelSelector: "B",
533
- result: "GREEN_DISPLACED"
534
- }), jsx("feColorMatrix", {
535
- in: "GREEN_DISPLACED",
536
- type: "matrix",
537
- values: "0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0",
538
- result: "GREEN_CHANNEL"
539
- }), jsx("feDisplacementMap", {
540
- in: "SourceGraphic",
541
- in2: "DISPLACEMENT_MAP",
542
- scale: displacementScale * (("shader" === mode ? 1 : -1) - .03 * aberrationIntensity),
543
- xChannelSelector: "R",
544
- yChannelSelector: "B",
545
- result: "BLUE_DISPLACED"
546
- }), jsx("feColorMatrix", {
547
- in: "BLUE_DISPLACED",
548
- type: "matrix",
549
- values: "0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0",
550
- result: "BLUE_CHANNEL"
551
- }), jsx("feBlend", {
552
- in: "GREEN_CHANNEL",
553
- in2: "BLUE_CHANNEL",
554
- mode: "screen",
555
- result: "GB_COMBINED"
556
- }), jsx("feBlend", {
557
- in: "RED_CHANNEL",
558
- in2: "GB_COMBINED",
559
- mode: "screen",
560
- result: "RGB_COMBINED"
561
- }), jsx("feGaussianBlur", {
562
- in: "RGB_COMBINED",
563
- result: "ABERRATED_BLURRED",
564
- stdDeviation: blurAmount * aberrationIntensity * .05
565
- }), jsx("feComposite", {
566
- in: "ABERRATED_BLURRED",
567
- in2: "EDGE_MASK",
568
- operator: "in",
569
- result: "EDGE_ABERRATION"
570
- }), jsx("feComponentTransfer", {
571
- in: "EDGE_MASK",
572
- result: "INVERTED_MASK",
573
- children: jsx("feFuncA", {
574
- type: "table",
575
- tableValues: "1 0"
576
- })
577
- }), jsx("feComposite", {
578
- in: "CENTER_ORIGINAL",
579
- in2: "INVERTED_MASK",
580
- operator: "in",
581
- result: "CENTER_CLEAN"
582
- }), jsx("feComposite", {
583
- in: "EDGE_ABERRATION",
584
- in2: "CENTER_CLEAN",
585
- operator: "over"
586
- }) ]
587
- }) ]
588
- })
542
+ return value;
543
+ }("__core-js_shared__", {});
544
+
545
+ /* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
546
+ version: "3.43.0",
547
+ mode: "pure",
548
+ copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
549
+ license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
550
+ source: "https://github.com/zloirock/core-js"
589
551
  });
590
552
 
553
+ var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
554
+ return hasOwnProperty($Object$1(requireObjectCoercible$1(it)), key);
555
+ }, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
556
+ return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
557
+ }, wellKnownSymbol$5 = function(name) {
558
+ return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
559
+ WellKnownSymbolsStore[name];
560
+ }, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$3 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
561
+ if (!isObject$3(input) || isSymbol$1(input)) return input;
562
+ var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$1(func));
563
+ if (exoticToPrim) {
564
+ if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
565
+ !isObject$3(result) || isSymbol$1(result)) return result;
566
+ throw new $TypeError$3("Can't convert object to primitive value");
567
+ }
568
+ return void 0 === pref && (pref = "number"), function(input, pref) {
569
+ var fn, val;
570
+ if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
571
+ if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
572
+ if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
573
+ throw new $TypeError$4("Can't convert object to primitive value");
574
+ }(input, pref);
575
+ }, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
576
+ var key = toPrimitive(argument, "string");
577
+ return isSymbol(key) ? key : key + "";
578
+ }, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$8((function() {
579
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
580
+ return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
581
+ get: function() {
582
+ return 7;
583
+ }
584
+ }).a;
585
+ var it;
586
+ })), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
587
+
588
+ // `Object.getOwnPropertyDescriptor` method
589
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
590
+ objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
591
+ if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
592
+ return $getOwnPropertyDescriptor$1(O, P);
593
+ } catch (error) {/* empty */}
594
+ if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
595
+ };
596
+
597
+ var fails$2 = fails$8, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
598
+ var value = data[normalize(feature)];
599
+ return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$2(detection) : !!detection);
600
+ }, normalize = isForced$1.normalize = function(string) {
601
+ return String(string).replace(replacement, ".").toLowerCase();
602
+ }, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable = aCallable$2, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$8((function() {
603
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
604
+ return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
605
+ value: 42,
606
+ writable: !1
607
+ }).prototype;
608
+ })), isObject$1 = isObject$5, $String$1 = String, $TypeError$2 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
609
+ if (isObject$1(argument)) return argument;
610
+ throw new $TypeError$2($String$1(argument) + " is not an object");
611
+ }, toPropertyKey = toPropertyKey$2, $TypeError$1 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
612
+
613
+ // `Object.defineProperty` method
614
+ // https://tc39.es/ecma262/#sec-object.defineproperty
615
+ objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
616
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
617
+ var current = $getOwnPropertyDescriptor(O, P);
618
+ current && current.writable && (O[P] = Attributes.value, Attributes = {
619
+ configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
620
+ enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
621
+ writable: !1
622
+ });
623
+ }
624
+ return $defineProperty(O, P, Attributes);
625
+ } : $defineProperty : function(O, P, Attributes) {
626
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
627
+ return $defineProperty(O, P, Attributes);
628
+ } catch (error) {/* empty */}
629
+ if ("get" in Attributes || "set" in Attributes) throw new $TypeError$1("Accessors not supported");
630
+ return "value" in Attributes && (O[P] = Attributes.value), O;
631
+ };
632
+
633
+ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
634
+ return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
635
+ } : function(object, key, value) {
636
+ return object[key] = value, object;
637
+ }, globalThis$2 = globalThis_1, apply = functionApply, uncurryThis$1 = functionUncurryThisClause, isCallable$1 = isCallable$8, getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f, isForced = isForced_1, path$1 = path$3, bind = function(fn, that) {
638
+ return aCallable(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
639
+ return fn.apply(that, arguments);
640
+ };
641
+ }, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
642
+ var Wrapper = function(a, b, c) {
643
+ if (this instanceof Wrapper) {
644
+ switch (arguments.length) {
645
+ case 0:
646
+ return new NativeConstructor;
647
+
648
+ case 1:
649
+ return new NativeConstructor(a);
650
+
651
+ case 2:
652
+ return new NativeConstructor(a, b);
653
+ }
654
+ return new NativeConstructor(a, b, c);
655
+ }
656
+ return apply(NativeConstructor, this, arguments);
657
+ };
658
+ return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
659
+ }, _export = function(options, source) {
660
+ var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$2 : STATIC ? globalThis$2[TARGET] : globalThis$2[TARGET] && globalThis$2[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
661
+ for (key in source)
662
+ // contains in native
663
+ USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
664
+ targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
665
+ // export native or implementation
666
+ sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
667
+ // bind methods to global for calling from export context
668
+ resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$2) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
669
+ // add a flag to not completely full polyfills
670
+ (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
671
+ createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
672
+ // export virtual prototype methods
673
+ createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
674
+ // export real prototype methods
675
+ options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
676
+ }, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
677
+ var n = +x;
678
+ return (n > 0 ? floor : ceil)(n);
679
+ }, toIntegerOrInfinity$2 = function(argument) {
680
+ var number = +argument;
681
+ // eslint-disable-next-line no-self-compare -- NaN check
682
+ return number != number || 0 === number ? 0 : trunc(number);
683
+ }, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, min$1 = Math.min, globalThis$1 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$2 = function(CONSTRUCTOR, METHOD) {
684
+ var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
685
+ if (pureMethod) return pureMethod;
686
+ var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
687
+ return NativePrototype && NativePrototype[METHOD];
688
+ };
689
+
591
690
  /**
592
- * Form Group-specific constants
593
- */ GlassFilterComponent.displayName = "GlassFilter";
691
+ * Component Utilities
692
+ *
693
+ * Helper functions for component development with the new customization system
694
+ */
695
+ /**
696
+ * Merge multiple class names
697
+ */
698
+ function mergeClassNames(...classes) {
699
+ return classes.filter(Boolean).join(" ");
700
+ }
594
701
 
595
- // Memoize component to prevent unnecessary re-renders
596
- const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
702
+ /**
703
+ * Utility to merge multiple React refs into one
704
+ */ function setRef(ref, value) {
705
+ "function" == typeof ref ? ref(value) : ref && (
706
+ // This is safe because we're checking that ref exists first
707
+ ref.current = value);
708
+ }
709
+
710
+ /**
711
+ * Combines two React refs into a single ref function
712
+ * This is used when you need to use and forward a ref at the same time
713
+ */ function useForkRef(refA, refB) {
714
+ return React.useMemo((() => null == refA && null == refB ? null : refValue => {
715
+ setRef(refA, refValue), setRef(refB, refValue);
716
+ }), [ refA, refB ]);
717
+ }
718
+
719
+ const {CONSTANTS: CONSTANTS$3} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
720
+ x: rect.left + rect.width / 2,
721
+ y: rect.top + rect.height / 2
722
+ } : {
597
723
  x: 0,
598
724
  y: 0
599
- }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
600
- width: 0,
601
- height: 0
602
- }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1,
603
- // Phase 1: Animation System props
604
- shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
605
- // React 18 useId stable, unique, and SSR-safe (no module-level counter)
606
- const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
607
- // Lazy load shader utilities only when shader mode is needed
608
- useEffect((() => {
609
- "shader" === mode ?
610
- // Dynamic import shader utilities with animation support
611
- Promise.resolve().then((() => shaderUtils)).then((shaderUtils => {
612
- shaderUtilsRef.current = {
613
- ShaderDisplacementGenerator: shaderUtils.ShaderDisplacementGenerator,
614
- fragmentShaders: shaderUtils.fragmentShaders
615
- };
616
- })).catch((error => {
617
- console.warn("AtomixGlassContainer: Error loading shader utilities", String(error).replace(/[\r\n]/g, ""));
725
+ }, calculateMouseInfluence = mouseOffset => {
726
+ if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
727
+ // Clamp influence to keep mouse response subtle and stable.
728
+ const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$3.MOUSE_INFLUENCE_DIVISOR;
729
+ return Math.min(.8, influence);
730
+ // Tighter cap to prevent blur/filter blow-out
731
+ }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$3.MIN_BLUR : Math.max(CONSTANTS$3.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$3.MAX_SIZE && size.height <= CONSTANTS$3.MAX_SIZE, parseBorderRadiusValue = value => {
732
+ if ("number" == typeof value) return Math.max(0, value);
733
+ if ("string" != typeof value || !value.trim()) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
734
+ const trimmedValue = value.trim();
735
+ // Handle px values
736
+ if (trimmedValue.endsWith("px")) {
737
+ const parsed = parseFloat(trimmedValue);
738
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
739
+ }
740
+ // Handle rem values (assume 16px = 1rem)
741
+ if (trimmedValue.endsWith("rem")) {
742
+ const parsed = parseFloat(trimmedValue);
743
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
744
+ }
745
+ // Handle em values (assume 16px = 1em for simplicity)
746
+ if (trimmedValue.endsWith("em")) {
747
+ const parsed = parseFloat(trimmedValue);
748
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
749
+ }
750
+ // Handle percentage (convert to approximate px value, assuming 200px container)
751
+ if (trimmedValue.endsWith("%")) {
752
+ const parsed = parseFloat(trimmedValue);
753
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
754
+ }
755
+ // Handle unitless numbers
756
+ const numValue = parseFloat(trimmedValue);
757
+ return isNaN(numValue) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
758
+ }, extractBorderRadiusFromElement = element => {
759
+ if (!element || !element.props) return null;
760
+ // Check inline styles first (highest priority)
761
+ if (element.props.style) {
762
+ const radiusFromStyle = (style => {
763
+ if (!style) return null;
764
+ // Check various border-radius properties
765
+ const borderRadius = style.borderRadius || style.borderTopLeftRadius || style.borderTopRightRadius || style.borderBottomLeftRadius || style.borderBottomRightRadius;
766
+ return void 0 !== borderRadius ? parseBorderRadiusValue(borderRadius) : null;
767
+ })(element.props.style);
768
+ if (null !== radiusFromStyle && radiusFromStyle > 0) return radiusFromStyle;
769
+ }
770
+ // If element has children, recursively check them
771
+ if (element.props.children) {
772
+ const childRadius = extractBorderRadiusFromChildren(element.props.children);
773
+ if (childRadius > 0 && childRadius !== CONSTANTS$3.DEFAULT_CORNER_RADIUS) return childRadius;
774
+ }
775
+ return null;
776
+ }, extractBorderRadiusFromChildren = children => {
777
+ if (!children) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
778
+ try {
779
+ const childArray = React.Children.toArray(children);
780
+ for (let i = 0; i < childArray.length; i++) {
781
+ const child = childArray[i];
782
+ if ( React.isValidElement(child)) {
783
+ const radius = extractBorderRadiusFromElement(child);
784
+ if (null !== radius) return radius;
785
+ }
786
+ }
787
+ } catch (error) {
788
+ // Silently handle errors
789
+ }
790
+ return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
791
+ }, smoothstep = t => {
792
+ const clamped = Math.max(0, Math.min(1, t));
793
+ return clamped * clamped * (3 - 2 * clamped);
794
+ }, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), clamp = (value, min, max) => "number" != typeof value || isNaN(value) ? min : Math.max(min, Math.min(max, value)), smoothstepEdge = (edge0, edge1, x) => "number" != typeof edge0 || "number" != typeof edge1 || "number" != typeof x ? 0 : smoothstep((x - edge0) / (edge1 - edge0)), easeInOutCubic = t => {
795
+ if ("number" != typeof t || isNaN(t)) return 0;
796
+ const clamped = Math.max(0, Math.min(1, t));
797
+ return clamped < .5 ? 4 * clamped * clamped * clamped : 1 - Math.pow(-2 * clamped + 2, 3) / 2;
798
+ }, easeOutQuart = t => {
799
+ if ("number" != typeof t || isNaN(t)) return 0;
800
+ const clamped = Math.max(0, Math.min(1, t));
801
+ return 1 - Math.pow(1 - clamped, 4);
802
+ }, vec2Length = (x, y) => {
803
+ if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
804
+ const maxComponent = Math.max(Math.abs(x), Math.abs(y));
805
+ if (0 === maxComponent) return 0;
806
+ const scaledX = x / maxComponent, scaledY = y / maxComponent;
807
+ return maxComponent * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
808
+ }, getInteractionIntensity = (isHovered, isActive) => ({
809
+ hoverIntensity: isHovered ? CONSTANTS$3.INTERACTION.HOVER_INTENSITY : 1,
810
+ activeIntensity: isActive ? CONSTANTS$3.INTERACTION.ACTIVE_INTENSITY : 1
811
+ })
812
+ /**
813
+ * Spring-damper integration helper
814
+ * Calculates the next value based on velocity, stiffness, and damping.
815
+ */ , calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
816
+ const newVelocity = (velocity + (target - current) * stiffness) * damping;
817
+ return {
818
+ value: current + newVelocity,
819
+ velocity: newVelocity
820
+ };
821
+ };
822
+
823
+ /**
824
+ * Calculate element center from bounding rect
825
+ */
826
+ /**
827
+ * Normalizes a layout inset for use in CSS custom properties.
828
+ *
829
+ * @param value - Raw inset from `style` (number, px string, or `auto`).
830
+ * @param fallback - Value used when `value` is undefined.
831
+ */
832
+ function formatGlassInsetValue(value, fallback = "auto") {
833
+ return void 0 === value ? "number" == typeof fallback ? `${fallback}px` : String(fallback) : "auto" === value ? "auto" : "number" == typeof value ? `${value}px` : value;
834
+ }
835
+
836
+ /**
837
+ * Determines whether the glass should use fixed/sticky layout semantics.
838
+ *
839
+ * @param explicit - Value of the `isFixedOrSticky` prop.
840
+ * @param position - `position` from the consumer `style` object.
841
+ */
842
+ /** Coerces a value to a finite number, returning `fallback` when invalid. */
843
+ function toSafeNumber(value, fallback = 0) {
844
+ return "number" != typeof value || isNaN(value) ? fallback : value;
845
+ }
846
+
847
+ /**
848
+ * Calculates the target frame rate for shader time-animation loops.
849
+ *
850
+ * Balances visual quality against distortion complexity and `animationSpeed`.
851
+ */
852
+ /**
853
+ * Computes per-channel displacement scale for the SVG chromatic-aberration filter.
854
+ */
855
+ function getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channelFactor) {
856
+ return displacementScale * (("shader" === mode ? 1 : -1) - aberrationIntensity * channelFactor);
857
+ }
858
+
859
+ /**
860
+ * Get displacement map URL based on mode
861
+ */ const getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
862
+ switch (mode) {
863
+ case "standard":
864
+ return displacementMap;
865
+
866
+ case "polar":
867
+ return polarDisplacementMap;
868
+
869
+ case "prominent":
870
+ return prominentDisplacementMap;
871
+
872
+ case "shader":
873
+ return shaderMapUrl || displacementMap;
874
+
875
+ default:
876
+ return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
877
+ }
878
+ }, sharedShaderCache = new Map, CHROMATIC_CHANNELS = [ {
879
+ result: "RED_DISPLACED",
880
+ channelResult: "RED_CHANNEL",
881
+ aberrationFactor: 0,
882
+ colorMatrix: "1 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
883
+ }, {
884
+ result: "GREEN_DISPLACED",
885
+ channelResult: "GREEN_CHANNEL",
886
+ aberrationFactor: .02,
887
+ colorMatrix: "0 0 0 0 0\n0 1 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
888
+ }, {
889
+ result: "BLUE_DISPLACED",
890
+ channelResult: "BLUE_CHANNEL",
891
+ aberrationFactor: .03,
892
+ colorMatrix: "0 0 0 0 0\n0 0 0 0 0\n0 0 1 0 0\n0 0 0 1 0"
893
+ } ], FILTER_SVG_STYLE = {
894
+ position: "absolute",
895
+ width: "100%",
896
+ height: "100%",
897
+ inset: 0
898
+ }, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
899
+ style: FILTER_SVG_STYLE,
900
+ "aria-hidden": "true",
901
+ children: jsxs("defs", {
902
+ children: [ jsxs("radialGradient", {
903
+ id: `${id}-edge-mask`,
904
+ cx: "50%",
905
+ cy: "50%",
906
+ r: "50%",
907
+ children: [ jsx("stop", {
908
+ offset: "0%",
909
+ stopColor: "black",
910
+ stopOpacity: "0"
911
+ }), jsx("stop", {
912
+ offset: `${Math.max(30, 80 - 2 * aberrationIntensity)}%`,
913
+ stopColor: "black",
914
+ stopOpacity: "0"
915
+ }), jsx("stop", {
916
+ offset: "100%",
917
+ stopColor: "white",
918
+ stopOpacity: "1"
919
+ }) ]
920
+ }), jsxs("filter", {
921
+ id: id,
922
+ x: "-35%",
923
+ y: "-35%",
924
+ width: "170%",
925
+ height: "170%",
926
+ colorInterpolationFilters: "sRGB",
927
+ children: [ jsx("feImage", {
928
+ id: `${id}-image`,
929
+ x: "0",
930
+ y: "0",
931
+ width: "100%",
932
+ height: "100%",
933
+ result: "DISPLACEMENT_MAP",
934
+ href: getDisplacementMap(mode, "data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/2wCEAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgHBwcHBwgLCAkJCQkICwsMDAwMDAsNDQ4ODQ0SEhISEhQUFBQUFBQUFBQBBQUFCAgIEAsLEBQODg4UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/CABEIAQABAAMBEQACEQEDEQH/xAAxAAEBAQEBAQAAAAAAAAAAAAADAgQIAQYBAQEBAQEBAQAAAAAAAAAAAAMCBAEACAf/2gAMAwEAAhADEAAAAPjPor6kOgOiKhKgKhKgOhKhOhKxKgKhOgKhKhKgKxOhKhOgKhKhKgKwKhKgKgKwG841nns9J/nn2KVCdCdCVAVCVCVAdCVCdiVAVidCVAVCVAdiVCVCdAVCVCVAVCVAVAViVZxsBrPPY6R/NvsY6E6ErEqAqE6ErAqE6E7E7ErA0ErArAqAqEuiVAXRLol0S6J0JUBWBUI0BXnG88djpH81+xjoToSoSoCoTsSoYQTsTsTQSsCsCsCsCsCoC6A0JeAuiXSLwn0SoioCoCoBsBrPFH0j+a/Yx0J0JUJUJ2BUMIR2MIRoBoJIBXnJAK840BUA0BdAegXhLpF4S8R+IuiVgVANAV546fSH5r9jHRHQFQlYxYnZQgnYwhQokgEgEmckzjecazlYD3OPQHoD0S8JcI/EXiPxF0SoSvONBFF0j+a/YxdI7EqA6KLGEKEKEGFI0AlA0AUzimYbzjecazjWce5w6BdEeCXhPhFwz8R+MuiVgVAdF0j+a/Yp0RUJ0MWUIUWUIUKUIJqBoArnJM4pmBMw3nCsw1mCs4+AegPBLxHwi4Z8KPGXSPojYH0ukfzX7FOiKhiyiylDiylDhBNRNQJAJcwpnBMopmC84XlCswdzj3OPQHwlwS8R8M+HHDPxl0ioDoukfzT7GOhOyiimzmzhDlShBNBNBJc4rmFMwJlBMwXlC82esoVmHucOgXgHxH4j4Zyccg/GfiOiKh6R/NPsY6GLOKObOUObOUI0KEAlEkzimYFygmUEyheXPeULzZ6yhWce5x8BeEuGfCj0HyI5EdM/EdD0h+a/Yx0U0cUflxNnNnCHCCdgSiSZgTMK5c6ZQvLnTLnvJnvKFZgrMHc5dAeiXijhn445E8g/RHTPpdI/mn2KdlFR5RzcTUTZxZwglYGgCmcEzAuUEyZ0y57yZ0yZ7yheUKzh3OPc5dEvEfij0RyI9E+iPGfT6T/NPsQ6OKiKmajy4ijmyOyKwNAFM4JlBMudMmdMue8mdMme8me8wVmGsw0A9A+kfjjxx6J9EememfT6W/MvsMqOamKiamKmKOKM7ErErAUzAmYLyZ0y50yZ0yZkyZ7yBeULzBeYazl0T6R9KPRPYj0T2J9B9Ppj8x+wjo4qY7M9iKmKg6MrIrErALzBeYEyZ0y50yZkyZ7x50yheXPeUbzjWcqA6I+lHYnsT6J7E9iOx0z+YfYBUc1MdmexHZjsHRlRBRDYBecEzZ7yAmXNeTOmTOmPOmXOmULyjeYbzlYnQxRx057E9mexPYij6a/L/r86OOzPpjsR6Y7B9MqIaILDPYZ7zZ0y57y50yZ0x5kyAmXPeUEyjeYUznQnYnRTUTUT2JqJ7EUfTn5d9fFRx2Z9EdmPTHjLsF0h6I2OegzXmzJmzplz3lzJjzpkBMudMoplBM5JnOwOyiimzmomomonsHRdO/l318VFHYj0x6I9McgumXiHpDQ56DPebMmbNebMmXMmQEy50yguQEzCmYkA7GLGEKaObibiaOKOKPp38s+vCsj7EeiPTHIP0Hwx6ReMKDP0M95895syZ815cy5c6ZQTKCZRXMKZiQDQYQYsps5uJs5qIsjounvyz68KyLpx4z9Mcg+GXoLxl4g6IUGes+a8+e82ZM2dMuZMoJmBcwrlJM5IBoMKMoUWc2c3E0cWRUXT/wCV/XQ2R0RdiPQfDPkFwy9BeIOiHQz0Ges+e82dM2ZM2dMwLmBcwpmJc5qBoMIUIUoU2c2cWZ0R0PT/AOV/XQ2RUJdM+wfDL0Hwy5A+EfEHQz0AUGe8+dM2e82dcwJnFcwrnJc5IEKUIMIUoUWc2cWRUJ0PT/5V9dFYjZFRF0z8ZeM+QPDLxD4Q6OfoBQhefPeYEz50ziucUzCoEuclCEKFGUKEKLOLI7E6EqHqD8o+uhsRsisSoi6ZeM+QPiHhj0R8IUIdALALzgmcEzimcVAlzioGomgyhQgwhRZHZFQHQlQ9Qfk/10NiVkNiNiVGXiPxj4x8Q9IfCFCPRCwC84oA3nFQFM5KBKJIMKEIUWRoUUJWJUJ0BUPUH5L9dDZFYigjYjZHRF0x8Q9IvEHRHojQjQhecUAUAkEkziomgGgkoxZGgxZFQFQlYnQHRdPfj/10KCSCKESCNiVkViPSLpD0h6I0Q0I0A2IoBWBIJIBKBIJoJIJ2R2J0JWBUJ0JUB0XTv479dFZDYiglYigkhEgjZFQjRFQjRFQjQigFYigHYigmgEgmglYlYnQlQlYlQHQlQnQ9P/kf1yVkNiNCNkNiVENiNiViNEViNkVCVgKCViViViSCViSCVgdCViVCViVCdgVCVCdD1D+U/XBWQ2I0I2Q2JUQ2I0JWQ0I2JUQ2JUI2JUI2J0JWJWJWA2R0BWJ0I2JUJ2BUJUJ0P//EABkQAQEBAQEBAAAAAAAAAAAAAAECABEDEP/aAAgBAQABAgB1atWrVq1atWrVq1atWrVq1atWrVq1atWrVq+OrVq1atWrVq1atWrVq1atWrVq1atWrVq1atXxVppppppdWrVq1atWrVq1NNNNNNNNNNNPVWmmmmms6tWrVq1atWpppppppppppppp6q0000uc51atWrVq1ammmmmmmmmmmmmt1Vpppc5znVq1atWrVqaaaaaaaaaaaaaeqtNLnOc51atWrVq1ammmmmmmmmmmmmnqrS5znOc6tWrVq16222mmmmmmlVppp6tKuc5znOrVq1a9TbbbbTTTTTSq000qtLnOc5zq1atWrW0222200000qqqtKqrnOc5zq1atTbbbbbbbbTTTSqqqqqq5znOc6tTTTbbbbbbbbTTTSqqqqrlVznOctNNNtttttttttNNNNKqqqrqznKqrTTTTbbbbbbbbbTTTSqqqqrqznOc5aaaabbbbbbbbbaaaaVVVVVdWc5znVq1NNttttttttttNNKqqqqudWc5znVq16tbbbbbbbbbbTTSqqqq5XVnOc6tWrVrb1tttttttttNNKqqqqrWrK5VWmmm2230bbbbbbaaaXOc5zlVa1KuVVppptttt9G22222mmlzlVznK6tWVVWmmmm2222222222mlznOc5znLWppVVWmmm22222229bTWrOc5znOcq1qaaVpWmm222222229erVqznOc5znKtatStK0rTbTTbbbberXr1as5znOc5aVpppppWlabaabbbb1ta9WrVnOc5znU0rTTTTTTTTTbTTbbbTWvVq1as5znOdTTStNNNNNNNNNtNNtttN6tWvVq1ZznOrU00rTTTTTTTTTTTTTbTWvVq1atWrOc6tTTTStNNNNNNNNNNtNNtNa9WrVq1Z1Z1NNNNNK1q1NNNNNNNNNNNtNatWrVq1atWrU00000rWrVq1atWrVq1alaaa1atWrVq1NNNammmmla1atWrVq1aterVq16tWrVnVqa1NK1qaaaVX/xAAWEAADAAAAAAAAAAAAAAAAAAAhgJD/2gAIAQEAAz8AaExf/8QAGhEBAQEBAQEBAAAAAAAAAAAAAQISEQADEP/aAAgBAgEBAgDx48ePHjx48ePHjx48ePHjx48ePHjx48ePHj86IiIiIiInjx48ePHjx48IiIiIj0oooooooooRERER73ve60UUUUUUVrWiiiiiihERERER73ve97ooooorRWiiiiihKERERER73ve973RRRRWtFFFFFFCIiIiIiPe973ve60UUVrRRRRRRQiIlCIiI973ve973pRRWiiiiiiiiiiiiiiihEe973ve973RRWtFFFFFFFFFFFFFFFFFFa13ve973WitaKKKKKKKKKKKKKKKKKK1rWtd1rutFa1oooooooooooosssooorWta1rWta1rRRRRRRRRRRZZZZZZZZZWta1rWta1rRRRRRRRRZZZZZZZZZZZZe9a1rWta1rWitaKLLLLLLLLLLLLLLLLL3rWta1rWtFbLLLLLLLLLLLLLLLLLLLL3vWta1rWita1ssssssss+hZZZZZZZZe961rWta0Vre97LLLLLLLLLLLPoWWWWWXrWta1oorWta3ssss+hZZZZ9Cyyyyyyyyiita1orWta1ve9llllllllllllllllFFa0VorWta1ve9llllllllllllllllllFFFaK1rWta1rWiyyyyyyyyyyyyiiiiiiitFFa1rWta1oosoosssssoooosoooorRRRWta1rWta0UUUUUWUUUUUUUUUUUVoooorWta1rWtaKKKKKKmiiiiiiiiiiiiiiitd73ve61oSiiipoqaKKKKKKKKKK0UUUVrve973vREREZoSihEooooorRRRRWtd73ve9EREREREoSiiiiitFllllla73ve9ERERERESiiiiiitH0PoWWWWVrXe96IiIiMoiJRRRRRRWjwlFFllllFFd6IiIiIlCUUUUUUUUUePHjx48ePCIiIiIiIiUUUUUUUUUUUePHjx48ePHjx48ePHjx48IiUUUUUUJRRRX//xAAWEQADAAAAAAAAAAAAAAAAAAABYJD/2gAIAQIBAz8AtEV7/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAECEP/aAAgBAwEBAgCtNNNNNNNNNNNNNNNNNNNNNNNNNNNNNcrTTTTTTTTTTTTTTTTTTTTTTTTTTTTTXKrTTTTTTTU000000000000000000001FVpppppqampqaaaaaaaaaaaaaaaaaaaa5Vaaaaampqampqammmmmmmmmmmlaaaaaaiq0001NTU1NTU1NTTTTTTTTTTSqqtNNNcqtNNSyzU1LNTU1NTTTTTTTTTSqqq001ytNLLLLNTU1NTU1NTbbbTTTTTSqqq001ytNLLLLLNTU1NTU3NttttNNNNNKqq001KrSyyyyyzU1NTU3Nzc02220000qqqqrSqqyyyyyzU1NTU3Nzc3NttttNNNKqqqqqqssssss1NTU3Nzc3NzbbbbTTTSqqqqqqrLLLLLNTU1Nzc3Nzc22220000qqqqqqqqssss1NTU3Nzc3NzbbbbbTTSqqqqqqqqqqzU1NTc3Nzc3Nzbc22000qqqqqqqqqqqtTU3Nzc3Nzc3NtzbTTSqqqqrKqqqqqtNNzc23Nzc3Nzc3NTU1KqqqrKqqqqqtNNNNttzc3Nzc3NzU1NLLLLLKqqqqqqqq0022223Nzc3NzU1NSyyyyyyqqqqqqqrTTbbbbc3Nzc3NTU1LLLLLLKsqqqqqqrTTTTbbbc3Nzc1NTUsssssssqqqqqqrTTTTTbbbTc3NTU1NTUsssssqqqqqqqq0000222023NTU1NTUsssssqqqqqqqq000000003NTU1NTU1LLLLLNKrTSqqqqtNNNNNNtNNTU1NSzUssss00qq0qqqqrTTTTTTTTTU1NTUs1LLLNNNKrTTTSqqq00000000001NTU1LNTU0000qtNNNKqqqtNNNNNNNNTU1NTUs1NNNNNKss1NNNK00qtK0000001NNTU0s000000qq000001NKrStNNNNK1NNNNStNNNNNKqtNNNNNNNK0000000rU0000rTTTTTSq00000rTTTTTTTTTTTTTTTTStNNNNKr/xAAUEQEAAAAAAAAAAAAAAAAAAACg/9oACAEDAQM/AAAf/9k=", "data:image/jpeg;base64,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", "data:image/png;base64,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", shaderMapUrl),
935
+ preserveAspectRatio: "xMidYMid slice"
936
+ }), jsx("feColorMatrix", {
937
+ in: "DISPLACEMENT_MAP",
938
+ type: "matrix",
939
+ values: "0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0.3 0.3 0.3 0 0\n 0 0 0 1 0",
940
+ result: "EDGE_INTENSITY"
941
+ }), jsx("feComponentTransfer", {
942
+ in: "EDGE_INTENSITY",
943
+ result: "EDGE_MASK",
944
+ children: jsx("feFuncA", {
945
+ type: "discrete",
946
+ tableValues: `0 ${.05 * aberrationIntensity} 1`
947
+ })
948
+ }), jsx("feOffset", {
949
+ in: "SourceGraphic",
950
+ dx: "0",
951
+ dy: "0",
952
+ result: "CENTER_ORIGINAL"
953
+ }), CHROMATIC_CHANNELS.map((channel => jsxs(React.Fragment, {
954
+ children: [ jsx("feDisplacementMap", {
955
+ in: "SourceGraphic",
956
+ in2: "DISPLACEMENT_MAP",
957
+ scale: getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channel.aberrationFactor),
958
+ xChannelSelector: "R",
959
+ yChannelSelector: "B",
960
+ result: channel.result
961
+ }), jsx("feColorMatrix", {
962
+ in: channel.result,
963
+ type: "matrix",
964
+ values: channel.colorMatrix,
965
+ result: channel.channelResult
966
+ }) ]
967
+ }, channel.channelResult))), jsx("feBlend", {
968
+ in: "GREEN_CHANNEL",
969
+ in2: "BLUE_CHANNEL",
970
+ mode: "screen",
971
+ result: "GB_COMBINED"
972
+ }), jsx("feBlend", {
973
+ in: "RED_CHANNEL",
974
+ in2: "GB_COMBINED",
975
+ mode: "screen",
976
+ result: "RGB_COMBINED"
977
+ }), jsx("feGaussianBlur", {
978
+ in: "RGB_COMBINED",
979
+ result: "ABERRATED_BLURRED",
980
+ stdDeviation: blurAmount * aberrationIntensity * .05
981
+ }), jsx("feComposite", {
982
+ in: "ABERRATED_BLURRED",
983
+ in2: "EDGE_MASK",
984
+ operator: "in",
985
+ result: "EDGE_ABERRATION"
986
+ }), jsx("feComponentTransfer", {
987
+ in: "EDGE_MASK",
988
+ result: "INVERTED_MASK",
989
+ children: jsx("feFuncA", {
990
+ type: "table",
991
+ tableValues: "1 0"
992
+ })
993
+ }), jsx("feComposite", {
994
+ in: "CENTER_ORIGINAL",
995
+ in2: "INVERTED_MASK",
996
+ operator: "in",
997
+ result: "CENTER_CLEAN"
998
+ }), jsx("feComposite", {
999
+ in: "EDGE_ABERRATION",
1000
+ in2: "CENTER_CLEAN",
1001
+ operator: "over"
1002
+ }) ]
1003
+ }) ]
1004
+ })
1005
+ });
1006
+
1007
+ /**
1008
+ * Module-level LRU cache for shader displacement maps.
1009
+ *
1010
+ * Shared across all `AtomixGlassContainer` instances so identical size and
1011
+ * variant combinations are generated once.
1012
+ */ GlassFilterComponent.displayName = "GlassFilter";
1013
+
1014
+ /** Shallow prop comparison to avoid redundant SVG filter regeneration. */
1015
+ const GlassFilter = memo(GlassFilterComponent, ((prevProps, nextProps) => prevProps.id === nextProps.id && prevProps.displacementScale === nextProps.displacementScale && prevProps.aberrationIntensity === nextProps.aberrationIntensity && prevProps.mode === nextProps.mode && prevProps.shaderMapUrl === nextProps.shaderMapUrl && prevProps.blurAmount === nextProps.blurAmount)), AtomixGlassContainer = forwardRef((({children: children, className: className = "", style: style, displacementScale: displacementScale = 25, blurAmount: blurAmount = .0625, saturation: saturation = 180, aberrationIntensity: aberrationIntensity = 2, mouseOffset: mouseOffset = {
1016
+ x: 0,
1017
+ y: 0
1018
+ }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, glassSize: glassSize = {
1019
+ width: 0,
1020
+ height: 0
1021
+ }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", contentRef: contentRef}, ref) => {
1022
+ // React 18 useId — stable, unique, and SSR-safe (no module-level counter)
1023
+ const rawId = useId(), filterId = useMemo((() => `atomix-glass-filter-${rawId.replace(/:/g, "")}`), [ rawId ]), containerRef = useForkRef(ref, null), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null), shaderUpdateTimeoutRef = useRef(null), animationFrameRef = useRef(null);
1024
+ // Lazy load shader utilities only when shader mode is needed
1025
+ useEffect((() => {
1026
+ "shader" === mode ?
1027
+ // Dynamic import shader utilities with animation support
1028
+ Promise.resolve().then((() => shaderUtils)).then((shaderUtils => {
1029
+ shaderUtilsRef.current = {
1030
+ ShaderDisplacementGenerator: shaderUtils.ShaderDisplacementGenerator,
1031
+ fragmentShaders: shaderUtils.fragmentShaders
1032
+ };
1033
+ })).catch((error => {
1034
+ console.warn("AtomixGlassContainer: Error loading shader utilities", String(error).replace(/[\r\n]/g, ""));
618
1035
  })) :
619
1036
  // Clear shader utils when not in shader mode to free memory
620
1037
  shaderUtilsRef.current = null;
@@ -681,15 +1098,23 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
681
1098
  shaderGeneratorRef.current = null;
682
1099
  }
683
1100
  };
684
- }), [ mode, glassSize, shaderVariant ]),
685
- // Phase 1: Time-Based Animation Loop - Continuous shader regeneration
686
- useEffect((() => {
1101
+ }), [ mode, glassSize, shaderVariant ]), useEffect((() => {
687
1102
  // Only run animations in shader mode with time animation enabled
688
1103
  if ("shader" !== mode || !withTimeAnimation || effectiveReducedMotion || effectiveWithoutEffects)
689
1104
  // Cancel any existing animation frame
690
1105
  return void (null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
691
1106
  animationFrameRef.current = null));
692
- const baseFps = "ultra" === distortionQuality ? 60 : "high" === distortionQuality ? 30 : "medium" === distortionQuality ? 24 : 20, effectiveSpeed = Math.max(.5, Math.min(2, animationSpeed || 1)), complexity = withMultiLayerDistortion ? Math.max(1, (distortionOctaves || 3) / 3 + .25 * Math.max(0, (distortionLacunarity || 2) - 2) + Math.max(0, (distortionGain || .5) - .5)) : 1, frameInterval = 1e3 / Math.max(12, Math.min(60, Math.round(baseFps * effectiveSpeed / complexity)));
1107
+ const targetFps = function(options) {
1108
+ const {distortionQuality: distortionQuality, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5} = options, baseFps = "ultra" === distortionQuality ? 60 : "high" === distortionQuality ? 30 : "medium" === distortionQuality ? 24 : 20, effectiveSpeed = Math.max(.5, Math.min(2, animationSpeed)), complexity = withMultiLayerDistortion ? Math.max(1, distortionOctaves / 3 + .25 * Math.max(0, distortionLacunarity - 2) + Math.max(0, distortionGain - .5)) : 1;
1109
+ return Math.max(12, Math.min(60, Math.round(baseFps * effectiveSpeed / complexity)));
1110
+ }({
1111
+ distortionQuality: distortionQuality,
1112
+ animationSpeed: animationSpeed,
1113
+ withMultiLayerDistortion: withMultiLayerDistortion,
1114
+ distortionOctaves: distortionOctaves,
1115
+ distortionLacunarity: distortionLacunarity,
1116
+ distortionGain: distortionGain
1117
+ }), frameInterval = 1e3 / targetFps;
693
1118
  let lastUpdate = 0, isCancelled = !1;
694
1119
  const animate = currentTime => {
695
1120
  if (!isCancelled) {
@@ -713,88 +1138,21 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
713
1138
  };
714
1139
  }), [ mode, withTimeAnimation, animationSpeed, displacementScale, withMultiLayerDistortion, distortionOctaves, distortionLacunarity, distortionGain, distortionQuality, effectiveReducedMotion, effectiveWithoutEffects, glassSize ]);
715
1140
  // Removed forced reflow to avoid layout thrash and potential feedback sizing loops
716
- const [rectCache, setRectCache] = useState(null);
717
- useEffect((() => {
718
- if (!ref || "function" == typeof ref) return;
719
- const element = ref.current;
720
- if (element) try {
721
- setRectCache(element.getBoundingClientRect());
722
- } catch (error) {
723
- console.warn("AtomixGlassContainer: Error getting element bounds", error), setRectCache(null);
724
- }
725
- }), [ ref, glassSize ]);
726
- const liquidBlur = useMemo((() => {
727
- const defaultBlur = {
728
- baseBlur: blurAmount,
729
- edgeBlur: 1.25 * blurAmount,
730
- centerBlur: 1.1 * blurAmount,
731
- flowBlur: 1.2 * blurAmount
732
- };
733
- // Enhanced validation for liquid blur
734
- if (!withLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
735
- try {
736
- const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = 2 * blurAmount, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * .15), edgeIntensity = .15 * mouseInfluence, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = .1 * mouseInfluence, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, 1.2 * baseBlur);
737
- // NOTE: hover/active multipliers intentionally omitted here —
738
- // they belong on opacity layers, not the blur filter itself.
739
- return {
740
- baseBlur: clampBlur(baseBlur),
741
- edgeBlur: clampBlur(edgeBlur),
742
- centerBlur: clampBlur(centerBlur),
743
- flowBlur: clampBlur(flowBlur)
744
- };
745
- } catch (error) {
746
- return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
747
- defaultBlur;
748
- }
749
- }), [ withLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = useMemo((() => {
750
- try {
751
- const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), validatedBaseBlur = "number" != typeof liquidBlur.baseBlur || isNaN(liquidBlur.baseBlur) ? 0 : liquidBlur.baseBlur, validatedEdgeBlur = "number" != typeof liquidBlur.edgeBlur || isNaN(liquidBlur.edgeBlur) ? 0 : liquidBlur.edgeBlur, validatedCenterBlur = "number" != typeof liquidBlur.centerBlur || isNaN(liquidBlur.centerBlur) ? 0 : liquidBlur.centerBlur, validatedFlowBlur = "number" != typeof liquidBlur.flowBlur || isNaN(liquidBlur.flowBlur) ? 0 : liquidBlur.flowBlur, area = rectCache ? rectCache.width * rectCache.height : 0;
752
- // Validate blur values before using them
753
- return !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? {
754
- backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
755
- } : {
756
- backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1}) brightness(${overLightConfig?.brightness || 1})`
757
- };
758
- // Single-pass fallback: stronger radius to match perceived blur of multi-pass
759
- } catch (error) {
760
- return console.warn("AtomixGlassContainer: Error calculating backdrop style", error),
761
- {
762
- backdropFilter: `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`
763
- };
764
- }
765
- }), [ liquidBlur, saturation, blurAmount, rectCache, effectiveReducedMotion, effectiveWithoutEffects, withLiquidBlur, overLightConfig ]), containerVars = useMemo((() => {
1141
+ const containerVars = useMemo((() => {
766
1142
  try {
767
- // Safe extraction of mouse offset values
768
- const mx = mouseOffset && "number" == typeof mouseOffset.x && !isNaN(mouseOffset.x) ? mouseOffset.x : 0, my = mouseOffset && "number" == typeof mouseOffset.y && !isNaN(mouseOffset.y) ? mouseOffset.y : 0;
769
1143
  return {
770
- "--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`,
771
- "--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
772
- "--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig?.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
773
- "--atomix-glass-container-shadow-opacity": effectiveWithoutEffects ? 0 : 1,
774
- // Background and shadow values use design token-aligned RGB values
775
- "--atomix-glass-container-bg": overLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none",
776
- "--atomix-glass-container-text-shadow": overLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)",
777
- "--atomix-glass-container-box-shadow": overLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)"
1144
+ "--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`
778
1145
  };
779
1146
  } catch (error) {
780
1147
  return console.warn("AtomixGlassContainer: Error generating container variables", error),
781
1148
  {
782
- "--atomix-glass-container-padding": "0 0",
783
- "--atomix-glass-container-radius": "0px",
784
- "--atomix-glass-container-backdrop": "none",
785
- "--atomix-glass-container-shadow": "none",
786
- "--atomix-glass-container-shadow-opacity": 1,
787
- "--atomix-glass-container-bg": "none",
788
- "--atomix-glass-container-text-shadow": "none"
1149
+ "--atomix-glass-container-radius": "0px"
789
1150
  };
790
1151
  }
791
- }), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
1152
+ }), [ borderRadius ]);
792
1153
  return jsx("div", {
793
- ref: el => {
794
- // Handle forwarded ref
795
- "function" == typeof ref ? ref(el) : ref && (ref.current = el);
796
- },
797
- className: `${ATOMIX_GLASS.CONTAINER_CLASS} ${className} ${isActive ? ATOMIX_GLASS.CLASSES.ACTIVE : ""} ${overLight ? ATOMIX_GLASS.CLASSES.OVER_LIGHT : ""}`,
1154
+ ref: containerRef,
1155
+ className: mergeClassNames(ATOMIX_GLASS.CONTAINER_CLASS, className, isActive && ATOMIX_GLASS.CLASSES.ACTIVE, overLight && ATOMIX_GLASS.CLASSES.OVER_LIGHT),
798
1156
  style: {
799
1157
  ...style,
800
1158
  ...containerVars
@@ -812,8 +1170,8 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
812
1170
  blurAmount: blurAmount,
813
1171
  mode: mode,
814
1172
  id: filterId,
815
- displacementScale: "number" != typeof displacementScale || isNaN(displacementScale) ? 0 : displacementScale,
816
- aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
1173
+ displacementScale: toSafeNumber(displacementScale),
1174
+ aberrationIntensity: toSafeNumber(aberrationIntensity),
817
1175
  shaderMapUrl: shaderMapUrl
818
1176
  }), jsx("div", {
819
1177
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
@@ -835,8 +1193,12 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
835
1193
  });
836
1194
  }));
837
1195
 
838
- // ─── Blur multiplier constants (module-level, never change at runtime) ────────
839
- AtomixGlassContainer.displayName = "AtomixGlassContainer";
1196
+ /**
1197
+ * Internal glass surface that owns backdrop-filter, SVG distortion, and content.
1198
+ *
1199
+ * Layout and stacking styles are applied via the `style` prop from the parent.
1200
+ * The root wrapper supplies CSS custom properties only.
1201
+ */ AtomixGlassContainer.displayName = "AtomixGlassContainer";
840
1202
 
841
1203
  // Singleton instance
842
1204
  const globalMouseTracker = new
@@ -951,28 +1313,32 @@ class {
951
1313
  */ getSubscriberCount() {
952
1314
  return this.listeners.size;
953
1315
  }
954
- }, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
1316
+ }, {BORDER: BORDER, CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, BORDER_GRADIENT = BORDER.GRADIENT, WHITE = CONSTANTS$2.PALETTE.WHITE, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
955
1317
  if (!wrapperElement && !containerElement) return;
956
1318
  if (!validateGlassSize(params.glassSize)) return;
957
- const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
1319
+ const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, isFixedOrSticky: isFixedOrSticky = !1, borderAnimated: borderAnimated = !0, borderOpacityMultiplier: borderOpacityMultiplier = 1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), overLightConfig = {
958
1320
  opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
959
1321
  contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
960
1322
  brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
961
1323
  shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
962
1324
  borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
963
1325
  saturationBoost: baseOverLightConfig.saturationBoost
964
- }, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, stretchMagnitude = ((pos1, pos2) => {
965
- if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
966
- const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
967
- return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
968
- })({
969
- x: 0,
970
- y: 0
971
- }, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
1326
+ }, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, tensionFactor =
1327
+ /**
1328
+ * Computes tension factor from elastic translation magnitude (0–1).
1329
+ */
1330
+ function(elasticTranslation) {
1331
+ const magnitude = Math.hypot(elasticTranslation.x, elasticTranslation.y);
1332
+ return smoothstep(magnitude / 80);
1333
+ }
1334
+ /**
1335
+ * Updates the styles of the AtomixGlass wrapper and container elements imperatively
1336
+ * to avoid React re-renders on mouse movement.
1337
+ */ (elasticTranslation), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
972
1338
  // Calculate mouse influence
973
1339
  // Update Wrapper Styles (glassVars)
974
1340
  if (wrapperElement) {
975
- const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, velocityRotation = (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5), borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, borderOpacities = [ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
1341
+ const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
976
1342
  hover1: {
977
1343
  x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
978
1344
  y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
@@ -989,28 +1355,55 @@ class {
989
1355
  x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
990
1356
  y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
991
1357
  }, opacityValues = {
992
- hover1: isHovered || isActive ? .5 : 0,
993
- hover2: isActive ? .5 : 0,
994
- hover3: isHovered ? .4 : isActive ? .8 : 0,
995
- base: isOverLight ? overLightConfig.opacity : 0,
996
- over: isOverLight ? 1.1 * overLightConfig.opacity : 0
1358
+ // hover-1: ambient highlight glow present on hover and during press
1359
+ hover1: isHovered || isActive ? 1 : 0,
1360
+ // hover-2: press depth shadow only fires on active (mousedown)
1361
+ hover2: isActive ? 1 : 0,
1362
+ // hover-3: global soft-light surface shift half-strength on hover, full on press
1363
+ hover3: isActive ? 1 : isHovered ? .55 : 0,
1364
+ // Dark chrome: faint smoky tint; over-light keeps stronger fill
1365
+ base: isOverLight ? overLightConfig.opacity : .14,
1366
+ over: isOverLight ? 1.1 * overLightConfig.opacity : .1
997
1367
  }, style = wrapperElement.style;
998
1368
  style.setProperty("--atomix-glass-transform", transformStyle || "none");
999
1369
  // Parallax for content (liquid refraction feel)
1000
1370
  const parallaxFactor = .38 + .12 * tensionFactor;
1001
1371
  style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
1002
- style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString()),
1372
+ style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString());
1003
1373
  // ── Chromatic Rim Lighting ──────────────────────────────────────
1004
- // Layer 1: Core White/Blue highlight
1005
- style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${angleB}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1006
- // Layer 2: Subtle Red/Warm highlight (offset angle)
1007
- style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${angleR}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1008
- // Hover gradients
1009
- style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`),
1010
- style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`),
1011
- style.setProperty("--atomix-glass-hover-3-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`),
1012
- style.setProperty("--atomix-glass-base-gradient", isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`),
1013
- style.setProperty("--atomix-glass-overlay-gradient", isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`),
1374
+ const borderVars = ATOMIX_GLASS.BORDER.GRADIENT_CSS_VARS;
1375
+ if (borderAnimated && !effectiveWithoutEffects) {
1376
+ const borderCssVars =
1377
+ /**
1378
+ * Builds animated chromatic rim CSS variables for border layers 1 and 2.
1379
+ * When empty, SCSS static conic/linear fallbacks apply.
1380
+ */
1381
+ function(params) {
1382
+ const {mouseOffset: mouseOffset, mouseVelocity: mouseVelocity, elasticVelocity: elasticVelocity, borderOpacity: borderOpacity, opacityMultiplier: opacityMultiplier = 1, tensionFactor: tensionFactor = 0} = params, mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), velocityRotation = (mouseVelocity.x + elasticVelocity.x) * BORDER_GRADIENT.VELOCITY_ANGLE_MULTIPLIER, borderGradientAngle = BORDER_GRADIENT.BASE_ANGLE + mx * BORDER_GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = BORDER_GRADIENT.CHROMATIC_OFFSET, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(BORDER_GRADIENT.STOP_1.MIN, BORDER_GRADIENT.STOP_1.BASE + my * BORDER_GRADIENT.STOP_1.MULTIPLIER), borderStop2 = Math.min(BORDER_GRADIENT.STOP_2.MAX, BORDER_GRADIENT.STOP_2.BASE + my * BORDER_GRADIENT.STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, opacities = BORDER_GRADIENT.OPACITY, borderOpacities = [ (opacities.BASE_1 + absMx * opacities.MULTIPLIER_LOW) * tensionGlow, (opacities.BASE_2 + absMx * opacities.MULTIPLIER_HIGH) * tensionGlow, (opacities.BASE_3 + absMx * opacities.MULTIPLIER_LOW) * tensionGlow, (opacities.BASE_4 + absMx * opacities.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = borderOpacity * opacityMultiplier, gradient1 = `linear-gradient(${angleB}deg, rgba(${WHITE}, 0) 0%, rgba(${WHITE}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${WHITE}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${WHITE}, 0) 100%)`, gradient2 = `linear-gradient(${angleR}deg, rgba(${WHITE}, 0) 0%, rgba(${WHITE}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${WHITE}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${WHITE}, 0) 100%)`;
1383
+ return {
1384
+ [BORDER.GRADIENT_CSS_VARS.GRADIENT_1]: gradient1,
1385
+ [BORDER.GRADIENT_CSS_VARS.GRADIENT_2]: gradient2
1386
+ };
1387
+ }({
1388
+ mouseOffset: mouseOffset,
1389
+ mouseVelocity: mouseVelocity,
1390
+ elasticVelocity: elasticVelocity,
1391
+ borderOpacity: overLightConfig.borderOpacity,
1392
+ opacityMultiplier: borderOpacityMultiplier,
1393
+ tensionFactor: tensionFactor
1394
+ });
1395
+ style.setProperty(borderVars.GRADIENT_1, borderCssVars[borderVars.GRADIENT_1] ?? ""),
1396
+ style.setProperty(borderVars.GRADIENT_2, borderCssVars[borderVars.GRADIENT_2] ?? "");
1397
+ } else style.removeProperty(borderVars.GRADIENT_1), style.removeProperty(borderVars.GRADIENT_2);
1398
+ // Hover gradients — cursor-relative radial positions for realistic light tracking.
1399
+ // hover-1: white overlay highlight following cursor (works on both dark + light)
1400
+ style.setProperty("--atomix-glass-hover-1-gradient", `radial-gradient(65% 55% at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, 0.24) 0%, rgba(${whiteColor}, 0.06) 45%, rgba(${whiteColor}, 0) 72%)`),
1401
+ // hover-2: press depth — darkens at cursor with multiply blend, isOverLight uses stronger black
1402
+ style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.22) 0%, rgba(${blackColor}, 0.06) 50%, rgba(${blackColor}, 0) 72%)` : `radial-gradient(60% 50% at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, 0.18) 0%, rgba(${blackColor}, 0.04) 50%, rgba(${blackColor}, 0) 72%)`),
1403
+ // hover-3: full-surface soft-light tint; linear gradient angled with cursor X
1404
+ style.setProperty("--atomix-glass-hover-3-gradient", `linear-gradient(${150 + .3 * mx}deg, rgba(${whiteColor}, ${isOverLight ? .08 : .12}) 0%, rgba(${whiteColor}, 0.04) 55%, rgba(${whiteColor}, 0) 100%)`),
1405
+ style.setProperty("--atomix-glass-base-gradient", isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `linear-gradient(180deg, rgba(${blackColor}, 0.42) 0%, rgba(${blackColor}, 0.22) 55%, rgba(${blackColor}, 0.12) 100%)`),
1406
+ style.setProperty("--atomix-glass-overlay-gradient", isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `radial-gradient(120% 80% at 50% 0%, rgba(${whiteColor}, 0.14) 0%, rgba(${whiteColor}, 0) 55%)`),
1014
1407
  // Opacities
1015
1408
  style.setProperty("--atomix-glass-hover-1-opacity", opacityValues.hover1.toString()),
1016
1409
  style.setProperty("--atomix-glass-hover-2-opacity", opacityValues.hover2.toString()),
@@ -1047,151 +1440,16 @@ class {
1047
1440
  backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
1048
1441
  // Container variables
1049
1442
  const style = containerElement.style;
1050
- style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
1443
+ style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
1051
1444
  style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
1052
1445
  // Shadows
1053
- style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset"),
1446
+ style.setProperty("--atomix-glass-container-shadow", isOverLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.35 + .002 * mx) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.15 + .001 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.06 + .001 * Math.abs(mx + my)) * (overLightConfig.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.08 + .002 * Math.abs(my)) * (overLightConfig.shadowIntensity || 1)})` ].join(", ") : ATOMIX_GLASS.CONSTANTS.CONTAINER_SHADOW.LIGHT),
1054
1447
  style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
1055
1448
  style.setProperty("--atomix-glass-container-bg", isOverLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none"),
1056
1449
  style.setProperty("--atomix-glass-container-text-shadow", isOverLight ? "0px 1px 2px rgba(255, 255, 255, 0.15)" : "0px 2px 12px rgba(0, 0, 0, 0.4)"),
1057
- style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0px 12px 40px rgba(0, 0, 0, 0.25)");
1450
+ style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0 4px 16px rgba(0, 0, 0, 0.14), 0 1px 4px rgba(0, 0, 0, 0.10)");
1058
1451
  }
1059
- };
1060
-
1061
- /**
1062
- * Updates the styles of the AtomixGlass wrapper and container elements imperatively
1063
- * to avoid React re-renders on mouse movement.
1064
- */
1065
- /**
1066
- * Animation System for AtomixGlass Component
1067
- *
1068
- * Implements Phase 1 features from the AtomixGlass Feature Implementation Roadmap:
1069
- * - Feature 1.1: Time-Based Animation System
1070
- * - Feature 1.2: Multi-Layer Distortion System (FBM)
1071
- *
1072
- * @packageDocumentation
1073
- */
1074
- // ============================================================================
1075
- // Noise Functions for FBM (Feature 1.2)
1076
- // ============================================================================
1077
- /**
1078
- * Perlin noise implementation for smooth gradient noise
1079
- *
1080
- * @param x - X coordinate
1081
- * @param y - Y coordinate
1082
- * @returns Noise value in range [0, 1]
1083
- */
1084
- function perlinNoise(x, y) {
1085
- // Simplified Perlin noise using pseudo-random gradients
1086
- const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = fade(xf), v = fade(yf), A = p[X] + Y & 255, B = p[X + 1] + Y & 255, ga = grad(p[A], xf, yf), gb = grad(p[B], xf - 1, yf), gc = grad(p[A + 1 & 255], xf, yf - 1), gd = grad(p[B + 1 & 255], xf - 1, yf - 1), lerpX1 = lerp(ga, gb, u), lerpX2 = lerp(gc, gd, u);
1087
- // Scale to [0, 1] range
1088
- return (lerp(lerpX1, lerpX2, v) + 1) / 2;
1089
- }
1090
-
1091
- // ============================================================================
1092
- // Fractal Brownian Motion (FBM) Engine (Feature 1.2)
1093
- // ============================================================================
1094
- /**
1095
- * Creates an FBM engine with configurable parameters
1096
- *
1097
- * @param config - FBM configuration (octaves, lacunarity, gain)
1098
- * @returns Object with fbm function
1099
- *
1100
- * @example
1101
- * ```typescript
1102
- * const fbmEngine = createFBMEngine({ octaves: 5, lacunarity: 2, gain: 0.5 });
1103
- *
1104
- * // Generate noise at position (0.5, 0.5) with time animation
1105
- * const noiseValue = fbmEngine.fbm(0.5, 0.5, Date.now());
1106
- * ```
1107
- */ function createFBMEngine(config) {
1108
- /**
1109
- * Fractal Brownian Motion function
1110
- * Combines multiple octaves of noise for complex, natural patterns
1111
- *
1112
- * @param x - X coordinate
1113
- * @param y - Y coordinate
1114
- * @param time - Optional time value for animation
1115
- * @returns FBM noise value in range [0, 1]
1116
- */
1117
- const fbm = (x, y, time = 0) => {
1118
- let value = 0, amplitude = .5, frequency = 1, phase = .001 * time;
1119
- // Convert to seconds for reasonable animation speed
1120
- for (let i = 0; i < config.octaves; i++)
1121
- // Apply time-based phase shift to all octaves
1122
- value += perlinNoise(x * frequency + phase, y * frequency + phase) * amplitude,
1123
- frequency *= config.lacunarity, // Increase frequency
1124
- amplitude *= config.gain;
1125
- return value;
1126
- };
1127
- /**
1128
- * Get FBM with simple time factor
1129
- */ return {
1130
- fbm: fbm,
1131
- fbmWithTime: (x, y, time) => fbm(x, y, time)
1132
- };
1133
- }
1134
-
1135
- /**
1136
- * Gets optimal FBM config based on quality preset
1137
- *
1138
- * @param quality - Quality preset level
1139
- * @returns FBM configuration for the quality level
1140
- */ const fbmEngineCache = new Map;
1141
-
1142
- // ============================================================================
1143
- // Shader Utility Functions for Time-Based Effects
1144
- // ============================================================================
1145
- /**
1146
- * Liquid glass distortion with time-based animation
1147
- * Uses FBM to create organic, flowing liquid effects
1148
- *
1149
- * @param uv - UV coordinates (normalized 0-1)
1150
- * @param time - Elapsed time in milliseconds
1151
- * @param config - FBM configuration
1152
- * @returns Distorted UV coordinates
1153
- */ function liquidGlassWithTime(uv, time, config) {
1154
- const configKey = `${config.octaves}-${config.lacunarity}-${config.gain}`;
1155
- let fbmEngine = fbmEngineCache.get(configKey);
1156
- fbmEngine || (fbmEngine = createFBMEngine(config), fbmEngineCache.set(configKey, fbmEngine));
1157
- // Animate noise with time
1158
- const animatedNoise = fbmEngine.fbmWithTime(2 * uv.x + 1e-4 * time, 2 * uv.y + 15e-5 * time, time);
1159
- return {
1160
- x: uv.x + .04 * (animatedNoise - .5),
1161
- y: uv.y + .04 * (animatedNoise - .5)
1162
- };
1163
- }
1164
-
1165
- // ============================================================================
1166
- // Helper Functions
1167
- // ============================================================================
1168
- /**
1169
- * Fade curve for smooth interpolation (Perlin's fade function)
1170
- */ function fade(t) {
1171
- return t * t * t * (t * (6 * t - 15) + 10);
1172
- }
1173
-
1174
- /**
1175
- * Linear interpolation
1176
- */ function lerp(a, b, t) {
1177
- return a + t * (b - a);
1178
- }
1179
-
1180
- /**
1181
- * Gradient calculation for Perlin noise
1182
- */ function grad(hash, x, y) {
1183
- const h = 15 & hash, u = h < 8 ? x : y, v = h < 4 ? y : 12 === h || 14 === h ? x : 0;
1184
- return (1 & h ? -u : u) + (2 & h ? -v : v);
1185
- }
1186
-
1187
- /**
1188
- * Permutation table for Perlin noise
1189
- */ const p = (() => {
1190
- const permutation = [];
1191
- for (let i = 0; i < 256; i++) permutation[i] = Math.floor(256 * Math.random());
1192
- // Duplicate for overflow handling
1193
- return [ ...permutation, ...permutation ];
1194
- })(), {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
1452
+ }, {CONSTANTS: CONSTANTS$1} = ATOMIX_GLASS;
1195
1453
 
1196
1454
  const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new WeakMap, setCachedBackgroundDetection = (parentElement, overLightConfig, result, threshold) => {
1197
1455
  parentElement && backgroundDetectionCache.set(parentElement, {
@@ -1206,12 +1464,35 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
1206
1464
  * Composable hook for AtomixGlass component logic
1207
1465
  * Manages all state, calculations, and event handlers
1208
1466
  */
1209
- function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, padding: padding, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1, withTimeAnimation:
1210
- // Default priority
1211
- // Phase 1: Animation System Props
1212
- withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: animationSpeed = ATOMIX_GLASS.DEFAULTS.ANIMATION_SPEED, withMultiLayerDistortion: withMultiLayerDistortion = ATOMIX_GLASS.DEFAULTS.WITH_MULTI_LAYER_DISTORTION, distortionOctaves: distortionOctaves = ATOMIX_GLASS.DEFAULTS.DISTORTION_OCTAVES, distortionLacunarity: distortionLacunarity = ATOMIX_GLASS.DEFAULTS.DISTORTION_LACUNARITY, distortionGain: distortionGain = ATOMIX_GLASS.DEFAULTS.DISTORTION_GAIN, distortionQuality: distortionQuality = ATOMIX_GLASS.DEFAULTS.DISTORTION_QUALITY}) {
1467
+ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef: wrapperRef, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, border: border, withBorder: withBorder = !0, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, onClick: onClick, debugBorderRadius: debugBorderRadius = !1, debugOverLight: debugOverLight = !1, children: children, blurAmount: blurAmount, saturation: saturation, withLiquidBlur: withLiquidBlur, isFixedOrSticky: isFixedOrSticky = !1, priority: priority = 1}) {
1213
1468
  // State
1214
- const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
1469
+ const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), resolvedBorder = useMemo((() =>
1470
+ /**
1471
+ * Resolves `border` and legacy `withBorder` into a single configuration object.
1472
+ */
1473
+ function(border, withBorder) {
1474
+ const legacyDefault = withBorder ?? !0;
1475
+ return void 0 === border ? {
1476
+ enabled: legacyDefault,
1477
+ width: BORDER.DEFAULT_WIDTH,
1478
+ opacityMultiplier: 1,
1479
+ animated: !0
1480
+ } : "boolean" == typeof border ? {
1481
+ enabled: border,
1482
+ width: BORDER.DEFAULT_WIDTH,
1483
+ opacityMultiplier: 1,
1484
+ animated: !0
1485
+ } : {
1486
+ enabled: border.enabled ?? legacyDefault,
1487
+ width: (value = border.width, void 0 === value ? BORDER.DEFAULT_WIDTH : "number" == typeof value ? `${value}px` : value),
1488
+ opacityMultiplier: border.opacity ?? 1,
1489
+ animated: !1 !== border.animated
1490
+ };
1491
+ /**
1492
+ * Formats border width for CSS custom properties.
1493
+ */
1494
+ var value;
1495
+ }(border, withBorder)), [ border, withBorder ]), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
1215
1496
  x: 0,
1216
1497
  y: 0
1217
1498
  }), internalMouseOffsetRef = useRef({
@@ -1235,52 +1516,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1235
1516
  }), scaleVelocityRef = useRef({
1236
1517
  x: 0,
1237
1518
  y: 0
1238
- });
1239
- useRef(0);
1240
- const mouseVelocityRef = useRef({
1519
+ }), mouseVelocityRef = useRef({
1241
1520
  x: 0,
1242
1521
  y: 0
1243
- }), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), animationFrameIdRef = useRef(null), animationStartTimeRef = useRef(0), elapsedTimeRef = useRef(0), shaderTimeRef = useRef(0), fbmConfig = useMemo((() => {
1244
- // If quality preset is provided, use it as base
1245
- const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
1246
- // Override with custom values if provided
1247
- var quality;
1248
- return {
1249
- octaves: distortionOctaves ?? preset.octaves,
1250
- lacunarity: distortionLacunarity ?? preset.lacunarity,
1251
- gain: distortionGain ?? preset.gain
1252
- };
1253
- }), [ distortionQuality, distortionOctaves, distortionLacunarity, distortionGain ]), fbmEngine = useMemo((() => withMultiLayerDistortion ? createFBMEngine(fbmConfig) : null), [ withMultiLayerDistortion, fbmConfig ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveWithTimeAnimation = useMemo((() => withTimeAnimation && !effectiveReducedMotion), [ withTimeAnimation, effectiveReducedMotion ]);
1254
- /**
1255
- * Animation loop for time-based effects
1256
- */
1257
- useEffect((() => {
1258
- if (!effectiveWithTimeAnimation || "undefined" == typeof window) return;
1259
- let lastFrameTime = performance.now();
1260
- /**
1261
- * Animation frame handler
1262
- */ const animate = currentTime => {
1263
- // Calculate delta time
1264
- const deltaTime = currentTime - lastFrameTime;
1265
- lastFrameTime = currentTime;
1266
- // Apply animation speed multiplier
1267
- const scaledDelta = deltaTime * animationSpeed;
1268
- elapsedTimeRef.current += scaledDelta, shaderTimeRef.current = elapsedTimeRef.current,
1269
- // Continue animation loop
1270
- animationFrameIdRef.current = requestAnimationFrame(animate);
1271
- };
1272
- // Start animation
1273
- // Cleanup
1274
- return animationStartTimeRef.current = performance.now(), animationFrameIdRef.current = requestAnimationFrame(animate),
1275
- () => {
1276
- null !== animationFrameIdRef.current && (cancelAnimationFrame(animationFrameIdRef.current),
1277
- animationFrameIdRef.current = null);
1278
- };
1279
- }), [ effectiveWithTimeAnimation, animationSpeed ]);
1280
- /**
1281
- * Get current shader time for animations
1282
- */
1283
- const getShaderTime = useCallback((() => shaderTimeRef.current), []), applyTimeBasedDistortion = useCallback((uv => effectiveWithTimeAnimation && fbmEngine ? liquidGlassWithTime(uv, shaderTimeRef.current, fbmConfig) : uv), [ effectiveWithTimeAnimation, fbmEngine, fbmConfig ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
1522
+ }), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
1284
1523
  const [glassSize, setGlassSize] = useState({
1285
1524
  width: 270,
1286
1525
  height: 69
@@ -1340,9 +1579,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1340
1579
  effectiveBorderRadius: effectiveBorderRadius,
1341
1580
  cachedRectRef: cachedRectRef
1342
1581
  }), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveWithoutEffects = useMemo((() => withoutEffects || effectiveReducedMotion), [ withoutEffects, effectiveReducedMotion ]), globalMousePosition = externalGlobalMousePosition || internalGlobalMousePositionRef.current, mouseOffset = externalMouseOffset || internalMouseOffsetRef.current;
1343
- /**
1344
- * Apply time-based distortion to UV coordinates
1345
- */
1346
1582
  // Extract border-radius from children
1347
1583
  useEffect((() => {
1348
1584
  const extractRadius = () => {
@@ -1502,25 +1738,26 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1502
1738
  * Get effective overLight value based on configuration
1503
1739
  */
1504
1740
  const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
1505
- const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
1741
+ const isOverLight = getEffectiveOverLight(), {hoverIntensity: hoverIntensity, activeIntensity: activeIntensity} = getInteractionIntensity(isHovered, isActive), baseConfig = {
1506
1742
  isOverLight: isOverLight,
1507
1743
  threshold: .7,
1508
1744
  opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1509
- contrast: 1.4,
1510
- brightness: .9,
1511
- saturationBoost: 1.3,
1512
- // Fixed value dynamic saturation amplifies perceived displacement
1513
- shadowIntensity: .9,
1514
- borderOpacity: .7
1745
+ // Dark UI (Apple Music): neutral contrast + slight brightness lift
1746
+ contrast: isOverLight ? 1.4 : 1.02,
1747
+ brightness: isOverLight ? .9 : 1.02,
1748
+ saturationBoost: isOverLight ? 1.3 : 1,
1749
+ shadowIntensity: isOverLight ? .9 : 1,
1750
+ borderOpacity: isOverLight ? ATOMIX_GLASS.BORDER.OVER_LIGHT.opacity : ATOMIX_GLASS.BORDER.DARK.opacity
1515
1751
  };
1516
1752
  if ("object" == typeof overLight && null !== overLight) {
1517
- const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
1753
+ const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), validatedBorderOpacity = validateConfigValue(objConfig.borderOpacity, .1, 1, baseConfig.borderOpacity), finalConfig = {
1518
1754
  ...baseConfig,
1519
1755
  threshold: validatedThreshold,
1520
1756
  opacity: validatedOpacity * hoverIntensity * activeIntensity,
1521
1757
  contrast: validatedContrast,
1522
1758
  brightness: validatedBrightness,
1523
- saturationBoost: validatedSaturationBoost
1759
+ saturationBoost: validatedSaturationBoost,
1760
+ borderOpacity: validatedBorderOpacity
1524
1761
  };
1525
1762
  return "undefined" == typeof process || process.env, finalConfig;
1526
1763
  }
@@ -1545,8 +1782,8 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1545
1782
  };
1546
1783
  const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
1547
1784
  internalGlobalMousePositionRef.current = {
1548
- x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
1549
- y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
1785
+ x: lerp(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
1786
+ y: lerp(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
1550
1787
  };
1551
1788
  // ── Calculate Elastic Physics ─────────────────────────────────────
1552
1789
  let targetElasticTranslation = {
@@ -1618,12 +1855,13 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1618
1855
  withLiquidBlur: withLiquidBlur,
1619
1856
  blurAmount: blurAmount,
1620
1857
  saturation: saturation,
1621
- padding: padding,
1622
- isFixedOrSticky: isFixedOrSticky
1858
+ isFixedOrSticky: isFixedOrSticky,
1859
+ borderAnimated: resolvedBorder.animated,
1860
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier
1623
1861
  }), Math.abs(mouseVelocityRef.current.x) < .001 && Math.abs(mouseVelocityRef.current.y) < .001 && Math.abs(elasticVelocityRef.current.x) < .001 && Math.abs(elasticVelocityRef.current.y) < .001 && Math.abs(scaleVelocityRef.current.x) < .001 && Math.abs(scaleVelocityRef.current.y) < .001 && Math.abs(internalMouseOffsetRef.current.x - targetMouseOffsetRef.current.x) < .001 && Math.abs(internalMouseOffsetRef.current.y - targetMouseOffsetRef.current.y) < .001 ? stopLerpLoop() : lerpRafRef.current = requestAnimationFrame(tick);
1624
1862
  };
1625
1863
  lerpRafRef.current = requestAnimationFrame(tick);
1626
- }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
1864
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, isFixedOrSticky, resolvedBorder.animated, resolvedBorder.opacityMultiplier, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
1627
1865
  if (externalGlobalMousePosition && externalMouseOffset) return;
1628
1866
  if (effectiveWithoutEffects) return;
1629
1867
  const container = mouseContainer?.current || glassRef.current;
@@ -1687,9 +1925,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1687
1925
  withLiquidBlur: withLiquidBlur,
1688
1926
  blurAmount: blurAmount,
1689
1927
  saturation: saturation,
1690
- padding: padding
1928
+ borderAnimated: resolvedBorder.animated,
1929
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier
1691
1930
  });
1692
- }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1931
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, resolvedBorder.animated, resolvedBorder.opacityMultiplier, onClick ]);
1693
1932
  // Event handlers
1694
1933
  const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1695
1934
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
@@ -1709,351 +1948,74 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1709
1948
  mouseOffset: mouseOffset,
1710
1949
  // This is now static (refs or props) unless prop changes
1711
1950
  overLightConfig: overLightConfig,
1951
+ resolvedBorder: resolvedBorder,
1712
1952
  transformStyle: transformStyle,
1713
- getShaderTime: getShaderTime,
1714
- applyTimeBasedDistortion: applyTimeBasedDistortion,
1715
1953
  handleMouseEnter: handleMouseEnter,
1716
1954
  handleMouseLeave: handleMouseLeave,
1717
1955
  handleMouseDown: handleMouseDown,
1718
1956
  handleMouseUp: handleMouseUp,
1719
- handleKeyDown: handleKeyDown
1720
- };
1721
- }
1722
-
1723
- /**
1724
- * Default responsive breakpoints configuration
1725
- *
1726
- * These breakpoints are optimized for glass effect performance across device classes:
1727
- * - Mobile: Reduced complexity for 60 FPS target
1728
- * - Tablet: Balanced quality and performance
1729
- * - Desktop: Full fidelity effects
1730
- */ const DEFAULT_BREAKPOINTS = {
1731
- mobile: {
1732
- maxWidth: 640,
1733
- params: {
1734
- distortionOctaves: 3,
1735
- displacementScale: .7,
1736
- blurAmount: .8,
1737
- animationSpeed: .8,
1738
- chromaticIntensity: .5
1739
- }
1740
- },
1741
- tablet: {
1742
- minWidth: 641,
1743
- maxWidth: 1024,
1744
- params: {
1745
- distortionOctaves: 4,
1746
- displacementScale: .85,
1747
- blurAmount: .9,
1748
- animationSpeed: .9,
1749
- chromaticIntensity: .75
1750
- }
1751
- },
1752
- desktop: {
1753
- minWidth: 1025,
1754
- params: {
1755
- distortionOctaves: 5,
1756
- displacementScale: 1,
1757
- blurAmount: 1,
1758
- animationSpeed: 1,
1759
- chromaticIntensity: 1
1760
- }
1761
- }
1762
- };
1763
-
1764
- /**
1765
- * Device performance tier detection
1766
- *
1767
- * Uses Device Memory API and Hardware Concurrency API to classify devices
1768
- * into performance tiers for automatic quality adjustment.
1769
- *
1770
- * @returns Performance tier classification
1771
- */ var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
1772
-
1773
- function getDefaultExportFromCjs(x) {
1774
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
1775
- }
1776
-
1777
- var fails$8 = function(exec) {
1778
- try {
1779
- return !!exec();
1780
- } catch (error) {
1781
- return !0;
1782
- }
1783
- }, functionBindNative = !fails$8((function() {
1784
- // eslint-disable-next-line es/no-function-prototype-bind -- safe
1785
- var test = function() {/* empty */}.bind();
1786
- // eslint-disable-next-line no-prototype-builtins -- safe
1787
- return "function" != typeof test || test.hasOwnProperty("prototype");
1788
- })), NATIVE_BIND$3 = functionBindNative, FunctionPrototype$1 = Function.prototype, call$5 = FunctionPrototype$1.call, uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$1.bind.bind(call$5, call$5), functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function(fn) {
1789
- return function() {
1790
- return call$5.apply(fn, arguments);
1791
- };
1792
- }, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
1793
- return it && it.Math === Math && it;
1794
- }, globalThis_1 =
1795
- // eslint-disable-next-line es/no-global-this -- safe
1796
- check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
1797
- // eslint-disable-next-line no-restricted-globals -- safe
1798
- check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
1799
- // eslint-disable-next-line no-new-func -- fallback
1800
- function() {
1801
- return this;
1802
- }() || Function("return this")(), NATIVE_BIND$2 = functionBindNative, FunctionPrototype = Function.prototype, apply$1 = FunctionPrototype.apply, call$4 = FunctionPrototype.call, functionApply = "object" == typeof Reflect && Reflect.apply || (NATIVE_BIND$2 ? call$4.bind(apply$1) : function() {
1803
- return call$4.apply(apply$1, arguments);
1804
- }), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
1805
- return stringSlice(toString$3(it), 8, -1);
1806
- }, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
1807
- // Nashorn bug:
1808
- // https://github.com/zloirock/core-js/issues/1128
1809
- // https://github.com/zloirock/core-js/issues/1130
1810
- if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
1811
- }, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
1812
- return "function" == typeof argument || argument === documentAll;
1813
- } : function(argument) {
1814
- return "function" == typeof argument;
1815
- }, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$8((function() {
1816
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
1817
- return 7 !== Object.defineProperty({}, 1, {
1818
- get: function() {
1819
- return 7;
1820
- }
1821
- })[1];
1822
- })), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
1823
- return call$3.apply(call$3, arguments);
1824
- }, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
1825
- 1: 2
1826
- }, 1);
1827
-
1828
- // `Object.prototype.propertyIsEnumerable` method implementation
1829
- // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
1830
- objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
1831
- var descriptor = getOwnPropertyDescriptor$1(this, V);
1832
- return !!descriptor && descriptor.enumerable;
1833
- } : $propertyIsEnumerable;
1834
-
1835
- var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
1836
- return {
1837
- enumerable: !(1 & bitmap),
1838
- configurable: !(2 & bitmap),
1839
- writable: !(4 & bitmap),
1840
- value: value
1841
- };
1842
- }, fails$5 = fails$8, classof$3 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$5((function() {
1843
- // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
1844
- // eslint-disable-next-line no-prototype-builtins -- safe
1845
- return !$Object$3("z").propertyIsEnumerable(0);
1846
- })) ? function(it) {
1847
- return "String" === classof$3(it) ? split(it, "") : $Object$3(it);
1848
- } : $Object$3, isNullOrUndefined$2 = function(it) {
1849
- return null == it;
1850
- }, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$6 = TypeError, requireObjectCoercible$3 = function(it) {
1851
- if (isNullOrUndefined$1(it)) throw new $TypeError$6("Can't call method on " + it);
1852
- return it;
1853
- }, IndexedObject = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
1854
- return IndexedObject(requireObjectCoercible$2(it));
1855
- }, isCallable$7 = isCallable$8, isObject$5 = function(it) {
1856
- return "object" == typeof it ? null !== it : isCallable$7(it);
1857
- }, path$3 = {}, path$2 = path$3, globalThis$a = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
1858
- return isCallable$6(variable) ? variable : void 0;
1859
- }, navigator$1 = globalThis_1.navigator, userAgent$1 = navigator$1 && navigator$1.userAgent, globalThis$8 = globalThis_1, userAgent = userAgent$1 ? String(userAgent$1) : "", process$1 = globalThis$8.process, Deno = globalThis$8.Deno, versions = process$1 && process$1.versions || Deno && Deno.version, v8 = versions && versions.v8;
1860
-
1861
- v8 && (
1862
- // in old Chrome, versions of V8 isn't V8 = Chrome / 10
1863
- // but their correct versions are not interesting for us
1864
- version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
1865
- // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
1866
- // so check `userAgent` even if `.v8` exists, but 0
1867
- !version && userAgent && (!(match = userAgent.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent.match(/Chrome\/(\d+)/)) && (version = +match[1]);
1868
-
1869
- var V8_VERSION = version, fails$4 = fails$8, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$4((function() {
1870
- var symbol = Symbol("symbol detection");
1871
- // Chrome 38 Symbol has incorrect toString conversion
1872
- // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
1873
- // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
1874
- // of course, fail.
1875
- return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
1876
- // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
1877
- !Symbol.sham && V8_VERSION && V8_VERSION < 41;
1878
- })), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$1 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
1879
- return "symbol" == typeof it;
1880
- } : function(it) {
1881
- var $Symbol = function(namespace, method) {
1882
- return arguments.length < 2 ? aFunction(path$2[namespace]) || aFunction(globalThis$a[namespace]) : path$2[namespace] && path$2[namespace][method] || globalThis$a[namespace] && globalThis$a[namespace][method];
1883
- }("Symbol");
1884
- return isCallable$5($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
1885
- }, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$5 = TypeError, aCallable$2 = function(argument) {
1886
- if (isCallable$4(argument)) return argument;
1887
- throw new $TypeError$5(function(argument) {
1888
- try {
1889
- return $String$2(argument);
1890
- } catch (error) {
1891
- return "Object";
1892
- }
1893
- }(argument) + " is not a function");
1894
- }, aCallable$1 = aCallable$2, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$4 = TypeError, sharedStore = {
1895
- exports: {}
1896
- }, globalThis$6 = globalThis_1, defineProperty = Object.defineProperty, globalThis$5 = globalThis_1, store$1 = sharedStore.exports = globalThis$5["__core-js_shared__"] || function(key, value) {
1897
- try {
1898
- defineProperty(globalThis$6, key, {
1899
- value: value,
1900
- configurable: !0,
1901
- writable: !0
1902
- });
1903
- } catch (error) {
1904
- globalThis$6[key] = value;
1905
- }
1906
- return value;
1907
- }("__core-js_shared__", {});
1908
-
1909
- /* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
1910
- version: "3.43.0",
1911
- mode: "pure",
1912
- copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
1913
- license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
1914
- source: "https://github.com/zloirock/core-js"
1915
- });
1916
-
1917
- var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
1918
- return hasOwnProperty($Object$1(requireObjectCoercible$1(it)), key);
1919
- }, uncurryThis$3 = functionUncurryThis, id = 0, postfix = Math.random(), toString$2 = uncurryThis$3(1.1.toString), hasOwn$2 = hasOwnProperty_1, NATIVE_SYMBOL = symbolConstructorDetection, USE_SYMBOL_AS_UID = useSymbolAsUid, Symbol$1 = globalThis_1.Symbol, WellKnownSymbolsStore = store[key = "wks"] || (store[key] = value || {}), createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1.for || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || function(key) {
1920
- return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
1921
- }, wellKnownSymbol$5 = function(name) {
1922
- return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
1923
- WellKnownSymbolsStore[name];
1924
- }, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$3 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
1925
- if (!isObject$3(input) || isSymbol$1(input)) return input;
1926
- var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$1(func));
1927
- if (exoticToPrim) {
1928
- if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
1929
- !isObject$3(result) || isSymbol$1(result)) return result;
1930
- throw new $TypeError$3("Can't convert object to primitive value");
1931
- }
1932
- return void 0 === pref && (pref = "number"), function(input, pref) {
1933
- var fn, val;
1934
- if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
1935
- if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
1936
- if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
1937
- throw new $TypeError$4("Can't convert object to primitive value");
1938
- }(input, pref);
1939
- }, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
1940
- var key = toPrimitive(argument, "string");
1941
- return isSymbol(key) ? key : key + "";
1942
- }, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$8((function() {
1943
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
1944
- return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
1945
- get: function() {
1946
- return 7;
1947
- }
1948
- }).a;
1949
- var it;
1950
- })), DESCRIPTORS$3 = descriptors, call = functionCall, propertyIsEnumerableModule = objectPropertyIsEnumerable, createPropertyDescriptor$1 = createPropertyDescriptor$2, toIndexedObject$1 = toIndexedObject$2, toPropertyKey$1 = toPropertyKey$2, hasOwn$1 = hasOwnProperty_1, IE8_DOM_DEFINE$1 = ie8DomDefine, $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
1951
-
1952
- // `Object.getOwnPropertyDescriptor` method
1953
- // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
1954
- objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
1955
- if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
1956
- return $getOwnPropertyDescriptor$1(O, P);
1957
- } catch (error) {/* empty */}
1958
- if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
1959
- };
1960
-
1961
- var fails$2 = fails$8, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
1962
- var value = data[normalize(feature)];
1963
- return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$2(detection) : !!detection);
1964
- }, normalize = isForced$1.normalize = function(string) {
1965
- return String(string).replace(replacement, ".").toLowerCase();
1966
- }, data = isForced$1.data = {}, NATIVE = isForced$1.NATIVE = "N", POLYFILL = isForced$1.POLYFILL = "P", isForced_1 = isForced$1, aCallable = aCallable$2, NATIVE_BIND = functionBindNative, bind$1 = functionUncurryThisClause(functionUncurryThisClause.bind), objectDefineProperty = {}, v8PrototypeDefineBug = descriptors && fails$8((function() {
1967
- // eslint-disable-next-line es/no-object-defineproperty -- required for testing
1968
- return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
1969
- value: 42,
1970
- writable: !1
1971
- }).prototype;
1972
- })), isObject$1 = isObject$5, $String$1 = String, $TypeError$2 = TypeError, DESCRIPTORS$1 = descriptors, IE8_DOM_DEFINE = ie8DomDefine, V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug, anObject = function(argument) {
1973
- if (isObject$1(argument)) return argument;
1974
- throw new $TypeError$2($String$1(argument) + " is not an object");
1975
- }, toPropertyKey = toPropertyKey$2, $TypeError$1 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1957
+ handleKeyDown: handleKeyDown
1958
+ };
1959
+ }
1976
1960
 
1977
- // `Object.defineProperty` method
1978
- // https://tc39.es/ecma262/#sec-object.defineproperty
1979
- objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
1980
- if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
1981
- var current = $getOwnPropertyDescriptor(O, P);
1982
- current && current.writable && (O[P] = Attributes.value, Attributes = {
1983
- configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
1984
- enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
1985
- writable: !1
1986
- });
1961
+ /**
1962
+ * Default responsive breakpoints configuration
1963
+ *
1964
+ * These breakpoints are optimized for glass effect performance across device classes:
1965
+ * - Mobile: Reduced complexity for 60 FPS target
1966
+ * - Tablet: Balanced quality and performance
1967
+ * - Desktop: Full fidelity effects
1968
+ */ const DEFAULT_BREAKPOINTS = {
1969
+ mobile: {
1970
+ maxWidth: 640,
1971
+ params: {
1972
+ distortionOctaves: 3,
1973
+ displacementScale: .7,
1974
+ blurAmount: .8,
1975
+ animationSpeed: .8,
1976
+ chromaticIntensity: .5
1977
+ }
1978
+ },
1979
+ tablet: {
1980
+ minWidth: 641,
1981
+ maxWidth: 1024,
1982
+ params: {
1983
+ distortionOctaves: 4,
1984
+ displacementScale: .85,
1985
+ blurAmount: .9,
1986
+ animationSpeed: .9,
1987
+ chromaticIntensity: .75
1988
+ }
1989
+ },
1990
+ desktop: {
1991
+ minWidth: 1025,
1992
+ params: {
1993
+ distortionOctaves: 5,
1994
+ displacementScale: 1,
1995
+ blurAmount: 1,
1996
+ animationSpeed: 1,
1997
+ chromaticIntensity: 1
1998
+ }
1987
1999
  }
1988
- return $defineProperty(O, P, Attributes);
1989
- } : $defineProperty : function(O, P, Attributes) {
1990
- if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
1991
- return $defineProperty(O, P, Attributes);
1992
- } catch (error) {/* empty */}
1993
- if ("get" in Attributes || "set" in Attributes) throw new $TypeError$1("Accessors not supported");
1994
- return "value" in Attributes && (O[P] = Attributes.value), O;
1995
2000
  };
1996
2001
 
1997
- var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
1998
- return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
1999
- } : function(object, key, value) {
2000
- return object[key] = value, object;
2001
- }, globalThis$2 = globalThis_1, apply = functionApply, uncurryThis$1 = functionUncurryThisClause, isCallable$1 = isCallable$8, getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f, isForced = isForced_1, path$1 = path$3, bind = function(fn, that) {
2002
- return aCallable(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
2003
- return fn.apply(that, arguments);
2004
- };
2005
- }, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
2006
- var Wrapper = function(a, b, c) {
2007
- if (this instanceof Wrapper) {
2008
- switch (arguments.length) {
2009
- case 0:
2010
- return new NativeConstructor;
2011
-
2012
- case 1:
2013
- return new NativeConstructor(a);
2014
-
2015
- case 2:
2016
- return new NativeConstructor(a, b);
2017
- }
2018
- return new NativeConstructor(a, b, c);
2019
- }
2020
- return apply(NativeConstructor, this, arguments);
2021
- };
2022
- return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
2023
- }, _export = function(options, source) {
2024
- var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE, key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor, TARGET = options.target, GLOBAL = options.global, STATIC = options.stat, PROTO = options.proto, nativeSource = GLOBAL ? globalThis$2 : STATIC ? globalThis$2[TARGET] : globalThis$2[TARGET] && globalThis$2[TARGET].prototype, target = GLOBAL ? path$1 : path$1[TARGET] || createNonEnumerableProperty(path$1, TARGET, {})[TARGET], targetPrototype = target.prototype;
2025
- for (key in source)
2026
- // contains in native
2027
- USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
2028
- targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
2029
- // export native or implementation
2030
- sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
2031
- // bind methods to global for calling from export context
2032
- resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$2) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
2033
- // add a flag to not completely full polyfills
2034
- (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
2035
- createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
2036
- // export virtual prototype methods
2037
- createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
2038
- // export real prototype methods
2039
- options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
2040
- }, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
2041
- var n = +x;
2042
- return (n > 0 ? floor : ceil)(n);
2043
- }, toIntegerOrInfinity$2 = function(argument) {
2044
- var number = +argument;
2045
- // eslint-disable-next-line no-self-compare -- NaN check
2046
- return number != number || 0 === number ? 0 : trunc(number);
2047
- }, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, max = Math.max, min$1 = Math.min, toIntegerOrInfinity = toIntegerOrInfinity$2, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = function(obj) {
2048
- return argument = obj.length, (len = toIntegerOrInfinity(argument)) > 0 ? min(len, 9007199254740991) : 0;
2002
+ /**
2003
+ * Device performance tier detection
2004
+ *
2005
+ * Uses Device Memory API and Hardware Concurrency API to classify devices
2006
+ * into performance tiers for automatic quality adjustment.
2007
+ *
2008
+ * @returns Performance tier classification
2009
+ */ var toIntegerOrInfinity = toIntegerOrInfinity$2, max = Math.max, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = function(obj) {
2010
+ return argument = obj.length, (len = toIntegerOrInfinity$1(argument)) > 0 ? min$1(len, 9007199254740991) : 0;
2049
2011
  var argument, len;
2050
2012
  }, createMethod = function(IS_INCLUDES) {
2051
2013
  return function($this, el, fromIndex) {
2052
2014
  var O = toIndexedObject($this), length = lengthOfArrayLike(O);
2053
2015
  if (0 === length) return !IS_INCLUDES && -1;
2054
2016
  var value, index = function(index, length) {
2055
- var integer = toIntegerOrInfinity$1(index);
2056
- return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
2017
+ var integer = toIntegerOrInfinity(index);
2018
+ return integer < 0 ? max(integer + length, 0) : min(integer, length);
2057
2019
  }(fromIndex, length);
2058
2020
  // Array#includes uses SameValueZero equality algorithm
2059
2021
  // eslint-disable-next-line no-self-compare -- NaN check
@@ -2082,12 +2044,7 @@ _export({
2082
2044
  }
2083
2045
  });
2084
2046
 
2085
- var globalThis$1 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$2 = function(CONSTRUCTOR, METHOD) {
2086
- var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
2087
- if (pureMethod) return pureMethod;
2088
- var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
2089
- return NativePrototype && NativePrototype[METHOD];
2090
- }, includes$4 = getBuiltInPrototypeMethod$2("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
2047
+ var includes$4 = getBuiltInPrototypeMethod$2("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
2091
2048
 
2092
2049
  test[wellKnownSymbol$5("toStringTag")] = "z";
2093
2050
 
@@ -2143,148 +2100,6 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
2143
2100
  /**
2144
2101
  * Get GPU memory info if available (Chrome DevTools only)
2145
2102
  */
2146
- /** Map an FPS value to a semantic color token string. */
2147
- const getQualityColor = quality => {
2148
- switch (quality) {
2149
- case "high":
2150
- return "var(--atomix-color-success, #4ade80)";
2151
-
2152
- case "medium":
2153
- return "var(--atomix-color-warning, #fbbf24)";
2154
-
2155
- case "low":
2156
- return "var(--atomix-color-danger, #ef4444)";
2157
-
2158
- default:
2159
- return "#9ca3af";
2160
- }
2161
- }, getFpsLabel = fps => fps >= 58 ? "Optimal" : fps >= 45 ? "Warning" : "Critical";
2162
-
2163
- /** Map a quality level string to a semantic color token string. */
2164
- // Inject keyframes once
2165
- if ("undefined" != typeof document) {
2166
- const styleId = "perf-dashboard-keyframes";
2167
- if (!document.getElementById(styleId)) {
2168
- const styleEl = document.createElement("style");
2169
- styleEl.id = styleId, styleEl.textContent = "\n@keyframes perf-dashboard-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n",
2170
- document.head.appendChild(styleEl);
2171
- }
2172
- }
2173
-
2174
- /**
2175
- * PerformanceDashboard - Real-time performance monitoring overlay.
2176
- *
2177
- * Displays FPS, frame time, quality level, GPU memory, and auto-scaling status.
2178
- * Rendered only when `debugPerformance={true}` on the parent `AtomixGlass`.
2179
- */ const PerformanceDashboard = memo((({metrics: metrics, isVisible: isVisible = !0, onClose: onClose}) => {
2180
- if (!isVisible) return null;
2181
- const fpsColor = (fps = metrics.fps) >= 58 ? "var(--atomix-color-success, #4ade80)" : fps >= 45 ? "var(--atomix-color-warning, #fbbf24)" : "var(--atomix-color-danger, #ef4444)";
2182
- var fps;
2183
- const isCritical = metrics.fps < 45;
2184
- return jsxs("div", {
2185
- className: "c-perf-dashboard u-position-fixed u-top-4 u-end-4 u-p-3 u-px-4 u-text-xs u-font-mono u-text-white u-rounded-md u-border u-border-white-alpha-10 u-shadow-lg",
2186
- style: {
2187
- zIndex: 9999,
2188
- minWidth: "12.5rem",
2189
- // 200px
2190
- backgroundColor: "rgba(17, 24, 39, 0.95)",
2191
- backdropFilter: "blur(8px)",
2192
- transition: "opacity 0.3s ease"
2193
- },
2194
- children: [ jsxs("div", {
2195
- className: "u-flex u-items-center u-justify-between u-mb-2 u-pb-2 u-border-b u-border-white-alpha-10",
2196
- children: [ jsx("span", {
2197
- className: "u-text-sm u-font-bold u-text-white",
2198
- children: "Performance Monitor"
2199
- }), onClose && jsx("button", {
2200
- className: "u-bg-transparent u-border-none u-p-0 u-line-height-1 u-text-base u-text-gray-400 u-cursor-pointer hover:u-text-white",
2201
- onClick: onClose,
2202
- "aria-label": "Close performance dashboard",
2203
- style: {
2204
- transition: "color 0.2s ease"
2205
- },
2206
- children: "×"
2207
- }) ]
2208
- }), jsxs("div", {
2209
- className: "u-flex u-items-center u-justify-between u-mb-1-5",
2210
- children: [ jsx("span", {
2211
- className: "u-text-gray-400 u-me-3",
2212
- children: "FPS"
2213
- }), jsx("span", {
2214
- className: "u-font-bold",
2215
- style: {
2216
- color: fpsColor
2217
- },
2218
- children: Math.round(metrics.fps)
2219
- }) ]
2220
- }), jsxs("div", {
2221
- className: "u-flex u-items-center u-justify-between u-mb-1-5",
2222
- children: [ jsx("span", {
2223
- className: "u-text-gray-400 u-me-3",
2224
- children: "Frame Time"
2225
- }), jsxs("span", {
2226
- className: "u-font-bold",
2227
- children: [ metrics.frameTime.toFixed(2), "ms" ]
2228
- }) ]
2229
- }), jsxs("div", {
2230
- className: "u-flex u-items-center u-justify-between u-mb-1-5",
2231
- children: [ jsx("span", {
2232
- className: "u-text-gray-400 u-me-3",
2233
- children: "Quality"
2234
- }), jsx("span", {
2235
- className: "u-font-bold u-text-uppercase",
2236
- style: {
2237
- fontSize: "0.6875rem",
2238
- // 11px
2239
- color: getQualityColor(metrics.qualityLevel)
2240
- },
2241
- children: metrics.qualityLevel
2242
- }) ]
2243
- }), metrics.gpuMemory && jsxs("div", {
2244
- className: "u-flex u-items-center u-justify-between u-mb-1-5",
2245
- children: [ jsx("span", {
2246
- className: "u-text-gray-400 u-me-3",
2247
- children: "GPU Memory"
2248
- }), jsxs("span", {
2249
- className: "u-font-bold",
2250
- children: [ "~", Math.round(metrics.gpuMemory / 1024), "MB" ]
2251
- }) ]
2252
- }), metrics.isAutoScaling && jsx("div", {
2253
- className: "u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10 u-text-center",
2254
- style: {
2255
- fontSize: "0.625rem",
2256
- // 10px
2257
- color: "#6b7280"
2258
- },
2259
- children: "Auto-scaling active"
2260
- }), jsxs("div", {
2261
- className: "u-flex u-items-center u-gap-2 u-mt-2 u-pt-2 u-border-t u-border-white-alpha-10",
2262
- children: [ jsx("div", {
2263
- className: "u-rounded-full",
2264
- style: {
2265
- width: "0.5rem",
2266
- height: "0.5rem",
2267
- flexShrink: 0,
2268
- backgroundColor: fpsColor,
2269
- ...isCritical && {
2270
- animation: "perf-dashboard-pulse 1s infinite"
2271
- }
2272
- }
2273
- }), jsx("span", {
2274
- className: "u-text-xs",
2275
- style: {
2276
- fontSize: "0.625rem",
2277
- // 10px
2278
- color: fpsColor
2279
- },
2280
- children: getFpsLabel(metrics.fps)
2281
- }) ]
2282
- }) ]
2283
- });
2284
- }));
2285
-
2286
- PerformanceDashboard.displayName = "PerformanceDashboard";
2287
-
2288
2103
  /**
2289
2104
  * Mobile optimization presets
2290
2105
  *
@@ -2404,18 +2219,13 @@ const PERFORMANCE_PRESET = {
2404
2219
  saturation: 70
2405
2220
  }
2406
2221
  }
2407
- }, AtomixGlassInner = forwardRef((function({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, withBorder: withBorder = !0, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, isFixedOrSticky: propsIsFixedOrSticky, ...rest}, ref) {
2408
- const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useMemo((() =>
2409
- // Helper to merge refs
2410
- function(...refs) {
2411
- return node => {
2412
- refs.forEach((ref => {
2413
- "function" == typeof ref ? ref(node) : null != ref && (ref.current = node);
2414
- }));
2415
- };
2416
- }
2417
- // Internal implementation with forwardRef
2418
- (ref, internalWrapperRef)), [ ref ]), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = propsIsFixedOrSticky || "fixed" === restStyle.position || "sticky" === restStyle.position, {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, getShaderTime: getShaderTime, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown} = useAtomixGlass({
2222
+ }, AtomixGlassInner = forwardRef((function({children: children, displacementScale: displacementScale = ATOMIX_GLASS.DEFAULTS.DISPLACEMENT_SCALE, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, aberrationIntensity: aberrationIntensity = ATOMIX_GLASS.DEFAULTS.ABERRATION_INTENSITY, elasticity: elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY, borderRadius: borderRadius, globalMousePosition: externalGlobalMousePosition, mouseOffset: externalMouseOffset, mouseContainer: mouseContainer = null, className: className = "", overLight: overLight = ATOMIX_GLASS.DEFAULTS.OVER_LIGHT, style: style = {}, mode: mode = ATOMIX_GLASS.DEFAULTS.MODE, onClick: onClick, shaderVariant: shaderVariant = "liquidGlass", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, role: role, tabIndex: tabIndex, reducedMotion: reducedMotion = !1, highContrast: highContrast = !1, withoutEffects: withoutEffects = !1, withLiquidBlur: withLiquidBlur = !1, border: border, withBorder: withBorder = !0, debugBorderRadius: debugBorderRadius = !1, withOverLightLayers: withOverLightLayers = ATOMIX_GLASS.DEFAULTS.ENABLE_OVER_LIGHT_LAYERS, debugPerformance: debugPerformance = !1, debugOverLight: debugOverLight = !1, height: height, width: width, withTimeAnimation: withTimeAnimation = !1, animationSpeed: animationSpeed = 1, withMultiLayerDistortion: withMultiLayerDistortion = !1, distortionOctaves: distortionOctaves = 3, distortionLacunarity: distortionLacunarity = 2, distortionGain: distortionGain = .5, distortionQuality: distortionQuality = "medium", devicePreset: devicePreset = "balanced", disableResponsiveBreakpoints: disableResponsiveBreakpoints = !1, isFixedOrSticky: propsIsFixedOrSticky, ...rest}, ref) {
2223
+ const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useForkRef(ref, internalWrapperRef), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = (explicit = propsIsFixedOrSticky,
2224
+ position = restStyle.position, Boolean(explicit || "fixed" === position || "sticky" === position));
2225
+ var explicit, position;
2226
+ /**
2227
+ * Extracts layout-related properties from a React `CSSProperties` object.
2228
+ */ const {isHovered: isHovered, isActive: isActive, glassSize: glassSize, effectiveBorderRadius: effectiveBorderRadius, effectiveReducedMotion: effectiveReducedMotion, effectiveHighContrast: effectiveHighContrast, effectiveWithoutEffects: effectiveWithoutEffects, overLightConfig: overLightConfig, globalMousePosition: globalMousePosition, mouseOffset: mouseOffset, transformStyle: transformStyle, handleMouseEnter: handleMouseEnter, handleMouseLeave: handleMouseLeave, handleMouseDown: handleMouseDown, handleMouseUp: handleMouseUp, handleKeyDown: handleKeyDown, resolvedBorder: resolvedBorder} = useAtomixGlass({
2419
2229
  glassRef: glassRef,
2420
2230
  contentRef: contentRef,
2421
2231
  wrapperRef: internalWrapperRef,
@@ -2435,20 +2245,13 @@ const PERFORMANCE_PRESET = {
2435
2245
  blurAmount: blurAmount,
2436
2246
  saturation: saturation,
2437
2247
  withLiquidBlur: withLiquidBlur,
2438
- padding: padding,
2248
+ border: border,
2249
+ withBorder: withBorder,
2250
+ debugBorderRadius: debugBorderRadius,
2439
2251
  style: style,
2440
- isFixedOrSticky: isFixedOrSticky,
2441
- // Phase 1: Animation System props
2442
- withTimeAnimation: withTimeAnimation,
2443
- animationSpeed: animationSpeed,
2444
- withMultiLayerDistortion: withMultiLayerDistortion,
2445
- distortionOctaves: distortionOctaves,
2446
- distortionLacunarity: distortionLacunarity,
2447
- distortionGain: distortionGain,
2448
- distortionQuality: distortionQuality
2252
+ isFixedOrSticky: isFixedOrSticky
2449
2253
  });
2450
- // Responsive breakpoint system - automatically adjusts parameters based on viewport
2451
- !
2254
+ (
2452
2255
  /**
2453
2256
  * Responsive Glass Parameters Hook
2454
2257
  *
@@ -2603,7 +2406,7 @@ const PERFORMANCE_PRESET = {
2603
2406
  }), [ enabled ]), useCallback((() => {
2604
2407
  calculateParams();
2605
2408
  }), [ calculateParams ]);
2606
- }({
2409
+ })({
2607
2410
  baseParams: {
2608
2411
  ...useMemo((() =>
2609
2412
  /**
@@ -2637,9 +2440,7 @@ const PERFORMANCE_PRESET = {
2637
2440
  breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
2638
2441
  enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
2639
2442
  debug: !1
2640
- });
2641
- // Performance monitoring - tracks FPS, frame time, memory usage
2642
- const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
2443
+ }),
2643
2444
  /**
2644
2445
  * Performance Monitor Hook
2645
2446
  *
@@ -2674,7 +2475,13 @@ const PERFORMANCE_PRESET = {
2674
2475
  timestamp: 0,
2675
2476
  isAutoScaling: !0,
2676
2477
  lowFpsCount: 0
2677
- }), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled), frameCountRef = useRef(0), lastFpsUpdateRef = useRef(0), lastFrameTimeRef = useRef(0), animationFrameRef = useRef(null), lowFpsCountRef = useRef(0), highFpsCountRef = useRef(0), qualityLevelRef = useRef("medium"), updateMetrics = useCallback((newMetrics => {
2478
+ }), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled);
2479
+ // Sync external `enabled` prop changes into internal state
2480
+ useEffect((() => {
2481
+ setIsEnabled(enabled ?? !0);
2482
+ }), [ enabled ]);
2483
+ // Refs for frame tracking
2484
+ const frameCountRef = useRef(0), lastFpsUpdateRef = useRef(0), lastFrameTimeRef = useRef(0), animationFrameRef = useRef(null), lowFpsCountRef = useRef(0), highFpsCountRef = useRef(0), qualityLevelRef = useRef("medium"), updateMetrics = useCallback((newMetrics => {
2678
2485
  setMetrics((prev => ({
2679
2486
  ...prev,
2680
2487
  ...newMetrics,
@@ -2794,191 +2601,214 @@ const PERFORMANCE_PRESET = {
2794
2601
  /**
2795
2602
  * Reset to auto-scaling mode
2796
2603
  */ var fps, currentQuality;
2797
- return {
2798
- metrics: metrics,
2799
- recommendedQuality: (fps = metrics.fps, currentQuality = metrics.qualityLevel, fps >= 58 ? "high" : fps >= 45 ? "high" === currentQuality ? "high" : "medium" : "low"),
2800
- isUnderperforming: metrics.fps < minFps,
2801
- setQualityLevel: setQualityLevel,
2802
- resetAutoScaling: resetAutoScaling,
2803
- toggleMonitoring: toggleMonitoring
2804
- };
2604
+ fps = metrics.fps, currentQuality = metrics.qualityLevel, metrics.fps;
2805
2605
  }({
2806
2606
  enabled: debugPerformance,
2807
- // Enable when debugPerformance is true
2808
2607
  debug: !1,
2809
2608
  showOverlay: !1
2810
2609
  });
2811
- // Auto-start performance monitoring when debugPerformance is enabled
2812
- React.useEffect((() => {
2813
- debugPerformance && toggleMonitoring();
2814
- // eslint-disable-next-line react-hooks/exhaustive-deps
2815
- }), [ debugPerformance ]);
2816
- // Re-run when debugPerformance changes
2817
- const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, rootLayoutStyle = useMemo((() => {
2818
- if (!isFixedOrSticky) return {};
2819
- const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
2820
- return {
2821
- ...p && {
2822
- position: p
2823
- },
2824
- ...void 0 !== t && {
2825
- top: t
2826
- },
2827
- ...void 0 !== l && {
2828
- left: l
2829
- },
2830
- ...void 0 !== r && {
2831
- right: r
2832
- },
2833
- ...void 0 !== b && {
2834
- bottom: b
2835
- }
2836
- };
2837
- }), [ isFixedOrSticky, restStyle ]);
2838
- // Calculate base style with transforms
2839
- // When layout is hoisted to the root, strip those props from the container
2840
- useMemo((() => {
2841
- if (isFixedOrSticky) {
2842
- const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
2843
- return {
2844
- ...visualStyle
2845
- };
2610
+ const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, containerStyle = useMemo((() => ({
2611
+ ...restStyle,
2612
+ ...void 0 !== customZIndex && {
2613
+ zIndex: customZIndex
2846
2614
  }
2615
+ })), [ restStyle, customZIndex ]), componentClassName = mergeClassNames(ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className), positionStyles = useMemo((() =>
2616
+ /**
2617
+ * Returns the internal positioning context for effect layers relative to the root.
2618
+ */
2619
+ function(isFixedOrSticky, restStyle) {
2847
2620
  return {
2848
- ...restStyle
2621
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
2622
+ top: 0,
2623
+ left: 0,
2624
+ right: "auto",
2625
+ bottom: "auto"
2849
2626
  };
2850
- }), [ isFixedOrSticky, restStyle ]);
2851
- // Build className with state modifiers
2852
- const componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveWithoutEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
2853
- position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
2854
- top: isFixedOrSticky ? restStyle.top ?? 0 : 0,
2855
- left: isFixedOrSticky ? restStyle.left ?? 0 : 0,
2856
- right: isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
2857
- bottom: isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto"
2858
- })), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), adjustedSize = useMemo((() => {
2859
- // Keep a reference to positionStyles to avoid unused-variable lint,
2860
- // but sizing is driven by explicit width/height or measured size.
2861
- positionStyles.position;
2862
- const resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
2627
+ }
2628
+ /**
2629
+ * Computes `--atomix-glass-width` and `--atomix-glass-height` values.
2630
+ *
2631
+ * Fixed/sticky elements prefer explicit dimensions or measured size; in-flow
2632
+ * elements default to `100%`.
2633
+ */ (isFixedOrSticky, restStyle)), [ isFixedOrSticky, restStyle ]), adjustedSize = useMemo((() => function(options) {
2634
+ const {width: width, height: height, restStyle: restStyle, glassSize: glassSize, isFixedOrSticky: isFixedOrSticky} = options, resolveLength = (value, measured) => void 0 !== value && isFixedOrSticky ? "number" == typeof value ? `${value}px` : value : measured > 0 && isFixedOrSticky ? `${measured}px` : "100%", effectiveWidth = width ?? restStyle.width, effectiveHeight = height ?? restStyle.height;
2863
2635
  return {
2864
2636
  width: resolveLength(effectiveWidth, glassSize.width),
2865
2637
  height: resolveLength(effectiveHeight, glassSize.height)
2866
2638
  };
2867
- }), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height, isFixedOrSticky ]), gradientValues = useMemo((() => {
2868
- const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
2869
- return {
2870
- borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
2871
- borderStop1: Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER),
2872
- borderStop2: Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER),
2873
- borderOpacities: [ GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH, GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW, GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH ],
2874
- hoverPositions: {
2875
- hover1: {
2876
- x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
2877
- y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
2878
- },
2879
- hover2: {
2880
- x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
2881
- y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2
2882
- },
2883
- hover3: {
2884
- x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
2885
- y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3
2886
- }
2887
- },
2888
- basePosition: {
2889
- x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
2890
- y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
2891
- },
2892
- mx: mx,
2893
- my: my,
2894
- absMx: absMx,
2895
- absMy: absMy
2896
- };
2897
- }), [ mouseOffset.x, mouseOffset.y ]), clampedOverLightOpacity = Math.max(0, Math.min(1, overLightConfig?.opacity ?? .4)), clampedBorderOpacity = Math.max(0, Math.min(1, overLightConfig?.borderOpacity ?? 1)), opacityValues = useMemo((() => ({
2898
- hover1: isHovered || isActive ? .5 : 0,
2899
- hover2: isActive ? .5 : 0,
2900
- hover3: isHovered ? .4 : isActive ? .8 : 0,
2901
- base: isOverLight ? clampedOverLightOpacity || .4 : 0,
2902
- over: isOverLight ? 1.1 * (clampedOverLightOpacity || .4) : 0
2903
- })), [ isHovered, isActive, isOverLight, clampedOverLightOpacity ]), glassVars = useMemo((() => {
2904
- const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues;
2639
+ }
2640
+ /**
2641
+ * Builds the CSS custom properties applied to the root `.c-atomix-glass` element.
2642
+ *
2643
+ * These variables drive layer geometry, transforms, and stacking offsets. They
2644
+ * must not include layout properties that would interfere with backdrop-filter.
2645
+ */ ({
2646
+ width: width,
2647
+ height: height,
2648
+ restStyle: restStyle,
2649
+ glassSize: glassSize,
2650
+ isFixedOrSticky: isFixedOrSticky
2651
+ })), [ width, height, restStyle, glassSize, isFixedOrSticky ]), glassVars = useMemo((() => function(input) {
2652
+ const {effectiveBorderRadius: effectiveBorderRadius, transformStyle: transformStyle, adjustedSize: adjustedSize, isOverLight: isOverLight, customZIndex: customZIndex, isFixedOrSticky: isFixedOrSticky, positionStyles: positionStyles, restStyle: restStyle, borderWidth: borderWidth = ATOMIX_GLASS.BORDER.DEFAULT_WIDTH} = input, layerPosition =
2653
+ /**
2654
+ * Resolves the `--atomix-glass-position` value for decorative layers.
2655
+ *
2656
+ * Fixed/sticky layers use the same positioning mode as the container; in-flow
2657
+ * layers default to the internal absolute positioning context.
2658
+ */
2659
+ function(isFixedOrSticky, positionStyles, restStyle) {
2660
+ return isFixedOrSticky ? `${function(style) {
2661
+ const {position: position, top: top, left: left, right: right, bottom: bottom, inset: inset} = style;
2662
+ return {
2663
+ ...null != position && {
2664
+ position: position
2665
+ },
2666
+ ...void 0 !== top && {
2667
+ top: top
2668
+ },
2669
+ ...void 0 !== left && {
2670
+ left: left
2671
+ },
2672
+ ...void 0 !== right && {
2673
+ right: right
2674
+ },
2675
+ ...void 0 !== bottom && {
2676
+ bottom: bottom
2677
+ },
2678
+ ...void 0 !== inset && {
2679
+ inset: inset
2680
+ }
2681
+ };
2682
+ }
2683
+ /**
2684
+ * Resolves inset custom properties for decorative layers (hover, borders, backgrounds).
2685
+ *
2686
+ * For fixed and sticky modes, insets mirror the container so sibling layers remain
2687
+ * aligned. In-flow modes, insets follow the consumer `style` when a non-default
2688
+ * `position` is provided.
2689
+ */ (restStyle).position ?? restStyle.position ?? "fixed"}` : `${positionStyles.position}`;
2690
+ }(isFixedOrSticky, positionStyles, restStyle), layerInsets = function(isFixedOrSticky, restStyle) {
2691
+ if (isFixedOrSticky) return {
2692
+ top: formatGlassInsetValue(restStyle.top, 0),
2693
+ left: formatGlassInsetValue(restStyle.left, 0),
2694
+ right: formatGlassInsetValue(restStyle.right, "auto"),
2695
+ bottom: formatGlassInsetValue(restStyle.bottom, "auto")
2696
+ };
2697
+ const position = restStyle.position;
2698
+ return null != position && "static" !== position && "relative" !== position ? {
2699
+ top: formatGlassInsetValue(restStyle.top, 0),
2700
+ left: formatGlassInsetValue(restStyle.left, 0),
2701
+ right: formatGlassInsetValue(restStyle.right, "auto"),
2702
+ bottom: formatGlassInsetValue(restStyle.bottom, "auto")
2703
+ } : {
2704
+ top: "0px",
2705
+ left: "0px",
2706
+ right: "auto",
2707
+ bottom: "auto"
2708
+ };
2709
+ }(isFixedOrSticky, restStyle);
2905
2710
  return {
2906
2711
  ...void 0 !== customZIndex && {
2907
2712
  "--atomix-glass-base-z-index": customZIndex
2908
2713
  },
2909
2714
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
2910
2715
  "--atomix-glass-transform": transformStyle || "none",
2911
- "--atomix-glass-container-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
2912
- "--atomix-glass-position": `${isFixedOrSticky ? rootLayoutStyle.position : positionStyles.position}`,
2913
- "--atomix-glass-top": `${isFixedOrSticky ? restStyle.top ?? 0 : 0}px`,
2914
- "--atomix-glass-left": `${isFixedOrSticky ? restStyle.left ?? 0 : 0}px`,
2915
- "--atomix-glass-right": isFixedOrSticky ? restStyle.right ?? "auto" : "auto",
2916
- "--atomix-glass-bottom": isFixedOrSticky ? restStyle.bottom ?? "auto" : "auto",
2716
+ "--atomix-glass-container-position": layerPosition,
2717
+ "--atomix-glass-position": layerPosition,
2718
+ "--atomix-glass-top": layerInsets.top,
2719
+ "--atomix-glass-left": layerInsets.left,
2720
+ "--atomix-glass-right": layerInsets.right,
2721
+ "--atomix-glass-bottom": layerInsets.bottom,
2917
2722
  "--atomix-glass-width": adjustedSize.width,
2918
2723
  "--atomix-glass-height": adjustedSize.height,
2919
- "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.125rem)",
2920
- "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
2921
- "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2922
- "--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * clampedBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * clampedBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
2923
- "--atomix-glass-hover-1-opacity": opacityValues.hover1,
2924
- "--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`,
2925
- "--atomix-glass-hover-2-opacity": opacityValues.hover2,
2926
- "--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`,
2927
- "--atomix-glass-hover-3-opacity": opacityValues.hover3,
2928
- "--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`,
2929
- "--atomix-glass-base-opacity": opacityValues.base,
2930
- "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
2931
- "--atomix-glass-overlay-opacity": opacityValues.over,
2932
- "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`,
2933
- "--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
2934
- "--atomix-glass-overlay-highlight-bg": `radial-gradient(circle at ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_X}% ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.POSITION_Y}%, rgba(255, 255, 255, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.WHITE_OPACITY}) 0%, transparent ${ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.STOP}%)`
2724
+ // Aliases maintained for backward compatibility and consumer overrides.
2725
+ "--atomix-glass-container-width": adjustedSize.width,
2726
+ "--atomix-glass-container-height": adjustedSize.height,
2727
+ [ATOMIX_GLASS.BORDER.WIDTH_CSS_VAR]: borderWidth,
2728
+ "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay"
2729
+ };
2730
+ }
2731
+ /**
2732
+ * Applies mode-specific multipliers and accessibility overrides to container effects.
2733
+ */ ({
2734
+ effectiveBorderRadius: effectiveBorderRadius,
2735
+ transformStyle: transformStyle,
2736
+ adjustedSize: adjustedSize,
2737
+ isOverLight: isOverLight,
2738
+ customZIndex: customZIndex,
2739
+ isFixedOrSticky: isFixedOrSticky,
2740
+ positionStyles: positionStyles,
2741
+ restStyle: restStyle,
2742
+ borderWidth: resolvedBorder.width
2743
+ })), [ effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, customZIndex, isFixedOrSticky, positionStyles, restStyle, resolvedBorder.width ]), containerEffects = useMemo((() => function(options) {
2744
+ const {MULTIPLIERS: MULTIPLIERS, SATURATION: SATURATION} = ATOMIX_GLASS.CONSTANTS, zeroMouse = {
2745
+ x: 0,
2746
+ y: 0
2747
+ }, resolveSaturation = () => options.effectiveHighContrast ? SATURATION.HIGH_CONTRAST : options.isOverLight ? options.saturation * options.saturationBoost : options.saturation;
2748
+ if (options.effectiveWithoutEffects) return {
2749
+ displacementScale: 0,
2750
+ blurAmount: 0,
2751
+ saturation: resolveSaturation(),
2752
+ aberrationIntensity: 0,
2753
+ mouseOffset: zeroMouse,
2754
+ globalMousePosition: zeroMouse
2935
2755
  };
2936
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, clampedBorderOpacity, customZIndex, isFixedOrSticky, positionStyles.position, rootLayoutStyle.position, restStyle.top, restStyle.left, restStyle.right, restStyle.bottom ]), renderBackgroundLayer = layerType => jsx("div", {
2937
- className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" ")
2756
+ let resolvedDisplacement = options.displacementScale;
2757
+ "shader" === options.mode ? resolvedDisplacement *= MULTIPLIERS.SHADER_DISPLACEMENT : options.isOverLight && (resolvedDisplacement *= MULTIPLIERS.OVER_LIGHT_DISPLACEMENT);
2758
+ let resolvedAberration = options.aberrationIntensity;
2759
+ return "shader" === options.mode && (resolvedAberration *= MULTIPLIERS.SHADER_ABERRATION),
2760
+ {
2761
+ displacementScale: resolvedDisplacement,
2762
+ blurAmount: options.blurAmount,
2763
+ saturation: resolveSaturation(),
2764
+ aberrationIntensity: resolvedAberration,
2765
+ mouseOffset: options.mouseOffset,
2766
+ globalMousePosition: options.globalMousePosition
2767
+ };
2768
+ }({
2769
+ displacementScale: displacementScale,
2770
+ blurAmount: blurAmount,
2771
+ saturation: saturation,
2772
+ aberrationIntensity: aberrationIntensity,
2773
+ mode: mode,
2774
+ effectiveWithoutEffects: effectiveWithoutEffects,
2775
+ effectiveHighContrast: effectiveHighContrast,
2776
+ isOverLight: isOverLight,
2777
+ saturationBoost: overLightConfig.saturationBoost,
2778
+ mouseOffset: mouseOffset,
2779
+ globalMousePosition: globalMousePosition
2780
+ })), [ displacementScale, blurAmount, saturation, aberrationIntensity, mode, effectiveWithoutEffects, effectiveHighContrast, isOverLight, overLightConfig.saturationBoost, mouseOffset, globalMousePosition ]), renderBackgroundLayer = layerType => jsx("div", {
2781
+ "aria-hidden": "true",
2782
+ className: mergeClassNames(ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS)
2938
2783
  });
2939
- // Calculate position and size styles for internal layers
2940
- // When root is fixed/sticky, internal layers use absolute (relative to root)
2941
- return jsxs("div", {
2784
+ return jsxs("div", {
2942
2785
  ...rest,
2943
2786
  ref: mergedRef,
2944
2787
  className: componentClassName,
2945
- style: {
2946
- ...glassVars
2947
- },
2788
+ style: glassVars,
2948
2789
  role: role || (onClick ? "button" : void 0),
2949
2790
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
2950
2791
  "aria-label": ariaLabel,
2951
2792
  "aria-describedby": ariaDescribedBy,
2952
2793
  "aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
2953
- "aria-pressed": onClick ? isActive : void 0,
2954
2794
  onKeyDown: onClick ? handleKeyDown : void 0,
2955
2795
  children: [ jsx(AtomixGlassContainer, {
2956
2796
  ref: glassRef,
2957
2797
  contentRef: contentRef,
2958
2798
  className: className,
2959
- style: {
2960
- ...restStyle
2961
- },
2799
+ style: containerStyle,
2962
2800
  borderRadius: effectiveBorderRadius,
2963
- displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
2964
- blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
2965
- saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
2966
- aberrationIntensity: effectiveWithoutEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
2801
+ displacementScale: containerEffects.displacementScale,
2802
+ blurAmount: containerEffects.blurAmount,
2803
+ saturation: containerEffects.saturation,
2804
+ aberrationIntensity: containerEffects.aberrationIntensity,
2967
2805
  glassSize: glassSize,
2968
- padding: padding,
2969
- mouseOffset: effectiveWithoutEffects ? {
2970
- x: 0,
2971
- y: 0
2972
- } : mouseOffset,
2973
- globalMousePosition: effectiveWithoutEffects ? {
2974
- x: 0,
2975
- y: 0
2976
- } : globalMousePosition,
2806
+ mouseOffset: containerEffects.mouseOffset,
2807
+ globalMousePosition: containerEffects.globalMousePosition,
2977
2808
  onMouseEnter: handleMouseEnter,
2978
2809
  onMouseLeave: handleMouseLeave,
2979
2810
  onMouseDown: handleMouseDown,
2980
2811
  onMouseUp: handleMouseUp,
2981
- isHovered: isHovered,
2982
2812
  isActive: isActive,
2983
2813
  overLight: isOverLight,
2984
2814
  overLightConfig: {
@@ -2994,8 +2824,6 @@ const PERFORMANCE_PRESET = {
2994
2824
  shaderVariant: shaderVariant,
2995
2825
  withLiquidBlur: withLiquidBlur,
2996
2826
  isFixedOrSticky: isFixedOrSticky,
2997
- // Phase 1: Animation System props
2998
- shaderTime: getShaderTime(),
2999
2827
  withTimeAnimation: withTimeAnimation,
3000
2828
  animationSpeed: animationSpeed,
3001
2829
  withMultiLayerDistortion: withMultiLayerDistortion,
@@ -3006,32 +2834,39 @@ const PERFORMANCE_PRESET = {
3006
2834
  children: children
3007
2835
  }), Boolean(onClick) && jsxs(Fragment, {
3008
2836
  children: [ jsx("div", {
2837
+ "aria-hidden": "true",
3009
2838
  className: ATOMIX_GLASS.HOVER_1_CLASS
3010
2839
  }), jsx("div", {
2840
+ "aria-hidden": "true",
3011
2841
  className: ATOMIX_GLASS.HOVER_2_CLASS
3012
2842
  }), jsx("div", {
2843
+ "aria-hidden": "true",
3013
2844
  className: ATOMIX_GLASS.HOVER_3_CLASS
3014
2845
  }) ]
3015
- }), renderBackgroundLayer("dark"), renderBackgroundLayer("black"), shouldRenderOverLightLayers && jsxs(Fragment, {
2846
+ }), [ "dark", "black" ].map((layerType => jsx(React.Fragment, {
2847
+ children: renderBackgroundLayer(layerType)
2848
+ }, layerType))), shouldRenderOverLightLayers && jsxs(Fragment, {
3016
2849
  children: [ jsx("div", {
2850
+ "aria-hidden": "true",
3017
2851
  className: ATOMIX_GLASS.BASE_LAYER_CLASS
3018
2852
  }), jsx("div", {
2853
+ "aria-hidden": "true",
3019
2854
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
3020
2855
  }), jsx("div", {
2856
+ "aria-hidden": "true",
3021
2857
  className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
3022
2858
  }) ]
3023
- }), withBorder && jsxs(Fragment, {
2859
+ }), resolvedBorder.enabled && jsxs(Fragment, {
3024
2860
  children: [ jsx("span", {
2861
+ "aria-hidden": "true",
3025
2862
  className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
3026
2863
  }), jsx("span", {
2864
+ "aria-hidden": "true",
3027
2865
  className: ATOMIX_GLASS.BORDER_1_CLASS
3028
2866
  }), jsx("span", {
2867
+ "aria-hidden": "true",
3029
2868
  className: ATOMIX_GLASS.BORDER_2_CLASS
3030
2869
  }) ]
3031
- }), debugPerformance && performanceMetrics && jsx(PerformanceDashboard, {
3032
- metrics: performanceMetrics,
3033
- isVisible: !0,
3034
- onClose: () => {}
3035
2870
  }) ]
3036
2871
  });
3037
2872
  }));
@@ -3041,10 +2876,7 @@ const PERFORMANCE_PRESET = {
3041
2876
  * Default preset for most mobile devices
3042
2877
  */ AtomixGlassInner.displayName = "AtomixGlass";
3043
2878
 
3044
- /**
3045
- * AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
3046
- * Ref is forwarded to the root `<div>` element.
3047
- */
2879
+ /** Memoized public export. Ref targets the root `.c-atomix-glass` wrapper. */
3048
2880
  const AtomixGlass = memo(AtomixGlassInner), Checkbox = React.memo( forwardRef((({label: label, checked: checked, onChange: onChange, className: className = "", style: style, disabled: disabled = !1, required: required = !1, id: id, name: name, value: value, invalid: invalid = !1, valid: valid = !1, indeterminate: indeterminate = !1, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, onClick: onClick, glass: glass, ...props}, ref) => {
3049
2881
  // Local ref to handle indeterminate state
3050
2882
  const localRef = useRef(null);
@@ -3095,14 +2927,7 @@ const AtomixGlass = memo(AtomixGlassInner), Checkbox = React.memo( forwardRef(
3095
2927
  style: style,
3096
2928
  children: inputElement
3097
2929
  }), glass) {
3098
- const defaultGlassProps = {
3099
- displacementScale: 40,
3100
- blurAmount: 1,
3101
- saturation: 160,
3102
- aberrationIntensity: .3,
3103
- borderRadius: 6,
3104
- mode: "shader"
3105
- }, glassProps = !0 === glass ? defaultGlassProps : {
2930
+ const defaultGlassProps = GLASS_DEFAULTS_CHECKBOX, glassProps = !0 === glass ? defaultGlassProps : {
3106
2931
  ...defaultGlassProps,
3107
2932
  ...glass
3108
2933
  };
@@ -3313,15 +3138,7 @@ const Input = memo( forwardRef((({type: type = "text", value: value, defaultVal
3313
3138
  } : style
3314
3139
  });
3315
3140
  if (glass) {
3316
- // Default glass settings for inputs
3317
- const defaultGlassProps = {
3318
- displacementScale: 60,
3319
- blurAmount: 1,
3320
- saturation: 180,
3321
- aberrationIntensity: .2,
3322
- borderRadius: 12,
3323
- mode: "shader"
3324
- }, glassProps = !0 === glass ? defaultGlassProps : {
3141
+ const defaultGlassProps = GLASS_DEFAULTS_INPUT, glassProps = !0 === glass ? defaultGlassProps : {
3325
3142
  ...defaultGlassProps,
3326
3143
  ...glass
3327
3144
  };
@@ -3398,15 +3215,7 @@ const Radio = memo((({label: label, checked: checked = !1, onChange: onChange,
3398
3215
  }) ]
3399
3216
  });
3400
3217
  if (glass) {
3401
- // Default glass settings for radio buttons
3402
- const defaultGlassProps = {
3403
- displacementScale: 40,
3404
- blurAmount: 1,
3405
- saturation: 160,
3406
- aberrationIntensity: .3,
3407
- borderRadius: 6,
3408
- mode: "shader"
3409
- }, glassProps = !0 === glass ? defaultGlassProps : {
3218
+ const defaultGlassProps = GLASS_DEFAULTS_RADIO, glassProps = !0 === glass ? defaultGlassProps : {
3410
3219
  ...defaultGlassProps,
3411
3220
  ...glass
3412
3221
  };
@@ -3724,12 +3533,7 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
3724
3533
  });
3725
3534
  // Handle item selection
3726
3535
  if (glass) {
3727
- // Default glass settings for select components
3728
- const defaultGlassProps = {
3729
- displacementScale: 60,
3730
- blurAmount: 10,
3731
- mode: "shader"
3732
- }, glassProps = !0 === glass ? defaultGlassProps : {
3536
+ const defaultGlassProps = GLASS_DEFAULTS_SELECT, glassProps = !0 === glass ? defaultGlassProps : {
3733
3537
  ...defaultGlassProps,
3734
3538
  ...glass
3735
3539
  };
@@ -3809,15 +3613,7 @@ const Textarea = memo( forwardRef((({value: value, defaultValue: defaultValue,
3809
3613
  } : style
3810
3614
  });
3811
3615
  if (glass) {
3812
- // Default glass settings for textareas
3813
- const defaultGlassProps = {
3814
- displacementScale: 60,
3815
- blurAmount: 1,
3816
- saturation: 180,
3817
- aberrationIntensity: 1,
3818
- borderRadius: 8,
3819
- mode: "shader"
3820
- }, glassProps = !0 === glass ? defaultGlassProps : {
3616
+ const defaultGlassProps = GLASS_DEFAULTS_TEXTAREA, glassProps = !0 === glass ? defaultGlassProps : {
3821
3617
  ...defaultGlassProps,
3822
3618
  ...glass
3823
3619
  };
@@ -3833,40 +3629,15 @@ Textarea.displayName = "Textarea";
3833
3629
 
3834
3630
  // Adapted from https://github.com/shuding/liquid-glass
3835
3631
  // Constants
3836
- const smoothStep = (a, b, t) => {
3837
- // Add input validation
3838
- if ("number" != typeof a || "number" != typeof b || "number" != typeof t) return 0;
3839
- const clamped = Math.max(0, Math.min(1, (t - a) / (b - a)));
3840
- return clamped * clamped * (3 - 2 * clamped);
3841
- }, calculateLength = (x, y) => {
3842
- // Add input validation and error handling
3843
- if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
3844
- // Prevent potential overflow
3845
- const maxX = Math.max(Math.abs(x), Math.abs(y));
3846
- if (0 === maxX) return 0;
3847
- const scaledX = x / maxX, scaledY = y / maxX;
3848
- return maxX * Math.sqrt(scaledX * scaledX + scaledY * scaledY);
3849
- }, roundedRectSDF = (x, y, width, height, radius) => {
3632
+ const roundedRectSDF = (x, y, width, height, radius) => {
3850
3633
  // Add input validation
3851
3634
  if ("number" != typeof x || "number" != typeof y || "number" != typeof width || "number" != typeof height || "number" != typeof radius) return 0;
3852
3635
  const qx = Math.abs(x) - width + radius, qy = Math.abs(y) - height + radius;
3853
- return Math.min(Math.max(qx, qy), 0) + calculateLength(Math.max(qx, 0), Math.max(qy, 0)) - radius;
3636
+ return Math.min(Math.max(qx, qy), 0) + vec2Length(Math.max(qx, 0), Math.max(qy, 0)) - radius;
3854
3637
  }, createTexture = (x, y) => ({
3855
3638
  x: "number" != typeof x || isNaN(x) ? .5 : Math.max(0, Math.min(1, x)),
3856
3639
  y: "number" != typeof y || isNaN(y) ? .5 : Math.max(0, Math.min(1, y))
3857
- }), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), clampValue = (value, min, max) =>
3858
- // Add input validation
3859
- "number" != typeof value || "number" != typeof min || "number" != typeof max || isNaN(value) ? min : isNaN(min) ? 0 : isNaN(max) ? 1 : Math.max(min, Math.min(max, value)), easeInOutCubic = t => {
3860
- // Add input validation
3861
- if ("number" != typeof t || isNaN(t)) return 0;
3862
- const clampedT = Math.max(0, Math.min(1, t));
3863
- return clampedT < .5 ? 4 * clampedT * clampedT * clampedT : 1 - Math.pow(-2 * clampedT + 2, 3) / 2;
3864
- }, easeOutQuart = t => {
3865
- // Add input validation
3866
- if ("number" != typeof t || isNaN(t)) return 0;
3867
- const clampedT = Math.max(0, Math.min(1, t));
3868
- return 1 - Math.pow(1 - clampedT, 4);
3869
- }, noise2D = (x, y) => {
3640
+ }), validateVec2 = vec => vec && "number" == typeof vec.x && "number" == typeof vec.y && !isNaN(vec.x) && !isNaN(vec.y), noise2D = (x, y) => {
3870
3641
  // Add input validation
3871
3642
  if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y)) return 0;
3872
3643
  const X = 255 & Math.floor(x), Y = 255 & Math.floor(y), xf = x - Math.floor(x), yf = y - Math.floor(y), u = easeInOutCubic(xf), v = easeInOutCubic(yf), hash = (i, j) => {
@@ -3905,13 +3676,13 @@ const smoothStep = (a, b, t) => {
3905
3676
  x: .5,
3906
3677
  y: .5
3907
3678
  };
3908
- const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(2 * mouseDistance, 1)), organicFlow = fbm(12 * (ix + .5 * mouseX) + time, 12 * (iy + .5 * mouseY) + .7 * time, 3) - .5, distanceToEdge = roundedRectSDF(ix, iy, .4, .3, .35), baseDisplacement = smoothStep(.8, 0, distanceToEdge - .05), radialDist = ((x, y, strength) => {
3679
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now(), mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(2 * mouseDistance, 1)), organicFlow = fbm(12 * (ix + .5 * mouseX) + time, 12 * (iy + .5 * mouseY) + .7 * time, 3) - .5, distanceToEdge = roundedRectSDF(ix, iy, .4, .3, .35), baseDisplacement = smoothstepEdge(.8, 0, distanceToEdge - .05), radialDist = ((x, y, strength) => {
3909
3680
  // Add input validation
3910
3681
  if ("number" != typeof x || "number" != typeof y || isNaN(x) || isNaN(y) || isNaN(strength)) return {
3911
3682
  x: 0,
3912
3683
  y: 0
3913
3684
  };
3914
- const distance = calculateLength(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
3685
+ const distance = vec2Length(x, y), distortion = Math.pow(Math.min(distance, 10), 2) * strength;
3915
3686
  // Limit distance to prevent extreme values
3916
3687
  return {
3917
3688
  x: x * (1 + distortion),
@@ -3923,7 +3694,7 @@ const smoothStep = (a, b, t) => {
3923
3694
  x: 0,
3924
3695
  y: 0
3925
3696
  };
3926
- const distance = calculateLength(x, y);
3697
+ const distance = vec2Length(x, y);
3927
3698
  // Prevent division by zero and extreme values
3928
3699
  if (0 === distance) return {
3929
3700
  x: 0,
@@ -3934,8 +3705,8 @@ const smoothStep = (a, b, t) => {
3934
3705
  x: Math.cos(angle) * distance * intensity,
3935
3706
  y: Math.sin(angle) * distance * intensity
3936
3707
  };
3937
- })(ix, iy, .015 * baseDisplacement), scaled = smoothStep(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
3938
- return createTexture(clampValue(finalX * scaled + .5, 0, 1), clampValue(finalY * scaled + .5, 0, 1));
3708
+ })(ix, iy, .015 * baseDisplacement), scaled = smoothstepEdge(0, 1, 1.15 * baseDisplacement), finalX = ix + totalDistortionX + .5 * chromaticOffset.x, finalY = iy + totalDistortionY + .5 * chromaticOffset.y;
3709
+ return createTexture(clamp(finalX * scaled + .5, 0, 1), clamp(finalY * scaled + .5, 0, 1));
3939
3710
  },
3940
3711
  // Premium Apple-style fluid glass with enhanced organic flow
3941
3712
  appleFluid: (uv, mousePosition) => {
@@ -3943,8 +3714,8 @@ const smoothStep = (a, b, t) => {
3943
3714
  x: .5,
3944
3715
  y: .5
3945
3716
  };
3946
- const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.5 * mouseDistance, 1)), organicX = fbm(10 * (ix + .3 * mouseX) + time, 10 * (iy + .3 * mouseY), 5) - .5, organicY = fbm(10 * (ix - .3 * mouseX), 10 * (iy - .3 * mouseY) + .8 * time, 5) - .5, distanceToEdge = roundedRectSDF(ix, iy, .42, .32, .38), mask = smoothStep(.85, -.1, distanceToEdge), fluidVelocityX = Math.sin(6 * ix + 2 * time) * Math.cos(4 * iy - time) * .025, fluidVelocityY = Math.cos(4 * ix - time) * Math.sin(6 * iy + 2 * time) * .025, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexStrength = mouseFalloff * mouseDistance * .08, vortexX = Math.cos(vortexAngle + time) * vortexStrength, totalY = iy + (.035 * organicY + fluidVelocityY + Math.sin(vortexAngle + time) * vortexStrength) * mask;
3947
- return createTexture(clampValue(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clampValue(totalY + .5, 0, 1));
3717
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .6, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.5 * mouseDistance, 1)), organicX = fbm(10 * (ix + .3 * mouseX) + time, 10 * (iy + .3 * mouseY), 5) - .5, organicY = fbm(10 * (ix - .3 * mouseX), 10 * (iy - .3 * mouseY) + .8 * time, 5) - .5, distanceToEdge = roundedRectSDF(ix, iy, .42, .32, .38), mask = smoothstepEdge(.85, -.1, distanceToEdge), fluidVelocityX = Math.sin(6 * ix + 2 * time) * Math.cos(4 * iy - time) * .025, fluidVelocityY = Math.cos(4 * ix - time) * Math.sin(6 * iy + 2 * time) * .025, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexStrength = mouseFalloff * mouseDistance * .08, vortexX = Math.cos(vortexAngle + time) * vortexStrength, totalY = iy + (.035 * organicY + fluidVelocityY + Math.sin(vortexAngle + time) * vortexStrength) * mask;
3718
+ return createTexture(clamp(ix + (.035 * organicX + fluidVelocityX + vortexX) * mask + .5, 0, 1), clamp(totalY + .5, 0, 1));
3948
3719
  },
3949
3720
  // High-end glass with advanced refraction and depth
3950
3721
  premiumGlass: (uv, mousePosition) => {
@@ -3952,7 +3723,7 @@ const smoothStep = (a, b, t) => {
3952
3723
  x: .5,
3953
3724
  y: .5
3954
3725
  };
3955
- const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), centerDistance = calculateLength(ix, iy), refractionStrength = .3 * Math.pow(Math.min(centerDistance, 1), 1.5), refractionAngle = Math.atan2(iy, ix);
3726
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .4, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), centerDistance = vec2Length(ix, iy), refractionStrength = .3 * Math.pow(Math.min(centerDistance, 1), 1.5), refractionAngle = Math.atan2(iy, ix);
3956
3727
  // Multi-layer depth effect
3957
3728
  let depthX = 0, depthY = 0;
3958
3729
  for (let layer = 0; layer < 3; layer++) {
@@ -3960,8 +3731,8 @@ const smoothStep = (a, b, t) => {
3960
3731
  depthX += Math.sin(ix * layerScale + layerTime) * layerStrength, depthY += Math.cos(iy * layerScale - layerTime) * layerStrength;
3961
3732
  }
3962
3733
  // Glass refraction with mouse influence
3963
- const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask = smoothStep(.9, -.05, distanceToEdge), finalY = iy + (refractionY + depthY + .015 * organicNoise) * edgeMask;
3964
- return createTexture(clampValue(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clampValue(finalY + .5, 0, 1));
3734
+ const refractionX = Math.cos(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), refractionY = Math.sin(refractionAngle) * refractionStrength * (1 + .5 * mouseDistance), organicNoise = fbm(8 * ix + time, 8 * iy - time, 2) - .5, distanceToEdge = roundedRectSDF(ix, iy, .43, .33, .36), edgeMask = smoothstepEdge(.9, -.05, distanceToEdge), finalY = iy + (refractionY + depthY + .015 * organicNoise) * edgeMask;
3735
+ return createTexture(clamp(ix + (refractionX + depthX + .015 * organicNoise) * edgeMask + .5, 0, 1), clamp(finalY + .5, 0, 1));
3965
3736
  },
3966
3737
  // Metallic liquid effect with shimmer
3967
3738
  liquidMetal: (uv, mousePosition) => {
@@ -3969,8 +3740,8 @@ const smoothStep = (a, b, t) => {
3969
3740
  x: .5,
3970
3741
  y: .5
3971
3742
  };
3972
- const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance = calculateLength(ix - mouseX, iy - mouseY), flowEffect = .02 * Math.sin(15 * flowDistance - 6 * time) * easeOutQuart(1 - Math.min(2 * flowDistance, 1)), distanceToEdge = roundedRectSDF(ix, iy, .41, .31, .37), mask = smoothStep(.88, -.08, distanceToEdge), totalX = ix + (wave1 + shimmer + Math.cos(flowAngle) * flowEffect) * mask, totalY = iy + (wave2 + .8 * shimmer + Math.sin(flowAngle) * flowEffect) * mask;
3973
- return createTexture(clampValue(totalX + .5, 0, 1), clampValue(totalY + .5, 0, 1));
3743
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * 1.2, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, wave1 = Math.sin(20 * ix + 4 * time) * Math.cos(15 * iy - 3 * time) * .02, wave2 = Math.cos(15 * ix - 2 * time) * Math.sin(20 * iy + 5 * time) * .015, shimmer = .025 * fbm(25 * ix + 2 * time, 25 * iy - 2 * time, 4), flowAngle = Math.atan2(iy - mouseY, ix - mouseX), flowDistance = vec2Length(ix - mouseX, iy - mouseY), flowEffect = .02 * Math.sin(15 * flowDistance - 6 * time) * easeOutQuart(1 - Math.min(2 * flowDistance, 1)), distanceToEdge = roundedRectSDF(ix, iy, .41, .31, .37), mask = smoothstepEdge(.88, -.08, distanceToEdge), totalX = ix + (wave1 + shimmer + Math.cos(flowAngle) * flowEffect) * mask, totalY = iy + (wave2 + .8 * shimmer + Math.sin(flowAngle) * flowEffect) * mask;
3744
+ return createTexture(clamp(totalX + .5, 0, 1), clamp(totalY + .5, 0, 1));
3974
3745
  },
3975
3746
  // basiBasi - Expert Premium Glass Shader
3976
3747
  // The most advanced shader with caustics, spectral dispersion, parallax depth, and volumetric effects
@@ -3979,7 +3750,7 @@ const smoothStep = (a, b, t) => {
3979
3750
  x: .5,
3980
3751
  y: .5
3981
3752
  };
3982
- const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = calculateLength(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.2 * mouseDistance, 1)), causticIntensity = ((x, y, time, intensity = 1) =>
3753
+ const ix = uv.x - .5, iy = uv.y - .5, time = 8e-4 * Date.now() * .5, mouseX = mousePosition && validateVec2(mousePosition) ? mousePosition.x - .5 : 0, mouseY = mousePosition && validateVec2(mousePosition) ? mousePosition.y - .5 : 0, mouseDistance = vec2Length(mouseX, mouseY), mouseFalloff = easeOutQuart(1 - Math.min(1.2 * mouseDistance, 1)), causticIntensity = ((x, y, time, intensity = 1) =>
3983
3754
  // Add input validation
3984
3755
  "number" != typeof x || "number" != typeof y || "number" != typeof time || "number" != typeof intensity || isNaN(x) || isNaN(y) || isNaN(time) || isNaN(intensity) ? .5 : .5 * (Math.sin(8 * x + 2 * time) * Math.cos(8 * y - 2 * time) * .5 + Math.sin(8 * (x + .5) * 1.3 - 2 * time * .8) * Math.cos(8 * (y - .3) * 1.3 + 2 * time * .8) * .3 + Math.sin(8 * (x - .3) * .7 + 2 * time * 1.2) * Math.cos(8 * (y + .4) * .7 - 2 * time * 1.2) * .2 + 1) * intensity)(ix, iy, time, .8), causticDistortion = .02 * (causticIntensity - .5), refractionAngle = Math.atan2(iy, ix), spectralDispersion = ((x, y, angle) => {
3985
3756
  // Add input validation
@@ -3997,7 +3768,7 @@ const smoothStep = (a, b, t) => {
3997
3768
  y: 0
3998
3769
  }
3999
3770
  };
4000
- const distance = calculateLength(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
3771
+ const distance = vec2Length(x, y), dispersionStrength = Math.min(.025 * distance, 1), redOffset = .8 * dispersionStrength, greenOffset = 1 * dispersionStrength, blueOffset = 1.2 * dispersionStrength;
4001
3772
  return {
4002
3773
  r: {
4003
3774
  x: Math.cos(angle) * redOffset,
@@ -4037,8 +3808,8 @@ const smoothStep = (a, b, t) => {
4037
3808
  return turbulence;
4038
3809
  })(6 * ix, 6 * iy, time, 6), turbulenceX = .012 * Math.cos(turbulence * Math.PI * 2), turbulenceY = .012 * Math.sin(turbulence * Math.PI * 2), microSurface = ((x, y, time) =>
4039
3810
  // Add input validation
4040
- "number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = calculateLength(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = calculateLength(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothStep(.92, -.12, distanceToEdge), edgeSoftness = smoothStep(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
4041
- return createTexture(clampValue(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clampValue(finalY + .5, 0, 1));
3811
+ "number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = vec2Length(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = vec2Length(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothstepEdge(.92, -.12, distanceToEdge), edgeSoftness = smoothstepEdge(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
3812
+ return createTexture(clamp(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clamp(finalY + .5, 0, 1));
4042
3813
  },
4043
3814
  // Aliases for compatibility
4044
3815
  plasma: (uv, mousePosition) => fragmentShaders.premiumGlass(uv, mousePosition),
@@ -4080,8 +3851,8 @@ const smoothStep = (a, b, t) => {
4080
3851
  let dx = pos.x * w - x, dy = pos.y * h - y;
4081
3852
  // Apply edge smoothing for Apple-like effect
4082
3853
  const edgeX = 2 * Math.min(x / w, (w - x) / w), edgeY = 2 * Math.min(y / h, (h - y) / h), edgeFactor = Math.min(edgeX, edgeY);
4083
- dx *= smoothStep(0, .2, edgeFactor), dy *= smoothStep(0, .2, edgeFactor), maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)),
4084
- rawValues.push(dx, dy);
3854
+ dx *= smoothstepEdge(0, .2, edgeFactor), dy *= smoothstepEdge(0, .2, edgeFactor),
3855
+ maxScale = Math.max(maxScale, Math.abs(dx), Math.abs(dy)), rawValues.push(dx, dy);
4085
3856
  }
4086
3857
  // Improved normalization to prevent artifacts while maintaining intensity
4087
3858
  maxScale = Math.max(maxScale, 1);
@@ -4091,9 +3862,9 @@ const smoothStep = (a, b, t) => {
4091
3862
  let rawIndex = 0;
4092
3863
  for (let y = 0; y < h; y++) for (let x = 0; x < w; x++) {
4093
3864
  const dx = rawValues[rawIndex++] || 0, dy = rawValues[rawIndex++] || 0, edgeDistance = Math.min(x, y, w - x - 1, h - y - 1), edgeFactor = Math.min(1, edgeDistance / 2), r = dx * edgeFactor / maxScale + .5, g = dy * edgeFactor / maxScale + .5, pixelIndex = 4 * (y * w + x);
4094
- data[pixelIndex] = clampValue(255 * r, 0, 255), // Red channel (X displacement)
4095
- data[pixelIndex + 1] = clampValue(255 * g, 0, 255), // Green channel (Y displacement)
4096
- data[pixelIndex + 2] = clampValue(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
3865
+ data[pixelIndex] = clamp(255 * r, 0, 255), // Red channel (X displacement)
3866
+ data[pixelIndex + 1] = clamp(255 * g, 0, 255), // Green channel (Y displacement)
3867
+ data[pixelIndex + 2] = clamp(255 * g, 0, 255), // Blue channel (Y displacement for SVG filter compatibility)
4097
3868
  data[pixelIndex + 3] = 255;
4098
3869
  }
4099
3870
  return this.context.putImageData(imageData, 0, 0), this.canvas.toDataURL();
@@ -4121,9 +3892,7 @@ const smoothStep = (a, b, t) => {
4121
3892
  return this.canvasDPI;
4122
3893
  }
4123
3894
  },
4124
- createFBMEngine: createFBMEngine,
4125
- fragmentShaders: fragmentShaders,
4126
- liquidGlassWithTime: liquidGlassWithTime
3895
+ fragmentShaders: fragmentShaders
4127
3896
  }, Symbol.toStringTag, {
4128
3897
  value: "Module"
4129
3898
  }));