@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/forms.js CHANGED
@@ -58,7 +58,9 @@ import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallb
58
58
  ENABLE_OVER_LIGHT_LAYERS: !0
59
59
  },
60
60
  CONSTANTS: {
61
- ACTIVATION_ZONE: 200,
61
+ ACTIVATION_ZONE: 350,
62
+ LERP_FACTOR: .08,
63
+ SMOOTHSTEP_POWER: 2.5,
62
64
  MIN_BLUR: .1,
63
65
  MOUSE_INFLUENCE_DIVISOR: 100,
64
66
  EDGE_FADE_PIXELS: 2,
@@ -294,7 +296,7 @@ import React, { memo, forwardRef, useMemo, useState, useRef, useEffect, useCallb
294
296
  // Silently handle errors
295
297
  }
296
298
  return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
297
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
299
+ }, 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) => {
298
300
  switch (mode) {
299
301
  case "standard":
300
302
  return displacementMap;
@@ -652,20 +654,12 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
652
654
  onClick: onClick,
653
655
  children: jsxs("div", {
654
656
  className: ATOMIX_GLASS.INNER_CLASS,
655
- style: {
656
- padding: "var(--atomix-glass-container-padding)",
657
- boxShadow: "var(--atomix-glass-container-box-shadow)"
658
- },
659
657
  onMouseEnter: onMouseEnter,
660
658
  onMouseLeave: onMouseLeave,
661
659
  onMouseDown: onMouseDown,
662
660
  onMouseUp: onMouseUp,
663
661
  children: [ jsxs("div", {
664
662
  className: ATOMIX_GLASS.FILTER_CLASS,
665
- style: {
666
- position: "absolute",
667
- inset: 0
668
- },
669
663
  children: [ jsx(GlassFilter, {
670
664
  blurAmount: blurAmount,
671
665
  mode: mode,
@@ -680,26 +674,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
680
674
  },
681
675
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
682
676
  style: {
683
- filter: `url(#${filterId})`,
684
- backdropFilter: "var(--atomix-glass-container-backdrop)",
685
- borderRadius: "var(--atomix-glass-container-radius)"
677
+ filter: `url(#${filterId})`
686
678
  }
687
679
  }), jsx("div", {
688
- className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
689
- style: {
690
- boxShadow: "var(--atomix-glass-container-shadow)",
691
- opacity: "var(--atomix-glass-container-shadow-opacity)",
692
- background: "var(--atomix-glass-container-bg)",
693
- borderRadius: "var(--atomix-glass-container-radius)"
694
- }
680
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
695
681
  }) ]
696
682
  }), jsx("div", {
697
683
  ref: contentRef,
698
684
  className: ATOMIX_GLASS.CONTENT_CLASS,
699
- style: {
700
- position: "relative",
701
- textShadow: "var(--atomix-glass-container-text-shadow)"
702
- },
703
685
  children: children
704
686
  }) ]
705
687
  })
@@ -803,31 +785,39 @@ class {
803
785
  saturationBoost: baseOverLightConfig.saturationBoost
804
786
  };
805
787
  // Calculate mouse influence
806
- // Calculate elastic translation
807
- let elasticTranslation = {
788
+ let computedDirectionalScale = directionalScale, elasticTranslation = {
808
789
  x: 0,
809
790
  y: 0
810
791
  };
811
- if (!effectiveWithoutEffects && wrapperElement) {
792
+ // Calculate elastic translation and directional scale
793
+ if (!effectiveWithoutEffects && wrapperElement) {
812
794
  const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
813
- // Calculate fade in factor
814
- let fadeInFactor = 0;
795
+ // Mouse presence and edge distance logic
815
796
  if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
816
- 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({
797
+ 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({
817
798
  x: edgeDistanceX,
818
799
  y: edgeDistanceY
819
800
  }, {
820
801
  x: 0,
821
802
  y: 0
822
- });
823
- fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
803
+ }), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
804
+ const clamped = Math.max(0, Math.min(1, t));
805
+ return clamped * clamped * (3 - 2 * clamped);
806
+ })(rawT);
807
+ // Directional scale
808
+ if (elasticTranslation = {
809
+ x: deltaX * elasticity * .1 * fadeInFactor,
810
+ y: deltaY * elasticity * .1 * fadeInFactor
811
+ }, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
812
+ const centerDistance = calculateDistance(globalMousePosition, center);
813
+ if (centerDistance > 0) {
814
+ 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);
815
+ computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
816
+ }
817
+ }
824
818
  }
825
- elasticTranslation = {
826
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
827
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
828
- };
829
819
  }
830
- 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}`;
820
+ 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}`;
831
821
  // Update Wrapper Styles (glassVars)
832
822
  if (wrapperElement) {
833
823
  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 = {
@@ -934,7 +924,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
934
924
  }), internalMouseOffsetRef = useRef({
935
925
  x: 0,
936
926
  y: 0
937
- }), [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}) {
927
+ }), targetMouseOffsetRef = useRef({
928
+ x: 0,
929
+ y: 0
930
+ }), targetGlobalMousePositionRef = useRef({
931
+ x: 0,
932
+ y: 0
933
+ }), 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}) {
938
934
  const [glassSize, setGlassSize] = useState({
939
935
  width: 270,
940
936
  height: 69
@@ -1031,7 +1027,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1031
1027
  const timeoutId = setTimeout(extractRadius, 100);
1032
1028
  return () => clearTimeout(timeoutId);
1033
1029
  }), [ children, debugBorderRadius, contentRef ]),
1034
- // Media query handlers and background detection
1030
+ // Media query detection for reduced motion and high contrast
1031
+ useEffect((() => {
1032
+ if ("undefined" == typeof window || "function" != typeof window.matchMedia) return;
1033
+ const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1034
+ setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1035
+ const handleReducedMotionChange = e => {
1036
+ setUserPrefersReducedMotion(e.matches);
1037
+ }, handleHighContrastChange = e => {
1038
+ setUserPrefersHighContrast(e.matches);
1039
+ };
1040
+ return mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1041
+ mediaQueryHighContrast.addEventListener("change", handleHighContrastChange), () => {
1042
+ mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
1043
+ mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange);
1044
+ };
1045
+ }), []),
1046
+ // Background detection for overLight auto-detect
1035
1047
  useEffect((() => {
1036
1048
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
1037
1049
  const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
@@ -1131,102 +1143,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1131
1143
  }), 150);
1132
1144
  return () => clearTimeout(timeoutId);
1133
1145
  }
1134
- if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
1135
- const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1136
- setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1137
- const handleReducedMotionChange = e => {
1138
- setUserPrefersReducedMotion(e.matches);
1139
- }, handleHighContrastChange = e => {
1140
- setUserPrefersHighContrast(e.matches);
1141
- };
1142
- return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1143
- mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
1144
- mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
1145
- // ignore
1146
- };
1147
- } catch (error) {
1148
- return;
1149
- }
1150
- }), [ overLight, glassRef, debugOverLight ]);
1146
+ "boolean" == typeof overLight && setDetectedOverLight(!1);
1147
+ }), [ overLight, glassRef ]);
1151
1148
  /**
1152
1149
  * Get effective overLight value based on configuration
1153
1150
  */
1154
- 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((() => {
1155
- const isOverLight = getEffectiveOverLight(), baseConfig = {
1151
+ 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((() => {
1152
+ const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
1156
1153
  isOverLight: isOverLight,
1157
1154
  threshold: .7,
1158
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
1159
- contrast: 1,
1160
- // Base contrast
1161
- brightness: 1,
1162
- // Base brightness
1155
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1156
+ contrast: 1.4,
1157
+ brightness: .9,
1163
1158
  saturationBoost: 1.3,
1159
+ // Fixed value — dynamic saturation amplifies perceived displacement
1164
1160
  shadowIntensity: .9,
1165
1161
  borderOpacity: .7
1166
1162
  };
1167
1163
  if ("object" == typeof overLight && null !== overLight) {
1168
- 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);
1169
- return {
1164
+ 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 = {
1170
1165
  ...baseConfig,
1171
1166
  threshold: validatedThreshold,
1172
- opacity: validatedOpacity,
1167
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
1173
1168
  contrast: validatedContrast,
1174
1169
  brightness: validatedBrightness,
1175
1170
  saturationBoost: validatedSaturationBoost
1176
1171
  };
1172
+ return "undefined" == typeof process || process.env, finalConfig;
1177
1173
  }
1178
- return baseConfig;
1179
- }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = useMemo((() => {
1180
- const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
1181
- return {
1182
- isOverLight: baseOverLightConfig.isOverLight,
1183
- threshold: baseOverLightConfig.threshold,
1184
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
1185
- contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
1186
- brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
1187
- saturationBoost: baseOverLightConfig.saturationBoost,
1188
- shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
1189
- borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
1190
- };
1191
- }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
1192
- if (baseOverLightConfig.isOverLight) return "scale(1)";
1193
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1194
- 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({
1195
- x: edgeDistanceX,
1196
- y: edgeDistanceY
1197
- }, {
1198
- x: 0,
1199
- y: 0
1200
- });
1201
- if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
1202
- const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
1203
- if (0 === centerDistance) return "scale(1)";
1204
- 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;
1205
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1206
- }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
1207
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1208
- 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({
1209
- x: edgeDistanceX,
1210
- y: edgeDistanceY
1211
- }, {
1212
- x: 0,
1213
- y: 0
1214
- });
1215
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
1216
- }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
1217
- if (!glassRef.current) return {
1218
- x: 0,
1219
- y: 0
1220
- };
1221
- const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
1222
- return {
1223
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1224
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1225
- };
1226
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
1227
- x: 0,
1228
- y: 0
1229
- } : 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 => {
1174
+ return "undefined" == typeof process || process.env, baseConfig;
1175
+ }), [ 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 => {
1230
1176
  if (externalGlobalMousePosition && externalMouseOffset) return;
1231
1177
  if (effectiveWithoutEffects) return;
1232
1178
  const container = mouseContainer?.current || glassRef.current;
@@ -1235,35 +1181,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1235
1181
  let rect = cachedRectRef.current;
1236
1182
  if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
1237
1183
  cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
1238
- const center = calculateElementCenter(rect), newOffset = {
1184
+ const center = calculateElementCenter(rect);
1185
+ // Write raw target — the lerp loop will smoothly pursue it
1186
+ targetMouseOffsetRef.current = {
1239
1187
  x: (globalPos.x - center.x) / rect.width * 100,
1240
1188
  y: (globalPos.y - center.y) / rect.height * 100
1189
+ }, targetGlobalMousePositionRef.current = globalPos;
1190
+ }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
1191
+ if (lerpActiveRef.current) return;
1192
+ lerpActiveRef.current = !0;
1193
+ const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
1194
+ if (!lerpActiveRef.current) return;
1195
+ const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
1196
+ // If we're close enough, snap and park
1197
+ if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
1198
+ ...tgt
1199
+ }, internalGlobalMousePositionRef.current = {
1200
+ ...targetGlobalMousePositionRef.current
1201
+ }; else {
1202
+ internalMouseOffsetRef.current = {
1203
+ x: lerp(cur.x, tgt.x, LERP_T),
1204
+ y: lerp(cur.y, tgt.y, LERP_T)
1205
+ };
1206
+ const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
1207
+ internalGlobalMousePositionRef.current = {
1208
+ x: lerp(curG.x, tgtG.x, LERP_T),
1209
+ y: lerp(curG.y, tgtG.y, LERP_T)
1210
+ };
1211
+ }
1212
+ // Imperative style update with the smoothed values
1213
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1214
+ mouseOffset: internalMouseOffsetRef.current,
1215
+ globalMousePosition: internalGlobalMousePositionRef.current,
1216
+ glassSize: glassSize,
1217
+ isHovered: isHovered,
1218
+ isActive: isActive,
1219
+ isOverLight: overLightConfig.isOverLight,
1220
+ baseOverLightConfig: overLightConfig,
1221
+ effectiveBorderRadius: effectiveBorderRadius,
1222
+ effectiveWithoutEffects: effectiveWithoutEffects,
1223
+ effectiveReducedMotion: effectiveReducedMotion,
1224
+ elasticity: elasticity,
1225
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1226
+ onClick: onClick,
1227
+ withLiquidBlur: withLiquidBlur,
1228
+ blurAmount: blurAmount,
1229
+ saturation: saturation,
1230
+ padding: padding
1231
+ }), lerpRafRef.current = requestAnimationFrame(tick);
1241
1232
  };
1242
- // Calculate offset relative to this container
1243
- // Store in refs instead of state
1244
- internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
1245
- // Imperative style update
1246
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1247
- mouseOffset: newOffset,
1248
- globalMousePosition: globalPos,
1249
- glassSize: glassSize,
1250
- isHovered: isHovered,
1251
- isActive: isActive,
1252
- isOverLight: baseOverLightConfig.isOverLight,
1253
- baseOverLightConfig: baseOverLightConfig,
1254
- effectiveBorderRadius: effectiveBorderRadius,
1255
- effectiveWithoutEffects: effectiveWithoutEffects,
1256
- effectiveReducedMotion: effectiveReducedMotion,
1257
- elasticity: elasticity,
1258
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1259
- // Simplified directional scale for fast path
1260
- onClick: onClick,
1261
- withLiquidBlur: withLiquidBlur,
1262
- blurAmount: blurAmount,
1263
- saturation: saturation,
1264
- padding: padding
1265
- });
1266
- }), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
1233
+ // 0.08 lower = more viscous
1234
+ lerpRafRef.current = requestAnimationFrame(tick);
1235
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = useCallback((() => {
1236
+ lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
1237
+ lerpRafRef.current = null);
1238
+ }), []);
1267
1239
  /**
1268
1240
  * Validate and clamp a numeric config value
1269
1241
  */
@@ -1271,7 +1243,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1271
1243
  useEffect((() => {
1272
1244
  if (externalGlobalMousePosition && externalMouseOffset) return;
1273
1245
  if (effectiveWithoutEffects) return;
1274
- const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
1246
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
1247
+ // Start the lerp loop — it will smoothly chase the target
1248
+ startLerpLoop();
1249
+ const container = mouseContainer?.current || glassRef.current;
1275
1250
  let resizeObserver = null;
1276
1251
  return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
1277
1252
  null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
@@ -1279,10 +1254,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1279
1254
  container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
1280
1255
  }));
1281
1256
  })), resizeObserver.observe(container)), () => {
1282
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1257
+ unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1283
1258
  updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
1284
1259
  };
1285
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1260
+ }), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1286
1261
  // Also call updateStyles on other state changes (hover, active, etc)
1287
1262
  useEffect((() => {
1288
1263
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
@@ -1291,22 +1266,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1291
1266
  glassSize: glassSize,
1292
1267
  isHovered: isHovered,
1293
1268
  isActive: isActive,
1294
- isOverLight: baseOverLightConfig.isOverLight,
1295
- baseOverLightConfig: baseOverLightConfig,
1269
+ isOverLight: overLightConfig.isOverLight,
1270
+ baseOverLightConfig: overLightConfig,
1296
1271
  effectiveBorderRadius: effectiveBorderRadius,
1297
1272
  effectiveWithoutEffects: effectiveWithoutEffects,
1298
1273
  effectiveReducedMotion: effectiveReducedMotion,
1299
1274
  elasticity: elasticity,
1300
- directionalScale: directionalScale,
1275
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1301
1276
  onClick: onClick,
1302
1277
  withLiquidBlur: withLiquidBlur,
1303
1278
  blurAmount: blurAmount,
1304
1279
  saturation: saturation,
1305
1280
  padding: padding
1306
1281
  });
1307
- }), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1282
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1308
1283
  // Event handlers
1309
- const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleMouseMove = useCallback((_e => {}), []), handleKeyDown = useCallback((e => {
1284
+ const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1310
1285
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1311
1286
  }), [ onClick ]);
1312
1287
  return {
@@ -1324,14 +1299,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1324
1299
  mouseOffset: mouseOffset,
1325
1300
  // This is now static (refs or props) unless prop changes
1326
1301
  overLightConfig: overLightConfig,
1327
- elasticTranslation: elasticTranslation,
1328
- directionalScale: directionalScale,
1329
1302
  transformStyle: transformStyle,
1330
1303
  handleMouseEnter: handleMouseEnter,
1331
1304
  handleMouseLeave: handleMouseLeave,
1332
1305
  handleMouseDown: handleMouseDown,
1333
1306
  handleMouseUp: handleMouseUp,
1334
- handleMouseMove: handleMouseMove,
1335
1307
  handleKeyDown: handleKeyDown
1336
1308
  };
1337
1309
  }
@@ -1429,25 +1401,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1429
1401
  withLiquidBlur: withLiquidBlur,
1430
1402
  padding: padding,
1431
1403
  style: style
1432
- }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
1433
- ...style,
1434
- ...!effectiveWithoutEffects && {
1435
- transform: transformStyle
1404
+ }), isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, rootLayoutStyle = useMemo((() => {
1405
+ if (!isFixedOrSticky) return {};
1406
+ const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
1407
+ return {
1408
+ ...p && {
1409
+ position: p
1410
+ },
1411
+ ...void 0 !== t && {
1412
+ top: t
1413
+ },
1414
+ ...void 0 !== l && {
1415
+ left: l
1416
+ },
1417
+ ...void 0 !== r && {
1418
+ right: r
1419
+ },
1420
+ ...void 0 !== b && {
1421
+ bottom: b
1422
+ }
1423
+ };
1424
+ }), [ isFixedOrSticky, restStyle ]), baseStyle = useMemo((() => {
1425
+ if (isFixedOrSticky) {
1426
+ const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
1427
+ return {
1428
+ ...visualStyle,
1429
+ ...!effectiveWithoutEffects && {
1430
+ transform: transformStyle
1431
+ }
1432
+ };
1436
1433
  }
1437
- }, 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((() => ({
1438
- position: style.position || "absolute",
1439
- top: style.top || 0,
1440
- left: style.left || 0
1441
- })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => {
1434
+ return {
1435
+ ...restStyle,
1436
+ ...!effectiveWithoutEffects && {
1437
+ transform: transformStyle
1438
+ }
1439
+ };
1440
+ }), [ 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((() => ({
1441
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
1442
+ top: isFixedOrSticky ? 0 : restStyle.top || 0,
1443
+ left: isFixedOrSticky ? 0 : restStyle.left || 0
1444
+ })), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = useMemo((() => {
1442
1445
  const resolveSize = (propValue, styleValue, measuredSize) => {
1443
1446
  const explicitSize = propValue ?? styleValue;
1444
1447
  return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
1445
1448
  };
1446
1449
  return {
1447
- width: resolveSize(width, style.width, glassSize.width),
1448
- height: resolveSize(height, style.height, glassSize.height)
1450
+ width: resolveSize(width, restStyle.width, glassSize.width),
1451
+ height: resolveSize(height, restStyle.height, glassSize.height)
1449
1452
  };
1450
- }), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1453
+ }), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1451
1454
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
1452
1455
  return {
1453
1456
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -1489,6 +1492,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1489
1492
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
1490
1493
  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;
1491
1494
  return {
1495
+ ...void 0 !== customZIndex && {
1496
+ "--atomix-glass-base-z-index": customZIndex
1497
+ },
1492
1498
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
1493
1499
  "--atomix-glass-transform": transformStyle || "none",
1494
1500
  "--atomix-glass-position": positionStyles.position,
@@ -1509,22 +1515,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1509
1515
  "--atomix-glass-base-opacity": opacityValues.base,
1510
1516
  "--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})`,
1511
1517
  "--atomix-glass-overlay-opacity": opacityValues.over,
1512
- "--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})`
1518
+ "--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})`,
1519
+ "--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1520
+ "--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}%)`
1513
1521
  };
1514
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
1515
- 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(" "),
1516
- style: {
1517
- ...positionStyles,
1518
- height: adjustedSize.height,
1519
- width: adjustedSize.width,
1520
- borderRadius: `${effectiveBorderRadius}px`,
1521
- transform: baseStyle.transform
1522
- }
1522
+ }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex ]), renderBackgroundLayer = layerType => jsx("div", {
1523
+ 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(" ")
1523
1524
  });
1524
1525
  return jsxs("div", {
1525
1526
  ...rest,
1526
1527
  className: componentClassName,
1527
- style: glassVars,
1528
+ style: {
1529
+ ...glassVars
1530
+ },
1528
1531
  role: role || (onClick ? "button" : void 0),
1529
1532
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
1530
1533
  "aria-label": ariaLabel,
@@ -1536,7 +1539,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1536
1539
  ref: glassRef,
1537
1540
  contentRef: contentRef,
1538
1541
  className: className,
1539
- style: baseStyle,
1542
+ style: rootLayoutStyle,
1540
1543
  borderRadius: effectiveBorderRadius,
1541
1544
  displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1542
1545
  blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
@@ -1587,11 +1590,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1587
1590
  }), jsx("div", {
1588
1591
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
1589
1592
  }), jsx("div", {
1590
- className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
1591
- style: {
1592
- opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1593
- 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}%)`
1594
- }
1593
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
1595
1594
  }) ]
1596
1595
  }), withBorder && jsxs(Fragment, {
1597
1596
  children: [ jsx("span", {