@shohojdhara/atomix 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/atomix.css +50 -11
  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/charts.js +184 -189
  6. package/dist/charts.js.map +1 -1
  7. package/dist/core.d.ts +4 -4
  8. package/dist/core.js +194 -199
  9. package/dist/core.js.map +1 -1
  10. package/dist/forms.js +184 -189
  11. package/dist/forms.js.map +1 -1
  12. package/dist/heavy.js +189 -194
  13. package/dist/heavy.js.map +1 -1
  14. package/dist/index.d.ts +44 -47
  15. package/dist/index.esm.js +496 -613
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +528 -631
  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 -39
  23. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -42
  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/Breadcrumb/Breadcrumb.tsx +5 -5
  29. package/src/components/Breadcrumb/BreadcrumbCompound.test.tsx +2 -2
  30. package/src/components/Button/Button.tsx +6 -6
  31. package/src/components/Card/Card.tsx +3 -3
  32. package/src/components/Dropdown/Dropdown.tsx +5 -3
  33. package/src/components/Footer/Footer.tsx +124 -166
  34. package/src/components/Footer/FooterLink.tsx +16 -19
  35. package/src/components/Footer/FooterSection.tsx +40 -39
  36. package/src/components/Footer/FooterSocialLink.tsx +59 -58
  37. package/src/components/Footer/README.md +1 -1
  38. package/src/components/Hero/Hero.tsx +72 -142
  39. package/src/components/Navigation/Menu/MegaMenu.tsx +17 -12
  40. package/src/components/Navigation/Menu/Menu.tsx +49 -24
  41. package/src/components/Navigation/Nav/NavItem.tsx +5 -3
  42. package/src/components/Navigation/Navbar/Navbar.tsx +13 -5
  43. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -2
  44. package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -4
  45. package/src/components/Slider/Slider.tsx +7 -4
  46. package/src/lib/composables/index.ts +1 -2
  47. package/src/lib/composables/useAtomixGlass.ts +246 -222
  48. package/src/lib/composables/useAtomixGlassStyles.ts +46 -23
  49. package/src/lib/composables/useFooter.ts +117 -20
  50. package/src/lib/composables/useSlider.ts +3 -1
  51. package/src/lib/constants/components.ts +3 -1
  52. package/src/lib/types/components.ts +44 -12
  53. package/src/styles/06-components/_components.atomix-glass.scss +72 -14
  54. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +0 -222
  55. package/src/lib/composables/atomix-glass/useGlassBackgroundDetection.ts +0 -329
  56. package/src/lib/composables/atomix-glass/useGlassCornerRadius.ts +0 -82
  57. package/src/lib/composables/atomix-glass/useGlassMouseTracking.ts +0 -153
  58. package/src/lib/composables/atomix-glass/useGlassOverLight.ts +0 -198
  59. package/src/lib/composables/atomix-glass/useGlassState.ts +0 -112
  60. package/src/lib/composables/atomix-glass/useGlassTransforms.ts +0 -160
  61. package/src/lib/composables/glass-styles.ts +0 -302
  62. 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;
@@ -483,7 +485,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
483
485
  }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, borderRadius: borderRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
484
486
  width: 0,
485
487
  height: 0
486
- }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
488
+ }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, contentRef: contentRef}, ref) => {
487
489
  // Generate a stable, deterministic ID for SSR compatibility
488
490
  // Use a module-level counter that's consistent across server and client
489
491
  const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
@@ -668,21 +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
- zIndex: 1,
683
- position: "absolute",
684
- inset: 0
685
- },
686
679
  children: [ jsx(GlassFilter, {
687
680
  blurAmount: blurAmount,
688
681
  mode: mode,
@@ -697,28 +690,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
697
690
  },
698
691
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
699
692
  style: {
700
- filter: `url(#${filterId})`,
701
- backdropFilter: "var(--atomix-glass-container-backdrop)",
702
- borderRadius: "var(--atomix-glass-container-radius)"
693
+ filter: `url(#${filterId})`
703
694
  }
704
695
  }), jsx("div", {
705
- className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
706
- style: {
707
- boxShadow: "var(--atomix-glass-container-shadow)",
708
- opacity: "var(--atomix-glass-container-shadow-opacity)",
709
- background: "var(--atomix-glass-container-bg)",
710
- borderRadius: "var(--atomix-glass-container-radius)"
711
- }
696
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
712
697
  }) ]
713
698
  }), jsx("div", {
714
699
  ref: contentRef,
715
700
  className: ATOMIX_GLASS.CONTENT_CLASS,
716
- style: {
717
- position: "relative",
718
- textShadow: "var(--atomix-glass-container-text-shadow)",
719
- // Ensure content is always above the filter layer (zIndex 1)
720
- zIndex: elasticity > 0 ? 100 : 2
721
- },
722
701
  children: children
723
702
  }) ]
724
703
  })
@@ -822,31 +801,39 @@ class {
822
801
  saturationBoost: baseOverLightConfig.saturationBoost
823
802
  };
824
803
  // Calculate mouse influence
825
- // Calculate elastic translation
826
- let elasticTranslation = {
804
+ let computedDirectionalScale = directionalScale, elasticTranslation = {
827
805
  x: 0,
828
806
  y: 0
829
807
  };
830
- if (!effectiveWithoutEffects && wrapperElement) {
808
+ // Calculate elastic translation and directional scale
809
+ if (!effectiveWithoutEffects && wrapperElement) {
831
810
  const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
832
- // Calculate fade in factor
833
- let fadeInFactor = 0;
811
+ // Mouse presence and edge distance logic
834
812
  if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
835
- 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({
836
814
  x: edgeDistanceX,
837
815
  y: edgeDistanceY
838
816
  }, {
839
817
  x: 0,
840
818
  y: 0
841
- });
842
- 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
+ }
843
834
  }
844
- elasticTranslation = {
845
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
846
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
847
- };
848
835
  }
849
- 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}`;
850
837
  // Update Wrapper Styles (glassVars)
851
838
  if (wrapperElement) {
852
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 = {
@@ -953,7 +940,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
953
940
  }), internalMouseOffsetRef = useRef({
954
941
  x: 0,
955
942
  y: 0
956
- }), [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}) {
957
950
  const [glassSize, setGlassSize] = useState({
958
951
  width: 270,
959
952
  height: 69
@@ -1050,7 +1043,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1050
1043
  const timeoutId = setTimeout(extractRadius, 100);
1051
1044
  return () => clearTimeout(timeoutId);
1052
1045
  }), [ children, debugBorderRadius, contentRef ]),
1053
- // 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
1054
1063
  useEffect((() => {
1055
1064
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
1056
1065
  const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
@@ -1150,102 +1159,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1150
1159
  }), 150);
1151
1160
  return () => clearTimeout(timeoutId);
1152
1161
  }
1153
- if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
1154
- const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1155
- setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1156
- const handleReducedMotionChange = e => {
1157
- setUserPrefersReducedMotion(e.matches);
1158
- }, handleHighContrastChange = e => {
1159
- setUserPrefersHighContrast(e.matches);
1160
- };
1161
- return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1162
- mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
1163
- mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
1164
- // ignore
1165
- };
1166
- } catch (error) {
1167
- return;
1168
- }
1169
- }), [ overLight, glassRef, debugOverLight ]);
1162
+ "boolean" == typeof overLight && setDetectedOverLight(!1);
1163
+ }), [ overLight, glassRef ]);
1170
1164
  /**
1171
1165
  * Get effective overLight value based on configuration
1172
1166
  */
1173
- 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((() => {
1174
- 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 = {
1175
1169
  isOverLight: isOverLight,
1176
1170
  threshold: .7,
1177
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
1178
- contrast: 1,
1179
- // Base contrast
1180
- brightness: 1,
1181
- // Base brightness
1171
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1172
+ contrast: 1.4,
1173
+ brightness: .9,
1182
1174
  saturationBoost: 1.3,
1175
+ // Fixed value — dynamic saturation amplifies perceived displacement
1183
1176
  shadowIntensity: .9,
1184
1177
  borderOpacity: .7
1185
1178
  };
1186
1179
  if ("object" == typeof overLight && null !== overLight) {
1187
- 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);
1188
- 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 = {
1189
1181
  ...baseConfig,
1190
1182
  threshold: validatedThreshold,
1191
- opacity: validatedOpacity,
1183
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
1192
1184
  contrast: validatedContrast,
1193
1185
  brightness: validatedBrightness,
1194
1186
  saturationBoost: validatedSaturationBoost
1195
1187
  };
1188
+ return "undefined" == typeof process || process.env, finalConfig;
1196
1189
  }
1197
- return baseConfig;
1198
- }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = useMemo((() => {
1199
- const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
1200
- return {
1201
- isOverLight: baseOverLightConfig.isOverLight,
1202
- threshold: baseOverLightConfig.threshold,
1203
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
1204
- contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
1205
- brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
1206
- saturationBoost: baseOverLightConfig.saturationBoost,
1207
- shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
1208
- borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
1209
- };
1210
- }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
1211
- if (baseOverLightConfig.isOverLight) return "scale(1)";
1212
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1213
- 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({
1214
- x: edgeDistanceX,
1215
- y: edgeDistanceY
1216
- }, {
1217
- x: 0,
1218
- y: 0
1219
- });
1220
- if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
1221
- const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
1222
- if (0 === centerDistance) return "scale(1)";
1223
- 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;
1224
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1225
- }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
1226
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1227
- 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({
1228
- x: edgeDistanceX,
1229
- y: edgeDistanceY
1230
- }, {
1231
- x: 0,
1232
- y: 0
1233
- });
1234
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
1235
- }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
1236
- if (!glassRef.current) return {
1237
- x: 0,
1238
- y: 0
1239
- };
1240
- const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
1241
- return {
1242
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1243
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1244
- };
1245
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
1246
- x: 0,
1247
- y: 0
1248
- } : 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 => {
1249
1192
  if (externalGlobalMousePosition && externalMouseOffset) return;
1250
1193
  if (effectiveWithoutEffects) return;
1251
1194
  const container = mouseContainer?.current || glassRef.current;
@@ -1254,35 +1197,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1254
1197
  let rect = cachedRectRef.current;
1255
1198
  if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
1256
1199
  cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
1257
- const center = calculateElementCenter(rect), newOffset = {
1200
+ const center = calculateElementCenter(rect);
1201
+ // Write raw target — the lerp loop will smoothly pursue it
1202
+ targetMouseOffsetRef.current = {
1258
1203
  x: (globalPos.x - center.x) / rect.width * 100,
1259
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);
1260
1248
  };
1261
- // Calculate offset relative to this container
1262
- // Store in refs instead of state
1263
- internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
1264
- // Imperative style update
1265
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1266
- mouseOffset: newOffset,
1267
- globalMousePosition: globalPos,
1268
- glassSize: glassSize,
1269
- isHovered: isHovered,
1270
- isActive: isActive,
1271
- isOverLight: baseOverLightConfig.isOverLight,
1272
- baseOverLightConfig: baseOverLightConfig,
1273
- effectiveBorderRadius: effectiveBorderRadius,
1274
- effectiveWithoutEffects: effectiveWithoutEffects,
1275
- effectiveReducedMotion: effectiveReducedMotion,
1276
- elasticity: elasticity,
1277
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1278
- // Simplified directional scale for fast path
1279
- onClick: onClick,
1280
- withLiquidBlur: withLiquidBlur,
1281
- blurAmount: blurAmount,
1282
- saturation: saturation,
1283
- padding: padding
1284
- });
1285
- }), [ 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
+ }), []);
1286
1255
  /**
1287
1256
  * Validate and clamp a numeric config value
1288
1257
  */
@@ -1290,7 +1259,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1290
1259
  useEffect((() => {
1291
1260
  if (externalGlobalMousePosition && externalMouseOffset) return;
1292
1261
  if (effectiveWithoutEffects) return;
1293
- 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;
1294
1266
  let resizeObserver = null;
1295
1267
  return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
1296
1268
  null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
@@ -1298,10 +1270,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1298
1270
  container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
1299
1271
  }));
1300
1272
  })), resizeObserver.observe(container)), () => {
1301
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1273
+ unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1302
1274
  updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
1303
1275
  };
1304
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1276
+ }), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1305
1277
  // Also call updateStyles on other state changes (hover, active, etc)
1306
1278
  useEffect((() => {
1307
1279
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
@@ -1310,22 +1282,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1310
1282
  glassSize: glassSize,
1311
1283
  isHovered: isHovered,
1312
1284
  isActive: isActive,
1313
- isOverLight: baseOverLightConfig.isOverLight,
1314
- baseOverLightConfig: baseOverLightConfig,
1285
+ isOverLight: overLightConfig.isOverLight,
1286
+ baseOverLightConfig: overLightConfig,
1315
1287
  effectiveBorderRadius: effectiveBorderRadius,
1316
1288
  effectiveWithoutEffects: effectiveWithoutEffects,
1317
1289
  effectiveReducedMotion: effectiveReducedMotion,
1318
1290
  elasticity: elasticity,
1319
- directionalScale: directionalScale,
1291
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1320
1292
  onClick: onClick,
1321
1293
  withLiquidBlur: withLiquidBlur,
1322
1294
  blurAmount: blurAmount,
1323
1295
  saturation: saturation,
1324
1296
  padding: padding
1325
1297
  });
1326
- }), [ 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 ]);
1327
1299
  // Event handlers
1328
- 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 => {
1329
1301
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1330
1302
  }), [ onClick ]);
1331
1303
  return {
@@ -1343,14 +1315,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1343
1315
  mouseOffset: mouseOffset,
1344
1316
  // This is now static (refs or props) unless prop changes
1345
1317
  overLightConfig: overLightConfig,
1346
- elasticTranslation: elasticTranslation,
1347
- directionalScale: directionalScale,
1348
1318
  transformStyle: transformStyle,
1349
1319
  handleMouseEnter: handleMouseEnter,
1350
1320
  handleMouseLeave: handleMouseLeave,
1351
1321
  handleMouseDown: handleMouseDown,
1352
1322
  handleMouseUp: handleMouseUp,
1353
- handleMouseMove: handleMouseMove,
1354
1323
  handleKeyDown: handleKeyDown
1355
1324
  };
1356
1325
  }
@@ -1448,25 +1417,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1448
1417
  withLiquidBlur: withLiquidBlur,
1449
1418
  padding: padding,
1450
1419
  style: style
1451
- }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
1452
- ...style,
1453
- ...!effectiveWithoutEffects && {
1454
- 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
+ };
1455
1449
  }
1456
- }, 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: style.position || "absolute",
1458
- top: style.top || 0,
1459
- left: style.left || 0
1460
- })), [ 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((() => {
1461
1461
  const resolveSize = (propValue, styleValue, measuredSize) => {
1462
1462
  const explicitSize = propValue ?? styleValue;
1463
1463
  return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
1464
1464
  };
1465
1465
  return {
1466
- width: resolveSize(width, style.width, glassSize.width),
1467
- height: resolveSize(height, style.height, glassSize.height)
1466
+ width: resolveSize(width, restStyle.width, glassSize.width),
1467
+ height: resolveSize(height, restStyle.height, glassSize.height)
1468
1468
  };
1469
- }), [ 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((() => {
1470
1470
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
1471
1471
  return {
1472
1472
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -1508,6 +1508,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1508
1508
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
1509
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;
1510
1510
  return {
1511
+ ...void 0 !== customZIndex && {
1512
+ "--atomix-glass-base-z-index": customZIndex
1513
+ },
1511
1514
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
1512
1515
  "--atomix-glass-transform": transformStyle || "none",
1513
1516
  "--atomix-glass-position": positionStyles.position,
@@ -1528,22 +1531,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1528
1531
  "--atomix-glass-base-opacity": opacityValues.base,
1529
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})`,
1530
1533
  "--atomix-glass-overlay-opacity": opacityValues.over,
1531
- "--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}%)`
1532
1537
  };
1533
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
1534
- 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(" "),
1535
- style: {
1536
- ...positionStyles,
1537
- height: adjustedSize.height,
1538
- width: adjustedSize.width,
1539
- borderRadius: `${effectiveBorderRadius}px`,
1540
- transform: baseStyle.transform
1541
- }
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(" ")
1542
1540
  });
1543
1541
  return jsxs("div", {
1544
1542
  ...rest,
1545
1543
  className: componentClassName,
1546
- style: glassVars,
1544
+ style: {
1545
+ ...glassVars
1546
+ },
1547
1547
  role: role || (onClick ? "button" : void 0),
1548
1548
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
1549
1549
  "aria-label": ariaLabel,
@@ -1555,7 +1555,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1555
1555
  ref: glassRef,
1556
1556
  contentRef: contentRef,
1557
1557
  className: className,
1558
- style: baseStyle,
1558
+ style: rootLayoutStyle,
1559
1559
  borderRadius: effectiveBorderRadius,
1560
1560
  displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1561
1561
  blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
@@ -1590,7 +1590,6 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1590
1590
  effectiveWithoutEffects: effectiveWithoutEffects,
1591
1591
  effectiveReducedMotion: effectiveReducedMotion,
1592
1592
  shaderVariant: shaderVariant,
1593
- elasticity: elasticity,
1594
1593
  withLiquidBlur: withLiquidBlur,
1595
1594
  children: children
1596
1595
  }), Boolean(onClick) && jsxs(Fragment, {
@@ -1607,11 +1606,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1607
1606
  }), jsx("div", {
1608
1607
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
1609
1608
  }), jsx("div", {
1610
- className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
1611
- style: {
1612
- opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
1613
- 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}%)`
1614
- }
1609
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
1615
1610
  }) ]
1616
1611
  }), withBorder && jsxs(Fragment, {
1617
1612
  children: [ jsx("span", {
@@ -3434,7 +3429,7 @@ class ThemeNaming {
3434
3429
 
3435
3430
  ThemeNaming.prefix = "atomix";
3436
3431
 
3437
- const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, LinkComponent: LinkComponent, ...props}, ref) => {
3432
+ const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, linkComponent: linkComponent, ...props}, ref) => {
3438
3433
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
3439
3434
  name: iconName,
3440
3435
  size: iconSize
@@ -3485,12 +3480,12 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3485
3480
  let content;
3486
3481
  // Render as anchor if href is provided
3487
3482
  if (shouldRenderAsLink)
3488
- // Use custom LinkComponent if provided (e.g., Next.js Link)
3489
- if (LinkComponent) {
3490
- const LinkComp = LinkComponent, linkProps = {
3483
+ // Use custom linkComponent if provided (e.g., Next.js Link)
3484
+ if (linkComponent) {
3485
+ const LinkComp = linkComponent, linkProps = {
3491
3486
  ...buttonProps,
3492
3487
  ref: ref,
3493
- // LinkComponent usually forwards ref to anchor
3488
+ // linkComponent usually forwards ref to anchor
3494
3489
  href: href,
3495
3490
  to: href,
3496
3491
  target: target,