@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/core.js CHANGED
@@ -567,7 +567,9 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
567
567
  ENABLE_OVER_LIGHT_LAYERS: !0
568
568
  },
569
569
  CONSTANTS: {
570
- ACTIVATION_ZONE: 200,
570
+ ACTIVATION_ZONE: 350,
571
+ LERP_FACTOR: .08,
572
+ SMOOTHSTEP_POWER: 2.5,
571
573
  MIN_BLUR: .1,
572
574
  MOUSE_INFLUENCE_DIVISOR: 100,
573
575
  EDGE_FADE_PIXELS: 2,
@@ -803,7 +805,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
803
805
  // Silently handle errors
804
806
  }
805
807
  return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
806
- }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
808
+ }, 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) => {
807
809
  switch (mode) {
808
810
  case "standard":
809
811
  return displacementMap;
@@ -979,7 +981,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
979
981
  }, 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 = {
980
982
  width: 0,
981
983
  height: 0
982
- }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
984
+ }, onClick: onClick, mode: mode = "standard", effectiveWithoutEffects: effectiveWithoutEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", withLiquidBlur: withLiquidBlur = !1, contentRef: contentRef}, ref) => {
983
985
  // Generate a stable, deterministic ID for SSR compatibility
984
986
  // Use a module-level counter that's consistent across server and client
985
987
  const filterId = useMemo((() => "atomix-glass-filter-" + ++idCounter), []), [shaderMapUrl, setShaderMapUrl] = useState(""), shaderGeneratorRef = useRef(null), shaderUtilsRef = useRef(null), shaderDebounceTimeoutRef = useRef(null);
@@ -1164,21 +1166,12 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
1164
1166
  onClick: onClick,
1165
1167
  children: jsxs("div", {
1166
1168
  className: ATOMIX_GLASS.INNER_CLASS,
1167
- style: {
1168
- padding: "var(--atomix-glass-container-padding)",
1169
- boxShadow: "var(--atomix-glass-container-box-shadow)"
1170
- },
1171
1169
  onMouseEnter: onMouseEnter,
1172
1170
  onMouseLeave: onMouseLeave,
1173
1171
  onMouseDown: onMouseDown,
1174
1172
  onMouseUp: onMouseUp,
1175
1173
  children: [ jsxs("div", {
1176
1174
  className: ATOMIX_GLASS.FILTER_CLASS,
1177
- style: {
1178
- zIndex: 1,
1179
- position: "absolute",
1180
- inset: 0
1181
- },
1182
1175
  children: [ jsx(GlassFilter, {
1183
1176
  blurAmount: blurAmount,
1184
1177
  mode: mode,
@@ -1193,28 +1186,14 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
1193
1186
  },
1194
1187
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
1195
1188
  style: {
1196
- filter: `url(#${filterId})`,
1197
- backdropFilter: "var(--atomix-glass-container-backdrop)",
1198
- borderRadius: "var(--atomix-glass-container-radius)"
1189
+ filter: `url(#${filterId})`
1199
1190
  }
1200
1191
  }), jsx("div", {
1201
- className: ATOMIX_GLASS.FILTER_SHADOW_CLASS,
1202
- style: {
1203
- boxShadow: "var(--atomix-glass-container-shadow)",
1204
- opacity: "var(--atomix-glass-container-shadow-opacity)",
1205
- background: "var(--atomix-glass-container-bg)",
1206
- borderRadius: "var(--atomix-glass-container-radius)"
1207
- }
1192
+ className: ATOMIX_GLASS.FILTER_SHADOW_CLASS
1208
1193
  }) ]
1209
1194
  }), jsx("div", {
1210
1195
  ref: contentRef,
1211
1196
  className: ATOMIX_GLASS.CONTENT_CLASS,
1212
- style: {
1213
- position: "relative",
1214
- textShadow: "var(--atomix-glass-container-text-shadow)",
1215
- // Ensure content is always above the filter layer (zIndex 1)
1216
- zIndex: elasticity > 0 ? 100 : 2
1217
- },
1218
1197
  children: children
1219
1198
  }) ]
1220
1199
  })
@@ -1318,31 +1297,39 @@ class {
1318
1297
  saturationBoost: baseOverLightConfig.saturationBoost
1319
1298
  };
1320
1299
  // Calculate mouse influence
1321
- // Calculate elastic translation
1322
- let elasticTranslation = {
1300
+ let computedDirectionalScale = directionalScale, elasticTranslation = {
1323
1301
  x: 0,
1324
1302
  y: 0
1325
1303
  };
1326
- if (!effectiveWithoutEffects && wrapperElement) {
1304
+ // Calculate elastic translation and directional scale
1305
+ if (!effectiveWithoutEffects && wrapperElement) {
1327
1306
  const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
1328
- // Calculate fade in factor
1329
- let fadeInFactor = 0;
1307
+ // Mouse presence and edge distance logic
1330
1308
  if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
1331
- 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({
1309
+ 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({
1332
1310
  x: edgeDistanceX,
1333
1311
  y: edgeDistanceY
1334
1312
  }, {
1335
1313
  x: 0,
1336
1314
  y: 0
1337
- });
1338
- fadeInFactor = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
1315
+ }), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
1316
+ const clamped = Math.max(0, Math.min(1, t));
1317
+ return clamped * clamped * (3 - 2 * clamped);
1318
+ })(rawT);
1319
+ // Directional scale
1320
+ if (elasticTranslation = {
1321
+ x: deltaX * elasticity * .1 * fadeInFactor,
1322
+ y: deltaY * elasticity * .1 * fadeInFactor
1323
+ }, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
1324
+ const centerDistance = calculateDistance(globalMousePosition, center);
1325
+ if (centerDistance > 0) {
1326
+ 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);
1327
+ computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
1328
+ }
1329
+ }
1339
1330
  }
1340
- elasticTranslation = {
1341
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1342
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1343
- };
1344
1331
  }
1345
- 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}`;
1332
+ 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}`;
1346
1333
  // Update Wrapper Styles (glassVars)
1347
1334
  if (wrapperElement) {
1348
1335
  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 = {
@@ -1449,7 +1436,13 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1449
1436
  }), internalMouseOffsetRef = useRef({
1450
1437
  x: 0,
1451
1438
  y: 0
1452
- }), [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}) {
1439
+ }), targetMouseOffsetRef = useRef({
1440
+ x: 0,
1441
+ y: 0
1442
+ }), targetGlobalMousePositionRef = useRef({
1443
+ x: 0,
1444
+ y: 0
1445
+ }), 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}) {
1453
1446
  const [glassSize, setGlassSize] = useState({
1454
1447
  width: 270,
1455
1448
  height: 69
@@ -1546,7 +1539,23 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1546
1539
  const timeoutId = setTimeout(extractRadius, 100);
1547
1540
  return () => clearTimeout(timeoutId);
1548
1541
  }), [ children, debugBorderRadius, contentRef ]),
1549
- // Media query handlers and background detection
1542
+ // Media query detection for reduced motion and high contrast
1543
+ useEffect((() => {
1544
+ if ("undefined" == typeof window || "function" != typeof window.matchMedia) return;
1545
+ const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1546
+ setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1547
+ const handleReducedMotionChange = e => {
1548
+ setUserPrefersReducedMotion(e.matches);
1549
+ }, handleHighContrastChange = e => {
1550
+ setUserPrefersHighContrast(e.matches);
1551
+ };
1552
+ return mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1553
+ mediaQueryHighContrast.addEventListener("change", handleHighContrastChange), () => {
1554
+ mediaQueryReducedMotion.removeEventListener("change", handleReducedMotionChange),
1555
+ mediaQueryHighContrast.removeEventListener("change", handleHighContrastChange);
1556
+ };
1557
+ }), []),
1558
+ // Background detection for overLight auto-detect
1550
1559
  useEffect((() => {
1551
1560
  if (("auto" === overLight || "object" == typeof overLight && null !== overLight) && glassRef.current) {
1552
1561
  const element = glassRef.current, cachedResult = ((parentElement, overLightConfig) => {
@@ -1646,102 +1655,36 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1646
1655
  }), 150);
1647
1656
  return () => clearTimeout(timeoutId);
1648
1657
  }
1649
- if ("boolean" == typeof overLight && setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
1650
- const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
1651
- setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
1652
- const handleReducedMotionChange = e => {
1653
- setUserPrefersReducedMotion(e.matches);
1654
- }, handleHighContrastChange = e => {
1655
- setUserPrefersHighContrast(e.matches);
1656
- };
1657
- return mediaQueryReducedMotion.addEventListener ? (mediaQueryReducedMotion.addEventListener("change", handleReducedMotionChange),
1658
- mediaQueryHighContrast.addEventListener("change", handleHighContrastChange)) : mediaQueryReducedMotion.addListener && (mediaQueryReducedMotion.addListener(handleReducedMotionChange),
1659
- mediaQueryHighContrast.addListener(handleHighContrastChange)), () => {
1660
- // ignore
1661
- };
1662
- } catch (error) {
1663
- return;
1664
- }
1665
- }), [ overLight, glassRef, debugOverLight ]);
1658
+ "boolean" == typeof overLight && setDetectedOverLight(!1);
1659
+ }), [ overLight, glassRef ]);
1666
1660
  /**
1667
1661
  * Get effective overLight value based on configuration
1668
1662
  */
1669
- 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((() => {
1670
- const isOverLight = getEffectiveOverLight(), baseConfig = {
1663
+ 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((() => {
1664
+ const isOverLight = getEffectiveOverLight(), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, baseConfig = {
1671
1665
  isOverLight: isOverLight,
1672
1666
  threshold: .7,
1673
- opacity: isOverLight ? Math.min(.6, Math.max(.2, .5)) : 0,
1674
- contrast: 1,
1675
- // Base contrast
1676
- brightness: 1,
1677
- // Base brightness
1667
+ opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1668
+ contrast: 1.4,
1669
+ brightness: .9,
1678
1670
  saturationBoost: 1.3,
1671
+ // Fixed value — dynamic saturation amplifies perceived displacement
1679
1672
  shadowIntensity: .9,
1680
1673
  borderOpacity: .7
1681
1674
  };
1682
1675
  if ("object" == typeof overLight && null !== overLight) {
1683
- 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);
1684
- return {
1676
+ 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 = {
1685
1677
  ...baseConfig,
1686
1678
  threshold: validatedThreshold,
1687
- opacity: validatedOpacity,
1679
+ opacity: validatedOpacity * hoverIntensity * activeIntensity,
1688
1680
  contrast: validatedContrast,
1689
1681
  brightness: validatedBrightness,
1690
1682
  saturationBoost: validatedSaturationBoost
1691
1683
  };
1684
+ return "undefined" == typeof process || process.env, finalConfig;
1692
1685
  }
1693
- return baseConfig;
1694
- }), [ overLight, getEffectiveOverLight, validateConfigValue ]), overLightConfig = useMemo((() => {
1695
- const mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1;
1696
- return {
1697
- isOverLight: baseOverLightConfig.isOverLight,
1698
- threshold: baseOverLightConfig.threshold,
1699
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
1700
- contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
1701
- brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
1702
- saturationBoost: baseOverLightConfig.saturationBoost,
1703
- shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
1704
- borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence))
1705
- };
1706
- }), [ baseOverLightConfig, mouseOffset, isHovered, isActive ]), updateRectRef = useRef(null), calculateDirectionalScale = useCallback((() => {
1707
- if (baseOverLightConfig.isOverLight) return "scale(1)";
1708
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1709
- 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({
1710
- x: edgeDistanceX,
1711
- y: edgeDistanceY
1712
- }, {
1713
- x: 0,
1714
- y: 0
1715
- });
1716
- if (edgeDistance > CONSTANTS.ACTIVATION_ZONE) return "scale(1)";
1717
- const fadeInFactor = 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE, centerDistance = calculateDistance(globalMousePosition, center);
1718
- if (0 === centerDistance) return "scale(1)";
1719
- 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;
1720
- return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1721
- }), [ globalMousePosition, elasticity, glassSize, glassRef, baseOverLightConfig ]), calculateFadeInFactor = useCallback((() => {
1722
- if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1723
- 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({
1724
- x: edgeDistanceX,
1725
- y: edgeDistanceY
1726
- }, {
1727
- x: 0,
1728
- y: 0
1729
- });
1730
- return edgeDistance > CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / CONSTANTS.ACTIVATION_ZONE;
1731
- }), [ globalMousePosition, glassSize, glassRef ]), calculateElasticTranslation = useCallback((() => {
1732
- if (!glassRef.current) return {
1733
- x: 0,
1734
- y: 0
1735
- };
1736
- const fadeInFactor = calculateFadeInFactor(), rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect);
1737
- return {
1738
- x: (globalMousePosition.x - center.x) * elasticity * .1 * fadeInFactor,
1739
- y: (globalMousePosition.y - center.y) * elasticity * .1 * fadeInFactor
1740
- };
1741
- }), [ globalMousePosition, elasticity, calculateFadeInFactor, glassRef ]), elasticTranslation = useMemo((() => effectiveWithoutEffects ? {
1742
- x: 0,
1743
- y: 0
1744
- } : 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 => {
1686
+ return "undefined" == typeof process || process.env, baseConfig;
1687
+ }), [ 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 => {
1745
1688
  if (externalGlobalMousePosition && externalMouseOffset) return;
1746
1689
  if (effectiveWithoutEffects) return;
1747
1690
  const container = mouseContainer?.current || glassRef.current;
@@ -1750,35 +1693,61 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1750
1693
  let rect = cachedRectRef.current;
1751
1694
  if (rect && 0 !== rect.width && 0 !== rect.height || (rect = container.getBoundingClientRect(),
1752
1695
  cachedRectRef.current = rect), 0 === rect.width || 0 === rect.height) return;
1753
- const center = calculateElementCenter(rect), newOffset = {
1696
+ const center = calculateElementCenter(rect);
1697
+ // Write raw target — the lerp loop will smoothly pursue it
1698
+ targetMouseOffsetRef.current = {
1754
1699
  x: (globalPos.x - center.x) / rect.width * 100,
1755
1700
  y: (globalPos.y - center.y) / rect.height * 100
1701
+ }, targetGlobalMousePositionRef.current = globalPos;
1702
+ }), [ mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]), startLerpLoop = useCallback((() => {
1703
+ if (lerpActiveRef.current) return;
1704
+ lerpActiveRef.current = !0;
1705
+ const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
1706
+ if (!lerpActiveRef.current) return;
1707
+ const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
1708
+ // If we're close enough, snap and park
1709
+ if (Math.abs(dx) < .05 && Math.abs(dy) < .05) internalMouseOffsetRef.current = {
1710
+ ...tgt
1711
+ }, internalGlobalMousePositionRef.current = {
1712
+ ...targetGlobalMousePositionRef.current
1713
+ }; else {
1714
+ internalMouseOffsetRef.current = {
1715
+ x: lerp(cur.x, tgt.x, LERP_T),
1716
+ y: lerp(cur.y, tgt.y, LERP_T)
1717
+ };
1718
+ const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
1719
+ internalGlobalMousePositionRef.current = {
1720
+ x: lerp(curG.x, tgtG.x, LERP_T),
1721
+ y: lerp(curG.y, tgtG.y, LERP_T)
1722
+ };
1723
+ }
1724
+ // Imperative style update with the smoothed values
1725
+ updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1726
+ mouseOffset: internalMouseOffsetRef.current,
1727
+ globalMousePosition: internalGlobalMousePositionRef.current,
1728
+ glassSize: glassSize,
1729
+ isHovered: isHovered,
1730
+ isActive: isActive,
1731
+ isOverLight: overLightConfig.isOverLight,
1732
+ baseOverLightConfig: overLightConfig,
1733
+ effectiveBorderRadius: effectiveBorderRadius,
1734
+ effectiveWithoutEffects: effectiveWithoutEffects,
1735
+ effectiveReducedMotion: effectiveReducedMotion,
1736
+ elasticity: elasticity,
1737
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1738
+ onClick: onClick,
1739
+ withLiquidBlur: withLiquidBlur,
1740
+ blurAmount: blurAmount,
1741
+ saturation: saturation,
1742
+ padding: padding
1743
+ }), lerpRafRef.current = requestAnimationFrame(tick);
1756
1744
  };
1757
- // Calculate offset relative to this container
1758
- // Store in refs instead of state
1759
- internalMouseOffsetRef.current = newOffset, internalGlobalMousePositionRef.current = globalPos,
1760
- // Imperative style update
1761
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1762
- mouseOffset: newOffset,
1763
- globalMousePosition: globalPos,
1764
- glassSize: glassSize,
1765
- isHovered: isHovered,
1766
- isActive: isActive,
1767
- isOverLight: baseOverLightConfig.isOverLight,
1768
- baseOverLightConfig: baseOverLightConfig,
1769
- effectiveBorderRadius: effectiveBorderRadius,
1770
- effectiveWithoutEffects: effectiveWithoutEffects,
1771
- effectiveReducedMotion: effectiveReducedMotion,
1772
- elasticity: elasticity,
1773
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1774
- // Simplified directional scale for fast path
1775
- onClick: onClick,
1776
- withLiquidBlur: withLiquidBlur,
1777
- blurAmount: blurAmount,
1778
- saturation: saturation,
1779
- padding: padding
1780
- });
1781
- }), [ mouseContainer, glassRef, wrapperRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects, glassSize, isHovered, isActive, baseOverLightConfig, effectiveBorderRadius, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]);
1745
+ // 0.08 lower = more viscous
1746
+ lerpRafRef.current = requestAnimationFrame(tick);
1747
+ }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding ]), stopLerpLoop = useCallback((() => {
1748
+ lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
1749
+ lerpRafRef.current = null);
1750
+ }), []);
1782
1751
  /**
1783
1752
  * Validate and clamp a numeric config value
1784
1753
  */
@@ -1786,7 +1755,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1786
1755
  useEffect((() => {
1787
1756
  if (externalGlobalMousePosition && externalMouseOffset) return;
1788
1757
  if (effectiveWithoutEffects) return;
1789
- const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition), container = mouseContainer?.current || glassRef.current;
1758
+ const unsubscribe = globalMouseTracker.subscribe(handleGlobalMousePosition);
1759
+ // Start the lerp loop — it will smoothly chase the target
1760
+ startLerpLoop();
1761
+ const container = mouseContainer?.current || glassRef.current;
1790
1762
  let resizeObserver = null;
1791
1763
  return container && "undefined" != typeof ResizeObserver && (resizeObserver = new ResizeObserver((() => {
1792
1764
  null !== updateRectRef.current && cancelAnimationFrame(updateRectRef.current), updateRectRef.current = requestAnimationFrame((() => {
@@ -1794,10 +1766,10 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1794
1766
  container && (cachedRectRef.current = container.getBoundingClientRect()), updateRectRef.current = null;
1795
1767
  }));
1796
1768
  })), resizeObserver.observe(container)), () => {
1797
- unsubscribe(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1769
+ unsubscribe(), stopLerpLoop(), null !== updateRectRef.current && (cancelAnimationFrame(updateRectRef.current),
1798
1770
  updateRectRef.current = null), resizeObserver && resizeObserver.disconnect();
1799
1771
  };
1800
- }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1772
+ }), [ handleGlobalMousePosition, startLerpLoop, stopLerpLoop, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveWithoutEffects ]),
1801
1773
  // Also call updateStyles on other state changes (hover, active, etc)
1802
1774
  useEffect((() => {
1803
1775
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
@@ -1806,22 +1778,22 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1806
1778
  glassSize: glassSize,
1807
1779
  isHovered: isHovered,
1808
1780
  isActive: isActive,
1809
- isOverLight: baseOverLightConfig.isOverLight,
1810
- baseOverLightConfig: baseOverLightConfig,
1781
+ isOverLight: overLightConfig.isOverLight,
1782
+ baseOverLightConfig: overLightConfig,
1811
1783
  effectiveBorderRadius: effectiveBorderRadius,
1812
1784
  effectiveWithoutEffects: effectiveWithoutEffects,
1813
1785
  effectiveReducedMotion: effectiveReducedMotion,
1814
1786
  elasticity: elasticity,
1815
- directionalScale: directionalScale,
1787
+ directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1816
1788
  onClick: onClick,
1817
1789
  withLiquidBlur: withLiquidBlur,
1818
1790
  blurAmount: blurAmount,
1819
1791
  saturation: saturation,
1820
1792
  padding: padding
1821
1793
  });
1822
- }), [ isHovered, isActive, glassSize, baseOverLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, directionalScale, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1794
+ }), [ isHovered, isActive, glassSize, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, wrapperRef, glassRef, externalMouseOffset, externalGlobalMousePosition, withLiquidBlur, blurAmount, saturation, padding, onClick ]);
1823
1795
  // Event handlers
1824
- const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleMouseMove = useCallback((_e => {}), []), handleKeyDown = useCallback((e => {
1796
+ const handleMouseEnter = useCallback((() => setIsHovered(!0)), []), handleMouseLeave = useCallback((() => setIsHovered(!1)), []), handleMouseDown = useCallback((() => setIsActive(!0)), []), handleMouseUp = useCallback((() => setIsActive(!1)), []), handleKeyDown = useCallback((e => {
1825
1797
  !onClick || "Enter" !== e.key && " " !== e.key || (e.preventDefault(), onClick());
1826
1798
  }), [ onClick ]);
1827
1799
  return {
@@ -1839,14 +1811,11 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1839
1811
  mouseOffset: mouseOffset,
1840
1812
  // This is now static (refs or props) unless prop changes
1841
1813
  overLightConfig: overLightConfig,
1842
- elasticTranslation: elasticTranslation,
1843
- directionalScale: directionalScale,
1844
1814
  transformStyle: transformStyle,
1845
1815
  handleMouseEnter: handleMouseEnter,
1846
1816
  handleMouseLeave: handleMouseLeave,
1847
1817
  handleMouseDown: handleMouseDown,
1848
1818
  handleMouseUp: handleMouseUp,
1849
- handleMouseMove: handleMouseMove,
1850
1819
  handleKeyDown: handleKeyDown
1851
1820
  };
1852
1821
  }
@@ -1944,25 +1913,56 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
1944
1913
  withLiquidBlur: withLiquidBlur,
1945
1914
  padding: padding,
1946
1915
  style: style
1947
- }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, baseStyle = {
1948
- ...style,
1949
- ...!effectiveWithoutEffects && {
1950
- transform: transformStyle
1916
+ }), isOverLight = useMemo((() => overLightConfig.isOverLight), [ overLightConfig.isOverLight ]), shouldRenderOverLightLayers = withOverLightLayers && isOverLight, {zIndex: customZIndex, ...restStyle} = style, isFixedOrSticky = "fixed" === restStyle.position || "sticky" === restStyle.position, rootLayoutStyle = useMemo((() => {
1917
+ if (!isFixedOrSticky) return {};
1918
+ const {position: p, top: t, left: l, right: r, bottom: b} = restStyle;
1919
+ return {
1920
+ ...p && {
1921
+ position: p
1922
+ },
1923
+ ...void 0 !== t && {
1924
+ top: t
1925
+ },
1926
+ ...void 0 !== l && {
1927
+ left: l
1928
+ },
1929
+ ...void 0 !== r && {
1930
+ right: r
1931
+ },
1932
+ ...void 0 !== b && {
1933
+ bottom: b
1934
+ }
1935
+ };
1936
+ }), [ isFixedOrSticky, restStyle ]), baseStyle = useMemo((() => {
1937
+ if (isFixedOrSticky) {
1938
+ const {position: _p, top: _t, left: _l, right: _r, bottom: _b, ...visualStyle} = restStyle;
1939
+ return {
1940
+ ...visualStyle,
1941
+ ...!effectiveWithoutEffects && {
1942
+ transform: transformStyle
1943
+ }
1944
+ };
1951
1945
  }
1952
- }, 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((() => ({
1953
- position: style.position || "absolute",
1954
- top: style.top || 0,
1955
- left: style.left || 0
1956
- })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => {
1946
+ return {
1947
+ ...restStyle,
1948
+ ...!effectiveWithoutEffects && {
1949
+ transform: transformStyle
1950
+ }
1951
+ };
1952
+ }), [ 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((() => ({
1953
+ position: isFixedOrSticky ? "absolute" : restStyle.position || "absolute",
1954
+ top: isFixedOrSticky ? 0 : restStyle.top || 0,
1955
+ left: isFixedOrSticky ? 0 : restStyle.left || 0
1956
+ })), [ isFixedOrSticky, restStyle.position, restStyle.top, restStyle.left ]), adjustedSize = useMemo((() => {
1957
1957
  const resolveSize = (propValue, styleValue, measuredSize) => {
1958
1958
  const explicitSize = propValue ?? styleValue;
1959
1959
  return void 0 !== explicitSize ? "number" == typeof explicitSize ? `${explicitSize}px` : explicitSize : "fixed" === positionStyles.position ? `${Math.max(measuredSize, 0)}px` : "100%";
1960
1960
  };
1961
1961
  return {
1962
- width: resolveSize(width, style.width, glassSize.width),
1963
- height: resolveSize(height, style.height, glassSize.height)
1962
+ width: resolveSize(width, restStyle.width, glassSize.width),
1963
+ height: resolveSize(height, restStyle.height, glassSize.height)
1964
1964
  };
1965
- }), [ width, height, style.width, style.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1965
+ }), [ width, height, restStyle.width, restStyle.height, positionStyles.position, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1966
1966
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
1967
1967
  return {
1968
1968
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -2004,6 +2004,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2004
2004
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
2005
2005
  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;
2006
2006
  return {
2007
+ ...void 0 !== customZIndex && {
2008
+ "--atomix-glass-base-z-index": customZIndex
2009
+ },
2007
2010
  "--atomix-glass-radius": `${effectiveBorderRadius}px`,
2008
2011
  "--atomix-glass-transform": transformStyle || "none",
2009
2012
  "--atomix-glass-position": positionStyles.position,
@@ -2024,22 +2027,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2024
2027
  "--atomix-glass-base-opacity": opacityValues.base,
2025
2028
  "--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})`,
2026
2029
  "--atomix-glass-overlay-opacity": opacityValues.over,
2027
- "--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})`
2030
+ "--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})`,
2031
+ "--atomix-glass-overlay-highlight-opacity": opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
2032
+ "--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}%)`
2028
2033
  };
2029
- }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
2030
- 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(" "),
2031
- style: {
2032
- ...positionStyles,
2033
- height: adjustedSize.height,
2034
- width: adjustedSize.width,
2035
- borderRadius: `${effectiveBorderRadius}px`,
2036
- transform: baseStyle.transform
2037
- }
2034
+ }), [ gradientValues, opacityValues, effectiveBorderRadius, transformStyle, positionStyles, adjustedSize, isOverLight, overLightConfig.borderOpacity, customZIndex ]), renderBackgroundLayer = layerType => jsx("div", {
2035
+ 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(" ")
2038
2036
  });
2039
2037
  return jsxs("div", {
2040
2038
  ...rest,
2041
2039
  className: componentClassName,
2042
- style: glassVars,
2040
+ style: {
2041
+ ...glassVars
2042
+ },
2043
2043
  role: role || (onClick ? "button" : void 0),
2044
2044
  tabIndex: onClick ? tabIndex ?? 0 : tabIndex,
2045
2045
  "aria-label": ariaLabel,
@@ -2051,7 +2051,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2051
2051
  ref: glassRef,
2052
2052
  contentRef: contentRef,
2053
2053
  className: className,
2054
- style: baseStyle,
2054
+ style: rootLayoutStyle,
2055
2055
  borderRadius: effectiveBorderRadius,
2056
2056
  displacementScale: effectiveWithoutEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
2057
2057
  blurAmount: effectiveWithoutEffects ? 0 : blurAmount,
@@ -2086,7 +2086,6 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2086
2086
  effectiveWithoutEffects: effectiveWithoutEffects,
2087
2087
  effectiveReducedMotion: effectiveReducedMotion,
2088
2088
  shaderVariant: shaderVariant,
2089
- elasticity: elasticity,
2090
2089
  withLiquidBlur: withLiquidBlur,
2091
2090
  children: children
2092
2091
  }), Boolean(onClick) && jsxs(Fragment, {
@@ -2103,11 +2102,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, wrapperRef:
2103
2102
  }), jsx("div", {
2104
2103
  className: ATOMIX_GLASS.OVERLAY_LAYER_CLASS
2105
2104
  }), jsx("div", {
2106
- className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS,
2107
- style: {
2108
- opacity: opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER,
2109
- 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}%)`
2110
- }
2105
+ className: ATOMIX_GLASS.OVERLAY_HIGHLIGHT_CLASS
2111
2106
  }) ]
2112
2107
  }), withBorder && jsxs(Fragment, {
2113
2108
  children: [ jsx("span", {
@@ -2538,7 +2533,7 @@ const BreadcrumbItem = forwardRef((({children: children, href: href, active: ac
2538
2533
 
2539
2534
  BreadcrumbItem.displayName = "BreadcrumbItem";
2540
2535
 
2541
- const Breadcrumb = memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", LinkComponent: LinkComponent, style: style, children: children}) {
2536
+ const Breadcrumb = memo((function({items: items, divider: divider, className: className = "", "aria-label": ariaLabel = "Breadcrumb", linkComponent: linkComponent, style: style, children: children}) {
2542
2537
  const breadcrumbClasses = [ BREADCRUMB.CLASSES.BASE, className ].filter(Boolean).join(" ");
2543
2538
  let content;
2544
2539
  if (items && items.length > 0)
@@ -2552,7 +2547,7 @@ const Breadcrumb = memo((function({items: items, divider: divider, className: c
2552
2547
  onClick: item.onClick,
2553
2548
  className: item.className,
2554
2549
  style: item.style,
2555
- linkAs: LinkComponent,
2550
+ linkAs: linkComponent,
2556
2551
  children: item.label
2557
2552
  }, index);
2558
2553
  })); else {
@@ -2564,7 +2559,7 @@ const Breadcrumb = memo((function({items: items, divider: divider, className: c
2564
2559
 
2565
2560
  return cloneElement(child, {
2566
2561
  active: active ?? (!!isLast || void 0),
2567
- linkAs: linkAs ?? LinkComponent
2562
+ linkAs: linkAs ?? linkComponent
2568
2563
  });
2569
2564
  }
2570
2565
  return child;
@@ -2766,7 +2761,7 @@ class ThemeNaming {
2766
2761
 
2767
2762
  ThemeNaming.prefix = "atomix";
2768
2763
 
2769
- 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) => {
2764
+ 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) => {
2770
2765
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
2771
2766
  name: iconName,
2772
2767
  size: iconSize
@@ -2817,12 +2812,12 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
2817
2812
  let content;
2818
2813
  // Render as anchor if href is provided
2819
2814
  if (shouldRenderAsLink)
2820
- // Use custom LinkComponent if provided (e.g., Next.js Link)
2821
- if (LinkComponent) {
2822
- const LinkComp = LinkComponent, linkProps = {
2815
+ // Use custom linkComponent if provided (e.g., Next.js Link)
2816
+ if (linkComponent) {
2817
+ const LinkComp = linkComponent, linkProps = {
2823
2818
  ...buttonProps,
2824
2819
  ref: ref,
2825
- // LinkComponent usually forwards ref to anchor
2820
+ // linkComponent usually forwards ref to anchor
2826
2821
  href: href,
2827
2822
  to: href,
2828
2823
  target: target,
@@ -2883,7 +2878,7 @@ header: header, image: image, imageAlt: imageAlt = "", title: title, text: text,
2883
2878
  // Interaction
2884
2879
  onClick: onClick, onHover: onHover, onFocus: onFocus, href: href, target: target,
2885
2880
  // Custom Link
2886
- LinkComponent: LinkComponent,
2881
+ linkComponent: linkComponent,
2887
2882
  // Glass
2888
2883
  glass: glass,
2889
2884
  // Accessibility
@@ -2968,7 +2963,7 @@ className: className = "", style: style, ...rest}, ref) => {
2968
2963
  // Render as anchor if href is provided
2969
2964
  if (href && !isDisabled) {
2970
2965
  let anchorElement;
2971
- return anchorElement = LinkComponent ? jsx(LinkComponent, {
2966
+ return anchorElement = linkComponent ? jsx(linkComponent, {
2972
2967
  ...commonProps,
2973
2968
  ref: ref,
2974
2969
  href: href,