@shohojdhara/atomix 0.4.5 → 0.4.7

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 (54) hide show
  1. package/dist/atomix.css +70 -33
  2. package/dist/atomix.css.map +1 -1
  3. package/dist/atomix.min.css +2 -2
  4. package/dist/atomix.min.css.map +1 -1
  5. package/dist/charts.d.ts +93 -109
  6. package/dist/charts.js +273 -371
  7. package/dist/charts.js.map +1 -1
  8. package/dist/core.js +183 -184
  9. package/dist/core.js.map +1 -1
  10. package/dist/forms.js +183 -184
  11. package/dist/forms.js.map +1 -1
  12. package/dist/heavy.js +183 -184
  13. package/dist/heavy.js.map +1 -1
  14. package/dist/index.d.ts +7 -51
  15. package/dist/index.esm.js +281 -470
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +287 -476
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.min.js +1 -1
  20. package/dist/index.min.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/components/AtomixGlass/AtomixGlass.tsx +60 -38
  23. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +6 -35
  24. package/src/components/AtomixGlass/glass-utils.ts +27 -14
  25. package/src/components/AtomixGlass/stories/Overview.stories.tsx +19 -21
  26. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1162 -515
  27. package/src/components/AtomixGlass/stories/shared-components.tsx +11 -3
  28. package/src/components/Chart/BubbleChart.tsx +6 -2
  29. package/src/components/Chart/Chart.stories.tsx +108 -96
  30. package/src/components/Chart/ChartToolbar.tsx +6 -4
  31. package/src/components/Chart/ChartTooltip.tsx +5 -4
  32. package/src/components/Chart/GaugeChart.tsx +20 -12
  33. package/src/components/Chart/HeatmapChart.tsx +53 -23
  34. package/src/components/Chart/TreemapChart.tsx +44 -15
  35. package/src/components/Chart/index.ts +0 -2
  36. package/src/components/Chart/types.ts +4 -4
  37. package/src/components/Navigation/Navbar/Navbar.tsx +13 -5
  38. package/src/components/index.ts +0 -1
  39. package/src/lib/composables/index.ts +1 -2
  40. package/src/lib/composables/useAtomixGlass.ts +246 -222
  41. package/src/lib/composables/useAtomixGlassStyles.ts +46 -23
  42. package/src/lib/constants/components.ts +3 -1
  43. package/src/styles/01-settings/_settings.chart.scss +13 -13
  44. package/src/styles/06-components/_components.atomix-glass.scss +45 -20
  45. package/src/styles/06-components/_components.chart.scss +23 -5
  46. package/src/components/Chart/AnimatedChart.tsx +0 -230
  47. package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +0 -329
  48. package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +0 -82
  49. package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +0 -153
  50. package/src/lib/composables/atomix-glass/useGlassOverLight.ts +0 -198
  51. package/src/lib/composables/atomix-glass/useGlassState.ts +0 -112
  52. package/src/lib/composables/atomix-glass/useGlassTransforms.ts +0 -160
  53. package/src/lib/composables/glass-styles.ts +0 -302
  54. package/src/lib/composables/useGlassContainer.ts +0 -177
package/dist/heavy.js CHANGED
@@ -76,7 +76,9 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
76
76
  ENABLE_OVER_LIGHT_LAYERS: !0
77
77
  },
78
78
  CONSTANTS: {
79
- ACTIVATION_ZONE: 200,
79
+ ACTIVATION_ZONE: 350,
80
+ LERP_FACTOR: .08,
81
+ SMOOTHSTEP_POWER: 2.5,
80
82
  MIN_BLUR: .1,
81
83
  MOUSE_INFLUENCE_DIVISOR: 100,
82
84
  EDGE_FADE_PIXELS: 2,
@@ -312,7 +314,7 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
312
314
  // Silently handle errors
313
315
  }
314
316
  return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
315
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
317
+ }, lerp = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
316
318
  switch (mode) {
317
319
  case "standard":
318
320
  return displacementMap;
@@ -668,20 +670,12 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
668
670
  onClick: onClick,
669
671
  children: jsxs("div", {
670
672
  className: ATOMIX_GLASS.INNER_CLASS,
671
- style: {
672
- padding: "var(--atomix-glass-container-padding)",
673
- boxShadow: "var(--atomix-glass-container-box-shadow)"
674
- },
675
673
  onMouseEnter: onMouseEnter,
676
674
  onMouseLeave: onMouseLeave,
677
675
  onMouseDown: onMouseDown,
678
676
  onMouseUp: onMouseUp,
679
677
  children: [ jsxs("div", {
680
678
  className: ATOMIX_GLASS.FILTER_CLASS,
681
- style: {
682
- position: "absolute",
683
- inset: 0
684
- },
685
679
  children: [ jsx(GlassFilter, {
686
680
  blurAmount: blurAmount,
687
681
  mode: mode,
@@ -696,26 +690,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
696
690
  },
697
691
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
698
692
  style: {
699
- filter: `url(#${filterId})`,
700
- backdropFilter: "var(--atomix-glass-container-backdrop)",
701
- borderRadius: "var(--atomix-glass-container-radius)"
693
+ filter: `url(#${filterId})`
702
694
  }
703
695
  }), jsx("div", {
704
- className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
705
- style: {
706
- boxShadow: "var(--atomix-glass-container-shadow)",
707
- opacity: "var(--atomix-glass-container-shadow-opacity)",
708
- background: "var(--atomix-glass-container-bg)",
709
- borderRadius: "var(--atomix-glass-container-radius)"
710
- }
696
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
711
697
  }) ]
712
698
  }), jsx("div", {
713
699
  ref: contentRef,
714
700
  className: ATOMIX_GLASS.CONTENT_CLASS,
715
- style: {
716
- position: "relative",
717
- textShadow: "var(--atomix-glass-container-text-shadow)"
718
- },
719
701
  children: children
720
702
  }) ]
721
703
  })
@@ -819,31 +801,39 @@ class {
819
801
  saturationBoost: baseOverLightConfig.saturationBoost
820
802
  };
821
803
  // Calculate mouse influence
822
- // Calculate elastic translation
823
- let elasticTranslation = {
804
+ let computedDirectionalScale = directionalScale, elasticTranslation = {
824
805
  x: 0,
825
806
  y: 0
826
807
  };
827
- if (!effectiveWithoutEffects && wrapperElement) {
808
+ // Calculate elastic translation and directional scale
809
+ if (!effectiveWithoutEffects && wrapperElement) {
828
810
  const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
829
- // Calculate fade in factor
830
- let fadeInFactor = 0;
811
+ // Mouse presence and edge distance logic
831
812
  if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
832
- const edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
813
+ const deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
833
814
  x: edgeDistanceX,
834
815
  y: edgeDistanceY
835
816
  }, {
836
817
  x: 0,
837
818
  y: 0
838
- });
839
- fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
819
+ }), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
820
+ const clamped = Math.max(0, Math.min(1, t));
821
+ return clamped * clamped * (3 - 2 * clamped);
822
+ })(rawT);
823
+ // Directional scale
824
+ if (elasticTranslation = {
825
+ x: deltaX * elasticity * .1 * fadeInFactor,
826
+ y: deltaY * elasticity * .1 * fadeInFactor
827
+ }, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
828
+ const centerDistance = calculateDistance(globalMousePosition, center);
829
+ if (centerDistance > 0) {
830
+ const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15, softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), .2), softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), .2);
831
+ computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
832
+ }
833
+ }
840
834
  }
841
- elasticTranslation = {
842
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
843
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
844
- };
845
835
  }
846
- const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`;
836
+ const transformStyle = effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : computedDirectionalScale}`;
847
837
  // Update Wrapper Styles (glassVars)
848
838
  if (wrapperElement) {
849
839
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER, 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), 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 ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
@@ -950,7 +940,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
950
940
  }), internalMouseOffsetRef = useRef({
951
941
  x: 0,
952
942
  y: 0
953
- }), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
943
+ }), targetMouseOffsetRef = useRef({
944
+ x: 0,
945
+ y: 0
946
+ }), targetGlobalMousePositionRef = useRef({
947
+ x: 0,
948
+ y: 0
949
+ }), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveBorderRadius = useMemo((() => void 0 !== borderRadius ? Math.max(0, borderRadius) : Math.max(0, dynamicBorderRadius)), [ borderRadius, dynamicBorderRadius ]), {glassSize: glassSize} = function({glassRef: glassRef, effectiveBorderRadius: effectiveBorderRadius, cachedRectRef: cachedRectRef}) {
954
950
  const [glassSize, setGlassSize] = useState({
955
951
  width: 270,
956
952
  height: 69
@@ -1047,7 +1043,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1047
1043
  const timeoutId = setTimeout(extractRadius, 100);
1048
1044
  return () => clearTimeout(timeoutId);
1049
1045
  }), [ children, debugBorderRadius, contentRef ]),
1050
- // Media query handlers and background detection
1046
+ // Media query detection for reduced motion and high contrast
1047
+ useEffect((() => {
1048
+ if ("undefined" == typeof window || "function" != typeof window.matchMedia) return;
1049
+ const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1050
+ setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1051
+ const handleReducedMotionChange = e => {
1052
+ setUserPrefersReducedMotion(e.matches);
1053
+ }, handleHighContrastChange = e => {
1054
+ setUserPrefersHighContrast(e.matches);
1055
+ };
1056
+ return mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1057
+ mediaQueryHighContrast.addEventListener("change", handleHighContrastChange), () => {
1058
+ mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
1059
+ mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange);
1060
+ };
1061
+ }), []),
1062
+ // Background detection for overLight auto-detect
1051
1063
  useEffect((() => {
1052
1064
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
1053
1065
  const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
@@ -1147,102 +1159,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1147
1159
  }), 150);
1148
1160
  return () => clearTimeout(timeoutId);
1149
1161
  }
1150
- if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
1151
- const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1152
- setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1153
- const handleReducedMotionChange = e => {
1154
- setUserPrefersReducedMotion(e.matches);
1155
- }, handleHighContrastChange = e => {
1156
- setUserPrefersHighContrast(e.matches);
1157
- };
1158
- return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1159
- mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
1160
- mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
1161
- // ignore
1162
- };
1163
- } catch (error) {
1164
- return;
1165
- }
1166
- }), [ overLight, glassRef, debugOverLight ]);
1162
+ "boolean" == typeof overLight && setDetectedOverLight(!1);
1163
+ }), [ overLight, glassRef ]);
1167
1164
  /**
1168
1165
  * Get effective overLight value based on configuration
1169
1166
  */
1170
- const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), baseOverLightConfig = useMemo((() => {
1171
- const isOverLight = getEffectiveOverLight(), baseConfig = {
1167
+ const getEffectiveOverLight = useCallback((() => "boolean" == typeof overLight ? overLight : ("auto" === overLight || "object" == typeof overLight && null !== overLight) && detectedOverLight), [ overLight, detectedOverLight ]), validateConfigValue = useCallback(((value, min, max, defaultValue) => "number" != typeof value || isNaN(value) || !isFinite(value) ? defaultValue : Math.min(max, Math.max(min, value))), []), overLightConfig = useMemo((() => {
1168
+ const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
1172
1169
  isOverLight: isOverLight,
1173
1170
  threshold: .7,
1174
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
1175
- contrast: 1,
1176
- // Base contrast
1177
- brightness: 1,
1178
- // Base brightness
1171
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1172
+ contrast: 1.4,
1173
+ brightness: .9,
1179
1174
  saturationBoost: 1.3,
1175
+ // Fixed value — dynamic saturation amplifies perceived displacement
1180
1176
  shadowIntensity: .9,
1181
1177
  borderOpacity: .7
1182
1178
  };
1183
1179
  if ("object" == typeof overLight && null !== overLight) {
1184
- 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);
1185
- return {
1180
+ 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 = {
1186
1181
  ...baseConfig,
1187
1182
  threshold: validatedThreshold,
1188
- opacity: validatedOpacity,
1183
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
1189
1184
  contrast: validatedContrast,
1190
1185
  brightness: validatedBrightness,
1191
1186
  saturationBoost: validatedSaturationBoost
1192
1187
  };
1188
+ return "undefined" == typeof process || process.env, finalConfig;
1193
1189
  }
1194
- return baseConfig;
1195
- }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = useMemo((() => {
1196
- const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
1197
- return {
1198
- isOverLight: baseOverLightConfig.isOverLight,
1199
- threshold: baseOverLightConfig.threshold,
1200
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
1201
- contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
1202
- brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
1203
- saturationBoost: baseOverLightConfig.saturationBoost,
1204
- shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
1205
- borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
1206
- };
1207
- }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
1208
- if (baseOverLightConfig.isOverLight) return "scale(1)";
1209
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1210
- const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
1211
- x: edgeDistanceX,
1212
- y: edgeDistanceY
1213
- }, {
1214
- x: 0,
1215
- y: 0
1216
- });
1217
- if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
1218
- const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
1219
- if (0 === centerDistance) return "scale(1)";
1220
- const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
1221
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1222
- }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
1223
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1224
- const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
1225
- x: edgeDistanceX,
1226
- y: edgeDistanceY
1227
- }, {
1228
- x: 0,
1229
- y: 0
1230
- });
1231
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
1232
- }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
1233
- if (!glassRef.current) return {
1234
- x: 0,
1235
- y: 0
1236
- };
1237
- const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
1238
- return {
1239
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1240
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1241
- };
1242
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
1243
- x: 0,
1244
- y: 0
1245
- } : calculateElasticTranslation()), [ calculateElasticTranslation, effectiveWithoutEffects ]), directionalScale = useMemo((() => effectiveWithoutEffects ? "scale(1)" : calculateDirectionalScale()), [ calculateDirectionalScale, effectiveWithoutEffects ]), transformStyle = useMemo((() => effectiveWithoutEffects ? isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)" : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? "scale(0.96)" : directionalScale}`), [ elasticTranslation, isActive, onClick, directionalScale, effectiveWithoutEffects ]), handleGlobalMousePosition = useCallback((globalPos => {
1190
+ return "undefined" == typeof process || process.env, baseConfig;
1191
+ }), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), handleGlobalMousePosition = useCallback((globalPos => {
1246
1192
  if (externalGlobalMousePosition && externalMouseOffset) return;
1247
1193
  if (effectiveWithoutEffects) return;
1248
1194
  const container = mouseContainer?.current || glassRef.current;
@@ -1251,35 +1197,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1251
1197
  let rect = cachedRectRef.current;
1252
1198
  if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
1253
1199
  cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
1254
- const center = calculateElementCenter(rect), newOffset = {
1200
+ const center = calculateElementCenter(rect);
1201
+ // Write raw target — the lerp loop will smoothly pursue it
1202
+ targetMouseOffsetRef.current = {
1255
1203
  x: (globalPos.x - center.x) / rect.width * 100,
1256
1204
  y: (globalPos.y - center.y) / rect.height * 100
1205
+ }, targetGlobalMousePositionRef.current = globalPos;
1206
+ }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
1207
+ if (lerpActiveRef.current) return;
1208
+ lerpActiveRef.current = !0;
1209
+ const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
1210
+ if (!lerpActiveRef.current) return;
1211
+ const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
1212
+ // If we're close enough, snap and park
1213
+ if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
1214
+ ...tgt
1215
+ }, internalGlobalMousePositionRef.current = {
1216
+ ...targetGlobalMousePositionRef.current
1217
+ }; else {
1218
+ internalMouseOffsetRef.current = {
1219
+ x: lerp(cur.x, tgt.x, LERP_T),
1220
+ y: lerp(cur.y, tgt.y, LERP_T)
1221
+ };
1222
+ const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
1223
+ internalGlobalMousePositionRef.current = {
1224
+ x: lerp(curG.x, tgtG.x, LERP_T),
1225
+ y: lerp(curG.y, tgtG.y, LERP_T)
1226
+ };
1227
+ }
1228
+ // Imperative style update with the smoothed values
1229
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1230
+ mouseOffset: internalMouseOffsetRef.current,
1231
+ globalMousePosition: internalGlobalMousePositionRef.current,
1232
+ glassSize: glassSize,
1233
+ isHovered: isHovered,
1234
+ isActive: isActive,
1235
+ isOverLight: overLightConfig.isOverLight,
1236
+ baseOverLightConfig: overLightConfig,
1237
+ effectiveBorderRadius: effectiveBorderRadius,
1238
+ effectiveWithoutEffects: effectiveWithoutEffects,
1239
+ effectiveReducedMotion: effectiveReducedMotion,
1240
+ elasticity: elasticity,
1241
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1242
+ onClick: onClick,
1243
+ withLiquidBlur: withLiquidBlur,
1244
+ blurAmount: blurAmount,
1245
+ saturation: saturation,
1246
+ padding: padding
1247
+ }), lerpRafRef.current = requestAnimationFrame(tick);
1257
1248
  };
1258
- // Calculate offset relative to this container
1259
- // Store in refs instead of state
1260
- internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
1261
- // Imperative style update
1262
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1263
- mouseOffset: newOffset,
1264
- globalMousePosition: globalPos,
1265
- glassSize: glassSize,
1266
- isHovered: isHovered,
1267
- isActive: isActive,
1268
- isOverLight: baseOverLightConfig.isOverLight,
1269
- baseOverLightConfig: baseOverLightConfig,
1270
- effectiveBorderRadius: effectiveBorderRadius,
1271
- effectiveWithoutEffects: effectiveWithoutEffects,
1272
- effectiveReducedMotion: effectiveReducedMotion,
1273
- elasticity: elasticity,
1274
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1275
- // Simplified directional scale for fast path
1276
- onClick: onClick,
1277
- withLiquidBlur: withLiquidBlur,
1278
- blurAmount: blurAmount,
1279
- saturation: saturation,
1280
- padding: padding
1281
- });
1282
- }), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
1249
+ // 0.08 lower = more viscous
1250
+ lerpRafRef.current = requestAnimationFrame(tick);
1251
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = useCallback((() => {
1252
+ lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
1253
+ lerpRafRef.current = null);
1254
+ }), []);
1283
1255
  /**
1284
1256
  * Validate and clamp a numeric config value
1285
1257
  */
@@ -1287,7 +1259,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1287
1259
  useEffect((() => {
1288
1260
  if (externalGlobalMousePosition && externalMouseOffset) return;
1289
1261
  if (effectiveWithoutEffects) return;
1290
- const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
1262
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
1263
+ // Start the lerp loop — it will smoothly chase the target
1264
+ startLerpLoop();
1265
+ const container = mouseContainer?.current || glassRef.current;
1291
1266
  let resizeObserver = null;
1292
1267
  return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
1293
1268
  null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
@@ -1295,10 +1270,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1295
1270
  container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
1296
1271
  }));
1297
1272
  })), resizeObserver.observe(container)), () => {
1298
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1273
+ unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1299
1274
  updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
1300
1275
  };
1301
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1276
+ }), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1302
1277
  // Also call updateStyles on other state changes (hover, active, etc)
1303
1278
  useEffect((() => {
1304
1279
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
@@ -1307,22 +1282,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1307
1282
  glassSize: glassSize,
1308
1283
  isHovered: isHovered,
1309
1284
  isActive: isActive,
1310
- isOverLight: baseOverLightConfig.isOverLight,
1311
- baseOverLightConfig: baseOverLightConfig,
1285
+ isOverLight: overLightConfig.isOverLight,
1286
+ baseOverLightConfig: overLightConfig,
1312
1287
  effectiveBorderRadius: effectiveBorderRadius,
1313
1288
  effectiveWithoutEffects: effectiveWithoutEffects,
1314
1289
  effectiveReducedMotion: effectiveReducedMotion,
1315
1290
  elasticity: elasticity,
1316
- directionalScale: directionalScale,
1291
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1317
1292
  onClick: onClick,
1318
1293
  withLiquidBlur: withLiquidBlur,
1319
1294
  blurAmount: blurAmount,
1320
1295
  saturation: saturation,
1321
1296
  padding: padding
1322
1297
  });
1323
- }), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1298
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1324
1299
  // Event handlers
1325
- const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleMouseMove = useCallback((_e => {}), []), handleKeyDown = useCallback((e => {
1300
+ const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1326
1301
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1327
1302
  }), [ onClick ]);
1328
1303
  return {
@@ -1340,14 +1315,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1340
1315
  mouseOffset: mouseOffset,
1341
1316
  // This is now static (refs or props) unless prop changes
1342
1317
  overLightConfig: overLightConfig,
1343
- elasticTranslation: elasticTranslation,
1344
- directionalScale: directionalScale,
1345
1318
  transformStyle: transformStyle,
1346
1319
  handleMouseEnter: handleMouseEnter,
1347
1320
  handleMouseLeave: handleMouseLeave,
1348
1321
  handleMouseDown: handleMouseDown,
1349
1322
  handleMouseUp: handleMouseUp,
1350
- handleMouseMove: handleMouseMove,
1351
1323
  handleKeyDown: handleKeyDown
1352
1324
  };
1353
1325
  }
@@ -1445,25 +1417,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1445
1417
  withLiquidBlur: withLiquidBlur,
1446
1418
  padding: padding,
1447
1419
  style: style
1448
- }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
1449
- ...style,
1450
- ...!effectiveWithoutEffects && {
1451
- transform: transformStyle
1420
+ }), isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, rootLayoutStyle = useMemo((() => {
1421
+ if (!isFixedOrSticky) return {};
1422
+ const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
1423
+ return {
1424
+ ...p && {
1425
+ position: p
1426
+ },
1427
+ ...void 0 !== t && {
1428
+ top: t
1429
+ },
1430
+ ...void 0 !== l && {
1431
+ left: l
1432
+ },
1433
+ ...void 0 !== r && {
1434
+ right: r
1435
+ },
1436
+ ...void 0 !== b && {
1437
+ bottom: b
1438
+ }
1439
+ };
1440
+ }), [ isFixedOrSticky, restStyle ]), baseStyle = useMemo((() => {
1441
+ if (isFixedOrSticky) {
1442
+ const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
1443
+ return {
1444
+ ...visualStyle,
1445
+ ...!effectiveWithoutEffects && {
1446
+ transform: transformStyle
1447
+ }
1448
+ };
1452
1449
  }
1453
- }, 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((() => ({
1454
- position: style.position || "absolute",
1455
- top: style.top || 0,
1456
- left: style.left || 0
1457
- })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => {
1450
+ return {
1451
+ ...restStyle,
1452
+ ...!effectiveWithoutEffects && {
1453
+ transform: transformStyle
1454
+ }
1455
+ };
1456
+ }), [ isFixedOrSticky, restStyle, effectiveWithoutEffects, transformStyle ]), 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((() => ({
1457
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
1458
+ top: isFixedOrSticky ? 0 : restStyle.top || 0,
1459
+ left: isFixedOrSticky ? 0 : restStyle.left || 0
1460
+ })), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = useMemo((() => {
1458
1461
  const resolveSize = (propValue, styleValue, measuredSize) => {
1459
1462
  const explicitSize = propValue ?? styleValue;
1460
1463
  return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
1461
1464
  };
1462
1465
  return {
1463
- width: resolveSize(width, style.width, glassSize.width),
1464
- height: resolveSize(height, style.height, glassSize.height)
1466
+ width: resolveSize(width, restStyle.width, glassSize.width),
1467
+ height: resolveSize(height, restStyle.height, glassSize.height)
1465
1468
  };
1466
- }), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1469
+ }), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1467
1470
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
1468
1471
  return {
1469
1472
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -1505,6 +1508,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1505
1508
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
1506
1509
  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, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
1507
1510
  return {
1511
+ ...void 0 !== customZIndex && {
1512
+ "--atomix-glass-base-z-index": customZIndex
1513
+ },
1508
1514
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
1509
1515
  "--atomix-glass-transform": transformStyle || "none",
1510
1516
  "--atomix-glass-position": positionStyles.position,
@@ -1525,22 +1531,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1525
1531
  "--atomix-glass-base-opacity": opacityValues.base,
1526
1532
  "--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})`,
1527
1533
  "--atomix-glass-overlay-opacity": opacityValues.over,
1528
- "--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})`
1534
+ "--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})`,
1535
+ "--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1536
+ "--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}%)`
1529
1537
  };
1530
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
1531
- 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(" "),
1532
- style: {
1533
- ...positionStyles,
1534
- height: adjustedSize.height,
1535
- width: adjustedSize.width,
1536
- borderRadius: `${effectiveBorderRadius}px`,
1537
- transform: baseStyle.transform
1538
- }
1538
+ }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex ]), renderBackgroundLayer = layerType => jsx("div", {
1539
+ 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(" ")
1539
1540
  });
1540
1541
  return jsxs("div", {
1541
1542
  ...rest,
1542
1543
  className: componentClassName,
1543
- style: glassVars,
1544
+ style: {
1545
+ ...glassVars
1546
+ },
1544
1547
  role: role || (onClick ? "button" : void 0),
1545
1548
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
1546
1549
  "aria-label": ariaLabel,
@@ -1552,7 +1555,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1552
1555
  ref: glassRef,
1553
1556
  contentRef: contentRef,
1554
1557
  className: className,
1555
- style: baseStyle,
1558
+ style: rootLayoutStyle,
1556
1559
  borderRadius: effectiveBorderRadius,
1557
1560
  displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1558
1561
  blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
@@ -1603,11 +1606,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1603
1606
  }), jsx("div", {
1604
1607
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
1605
1608
  }), jsx("div", {
1606
- className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
1607
- style: {
1608
- opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1609
- background: `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}%)`
1610
- }
1609
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
1611
1610
  }) ]
1612
1611
  }), withBorder && jsxs(Fragment, {
1613
1612
  children: [ jsx("span", {