@shohojdhara/atomix 0.6.3 → 0.6.5

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 (77) hide show
  1. package/dist/atomix.css +119 -40
  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 +566 -597
  10. package/dist/charts.js.map +1 -1
  11. package/dist/core.d.ts +30 -1
  12. package/dist/core.js +600 -624
  13. package/dist/core.js.map +1 -1
  14. package/dist/forms.d.ts +30 -1
  15. package/dist/forms.js +1122 -1163
  16. package/dist/forms.js.map +1 -1
  17. package/dist/heavy.d.ts +31 -89
  18. package/dist/heavy.js +1015 -1045
  19. package/dist/heavy.js.map +1 -1
  20. package/dist/index.d.ts +378 -104
  21. package/dist/index.esm.js +10959 -10837
  22. package/dist/index.esm.js.map +1 -1
  23. package/dist/index.js +10935 -10812
  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 -355
  31. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +32 -249
  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 +411 -6
  38. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +158 -537
  39. package/src/components/AtomixGlass/stories/Border.stories.tsx +149 -0
  40. package/src/components/AtomixGlass/stories/Examples.stories.tsx +229 -89
  41. package/src/components/AtomixGlass/stories/Playground.stories.tsx +29 -340
  42. package/src/components/AtomixGlass/stories/argTypes.ts +30 -13
  43. package/src/components/AtomixGlass/stories/premium-presets.ts +206 -0
  44. package/src/components/AtomixGlass/stories/shared-components.tsx +52 -8
  45. package/src/components/Badge/Badge.tsx +4 -4
  46. package/src/components/Button/Button.tsx +2 -6
  47. package/src/components/Callout/Callout.test.tsx +4 -3
  48. package/src/components/Callout/Callout.tsx +2 -5
  49. package/src/components/Dropdown/Dropdown.tsx +3 -7
  50. package/src/components/Form/Checkbox.tsx +2 -8
  51. package/src/components/Form/Input.tsx +2 -9
  52. package/src/components/Form/Radio.tsx +2 -9
  53. package/src/components/Form/Select.tsx +2 -7
  54. package/src/components/Form/Textarea.tsx +2 -9
  55. package/src/components/Messages/Messages.tsx +2 -8
  56. package/src/components/Modal/Modal.tsx +4 -5
  57. package/src/components/Navigation/Nav/Nav.tsx +2 -6
  58. package/src/components/Navigation/Navbar/Navbar.tsx +2 -9
  59. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -6
  60. package/src/components/Pagination/Pagination.tsx +2 -10
  61. package/src/components/Popover/Popover.tsx +2 -9
  62. package/src/components/Progress/Progress.tsx +2 -7
  63. package/src/components/Rating/Rating.tsx +2 -10
  64. package/src/components/Spinner/Spinner.tsx +2 -7
  65. package/src/components/Steps/Steps.tsx +2 -10
  66. package/src/components/Tabs/Tabs.tsx +2 -9
  67. package/src/components/Toggle/Toggle.tsx +2 -10
  68. package/src/components/Tooltip/Tooltip.tsx +2 -5
  69. package/src/lib/composables/useAtomixGlass.ts +41 -10
  70. package/src/lib/composables/useAtomixGlassStyles.ts +59 -75
  71. package/src/lib/composables/usePerformanceMonitor.ts +5 -0
  72. package/src/lib/constants/components.ts +358 -46
  73. package/src/lib/types/components.ts +33 -1
  74. package/src/styles/01-settings/_settings.atomix-glass.scss +69 -31
  75. package/src/styles/02-tools/_tools.glass.scss +45 -3
  76. package/src/styles/06-components/_components.atomix-glass.scss +114 -77
  77. 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,24 @@ 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
+ // Elasticity physics constants — Apple-tuned: soft springs, fast settling, minimal stretch
161
+ ELASTICITY_TRANSLATION_FACTOR: .06,
162
+ // Subtler elastic shift (was 0.1)
90
163
  ELASTICITY_DISTANCE_THRESHOLD: 200,
91
164
  ELASTICITY_COMPRESSION_FACTOR: .3,
92
- ELASTICITY_STIFFNESS: .1,
93
- ELASTICITY_DAMPING: .76,
165
+ ELASTICITY_STIFFNESS: .06,
166
+ // Softer springs = gentler motion (was 0.1)
167
+ ELASTICITY_DAMPING: .88,
168
+ // Fast settling, no wobble (was 0.76)
94
169
  ELASTICITY_VELOCITY_FACTOR: .65,
95
- ELASTICITY_STRETCH_RATIO: .45,
170
+ ELASTICITY_STRETCH_RATIO: .25,
171
+ // Less visible surface tension stretch (was 0.45)
96
172
  ELASTICITY_MAGNIFICATION_BASE: 1.02,
97
173
  // Note: This default must match the SCSS variable --atomix-radius-md
98
174
  // @see src/styles/01-settings/_settings.global.scss
@@ -106,55 +182,16 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
106
182
  },
107
183
  // Gradient calculation constants
108
184
  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
- },
185
+ BASE_ANGLE: GLASS_BORDER_GRADIENT.BASE_ANGLE,
186
+ ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.ANGLE_MULTIPLIER,
187
+ VELOCITY_ANGLE_MULTIPLIER: GLASS_BORDER_GRADIENT.VELOCITY_ANGLE_MULTIPLIER,
188
+ CHROMATIC_OFFSET: GLASS_BORDER_GRADIENT.CHROMATIC_OFFSET,
189
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_1 */
190
+ BORDER_STOP_1: GLASS_BORDER_GRADIENT.STOP_1,
191
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.STOP_2 */
192
+ BORDER_STOP_2: GLASS_BORDER_GRADIENT.STOP_2,
193
+ /** @deprecated Use ATOMIX_GLASS.BORDER.GRADIENT.OPACITY */
194
+ BORDER_OPACITY: GLASS_BORDER_GRADIENT.OPACITY,
158
195
  CENTER_POSITION: 50,
159
196
  // Center position percentage (50%)
160
197
  HOVER_POSITION: {
@@ -187,8 +224,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
187
224
  return 2 * this.BLACK_STOP;
188
225
  },
189
226
  // End percentage for black hover 1
190
- WHITE_START: .5,
191
- // Start opacity for white hover 1
227
+ WHITE_START: .35,
228
+ // Gentler hover flash Apple hover is barely visible
192
229
  get WHITE_STOP() {
193
230
  return this.BLACK_END - 10;
194
231
  }
@@ -206,8 +243,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
206
243
  return 2 * this.BLACK_STOP;
207
244
  },
208
245
  // End percentage for black hover 2
209
- WHITE_START: 1,
210
- // Start opacity for white hover 2
246
+ WHITE_START: .7,
247
+ // Gentler hover flash
211
248
  get WHITE_STOP() {
212
249
  return this.BLACK_END;
213
250
  }
@@ -225,8 +262,8 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
225
262
  return 2 * this.BLACK_STOP;
226
263
  },
227
264
  // End percentage for black hover 3
228
- WHITE_START: 1,
229
- // Start opacity for white hover 3
265
+ WHITE_START: .7,
266
+ // Gentler hover flash
230
267
  get WHITE_STOP() {
231
268
  return this.BLACK_END;
232
269
  }
@@ -236,13 +273,13 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
236
273
  BASE_GRADIENT: {
237
274
  ANGLE: 135,
238
275
  // Gradient angle in degrees
239
- BLACK_START_BASE: .15,
276
+ BLACK_START_BASE: .1,
240
277
  // Base start opacity for black
241
278
  get BLACK_START_MULTIPLIER() {
242
279
  return .02 * this.BLACK_START_BASE;
243
280
  },
244
281
  // Multiplier for mouse X influence on start
245
- BLACK_MID_BASE: .1,
282
+ BLACK_MID_BASE: .07,
246
283
  // Base mid opacity for black
247
284
  get BLACK_MID_MULTIPLIER() {
248
285
  return .02 * this.BLACK_MID_BASE;
@@ -263,7 +300,7 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
263
300
  }
264
301
  },
265
302
  OVERLAY_GRADIENT: {
266
- BLACK_START_BASE: .12,
303
+ BLACK_START_BASE: .08,
267
304
  // Base start opacity for black overlay
268
305
  get BLACK_START_MULTIPLIER() {
269
306
  return .025 * this.BLACK_START_BASE;
@@ -287,14 +324,14 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
287
324
  return .416 * this.BLACK_START_BASE;
288
325
  }
289
326
  },
290
- // Overlay highlight constants
327
+ // Overlay highlight constants — Apple places specular at the top-center
291
328
  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
329
+ POSITION_X: 50,
330
+ // Centered horizontal — Apple's top-center specular
331
+ POSITION_Y: 5,
332
+ // Very top — catches light like a curved glass surface
333
+ WHITE_OPACITY: .28,
334
+ // Softer specular visible but not glaring
298
335
  get STOP() {
299
336
  return 150 * this.WHITE_OPACITY;
300
337
  },
@@ -315,6 +352,10 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
315
352
  SATURATION: {
316
353
  HIGH_CONTRAST: 200
317
354
  },
355
+ // Container shadows — hairline inner catch + soft floating lift (Apple player bar)
356
+ CONTAINER_SHADOW: {
357
+ LIGHT: "inset 0 0.5px 0 rgba(255, 255, 255, 0.32), inset 0 1px 2px rgba(255, 255, 255, 0.06), 0 8px 32px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.16)"
358
+ },
318
359
  // Phase 1: Animation System Constants
319
360
  ANIMATION: {
320
361
  // Breathing effect timing (in milliseconds)
@@ -354,267 +395,617 @@ import React, { memo, forwardRef, useId, useMemo, useState, useRef, useEffect, u
354
395
  }
355
396
  }
356
397
  }
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;
398
+ };
399
+
400
+ /**
401
+ * Form Group-specific constants
402
+ */ var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
403
+
404
+ function getDefaultExportFromCjs(x) {
405
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
406
+ }
407
+
408
+ var fails$8 = function(exec) {
416
409
  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
- }
410
+ return !!exec();
425
411
  } catch (error) {
426
- // Silently handle errors
412
+ return !0;
427
413
  }
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
414
+ }, functionBindNative = !fails$8((function() {
415
+ // eslint-disable-next-line es/no-function-prototype-bind -- safe
416
+ var test = function() {/* empty */}.bind();
417
+ // eslint-disable-next-line no-prototype-builtins -- safe
418
+ return "function" != typeof test || test.hasOwnProperty("prototype");
419
+ })), 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) {
420
+ return function() {
421
+ return call$5.apply(fn, arguments);
437
422
  };
438
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
439
- switch (mode) {
440
- case "standard":
441
- return displacementMap;
423
+ }, objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf), check = function(it) {
424
+ return it && it.Math === Math && it;
425
+ }, globalThis_1 =
426
+ // eslint-disable-next-line es/no-global-this -- safe
427
+ check("object" == typeof globalThis && globalThis) || check("object" == typeof window && window) ||
428
+ // eslint-disable-next-line no-restricted-globals -- safe
429
+ check("object" == typeof self && self) || check("object" == typeof commonjsGlobal && commonjsGlobal) || check("object" == typeof commonjsGlobal && commonjsGlobal) ||
430
+ // eslint-disable-next-line no-new-func -- fallback
431
+ function() {
432
+ return this;
433
+ }() || 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() {
434
+ return call$4.apply(apply$1, arguments);
435
+ }), uncurryThis$7 = functionUncurryThis, toString$3 = uncurryThis$7({}.toString), stringSlice = uncurryThis$7("".slice), classofRaw$2 = function(it) {
436
+ return stringSlice(toString$3(it), 8, -1);
437
+ }, classofRaw$1 = classofRaw$2, uncurryThis$6 = functionUncurryThis, functionUncurryThisClause = function(fn) {
438
+ // Nashorn bug:
439
+ // https://github.com/zloirock/core-js/issues/1128
440
+ // https://github.com/zloirock/core-js/issues/1130
441
+ if ("Function" === classofRaw$1(fn)) return uncurryThis$6(fn);
442
+ }, documentAll = "object" == typeof document && document.all, isCallable$8 = void 0 === documentAll && void 0 !== documentAll ? function(argument) {
443
+ return "function" == typeof argument || argument === documentAll;
444
+ } : function(argument) {
445
+ return "function" == typeof argument;
446
+ }, objectGetOwnPropertyDescriptor = {}, descriptors = !fails$8((function() {
447
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
448
+ return 7 !== Object.defineProperty({}, 1, {
449
+ get: function() {
450
+ return 7;
451
+ }
452
+ })[1];
453
+ })), NATIVE_BIND$1 = functionBindNative, call$3 = Function.prototype.call, functionCall = NATIVE_BIND$1 ? call$3.bind(call$3) : function() {
454
+ return call$3.apply(call$3, arguments);
455
+ }, objectPropertyIsEnumerable = {}, $propertyIsEnumerable = {}.propertyIsEnumerable, getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor, NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
456
+ 1: 2
457
+ }, 1);
442
458
 
443
- case "polar":
444
- return polarDisplacementMap;
459
+ // `Object.prototype.propertyIsEnumerable` method implementation
460
+ // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
461
+ objectPropertyIsEnumerable.f = NASHORN_BUG ? function(V) {
462
+ var descriptor = getOwnPropertyDescriptor$1(this, V);
463
+ return !!descriptor && descriptor.enumerable;
464
+ } : $propertyIsEnumerable;
445
465
 
446
- case "prominent":
447
- return prominentDisplacementMap;
466
+ var match, version, createPropertyDescriptor$2 = function(bitmap, value) {
467
+ return {
468
+ enumerable: !(1 & bitmap),
469
+ configurable: !(2 & bitmap),
470
+ writable: !(4 & bitmap),
471
+ value: value
472
+ };
473
+ }, fails$5 = fails$8, classof$3 = classofRaw$2, $Object$3 = Object, split = functionUncurryThis("".split), indexedObject = fails$5((function() {
474
+ // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
475
+ // eslint-disable-next-line no-prototype-builtins -- safe
476
+ return !$Object$3("z").propertyIsEnumerable(0);
477
+ })) ? function(it) {
478
+ return "String" === classof$3(it) ? split(it, "") : $Object$3(it);
479
+ } : $Object$3, isNullOrUndefined$2 = function(it) {
480
+ return null == it;
481
+ }, isNullOrUndefined$1 = isNullOrUndefined$2, $TypeError$6 = TypeError, requireObjectCoercible$3 = function(it) {
482
+ if (isNullOrUndefined$1(it)) throw new $TypeError$6("Can't call method on " + it);
483
+ return it;
484
+ }, IndexedObject = indexedObject, requireObjectCoercible$2 = requireObjectCoercible$3, toIndexedObject$2 = function(it) {
485
+ return IndexedObject(requireObjectCoercible$2(it));
486
+ }, isCallable$7 = isCallable$8, isObject$5 = function(it) {
487
+ return "object" == typeof it ? null !== it : isCallable$7(it);
488
+ }, path$3 = {}, path$2 = path$3, globalThis$a = globalThis_1, isCallable$6 = isCallable$8, aFunction = function(variable) {
489
+ return isCallable$6(variable) ? variable : void 0;
490
+ }, 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
491
 
449
- case "shader":
450
- return shaderMapUrl || displacementMap;
492
+ v8 && (
493
+ // in old Chrome, versions of V8 isn't V8 = Chrome / 10
494
+ // but their correct versions are not interesting for us
495
+ version = (match = v8.split("."))[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1])),
496
+ // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
497
+ // so check `userAgent` even if `.v8` exists, but 0
498
+ !version && userAgent && (!(match = userAgent.match(/Edge\/(\d+)/)) || match[1] >= 74) && (match = userAgent.match(/Chrome\/(\d+)/)) && (version = +match[1]);
451
499
 
452
- default:
453
- return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
500
+ var V8_VERSION = version, fails$4 = fails$8, $String$3 = globalThis_1.String, symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$4((function() {
501
+ var symbol = Symbol("symbol detection");
502
+ // Chrome 38 Symbol has incorrect toString conversion
503
+ // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
504
+ // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
505
+ // of course, fail.
506
+ return !$String$3(symbol) || !(Object(symbol) instanceof Symbol) ||
507
+ // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
508
+ !Symbol.sham && V8_VERSION && V8_VERSION < 41;
509
+ })), useSymbolAsUid = symbolConstructorDetection && !Symbol.sham && "symbol" == typeof Symbol.iterator, isCallable$5 = isCallable$8, isPrototypeOf$1 = objectIsPrototypeOf, $Object$2 = Object, isSymbol$2 = useSymbolAsUid ? function(it) {
510
+ return "symbol" == typeof it;
511
+ } : function(it) {
512
+ var $Symbol = function(namespace, method) {
513
+ 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];
514
+ }("Symbol");
515
+ return isCallable$5($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
516
+ }, $String$2 = String, isCallable$4 = isCallable$8, $TypeError$5 = TypeError, aCallable$2 = function(argument) {
517
+ if (isCallable$4(argument)) return argument;
518
+ throw new $TypeError$5(function(argument) {
519
+ try {
520
+ return $String$2(argument);
521
+ } catch (error) {
522
+ return "Object";
523
+ }
524
+ }(argument) + " is not a function");
525
+ }, aCallable$1 = aCallable$2, isNullOrUndefined = isNullOrUndefined$2, call$2 = functionCall, isCallable$3 = isCallable$8, isObject$4 = isObject$5, $TypeError$4 = TypeError, sharedStore = {
526
+ exports: {}
527
+ }, globalThis$6 = globalThis_1, defineProperty = Object.defineProperty, globalThis$5 = globalThis_1, store$1 = sharedStore.exports = globalThis$5["__core-js_shared__"] || function(key, value) {
528
+ try {
529
+ defineProperty(globalThis$6, key, {
530
+ value: value,
531
+ configurable: !0,
532
+ writable: !0
533
+ });
534
+ } catch (error) {
535
+ globalThis$6[key] = value;
454
536
  }
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,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", "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
- })
537
+ return value;
538
+ }("__core-js_shared__", {});
539
+
540
+ /* eslint-disable es/no-symbol -- required for testing */ (store$1.versions || (store$1.versions = [])).push({
541
+ version: "3.43.0",
542
+ mode: "pure",
543
+ copyright: "© 2014-2025 Denis Pushkarev (zloirock.ru)",
544
+ license: "https://github.com/zloirock/core-js/blob/v3.43.0/LICENSE",
545
+ source: "https://github.com/zloirock/core-js"
589
546
  });
590
547
 
548
+ var key, value, store = sharedStore.exports, requireObjectCoercible$1 = requireObjectCoercible$3, $Object$1 = Object, hasOwnProperty = functionUncurryThis({}.hasOwnProperty), hasOwnProperty_1 = Object.hasOwn || function(it, key) {
549
+ return hasOwnProperty($Object$1(requireObjectCoercible$1(it)), key);
550
+ }, 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) {
551
+ return "Symbol(" + (void 0 === key ? "" : key) + ")_" + toString$2(++id + postfix, 36);
552
+ }, wellKnownSymbol$5 = function(name) {
553
+ return hasOwn$2(WellKnownSymbolsStore, name) || (WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$2(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name)),
554
+ WellKnownSymbolsStore[name];
555
+ }, call$1 = functionCall, isObject$3 = isObject$5, isSymbol$1 = isSymbol$2, $TypeError$3 = TypeError, TO_PRIMITIVE = wellKnownSymbol$5("toPrimitive"), toPrimitive = function(input, pref) {
556
+ if (!isObject$3(input) || isSymbol$1(input)) return input;
557
+ var result, func, exoticToPrim = (func = input[TO_PRIMITIVE], isNullOrUndefined(func) ? void 0 : aCallable$1(func));
558
+ if (exoticToPrim) {
559
+ if (void 0 === pref && (pref = "default"), result = call$1(exoticToPrim, input, pref),
560
+ !isObject$3(result) || isSymbol$1(result)) return result;
561
+ throw new $TypeError$3("Can't convert object to primitive value");
562
+ }
563
+ return void 0 === pref && (pref = "number"), function(input, pref) {
564
+ var fn, val;
565
+ if ("string" === pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
566
+ if (isCallable$3(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
567
+ if ("string" !== pref && isCallable$3(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
568
+ throw new $TypeError$4("Can't convert object to primitive value");
569
+ }(input, pref);
570
+ }, isSymbol = isSymbol$2, toPropertyKey$2 = function(argument) {
571
+ var key = toPrimitive(argument, "string");
572
+ return isSymbol(key) ? key : key + "";
573
+ }, isObject$2 = isObject$5, document$1 = globalThis_1.document, EXISTS = isObject$2(document$1) && isObject$2(document$1.createElement), ie8DomDefine = !descriptors && !fails$8((function() {
574
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
575
+ return 7 !== Object.defineProperty((it = "div", EXISTS ? document$1.createElement(it) : {}), "a", {
576
+ get: function() {
577
+ return 7;
578
+ }
579
+ }).a;
580
+ var it;
581
+ })), 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;
582
+
583
+ // `Object.getOwnPropertyDescriptor` method
584
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
585
+ objectGetOwnPropertyDescriptor.f = DESCRIPTORS$3 ? $getOwnPropertyDescriptor$1 : function(O, P) {
586
+ if (O = toIndexedObject$1(O), P = toPropertyKey$1(P), IE8_DOM_DEFINE$1) try {
587
+ return $getOwnPropertyDescriptor$1(O, P);
588
+ } catch (error) {/* empty */}
589
+ if (hasOwn$1(O, P)) return createPropertyDescriptor$1(!call(propertyIsEnumerableModule.f, O, P), O[P]);
590
+ };
591
+
592
+ var fails$2 = fails$8, isCallable$2 = isCallable$8, replacement = /#|\.prototype\./, isForced$1 = function(feature, detection) {
593
+ var value = data[normalize(feature)];
594
+ return value === POLYFILL || value !== NATIVE && (isCallable$2(detection) ? fails$2(detection) : !!detection);
595
+ }, normalize = isForced$1.normalize = function(string) {
596
+ return String(string).replace(replacement, ".").toLowerCase();
597
+ }, 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() {
598
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
599
+ return 42 !== Object.defineProperty((function() {/* empty */}), "prototype", {
600
+ value: 42,
601
+ writable: !1
602
+ }).prototype;
603
+ })), 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) {
604
+ if (isObject$1(argument)) return argument;
605
+ throw new $TypeError$2($String$1(argument) + " is not an object");
606
+ }, toPropertyKey = toPropertyKey$2, $TypeError$1 = TypeError, $defineProperty = Object.defineProperty, $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
607
+
608
+ // `Object.defineProperty` method
609
+ // https://tc39.es/ecma262/#sec-object.defineproperty
610
+ objectDefineProperty.f = DESCRIPTORS$1 ? V8_PROTOTYPE_DEFINE_BUG ? function(O, P, Attributes) {
611
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), "function" == typeof O && "prototype" === P && "value" in Attributes && "writable" in Attributes && !Attributes.writable) {
612
+ var current = $getOwnPropertyDescriptor(O, P);
613
+ current && current.writable && (O[P] = Attributes.value, Attributes = {
614
+ configurable: "configurable" in Attributes ? Attributes.configurable : current.configurable,
615
+ enumerable: "enumerable" in Attributes ? Attributes.enumerable : current.enumerable,
616
+ writable: !1
617
+ });
618
+ }
619
+ return $defineProperty(O, P, Attributes);
620
+ } : $defineProperty : function(O, P, Attributes) {
621
+ if (anObject(O), P = toPropertyKey(P), anObject(Attributes), IE8_DOM_DEFINE) try {
622
+ return $defineProperty(O, P, Attributes);
623
+ } catch (error) {/* empty */}
624
+ if ("get" in Attributes || "set" in Attributes) throw new $TypeError$1("Accessors not supported");
625
+ return "value" in Attributes && (O[P] = Attributes.value), O;
626
+ };
627
+
628
+ var definePropertyModule = objectDefineProperty, createPropertyDescriptor = createPropertyDescriptor$2, createNonEnumerableProperty$1 = descriptors ? function(object, key, value) {
629
+ return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
630
+ } : function(object, key, value) {
631
+ return object[key] = value, object;
632
+ }, 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) {
633
+ return aCallable(fn), void 0 === that ? fn : NATIVE_BIND ? bind$1(fn, that) : function() {
634
+ return fn.apply(that, arguments);
635
+ };
636
+ }, createNonEnumerableProperty = createNonEnumerableProperty$1, hasOwn = hasOwnProperty_1, wrapConstructor = function(NativeConstructor) {
637
+ var Wrapper = function(a, b, c) {
638
+ if (this instanceof Wrapper) {
639
+ switch (arguments.length) {
640
+ case 0:
641
+ return new NativeConstructor;
642
+
643
+ case 1:
644
+ return new NativeConstructor(a);
645
+
646
+ case 2:
647
+ return new NativeConstructor(a, b);
648
+ }
649
+ return new NativeConstructor(a, b, c);
650
+ }
651
+ return apply(NativeConstructor, this, arguments);
652
+ };
653
+ return Wrapper.prototype = NativeConstructor.prototype, Wrapper;
654
+ }, _export = function(options, source) {
655
+ 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;
656
+ for (key in source)
657
+ // contains in native
658
+ USE_NATIVE = !(FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced)) && nativeSource && hasOwn(nativeSource, key),
659
+ targetProperty = target[key], USE_NATIVE && (nativeProperty = options.dontCallGetSet ? (descriptor = getOwnPropertyDescriptor(nativeSource, key)) && descriptor.value : nativeSource[key]),
660
+ // export native or implementation
661
+ sourceProperty = USE_NATIVE && nativeProperty ? nativeProperty : source[key], (FORCED || PROTO || typeof targetProperty != typeof sourceProperty) && (
662
+ // bind methods to global for calling from export context
663
+ resultProperty = options.bind && USE_NATIVE ? bind(sourceProperty, globalThis$2) : options.wrap && USE_NATIVE ? wrapConstructor(sourceProperty) : PROTO && isCallable$1(sourceProperty) ? uncurryThis$1(sourceProperty) : sourceProperty,
664
+ // add a flag to not completely full polyfills
665
+ (options.sham || sourceProperty && sourceProperty.sham || targetProperty && targetProperty.sham) && createNonEnumerableProperty(resultProperty, "sham", !0),
666
+ createNonEnumerableProperty(target, key, resultProperty), PROTO && (hasOwn(path$1, VIRTUAL_PROTOTYPE = TARGET + "Prototype") || createNonEnumerableProperty(path$1, VIRTUAL_PROTOTYPE, {}),
667
+ // export virtual prototype methods
668
+ createNonEnumerableProperty(path$1[VIRTUAL_PROTOTYPE], key, sourceProperty),
669
+ // export real prototype methods
670
+ options.real && targetPrototype && (FORCED || !targetPrototype[key]) && createNonEnumerableProperty(targetPrototype, key, sourceProperty)));
671
+ }, ceil = Math.ceil, floor = Math.floor, trunc = Math.trunc || function(x) {
672
+ var n = +x;
673
+ return (n > 0 ? floor : ceil)(n);
674
+ }, toIntegerOrInfinity$2 = function(argument) {
675
+ var number = +argument;
676
+ // eslint-disable-next-line no-self-compare -- NaN check
677
+ return number != number || 0 === number ? 0 : trunc(number);
678
+ }, toIntegerOrInfinity$1 = toIntegerOrInfinity$2, min$1 = Math.min, globalThis$1 = globalThis_1, path = path$3, getBuiltInPrototypeMethod$2 = function(CONSTRUCTOR, METHOD) {
679
+ var Namespace = path[CONSTRUCTOR + "Prototype"], pureMethod = Namespace && Namespace[METHOD];
680
+ if (pureMethod) return pureMethod;
681
+ var NativeConstructor = globalThis$1[CONSTRUCTOR], NativePrototype = NativeConstructor && NativeConstructor.prototype;
682
+ return NativePrototype && NativePrototype[METHOD];
683
+ };
684
+
591
685
  /**
592
- * Form Group-specific constants
593
- */ GlassFilterComponent.displayName = "GlassFilter";
686
+ * Component Utilities
687
+ *
688
+ * Helper functions for component development with the new customization system
689
+ */
690
+ /**
691
+ * Merge multiple class names
692
+ */
693
+ function mergeClassNames(...classes) {
694
+ return classes.filter(Boolean).join(" ");
695
+ }
594
696
 
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 = {
697
+ /**
698
+ * Utility to merge multiple React refs into one
699
+ */ function setRef(ref, value) {
700
+ "function" == typeof ref ? ref(value) : ref && (
701
+ // This is safe because we're checking that ref exists first
702
+ ref.current = value);
703
+ }
704
+
705
+ /**
706
+ * Combines two React refs into a single ref function
707
+ * This is used when you need to use and forward a ref at the same time
708
+ */ function useForkRef(refA, refB) {
709
+ return React.useMemo((() => null == refA && null == refB ? null : refValue => {
710
+ setRef(refA, refValue), setRef(refB, refValue);
711
+ }), [ refA, refB ]);
712
+ }
713
+
714
+ const {CONSTANTS: CONSTANTS$3} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
715
+ x: rect.left + rect.width / 2,
716
+ y: rect.top + rect.height / 2
717
+ } : {
597
718
  x: 0,
598
719
  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, ""));
720
+ }, calculateMouseInfluence = mouseOffset => {
721
+ if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
722
+ // Clamp influence to keep mouse response subtle and stable.
723
+ const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$3.MOUSE_INFLUENCE_DIVISOR;
724
+ return Math.min(.8, influence);
725
+ // Tighter cap to prevent blur/filter blow-out
726
+ }, 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 => {
727
+ if ("number" == typeof value) return Math.max(0, value);
728
+ if ("string" != typeof value || !value.trim()) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
729
+ const trimmedValue = value.trim();
730
+ // Handle px values
731
+ if (trimmedValue.endsWith("px")) {
732
+ const parsed = parseFloat(trimmedValue);
733
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed);
734
+ }
735
+ // Handle rem values (assume 16px = 1rem)
736
+ if (trimmedValue.endsWith("rem")) {
737
+ const parsed = parseFloat(trimmedValue);
738
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
739
+ }
740
+ // Handle em values (assume 16px = 1em for simplicity)
741
+ if (trimmedValue.endsWith("em")) {
742
+ const parsed = parseFloat(trimmedValue);
743
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, 16 * parsed);
744
+ }
745
+ // Handle percentage (convert to approximate px value, assuming 200px container)
746
+ if (trimmedValue.endsWith("%")) {
747
+ const parsed = parseFloat(trimmedValue);
748
+ return isNaN(parsed) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, parsed / 100 * 200);
749
+ }
750
+ // Handle unitless numbers
751
+ const numValue = parseFloat(trimmedValue);
752
+ return isNaN(numValue) ? CONSTANTS$3.DEFAULT_CORNER_RADIUS : Math.max(0, numValue);
753
+ }, extractBorderRadiusFromElement = element => {
754
+ if (!element || !element.props) return null;
755
+ // Check inline styles first (highest priority)
756
+ if (element.props.style) {
757
+ const radiusFromStyle = (style => {
758
+ if (!style) return null;
759
+ // Check various border-radius properties
760
+ const borderRadius = style.borderRadius || style.borderTopLeftRadius || style.borderTopRightRadius || style.borderBottomLeftRadius || style.borderBottomRightRadius;
761
+ return void 0 !== borderRadius ? parseBorderRadiusValue(borderRadius) : null;
762
+ })(element.props.style);
763
+ if (null !== radiusFromStyle && radiusFromStyle > 0) return radiusFromStyle;
764
+ }
765
+ // If element has children, recursively check them
766
+ if (element.props.children) {
767
+ const childRadius = extractBorderRadiusFromChildren(element.props.children);
768
+ if (childRadius > 0 && childRadius !== CONSTANTS$3.DEFAULT_CORNER_RADIUS) return childRadius;
769
+ }
770
+ return null;
771
+ }, extractBorderRadiusFromChildren = children => {
772
+ if (!children) return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
773
+ try {
774
+ const childArray = React.Children.toArray(children);
775
+ for (let i = 0; i < childArray.length; i++) {
776
+ const child = childArray[i];
777
+ if ( React.isValidElement(child)) {
778
+ const radius = extractBorderRadiusFromElement(child);
779
+ if (null !== radius) return radius;
780
+ }
781
+ }
782
+ } catch (error) {
783
+ // Silently handle errors
784
+ }
785
+ return CONSTANTS$3.DEFAULT_CORNER_RADIUS;
786
+ }, smoothstep = t => {
787
+ const clamped = Math.max(0, Math.min(1, t));
788
+ return clamped * clamped * (3 - 2 * clamped);
789
+ }, 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) => {
790
+ const newVelocity = (velocity + (target - current) * stiffness) * damping;
791
+ return {
792
+ value: current + newVelocity,
793
+ velocity: newVelocity
794
+ };
795
+ };
796
+
797
+ /**
798
+ * Calculate element center from bounding rect
799
+ */
800
+ /**
801
+ * Normalizes a layout inset for use in CSS custom properties.
802
+ *
803
+ * @param value - Raw inset from `style` (number, px string, or `auto`).
804
+ * @param fallback - Value used when `value` is undefined.
805
+ */
806
+ function formatGlassInsetValue(value, fallback = "auto") {
807
+ return void 0 === value ? "number" == typeof fallback ? `${fallback}px` : String(fallback) : "auto" === value ? "auto" : "number" == typeof value ? `${value}px` : value;
808
+ }
809
+
810
+ /**
811
+ * Determines whether the glass should use fixed/sticky layout semantics.
812
+ *
813
+ * @param explicit - Value of the `isFixedOrSticky` prop.
814
+ * @param position - `position` from the consumer `style` object.
815
+ */
816
+ /** Coerces a value to a finite number, returning `fallback` when invalid. */
817
+ function toSafeNumber(value, fallback = 0) {
818
+ return "number" != typeof value || isNaN(value) ? fallback : value;
819
+ }
820
+
821
+ /**
822
+ * Calculates the target frame rate for shader time-animation loops.
823
+ *
824
+ * Balances visual quality against distortion complexity and `animationSpeed`.
825
+ */
826
+ /**
827
+ * Computes per-channel displacement scale for the SVG chromatic-aberration filter.
828
+ */
829
+ function getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channelFactor) {
830
+ return displacementScale * (("shader" === mode ? 1 : -1) - aberrationIntensity * channelFactor);
831
+ }
832
+
833
+ /**
834
+ * Get displacement map URL based on mode
835
+ */ const getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
836
+ switch (mode) {
837
+ case "standard":
838
+ return displacementMap;
839
+
840
+ case "polar":
841
+ return polarDisplacementMap;
842
+
843
+ case "prominent":
844
+ return prominentDisplacementMap;
845
+
846
+ case "shader":
847
+ return shaderMapUrl || displacementMap;
848
+
849
+ default:
850
+ return console.warn("AtomixGlass: Invalid displacement mode"), displacementMap;
851
+ }
852
+ }, sharedShaderCache = new Map, CHROMATIC_CHANNELS = [ {
853
+ result: "RED_DISPLACED",
854
+ channelResult: "RED_CHANNEL",
855
+ aberrationFactor: 0,
856
+ colorMatrix: "1 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
857
+ }, {
858
+ result: "GREEN_DISPLACED",
859
+ channelResult: "GREEN_CHANNEL",
860
+ aberrationFactor: .02,
861
+ colorMatrix: "0 0 0 0 0\n0 1 0 0 0\n0 0 0 0 0\n0 0 0 1 0"
862
+ }, {
863
+ result: "BLUE_DISPLACED",
864
+ channelResult: "BLUE_CHANNEL",
865
+ aberrationFactor: .03,
866
+ colorMatrix: "0 0 0 0 0\n0 0 0 0 0\n0 0 1 0 0\n0 0 0 1 0"
867
+ } ], FILTER_SVG_STYLE = {
868
+ position: "absolute",
869
+ width: "100%",
870
+ height: "100%",
871
+ inset: 0
872
+ }, GlassFilterComponent = ({id: id, displacementScale: displacementScale, aberrationIntensity: aberrationIntensity, mode: mode, shaderMapUrl: shaderMapUrl, blurAmount: blurAmount}) => jsx("svg", {
873
+ style: FILTER_SVG_STYLE,
874
+ "aria-hidden": "true",
875
+ children: jsxs("defs", {
876
+ children: [ jsxs("radialGradient", {
877
+ id: `${id}-edge-mask`,
878
+ cx: "50%",
879
+ cy: "50%",
880
+ r: "50%",
881
+ children: [ jsx("stop", {
882
+ offset: "0%",
883
+ stopColor: "black",
884
+ stopOpacity: "0"
885
+ }), jsx("stop", {
886
+ offset: `${Math.max(30, 80 - 2 * aberrationIntensity)}%`,
887
+ stopColor: "black",
888
+ stopOpacity: "0"
889
+ }), jsx("stop", {
890
+ offset: "100%",
891
+ stopColor: "white",
892
+ stopOpacity: "1"
893
+ }) ]
894
+ }), jsxs("filter", {
895
+ id: id,
896
+ x: "-35%",
897
+ y: "-35%",
898
+ width: "170%",
899
+ height: "170%",
900
+ colorInterpolationFilters: "sRGB",
901
+ children: [ jsx("feImage", {
902
+ id: `${id}-image`,
903
+ x: "0",
904
+ y: "0",
905
+ width: "100%",
906
+ height: "100%",
907
+ result: "DISPLACEMENT_MAP",
908
+ 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,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", "data:image/png;base64,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", shaderMapUrl),
909
+ preserveAspectRatio: "xMidYMid slice"
910
+ }), jsx("feColorMatrix", {
911
+ in: "DISPLACEMENT_MAP",
912
+ type: "matrix",
913
+ 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",
914
+ result: "EDGE_INTENSITY"
915
+ }), jsx("feComponentTransfer", {
916
+ in: "EDGE_INTENSITY",
917
+ result: "EDGE_MASK",
918
+ children: jsx("feFuncA", {
919
+ type: "discrete",
920
+ tableValues: `0 ${.05 * aberrationIntensity} 1`
921
+ })
922
+ }), jsx("feOffset", {
923
+ in: "SourceGraphic",
924
+ dx: "0",
925
+ dy: "0",
926
+ result: "CENTER_ORIGINAL"
927
+ }), CHROMATIC_CHANNELS.map((channel => jsxs(React.Fragment, {
928
+ children: [ jsx("feDisplacementMap", {
929
+ in: "SourceGraphic",
930
+ in2: "DISPLACEMENT_MAP",
931
+ scale: getChromaticDisplacementScale(mode, displacementScale, aberrationIntensity, channel.aberrationFactor),
932
+ xChannelSelector: "R",
933
+ yChannelSelector: "B",
934
+ result: channel.result
935
+ }), jsx("feColorMatrix", {
936
+ in: channel.result,
937
+ type: "matrix",
938
+ values: channel.colorMatrix,
939
+ result: channel.channelResult
940
+ }) ]
941
+ }, channel.channelResult))), jsx("feBlend", {
942
+ in: "GREEN_CHANNEL",
943
+ in2: "BLUE_CHANNEL",
944
+ mode: "screen",
945
+ result: "GB_COMBINED"
946
+ }), jsx("feBlend", {
947
+ in: "RED_CHANNEL",
948
+ in2: "GB_COMBINED",
949
+ mode: "screen",
950
+ result: "RGB_COMBINED"
951
+ }), jsx("feGaussianBlur", {
952
+ in: "RGB_COMBINED",
953
+ result: "ABERRATED_BLURRED",
954
+ stdDeviation: blurAmount * aberrationIntensity * .05
955
+ }), jsx("feComposite", {
956
+ in: "ABERRATED_BLURRED",
957
+ in2: "EDGE_MASK",
958
+ operator: "in",
959
+ result: "EDGE_ABERRATION"
960
+ }), jsx("feComponentTransfer", {
961
+ in: "EDGE_MASK",
962
+ result: "INVERTED_MASK",
963
+ children: jsx("feFuncA", {
964
+ type: "table",
965
+ tableValues: "1 0"
966
+ })
967
+ }), jsx("feComposite", {
968
+ in: "CENTER_ORIGINAL",
969
+ in2: "INVERTED_MASK",
970
+ operator: "in",
971
+ result: "CENTER_CLEAN"
972
+ }), jsx("feComposite", {
973
+ in: "EDGE_ABERRATION",
974
+ in2: "CENTER_CLEAN",
975
+ operator: "over"
976
+ }) ]
977
+ }) ]
978
+ })
979
+ });
980
+
981
+ /**
982
+ * Module-level LRU cache for shader displacement maps.
983
+ *
984
+ * Shared across all `AtomixGlassContainer` instances so identical size and
985
+ * variant combinations are generated once.
986
+ */ GlassFilterComponent.displayName = "GlassFilter";
987
+
988
+ /** Shallow prop comparison to avoid redundant SVG filter regeneration. */
989
+ 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 = {
990
+ x: 0,
991
+ y: 0
992
+ }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, glassSize: glassSize = {
993
+ width: 0,
994
+ height: 0
995
+ }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, isFixedOrSticky: isFixedOrSticky = !1, 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) => {
996
+ // React 18 useId — stable, unique, and SSR-safe (no module-level counter)
997
+ 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);
998
+ // Lazy load shader utilities only when shader mode is needed
999
+ useEffect((() => {
1000
+ "shader" === mode ?
1001
+ // Dynamic import shader utilities with animation support
1002
+ Promise.resolve().then((() => shaderUtils)).then((shaderUtils => {
1003
+ shaderUtilsRef.current = {
1004
+ ShaderDisplacementGenerator: shaderUtils.ShaderDisplacementGenerator,
1005
+ fragmentShaders: shaderUtils.fragmentShaders
1006
+ };
1007
+ })).catch((error => {
1008
+ console.warn("AtomixGlassContainer: Error loading shader utilities", String(error).replace(/[\r\n]/g, ""));
618
1009
  })) :
619
1010
  // Clear shader utils when not in shader mode to free memory
620
1011
  shaderUtilsRef.current = null;
@@ -681,15 +1072,23 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
681
1072
  shaderGeneratorRef.current = null;
682
1073
  }
683
1074
  };
684
- }), [ mode, glassSize, shaderVariant ]),
685
- // Phase 1: Time-Based Animation Loop - Continuous shader regeneration
686
- useEffect((() => {
1075
+ }), [ mode, glassSize, shaderVariant ]), useEffect((() => {
687
1076
  // Only run animations in shader mode with time animation enabled
688
1077
  if ("shader" !== mode || !withTimeAnimation || effectiveReducedMotion || effectiveWithoutEffects)
689
1078
  // Cancel any existing animation frame
690
1079
  return void (null !== animationFrameRef.current && (cancelAnimationFrame(animationFrameRef.current),
691
1080
  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)));
1081
+ const targetFps = function(options) {
1082
+ 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;
1083
+ return Math.max(12, Math.min(60, Math.round(baseFps * effectiveSpeed / complexity)));
1084
+ }({
1085
+ distortionQuality: distortionQuality,
1086
+ animationSpeed: animationSpeed,
1087
+ withMultiLayerDistortion: withMultiLayerDistortion,
1088
+ distortionOctaves: distortionOctaves,
1089
+ distortionLacunarity: distortionLacunarity,
1090
+ distortionGain: distortionGain
1091
+ }), frameInterval = 1e3 / targetFps;
693
1092
  let lastUpdate = 0, isCancelled = !1;
694
1093
  const animate = currentTime => {
695
1094
  if (!isCancelled) {
@@ -713,88 +1112,21 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
713
1112
  };
714
1113
  }), [ mode, withTimeAnimation, animationSpeed, displacementScale, withMultiLayerDistortion, distortionOctaves, distortionLacunarity, distortionGain, distortionQuality, effectiveReducedMotion, effectiveWithoutEffects, glassSize ]);
715
1114
  // 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((() => {
1115
+ const containerVars = useMemo((() => {
766
1116
  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
1117
  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)"
1118
+ "--atomix-glass-container-radius": `${"number" != typeof borderRadius || isNaN(borderRadius) ? 0 : borderRadius}px`
778
1119
  };
779
1120
  } catch (error) {
780
1121
  return console.warn("AtomixGlassContainer: Error generating container variables", error),
781
1122
  {
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"
1123
+ "--atomix-glass-container-radius": "0px"
789
1124
  };
790
1125
  }
791
- }), [ borderRadius, backdropStyle, mouseOffset, overLight, effectiveWithoutEffects, overLightConfig ]);
1126
+ }), [ borderRadius ]);
792
1127
  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 : ""}`,
1128
+ ref: containerRef,
1129
+ className: mergeClassNames(ATOMIX_GLASS.CONTAINER_CLASS, className, isActive && ATOMIX_GLASS.CLASSES.ACTIVE, overLight && ATOMIX_GLASS.CLASSES.OVER_LIGHT),
798
1130
  style: {
799
1131
  ...style,
800
1132
  ...containerVars
@@ -812,8 +1144,8 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
812
1144
  blurAmount: blurAmount,
813
1145
  mode: mode,
814
1146
  id: filterId,
815
- displacementScale: "number" != typeof displacementScale || isNaN(displacementScale) ? 0 : displacementScale,
816
- aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
1147
+ displacementScale: toSafeNumber(displacementScale),
1148
+ aberrationIntensity: toSafeNumber(aberrationIntensity),
817
1149
  shaderMapUrl: shaderMapUrl
818
1150
  }), jsx("div", {
819
1151
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
@@ -835,8 +1167,12 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
835
1167
  });
836
1168
  }));
837
1169
 
838
- // ─── Blur multiplier constants (module-level, never change at runtime) ────────
839
- AtomixGlassContainer.displayName = "AtomixGlassContainer";
1170
+ /**
1171
+ * Internal glass surface that owns backdrop-filter, SVG distortion, and content.
1172
+ *
1173
+ * Layout and stacking styles are applied via the `style` prop from the parent.
1174
+ * The root wrapper supplies CSS custom properties only.
1175
+ */ AtomixGlassContainer.displayName = "AtomixGlassContainer";
840
1176
 
841
1177
  // Singleton instance
842
1178
  const globalMouseTracker = new
@@ -951,28 +1287,32 @@ class {
951
1287
  */ getSubscriberCount() {
952
1288
  return this.listeners.size;
953
1289
  }
954
- }, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
1290
+ }, {BORDER: BORDER, CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, BORDER_GRADIENT = BORDER.GRADIENT, WHITE = CONSTANTS$2.PALETTE.WHITE, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
955
1291
  if (!wrapperElement && !containerElement) return;
956
1292
  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 = {
1293
+ 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 = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
958
1294
  opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
959
1295
  contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
960
1296
  brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
961
1297
  shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
962
1298
  borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
963
1299
  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);
1300
+ }, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, tensionFactor =
1301
+ /**
1302
+ * Computes tension factor from elastic translation magnitude (0–1).
1303
+ */
1304
+ function(elasticTranslation) {
1305
+ const magnitude = Math.hypot(elasticTranslation.x, elasticTranslation.y);
1306
+ return smoothstep(magnitude / 80);
1307
+ }
1308
+ /**
1309
+ * Updates the styles of the AtomixGlass wrapper and container elements imperatively
1310
+ * to avoid React re-renders on mouse movement.
1311
+ */ (elasticTranslation), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
972
1312
  // Calculate mouse influence
973
1313
  // Update Wrapper Styles (glassVars)
974
1314
  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 = {
1315
+ 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
1316
  hover1: {
977
1317
  x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
978
1318
  y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
@@ -989,28 +1329,55 @@ class {
989
1329
  x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
990
1330
  y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER
991
1331
  }, 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
1332
+ // hover-1: ambient highlight glow present on hover and during press
1333
+ hover1: isHovered || isActive ? 1 : 0,
1334
+ // hover-2: press depth shadow only fires on active (mousedown)
1335
+ hover2: isActive ? 1 : 0,
1336
+ // hover-3: global soft-light surface shift half-strength on hover, full on press
1337
+ hover3: isActive ? 1 : isHovered ? .55 : 0,
1338
+ // Dark chrome: faint smoky tint; over-light keeps stronger fill
1339
+ base: isOverLight ? overLightConfig.opacity : .14,
1340
+ over: isOverLight ? 1.1 * overLightConfig.opacity : .1
997
1341
  }, style = wrapperElement.style;
998
1342
  style.setProperty("--atomix-glass-transform", transformStyle || "none");
999
1343
  // Parallax for content (liquid refraction feel)
1000
1344
  const parallaxFactor = .38 + .12 * tensionFactor;
1001
1345
  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()),
1346
+ style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString());
1003
1347
  // ── 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})`),
1348
+ const borderVars = ATOMIX_GLASS.BORDER.GRADIENT_CSS_VARS;
1349
+ if (borderAnimated && !effectiveWithoutEffects) {
1350
+ const borderCssVars =
1351
+ /**
1352
+ * Builds animated chromatic rim CSS variables for border layers 1 and 2.
1353
+ * When empty, SCSS static conic/linear fallbacks apply.
1354
+ */
1355
+ function(params) {
1356
+ 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%)`;
1357
+ return {
1358
+ [BORDER.GRADIENT_CSS_VARS.GRADIENT_1]: gradient1,
1359
+ [BORDER.GRADIENT_CSS_VARS.GRADIENT_2]: gradient2
1360
+ };
1361
+ }({
1362
+ mouseOffset: mouseOffset,
1363
+ mouseVelocity: mouseVelocity,
1364
+ elasticVelocity: elasticVelocity,
1365
+ borderOpacity: overLightConfig.borderOpacity,
1366
+ opacityMultiplier: borderOpacityMultiplier,
1367
+ tensionFactor: tensionFactor
1368
+ });
1369
+ style.setProperty(borderVars.GRADIENT_1, borderCssVars[borderVars.GRADIENT_1] ?? ""),
1370
+ style.setProperty(borderVars.GRADIENT_2, borderCssVars[borderVars.GRADIENT_2] ?? "");
1371
+ } else style.removeProperty(borderVars.GRADIENT_1), style.removeProperty(borderVars.GRADIENT_2);
1372
+ // Hover gradients — cursor-relative radial positions for realistic light tracking.
1373
+ // hover-1: white overlay highlight following cursor (works on both dark + light)
1374
+ 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%)`),
1375
+ // hover-2: press depth — darkens at cursor with multiply blend, isOverLight uses stronger black
1376
+ 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%)`),
1377
+ // hover-3: full-surface soft-light tint; linear gradient angled with cursor X
1378
+ 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%)`),
1379
+ 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%)`),
1380
+ 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
1381
  // Opacities
1015
1382
  style.setProperty("--atomix-glass-hover-1-opacity", opacityValues.hover1.toString()),
1016
1383
  style.setProperty("--atomix-glass-hover-2-opacity", opacityValues.hover2.toString()),
@@ -1047,21 +1414,17 @@ class {
1047
1414
  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
1415
  // Container variables
1049
1416
  const style = containerElement.style;
1050
- style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
1417
+ style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
1051
1418
  style.setProperty("--atomix-glass-container-backdrop", backdropFilterString),
1052
1419
  // 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"),
1420
+ 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
1421
  style.setProperty("--atomix-glass-container-shadow-opacity", effectiveWithoutEffects ? "0" : "1"),
1055
1422
  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
1423
  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)");
1424
+ style.setProperty("--atomix-glass-container-box-shadow", isOverLight ? "0px 16px 70px rgba(0, 0, 0, 0.75)" : "0 8px 32px rgba(0, 0, 0, 0.32), 0 2px 8px rgba(0, 0, 0, 0.18)");
1058
1425
  }
1059
1426
  };
1060
1427
 
1061
- /**
1062
- * Updates the styles of the AtomixGlass wrapper and container elements imperatively
1063
- * to avoid React re-renders on mouse movement.
1064
- */
1065
1428
  /**
1066
1429
  * Animation System for AtomixGlass Component
1067
1430
  *
@@ -1206,12 +1569,38 @@ const {CONSTANTS: CONSTANTS} = ATOMIX_GLASS, backgroundDetectionCache = new Weak
1206
1569
  * Composable hook for AtomixGlass component logic
1207
1570
  * Manages all state, calculations, and event handlers
1208
1571
  */
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:
1572
+ 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, withTimeAnimation:
1210
1573
  // Default priority
1211
1574
  // Phase 1: Animation System Props
1212
1575
  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}) {
1213
1576
  // State
1214
- const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
1577
+ const [isHovered, setIsHovered] = useState(!1), [isActive, setIsActive] = useState(!1), resolvedBorder = useMemo((() =>
1578
+ /**
1579
+ * Resolves `border` and legacy `withBorder` into a single configuration object.
1580
+ */
1581
+ function(border, withBorder) {
1582
+ const legacyDefault = withBorder ?? !0;
1583
+ return void 0 === border ? {
1584
+ enabled: legacyDefault,
1585
+ width: BORDER.DEFAULT_WIDTH,
1586
+ opacityMultiplier: 1,
1587
+ animated: !0
1588
+ } : "boolean" == typeof border ? {
1589
+ enabled: border,
1590
+ width: BORDER.DEFAULT_WIDTH,
1591
+ opacityMultiplier: 1,
1592
+ animated: !0
1593
+ } : {
1594
+ enabled: border.enabled ?? legacyDefault,
1595
+ width: (value = border.width, void 0 === value ? BORDER.DEFAULT_WIDTH : "number" == typeof value ? `${value}px` : value),
1596
+ opacityMultiplier: border.opacity ?? 1,
1597
+ animated: !1 !== border.animated
1598
+ };
1599
+ /**
1600
+ * Formats border width for CSS custom properties.
1601
+ */
1602
+ var value;
1603
+ }(border, withBorder)), [ border, withBorder ]), cachedRectRef = useRef(null), internalGlobalMousePositionRef = useRef({
1215
1604
  x: 0,
1216
1605
  y: 0
1217
1606
  }), internalMouseOffsetRef = useRef({
@@ -1506,21 +1895,22 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1506
1895
  isOverLight: isOverLight,
1507
1896
  threshold: .7,
1508
1897
  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
1898
+ // Dark UI (Apple Music): neutral contrast + slight brightness lift
1899
+ contrast: isOverLight ? 1.4 : 1.02,
1900
+ brightness: isOverLight ? .9 : 1.02,
1901
+ saturationBoost: isOverLight ? 1.3 : 1,
1902
+ shadowIntensity: isOverLight ? .9 : 1,
1903
+ borderOpacity: isOverLight ? ATOMIX_GLASS.BORDER.OVER_LIGHT.opacity : ATOMIX_GLASS.BORDER.DARK.opacity
1515
1904
  };
1516
1905
  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 = {
1906
+ 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
1907
  ...baseConfig,
1519
1908
  threshold: validatedThreshold,
1520
1909
  opacity: validatedOpacity * hoverIntensity * activeIntensity,
1521
1910
  contrast: validatedContrast,
1522
1911
  brightness: validatedBrightness,
1523
- saturationBoost: validatedSaturationBoost
1912
+ saturationBoost: validatedSaturationBoost,
1913
+ borderOpacity: validatedBorderOpacity
1524
1914
  };
1525
1915
  return "undefined" == typeof process || process.env, finalConfig;
1526
1916
  }
@@ -1618,12 +2008,13 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1618
2008
  withLiquidBlur: withLiquidBlur,
1619
2009
  blurAmount: blurAmount,
1620
2010
  saturation: saturation,
1621
- padding: padding,
1622
- isFixedOrSticky: isFixedOrSticky
2011
+ isFixedOrSticky: isFixedOrSticky,
2012
+ borderAnimated: resolvedBorder.animated,
2013
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier
1623
2014
  }), 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
2015
  };
1625
2016
  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 => {
2017
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, isFixedOrSticky, resolvedBorder.animated, resolvedBorder.opacityMultiplier, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
1627
2018
  if (externalGlobalMousePosition && externalMouseOffset) return;
1628
2019
  if (effectiveWithoutEffects) return;
1629
2020
  const container = mouseContainer?.current || glassRef.current;
@@ -1687,9 +2078,10 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1687
2078
  withLiquidBlur: withLiquidBlur,
1688
2079
  blurAmount: blurAmount,
1689
2080
  saturation: saturation,
1690
- padding: padding
2081
+ borderAnimated: resolvedBorder.animated,
2082
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier
1691
2083
  });
1692
- }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
2084
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, resolvedBorder.animated, resolvedBorder.opacityMultiplier, onClick ]);
1693
2085
  // Event handlers
1694
2086
  const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1695
2087
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
@@ -1707,353 +2099,78 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1707
2099
  globalMousePosition: globalMousePosition,
1708
2100
  // This is now static (refs or props) unless prop changes
1709
2101
  mouseOffset: mouseOffset,
1710
- // This is now static (refs or props) unless prop changes
1711
- overLightConfig: overLightConfig,
1712
- transformStyle: transformStyle,
1713
- getShaderTime: getShaderTime,
1714
- applyTimeBasedDistortion: applyTimeBasedDistortion,
1715
- handleMouseEnter: handleMouseEnter,
1716
- handleMouseLeave: handleMouseLeave,
1717
- handleMouseDown: handleMouseDown,
1718
- 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;
2102
+ // This is now static (refs or props) unless prop changes
2103
+ overLightConfig: overLightConfig,
2104
+ resolvedBorder: resolvedBorder,
2105
+ transformStyle: transformStyle,
2106
+ getShaderTime: getShaderTime,
2107
+ applyTimeBasedDistortion: applyTimeBasedDistortion,
2108
+ handleMouseEnter: handleMouseEnter,
2109
+ handleMouseLeave: handleMouseLeave,
2110
+ handleMouseDown: handleMouseDown,
2111
+ handleMouseUp: handleMouseUp,
2112
+ handleKeyDown: handleKeyDown
2113
+ };
2114
+ }
1976
2115
 
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
- });
2116
+ /**
2117
+ * Default responsive breakpoints configuration
2118
+ *
2119
+ * These breakpoints are optimized for glass effect performance across device classes:
2120
+ * - Mobile: Reduced complexity for 60 FPS target
2121
+ * - Tablet: Balanced quality and performance
2122
+ * - Desktop: Full fidelity effects
2123
+ */ const DEFAULT_BREAKPOINTS = {
2124
+ mobile: {
2125
+ maxWidth: 640,
2126
+ params: {
2127
+ distortionOctaves: 3,
2128
+ displacementScale: .7,
2129
+ blurAmount: .8,
2130
+ animationSpeed: .8,
2131
+ chromaticIntensity: .5
2132
+ }
2133
+ },
2134
+ tablet: {
2135
+ minWidth: 641,
2136
+ maxWidth: 1024,
2137
+ params: {
2138
+ distortionOctaves: 4,
2139
+ displacementScale: .85,
2140
+ blurAmount: .9,
2141
+ animationSpeed: .9,
2142
+ chromaticIntensity: .75
2143
+ }
2144
+ },
2145
+ desktop: {
2146
+ minWidth: 1025,
2147
+ params: {
2148
+ distortionOctaves: 5,
2149
+ displacementScale: 1,
2150
+ blurAmount: 1,
2151
+ animationSpeed: 1,
2152
+ chromaticIntensity: 1
2153
+ }
1987
2154
  }
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
2155
  };
1996
2156
 
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;
2157
+ /**
2158
+ * Device performance tier detection
2159
+ *
2160
+ * Uses Device Memory API and Hardware Concurrency API to classify devices
2161
+ * into performance tiers for automatic quality adjustment.
2162
+ *
2163
+ * @returns Performance tier classification
2164
+ */ var toIntegerOrInfinity = toIntegerOrInfinity$2, max = Math.max, min = Math.min, toIndexedObject = toIndexedObject$2, lengthOfArrayLike = function(obj) {
2165
+ return argument = obj.length, (len = toIntegerOrInfinity$1(argument)) > 0 ? min$1(len, 9007199254740991) : 0;
2049
2166
  var argument, len;
2050
2167
  }, createMethod = function(IS_INCLUDES) {
2051
2168
  return function($this, el, fromIndex) {
2052
2169
  var O = toIndexedObject($this), length = lengthOfArrayLike(O);
2053
2170
  if (0 === length) return !IS_INCLUDES && -1;
2054
2171
  var value, index = function(index, length) {
2055
- var integer = toIntegerOrInfinity$1(index);
2056
- return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
2172
+ var integer = toIntegerOrInfinity(index);
2173
+ return integer < 0 ? max(integer + length, 0) : min(integer, length);
2057
2174
  }(fromIndex, length);
2058
2175
  // Array#includes uses SameValueZero equality algorithm
2059
2176
  // eslint-disable-next-line no-self-compare -- NaN check
@@ -2082,12 +2199,7 @@ _export({
2082
2199
  }
2083
2200
  });
2084
2201
 
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 = {};
2202
+ var includes$4 = getBuiltInPrototypeMethod$2("Array", "includes"), isObject = isObject$5, classof$2 = classofRaw$2, MATCH$1 = wellKnownSymbol$5("match"), $TypeError = TypeError, test = {};
2091
2203
 
2092
2204
  test[wellKnownSymbol$5("toStringTag")] = "z";
2093
2205
 
@@ -2143,148 +2255,6 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
2143
2255
  /**
2144
2256
  * Get GPU memory info if available (Chrome DevTools only)
2145
2257
  */
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
2258
  /**
2289
2259
  * Mobile optimization presets
2290
2260
  *
@@ -2404,18 +2374,13 @@ const PERFORMANCE_PRESET = {
2404
2374
  saturation: 70
2405
2375
  }
2406
2376
  }
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({
2377
+ }, 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) {
2378
+ const glassRef = useRef(null), contentRef = useRef(null), internalWrapperRef = useRef(null), mergedRef = useForkRef(ref, internalWrapperRef), {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = (explicit = propsIsFixedOrSticky,
2379
+ position = restStyle.position, Boolean(explicit || "fixed" === position || "sticky" === position));
2380
+ var explicit, position;
2381
+ /**
2382
+ * Extracts layout-related properties from a React `CSSProperties` object.
2383
+ */ const {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, resolvedBorder: resolvedBorder} = useAtomixGlass({
2419
2384
  glassRef: glassRef,
2420
2385
  contentRef: contentRef,
2421
2386
  wrapperRef: internalWrapperRef,
@@ -2435,10 +2400,11 @@ const PERFORMANCE_PRESET = {
2435
2400
  blurAmount: blurAmount,
2436
2401
  saturation: saturation,
2437
2402
  withLiquidBlur: withLiquidBlur,
2438
- padding: padding,
2403
+ border: border,
2404
+ withBorder: withBorder,
2405
+ debugBorderRadius: debugBorderRadius,
2439
2406
  style: style,
2440
2407
  isFixedOrSticky: isFixedOrSticky,
2441
- // Phase 1: Animation System props
2442
2408
  withTimeAnimation: withTimeAnimation,
2443
2409
  animationSpeed: animationSpeed,
2444
2410
  withMultiLayerDistortion: withMultiLayerDistortion,
@@ -2447,8 +2413,7 @@ const PERFORMANCE_PRESET = {
2447
2413
  distortionGain: distortionGain,
2448
2414
  distortionQuality: distortionQuality
2449
2415
  });
2450
- // Responsive breakpoint system - automatically adjusts parameters based on viewport
2451
- !
2416
+ (
2452
2417
  /**
2453
2418
  * Responsive Glass Parameters Hook
2454
2419
  *
@@ -2603,7 +2568,7 @@ const PERFORMANCE_PRESET = {
2603
2568
  }), [ enabled ]), useCallback((() => {
2604
2569
  calculateParams();
2605
2570
  }), [ calculateParams ]);
2606
- }({
2571
+ })({
2607
2572
  baseParams: {
2608
2573
  ...useMemo((() =>
2609
2574
  /**
@@ -2637,9 +2602,7 @@ const PERFORMANCE_PRESET = {
2637
2602
  breakpoints: MOBILE_OPTIMIZED_BREAKPOINTS,
2638
2603
  enabled: !disableResponsiveBreakpoints && "undefined" != typeof window,
2639
2604
  debug: !1
2640
- });
2641
- // Performance monitoring - tracks FPS, frame time, memory usage
2642
- const {metrics: performanceMetrics, toggleMonitoring: toggleMonitoring} =
2605
+ }),
2643
2606
  /**
2644
2607
  * Performance Monitor Hook
2645
2608
  *
@@ -2674,7 +2637,13 @@ const PERFORMANCE_PRESET = {
2674
2637
  timestamp: 0,
2675
2638
  isAutoScaling: !0,
2676
2639
  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 => {
2640
+ }), [manualOverride, setManualOverride] = useState(!1), [isEnabled, setIsEnabled] = useState(enabled);
2641
+ // Sync external `enabled` prop changes into internal state
2642
+ useEffect((() => {
2643
+ setIsEnabled(enabled ?? !0);
2644
+ }), [ enabled ]);
2645
+ // Refs for frame tracking
2646
+ 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
2647
  setMetrics((prev => ({
2679
2648
  ...prev,
2680
2649
  ...newMetrics,
@@ -2794,191 +2763,214 @@ const PERFORMANCE_PRESET = {
2794
2763
  /**
2795
2764
  * Reset to auto-scaling mode
2796
2765
  */ 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
- };
2766
+ fps = metrics.fps, currentQuality = metrics.qualityLevel, metrics.fps;
2805
2767
  }({
2806
2768
  enabled: debugPerformance,
2807
- // Enable when debugPerformance is true
2808
2769
  debug: !1,
2809
2770
  showOverlay: !1
2810
2771
  });
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
- };
2772
+ const isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, containerStyle = useMemo((() => ({
2773
+ ...restStyle,
2774
+ ...void 0 !== customZIndex && {
2775
+ zIndex: customZIndex
2846
2776
  }
2777
+ })), [ 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((() =>
2778
+ /**
2779
+ * Returns the internal positioning context for effect layers relative to the root.
2780
+ */
2781
+ function(isFixedOrSticky, restStyle) {
2847
2782
  return {
2848
- ...restStyle
2783
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
2784
+ top: 0,
2785
+ left: 0,
2786
+ right: "auto",
2787
+ bottom: "auto"
2849
2788
  };
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;
2789
+ }
2790
+ /**
2791
+ * Computes `--atomix-glass-width` and `--atomix-glass-height` values.
2792
+ *
2793
+ * Fixed/sticky elements prefer explicit dimensions or measured size; in-flow
2794
+ * elements default to `100%`.
2795
+ */ (isFixedOrSticky, restStyle)), [ isFixedOrSticky, restStyle ]), adjustedSize = useMemo((() => function(options) {
2796
+ 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
2797
  return {
2864
2798
  width: resolveLength(effectiveWidth, glassSize.width),
2865
2799
  height: resolveLength(effectiveHeight, glassSize.height)
2866
2800
  };
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;
2801
+ }
2802
+ /**
2803
+ * Builds the CSS custom properties applied to the root `.c-atomix-glass` element.
2804
+ *
2805
+ * These variables drive layer geometry, transforms, and stacking offsets. They
2806
+ * must not include layout properties that would interfere with backdrop-filter.
2807
+ */ ({
2808
+ width: width,
2809
+ height: height,
2810
+ restStyle: restStyle,
2811
+ glassSize: glassSize,
2812
+ isFixedOrSticky: isFixedOrSticky
2813
+ })), [ width, height, restStyle, glassSize, isFixedOrSticky ]), glassVars = useMemo((() => function(input) {
2814
+ 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 =
2815
+ /**
2816
+ * Resolves the `--atomix-glass-position` value for decorative layers.
2817
+ *
2818
+ * Fixed/sticky layers use the same positioning mode as the container; in-flow
2819
+ * layers default to the internal absolute positioning context.
2820
+ */
2821
+ function(isFixedOrSticky, positionStyles, restStyle) {
2822
+ return isFixedOrSticky ? `${function(style) {
2823
+ const {position: position, top: top, left: left, right: right, bottom: bottom, inset: inset} = style;
2824
+ return {
2825
+ ...null != position && {
2826
+ position: position
2827
+ },
2828
+ ...void 0 !== top && {
2829
+ top: top
2830
+ },
2831
+ ...void 0 !== left && {
2832
+ left: left
2833
+ },
2834
+ ...void 0 !== right && {
2835
+ right: right
2836
+ },
2837
+ ...void 0 !== bottom && {
2838
+ bottom: bottom
2839
+ },
2840
+ ...void 0 !== inset && {
2841
+ inset: inset
2842
+ }
2843
+ };
2844
+ }
2845
+ /**
2846
+ * Resolves inset custom properties for decorative layers (hover, borders, backgrounds).
2847
+ *
2848
+ * For fixed and sticky modes, insets mirror the container so sibling layers remain
2849
+ * aligned. In-flow modes, insets follow the consumer `style` when a non-default
2850
+ * `position` is provided.
2851
+ */ (restStyle).position ?? restStyle.position ?? "fixed"}` : `${positionStyles.position}`;
2852
+ }(isFixedOrSticky, positionStyles, restStyle), layerInsets = function(isFixedOrSticky, restStyle) {
2853
+ if (isFixedOrSticky) return {
2854
+ top: formatGlassInsetValue(restStyle.top, 0),
2855
+ left: formatGlassInsetValue(restStyle.left, 0),
2856
+ right: formatGlassInsetValue(restStyle.right, "auto"),
2857
+ bottom: formatGlassInsetValue(restStyle.bottom, "auto")
2858
+ };
2859
+ const position = restStyle.position;
2860
+ return null != position && "static" !== position && "relative" !== position ? {
2861
+ top: formatGlassInsetValue(restStyle.top, 0),
2862
+ left: formatGlassInsetValue(restStyle.left, 0),
2863
+ right: formatGlassInsetValue(restStyle.right, "auto"),
2864
+ bottom: formatGlassInsetValue(restStyle.bottom, "auto")
2865
+ } : {
2866
+ top: "0px",
2867
+ left: "0px",
2868
+ right: "auto",
2869
+ bottom: "auto"
2870
+ };
2871
+ }(isFixedOrSticky, restStyle);
2905
2872
  return {
2906
2873
  ...void 0 !== customZIndex && {
2907
2874
  "--atomix-glass-base-z-index": customZIndex
2908
2875
  },
2909
2876
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
2910
2877
  "--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",
2878
+ "--atomix-glass-container-position": layerPosition,
2879
+ "--atomix-glass-position": layerPosition,
2880
+ "--atomix-glass-top": layerInsets.top,
2881
+ "--atomix-glass-left": layerInsets.left,
2882
+ "--atomix-glass-right": layerInsets.right,
2883
+ "--atomix-glass-bottom": layerInsets.bottom,
2917
2884
  "--atomix-glass-width": adjustedSize.width,
2918
2885
  "--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}%)`
2886
+ // Aliases maintained for backward compatibility and consumer overrides.
2887
+ "--atomix-glass-container-width": adjustedSize.width,
2888
+ "--atomix-glass-container-height": adjustedSize.height,
2889
+ [ATOMIX_GLASS.BORDER.WIDTH_CSS_VAR]: borderWidth,
2890
+ "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay"
2891
+ };
2892
+ }
2893
+ /**
2894
+ * Applies mode-specific multipliers and accessibility overrides to container effects.
2895
+ */ ({
2896
+ effectiveBorderRadius: effectiveBorderRadius,
2897
+ transformStyle: transformStyle,
2898
+ adjustedSize: adjustedSize,
2899
+ isOverLight: isOverLight,
2900
+ customZIndex: customZIndex,
2901
+ isFixedOrSticky: isFixedOrSticky,
2902
+ positionStyles: positionStyles,
2903
+ restStyle: restStyle,
2904
+ borderWidth: resolvedBorder.width
2905
+ })), [ effectiveBorderRadius, transformStyle, adjustedSize, isOverLight, customZIndex, isFixedOrSticky, positionStyles, restStyle, resolvedBorder.width ]), containerEffects = useMemo((() => function(options) {
2906
+ const {MULTIPLIERS: MULTIPLIERS, SATURATION: SATURATION} = ATOMIX_GLASS.CONSTANTS, zeroMouse = {
2907
+ x: 0,
2908
+ y: 0
2909
+ }, resolveSaturation = () => options.effectiveHighContrast ? SATURATION.HIGH_CONTRAST : options.isOverLight ? options.saturation * options.saturationBoost : options.saturation;
2910
+ if (options.effectiveWithoutEffects) return {
2911
+ displacementScale: 0,
2912
+ blurAmount: 0,
2913
+ saturation: resolveSaturation(),
2914
+ aberrationIntensity: 0,
2915
+ mouseOffset: zeroMouse,
2916
+ globalMousePosition: zeroMouse
2935
2917
  };
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(" ")
2918
+ let resolvedDisplacement = options.displacementScale;
2919
+ "shader" === options.mode ? resolvedDisplacement *= MULTIPLIERS.SHADER_DISPLACEMENT : options.isOverLight && (resolvedDisplacement *= MULTIPLIERS.OVER_LIGHT_DISPLACEMENT);
2920
+ let resolvedAberration = options.aberrationIntensity;
2921
+ return "shader" === options.mode && (resolvedAberration *= MULTIPLIERS.SHADER_ABERRATION),
2922
+ {
2923
+ displacementScale: resolvedDisplacement,
2924
+ blurAmount: options.blurAmount,
2925
+ saturation: resolveSaturation(),
2926
+ aberrationIntensity: resolvedAberration,
2927
+ mouseOffset: options.mouseOffset,
2928
+ globalMousePosition: options.globalMousePosition
2929
+ };
2930
+ }({
2931
+ displacementScale: displacementScale,
2932
+ blurAmount: blurAmount,
2933
+ saturation: saturation,
2934
+ aberrationIntensity: aberrationIntensity,
2935
+ mode: mode,
2936
+ effectiveWithoutEffects: effectiveWithoutEffects,
2937
+ effectiveHighContrast: effectiveHighContrast,
2938
+ isOverLight: isOverLight,
2939
+ saturationBoost: overLightConfig.saturationBoost,
2940
+ mouseOffset: mouseOffset,
2941
+ globalMousePosition: globalMousePosition
2942
+ })), [ displacementScale, blurAmount, saturation, aberrationIntensity, mode, effectiveWithoutEffects, effectiveHighContrast, isOverLight, overLightConfig.saturationBoost, mouseOffset, globalMousePosition ]), renderBackgroundLayer = layerType => jsx("div", {
2943
+ "aria-hidden": "true",
2944
+ 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
2945
  });
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", {
2946
+ return jsxs("div", {
2942
2947
  ...rest,
2943
2948
  ref: mergedRef,
2944
2949
  className: componentClassName,
2945
- style: {
2946
- ...glassVars
2947
- },
2950
+ style: glassVars,
2948
2951
  role: role || (onClick ? "button" : void 0),
2949
2952
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
2950
2953
  "aria-label": ariaLabel,
2951
2954
  "aria-describedby": ariaDescribedBy,
2952
2955
  "aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
2953
- "aria-pressed": onClick ? isActive : void 0,
2954
2956
  onKeyDown: onClick ? handleKeyDown : void 0,
2955
2957
  children: [ jsx(AtomixGlassContainer, {
2956
2958
  ref: glassRef,
2957
2959
  contentRef: contentRef,
2958
2960
  className: className,
2959
- style: {
2960
- ...restStyle
2961
- },
2961
+ style: containerStyle,
2962
2962
  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,
2963
+ displacementScale: containerEffects.displacementScale,
2964
+ blurAmount: containerEffects.blurAmount,
2965
+ saturation: containerEffects.saturation,
2966
+ aberrationIntensity: containerEffects.aberrationIntensity,
2967
2967
  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,
2968
+ mouseOffset: containerEffects.mouseOffset,
2969
+ globalMousePosition: containerEffects.globalMousePosition,
2977
2970
  onMouseEnter: handleMouseEnter,
2978
2971
  onMouseLeave: handleMouseLeave,
2979
2972
  onMouseDown: handleMouseDown,
2980
2973
  onMouseUp: handleMouseUp,
2981
- isHovered: isHovered,
2982
2974
  isActive: isActive,
2983
2975
  overLight: isOverLight,
2984
2976
  overLightConfig: {
@@ -2994,7 +2986,6 @@ const PERFORMANCE_PRESET = {
2994
2986
  shaderVariant: shaderVariant,
2995
2987
  withLiquidBlur: withLiquidBlur,
2996
2988
  isFixedOrSticky: isFixedOrSticky,
2997
- // Phase 1: Animation System props
2998
2989
  shaderTime: getShaderTime(),
2999
2990
  withTimeAnimation: withTimeAnimation,
3000
2991
  animationSpeed: animationSpeed,
@@ -3006,32 +2997,39 @@ const PERFORMANCE_PRESET = {
3006
2997
  children: children
3007
2998
  }), Boolean(onClick) && jsxs(Fragment, {
3008
2999
  children: [ jsx("div", {
3000
+ "aria-hidden": "true",
3009
3001
  className: ATOMIX_GLASS.HOVER_1_CLASS
3010
3002
  }), jsx("div", {
3003
+ "aria-hidden": "true",
3011
3004
  className: ATOMIX_GLASS.HOVER_2_CLASS
3012
3005
  }), jsx("div", {
3006
+ "aria-hidden": "true",
3013
3007
  className: ATOMIX_GLASS.HOVER_3_CLASS
3014
3008
  }) ]
3015
- }), renderBackgroundLayer("dark"), renderBackgroundLayer("black"), shouldRenderOverLightLayers && jsxs(Fragment, {
3009
+ }), [ "dark", "black" ].map((layerType => jsx(React.Fragment, {
3010
+ children: renderBackgroundLayer(layerType)
3011
+ }, layerType))), shouldRenderOverLightLayers && jsxs(Fragment, {
3016
3012
  children: [ jsx("div", {
3013
+ "aria-hidden": "true",
3017
3014
  className: ATOMIX_GLASS.BASE_LAYER_CLASS
3018
3015
  }), jsx("div", {
3016
+ "aria-hidden": "true",
3019
3017
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
3020
3018
  }), jsx("div", {
3019
+ "aria-hidden": "true",
3021
3020
  className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
3022
3021
  }) ]
3023
- }), withBorder && jsxs(Fragment, {
3022
+ }), resolvedBorder.enabled && jsxs(Fragment, {
3024
3023
  children: [ jsx("span", {
3024
+ "aria-hidden": "true",
3025
3025
  className: ATOMIX_GLASS.BORDER_BACKDROP_CLASS
3026
3026
  }), jsx("span", {
3027
+ "aria-hidden": "true",
3027
3028
  className: ATOMIX_GLASS.BORDER_1_CLASS
3028
3029
  }), jsx("span", {
3030
+ "aria-hidden": "true",
3029
3031
  className: ATOMIX_GLASS.BORDER_2_CLASS
3030
3032
  }) ]
3031
- }), debugPerformance && performanceMetrics && jsx(PerformanceDashboard, {
3032
- metrics: performanceMetrics,
3033
- isVisible: !0,
3034
- onClose: () => {}
3035
3033
  }) ]
3036
3034
  });
3037
3035
  }));
@@ -3041,10 +3039,7 @@ const PERFORMANCE_PRESET = {
3041
3039
  * Default preset for most mobile devices
3042
3040
  */ AtomixGlassInner.displayName = "AtomixGlass";
3043
3041
 
3044
- /**
3045
- * AtomixGlass - wrapped with React.memo to prevent unnecessary re-renders.
3046
- * Ref is forwarded to the root `<div>` element.
3047
- */
3042
+ /** Memoized public export. Ref targets the root `.c-atomix-glass` wrapper. */
3048
3043
  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
3044
  // Local ref to handle indeterminate state
3050
3045
  const localRef = useRef(null);
@@ -3095,14 +3090,7 @@ const AtomixGlass = memo(AtomixGlassInner), Checkbox = React.memo( forwardRef(
3095
3090
  style: style,
3096
3091
  children: inputElement
3097
3092
  }), 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 : {
3093
+ const defaultGlassProps = GLASS_DEFAULTS_CHECKBOX, glassProps = !0 === glass ? defaultGlassProps : {
3106
3094
  ...defaultGlassProps,
3107
3095
  ...glass
3108
3096
  };
@@ -3313,15 +3301,7 @@ const Input = memo( forwardRef((({type: type = "text", value: value, defaultVal
3313
3301
  } : style
3314
3302
  });
3315
3303
  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 : {
3304
+ const defaultGlassProps = GLASS_DEFAULTS_INPUT, glassProps = !0 === glass ? defaultGlassProps : {
3325
3305
  ...defaultGlassProps,
3326
3306
  ...glass
3327
3307
  };
@@ -3398,15 +3378,7 @@ const Radio = memo((({label: label, checked: checked = !1, onChange: onChange,
3398
3378
  }) ]
3399
3379
  });
3400
3380
  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 : {
3381
+ const defaultGlassProps = GLASS_DEFAULTS_RADIO, glassProps = !0 === glass ? defaultGlassProps : {
3410
3382
  ...defaultGlassProps,
3411
3383
  ...glass
3412
3384
  };
@@ -3724,12 +3696,7 @@ const SelectComponentBase = ({options: options, value: value, onChange: onChange
3724
3696
  });
3725
3697
  // Handle item selection
3726
3698
  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 : {
3699
+ const defaultGlassProps = GLASS_DEFAULTS_SELECT, glassProps = !0 === glass ? defaultGlassProps : {
3733
3700
  ...defaultGlassProps,
3734
3701
  ...glass
3735
3702
  };
@@ -3809,15 +3776,7 @@ const Textarea = memo( forwardRef((({value: value, defaultValue: defaultValue,
3809
3776
  } : style
3810
3777
  });
3811
3778
  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 : {
3779
+ const defaultGlassProps = GLASS_DEFAULTS_TEXTAREA, glassProps = !0 === glass ? defaultGlassProps : {
3821
3780
  ...defaultGlassProps,
3822
3781
  ...glass
3823
3782
  };