@shohojdhara/atomix 0.6.2 → 0.6.4

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 (63) hide show
  1. package/README.md +510 -106
  2. package/dist/atomix.css +26 -22
  3. package/dist/atomix.css.map +1 -1
  4. package/dist/atomix.min.css +5 -5
  5. package/dist/atomix.min.css.map +1 -1
  6. package/dist/atomix.umd.js +1 -1
  7. package/dist/atomix.umd.js.map +1 -1
  8. package/dist/atomix.umd.min.js +1 -1
  9. package/dist/charts.d.ts +2 -2
  10. package/dist/charts.js +251 -131
  11. package/dist/charts.js.map +1 -1
  12. package/dist/core.d.ts +5 -39
  13. package/dist/core.js +254 -137
  14. package/dist/core.js.map +1 -1
  15. package/dist/forms.d.ts +2 -1
  16. package/dist/forms.js +342 -177
  17. package/dist/forms.js.map +1 -1
  18. package/dist/heavy.js +254 -135
  19. package/dist/heavy.js.map +1 -1
  20. package/dist/index.d.ts +141 -159
  21. package/dist/index.esm.js +348 -195
  22. package/dist/index.esm.js.map +1 -1
  23. package/dist/index.js +348 -195
  24. package/dist/index.js.map +1 -1
  25. package/dist/index.min.js +1 -1
  26. package/dist/index.min.js.map +1 -1
  27. package/dist/theme.d.ts +14 -6
  28. package/dist/theme.js +2 -9
  29. package/dist/theme.js.map +1 -1
  30. package/package.json +26 -26
  31. package/src/components/AtomixGlass/AtomixGlass.tsx +1 -1
  32. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +8 -1
  33. package/src/components/AtomixGlass/glass-utils.ts +29 -0
  34. package/src/components/AtomixGlass/stories/Playground.stories.tsx +32 -1
  35. package/src/components/Button/Button.stories.tsx +1 -1
  36. package/src/components/Button/Button.tsx +6 -5
  37. package/src/components/Card/Card.tsx +2 -2
  38. package/src/components/Dropdown/Dropdown.tsx +1 -0
  39. package/src/components/EdgePanel/EdgePanel.tsx +1 -3
  40. package/src/components/Form/Select.test.tsx +75 -0
  41. package/src/components/Form/Select.tsx +348 -252
  42. package/src/components/Form/SelectOption.tsx +16 -10
  43. package/src/components/index.ts +1 -1
  44. package/src/layouts/CssGrid/index.ts +1 -0
  45. package/src/lib/composables/useAtomixGlass.ts +238 -138
  46. package/src/lib/composables/useAtomixGlassStyles.ts +201 -149
  47. package/src/lib/constants/components.ts +50 -35
  48. package/src/lib/theme/config/configLoader.ts +1 -1
  49. package/src/lib/theme/test/testTheme.ts +2 -2
  50. package/src/lib/theme/utils/themeUtils.ts +98 -110
  51. package/src/lib/types/components.ts +21 -63
  52. package/src/styles/01-settings/_settings.atomix-glass.scss +5 -5
  53. package/src/styles/01-settings/_settings.spacing.scss +6 -1
  54. package/src/styles/03-generic/_generic.reset.scss +1 -1
  55. package/src/styles/06-components/_components.atomix-glass.scss +20 -29
  56. package/src/styles/06-components/_components.data-table.scss +5 -4
  57. package/src/styles/06-components/_components.dynamic-background.scss +9 -8
  58. package/src/styles/06-components/_components.footer.scss +8 -7
  59. package/src/styles/06-components/_components.hero.scss +2 -2
  60. package/src/styles/06-components/_components.messages.scss +16 -16
  61. package/src/styles/06-components/_components.select.scss +15 -2
  62. package/src/styles/06-components/_components.upload.scss +3 -3
  63. package/CHANGELOG.md +0 -165
package/dist/core.js CHANGED
@@ -556,12 +556,23 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
556
556
  },
557
557
  DEFAULTS: {
558
558
  DISPLACEMENT_SCALE: 70,
559
- BLUR_AMOUNT: 0,
560
- SATURATION: 140,
561
- ABERRATION_INTENSITY: 2,
559
+ get BLUR_AMOUNT() {
560
+ return .15 * this.DISPLACEMENT_SCALE;
561
+ // Dynamically computed based on displacement
562
+ },
563
+ get SATURATION() {
564
+ return 100 + .5 * this.DISPLACEMENT_SCALE;
565
+ // Saturate relative to intensity
566
+ },
567
+ get ABERRATION_INTENSITY() {
568
+ return .03 * this.DISPLACEMENT_SCALE;
569
+ // Scale aberration with displacement
570
+ },
562
571
  ELASTICITY: .15,
563
- CORNER_RADIUS: 20,
564
- // Default border-radius matching design system
572
+ get CORNER_RADIUS() {
573
+ return 16;
574
+ // Use 16 to match SCSS design system (was 20)
575
+ },
565
576
  PADDING: "0",
566
577
  MODE: "standard",
567
578
  OVER_LIGHT: !1,
@@ -587,6 +598,11 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
587
598
  ELASTICITY_TRANSLATION_FACTOR: .1,
588
599
  ELASTICITY_DISTANCE_THRESHOLD: 200,
589
600
  ELASTICITY_COMPRESSION_FACTOR: .3,
601
+ ELASTICITY_STIFFNESS: .1,
602
+ ELASTICITY_DAMPING: .76,
603
+ ELASTICITY_VELOCITY_FACTOR: .65,
604
+ ELASTICITY_STRETCH_RATIO: .45,
605
+ ELASTICITY_MAGNIFICATION_BASE: 1.02,
590
606
  // Note: This default must match the SCSS variable --atomix-radius-md
591
607
  // @see src/styles/01-settings/_settings.global.scss
592
608
  DEFAULT_CORNER_RADIUS: 16,
@@ -603,84 +619,126 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
603
619
  // Base angle for border gradients (degrees)
604
620
  ANGLE_MULTIPLIER: 1.2,
605
621
  // Multiplier for mouse influence on angle
622
+ VELOCITY_ANGLE_MULTIPLIER: 2.5,
623
+ // How much velocity affects gradient rotation
624
+ CHROMATIC_OFFSET: 1.5,
625
+ // Degree offset for chromatic rim layers
606
626
  BORDER_STOP_1: {
607
627
  MIN: 10,
608
628
  // Minimum percentage for border stop 1
609
629
  BASE: 33,
610
630
  // Base percentage for border stop 1
611
- MULTIPLIER: .3
631
+ get MULTIPLIER() {
632
+ return .009 * this.BASE;
633
+ }
612
634
  },
613
635
  BORDER_STOP_2: {
614
636
  MAX: 90,
615
637
  // Maximum percentage for border stop 2
616
638
  BASE: 66,
617
639
  // Base percentage for border stop 2
618
- MULTIPLIER: .4
640
+ get MULTIPLIER() {
641
+ return .006 * this.BASE;
642
+ }
619
643
  },
620
644
  BORDER_OPACITY: {
621
645
  BASE_1: .12,
622
646
  // Base opacity for border gradient 1
623
- BASE_2: .4,
647
+ get BASE_2() {
648
+ return 3.33 * this.BASE_1;
649
+ },
624
650
  // Base opacity for border gradient 2
625
- BASE_3: .32,
651
+ get BASE_3() {
652
+ return 2.66 * this.BASE_1;
653
+ },
626
654
  // Base opacity for border gradient 3
627
- BASE_4: .6,
655
+ get BASE_4() {
656
+ return 5 * this.BASE_1;
657
+ },
628
658
  // Base opacity for border gradient 4
629
- MULTIPLIER_LOW: .008,
659
+ get MULTIPLIER_LOW() {
660
+ return .066 * this.BASE_1;
661
+ },
630
662
  // Low multiplier for mouse influence on opacity
631
- MULTIPLIER_HIGH: .012
663
+ get MULTIPLIER_HIGH() {
664
+ return .1 * this.BASE_1;
665
+ }
632
666
  },
633
667
  CENTER_POSITION: 50,
634
668
  // Center position percentage (50%)
635
669
  HOVER_POSITION: {
636
670
  DIVISOR_1: 2,
637
671
  // Divisor for hover 1 position calculation
638
- DIVISOR_2: 1.5,
672
+ get DIVISOR_2() {
673
+ return .75 * this.DIVISOR_1;
674
+ },
639
675
  // Divisor for hover 2 position calculation
640
- MULTIPLIER_3: 1
676
+ get MULTIPLIER_3() {
677
+ return .5 * this.DIVISOR_1;
678
+ }
641
679
  },
642
- BASE_LAYER_MULTIPLIER: .5
680
+ get BASE_LAYER_MULTIPLIER() {
681
+ return .5;
682
+ }
643
683
  },
644
684
  // Gradient opacity values for hover effects
645
685
  GRADIENT_OPACITY: {
646
686
  HOVER_1: {
647
687
  BLACK_START: .3,
648
688
  // Start opacity for black hover 1
649
- BLACK_MID: .1,
689
+ get BLACK_MID() {
690
+ return this.BLACK_START / 3;
691
+ },
650
692
  // Mid opacity for black hover 1
651
693
  BLACK_STOP: 30,
652
694
  // Stop percentage for black hover 1
653
- BLACK_END: 60,
695
+ get BLACK_END() {
696
+ return 2 * this.BLACK_STOP;
697
+ },
654
698
  // End percentage for black hover 1
655
699
  WHITE_START: .5,
656
700
  // Start opacity for white hover 1
657
- WHITE_STOP: 50
701
+ get WHITE_STOP() {
702
+ return this.BLACK_END - 10;
703
+ }
658
704
  },
659
705
  HOVER_2: {
660
706
  BLACK_START: .4,
661
707
  // Start opacity for black hover 2
662
- BLACK_MID: .15,
708
+ get BLACK_MID() {
709
+ return .375 * this.BLACK_START;
710
+ },
663
711
  // Mid opacity for black hover 2
664
712
  BLACK_STOP: 40,
665
713
  // Stop percentage for black hover 2
666
- BLACK_END: 80,
714
+ get BLACK_END() {
715
+ return 2 * this.BLACK_STOP;
716
+ },
667
717
  // End percentage for black hover 2
668
718
  WHITE_START: 1,
669
719
  // Start opacity for white hover 2
670
- WHITE_STOP: 80
720
+ get WHITE_STOP() {
721
+ return this.BLACK_END;
722
+ }
671
723
  },
672
724
  HOVER_3: {
673
725
  BLACK_START: .5,
674
726
  // Start opacity for black hover 3
675
- BLACK_MID: .2,
727
+ get BLACK_MID() {
728
+ return .4 * this.BLACK_START;
729
+ },
676
730
  // Mid opacity for black hover 3
677
731
  BLACK_STOP: 50,
678
732
  // Stop percentage for black hover 3
679
- BLACK_END: 100,
733
+ get BLACK_END() {
734
+ return 2 * this.BLACK_STOP;
735
+ },
680
736
  // End percentage for black hover 3
681
737
  WHITE_START: 1,
682
738
  // Start opacity for white hover 3
683
- WHITE_STOP: 100
739
+ get WHITE_STOP() {
740
+ return this.BLACK_END;
741
+ }
684
742
  }
685
743
  },
686
744
  // Base and overlay gradient constants
@@ -689,34 +747,54 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
689
747
  // Gradient angle in degrees
690
748
  BLACK_START_BASE: .15,
691
749
  // Base start opacity for black
692
- BLACK_START_MULTIPLIER: .003,
750
+ get BLACK_START_MULTIPLIER() {
751
+ return .02 * this.BLACK_START_BASE;
752
+ },
693
753
  // Multiplier for mouse X influence on start
694
754
  BLACK_MID_BASE: .1,
695
755
  // Base mid opacity for black
696
- BLACK_MID_MULTIPLIER: .002,
756
+ get BLACK_MID_MULTIPLIER() {
757
+ return .02 * this.BLACK_MID_BASE;
758
+ },
697
759
  // Multiplier for mouse Y influence on mid
698
760
  BLACK_MID_STOP: 50,
699
761
  // Mid stop percentage
700
- BLACK_END_BASE: .18,
762
+ get BLACK_END_BASE() {
763
+ return 1.2 * this.BLACK_START_BASE;
764
+ },
701
765
  // Base end opacity for black
702
- BLACK_END_MULTIPLIER: .004,
766
+ get BLACK_END_MULTIPLIER() {
767
+ return .022 * this.BLACK_END_BASE;
768
+ },
703
769
  // Multiplier for mouse X influence on end
704
- WHITE_OPACITY: .1
770
+ get WHITE_OPACITY() {
771
+ return .666 * this.BLACK_START_BASE;
772
+ }
705
773
  },
706
774
  OVERLAY_GRADIENT: {
707
775
  BLACK_START_BASE: .12,
708
776
  // Base start opacity for black overlay
709
- BLACK_START_MULTIPLIER: .003,
777
+ get BLACK_START_MULTIPLIER() {
778
+ return .025 * this.BLACK_START_BASE;
779
+ },
710
780
  // Multiplier for mouse X influence on start
711
- BLACK_MID: .06,
781
+ get BLACK_MID() {
782
+ return .5 * this.BLACK_START_BASE;
783
+ },
712
784
  // Mid opacity for black overlay
713
785
  BLACK_MID_STOP: 40,
714
786
  // Mid stop percentage
715
- BLACK_END_BASE: .15,
787
+ get BLACK_END_BASE() {
788
+ return 1.25 * this.BLACK_START_BASE;
789
+ },
716
790
  // Base end opacity for black overlay
717
- BLACK_END_MULTIPLIER: .003,
791
+ get BLACK_END_MULTIPLIER() {
792
+ return .02 * this.BLACK_END_BASE;
793
+ },
718
794
  // Multiplier for mouse Y influence on end
719
- WHITE_OPACITY: .05
795
+ get WHITE_OPACITY() {
796
+ return .416 * this.BLACK_START_BASE;
797
+ }
720
798
  },
721
799
  // Overlay highlight constants
722
800
  OVERLAY_HIGHLIGHT: {
@@ -726,9 +804,13 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
726
804
  // Y position percentage
727
805
  WHITE_OPACITY: .4,
728
806
  // White opacity in gradient
729
- STOP: 60,
807
+ get STOP() {
808
+ return 150 * this.WHITE_OPACITY;
809
+ },
730
810
  // Stop percentage
731
- OPACITY_MULTIPLIER: .7
811
+ get OPACITY_MULTIPLIER() {
812
+ return 1.75 * this.WHITE_OPACITY;
813
+ }
732
814
  },
733
815
  // Displacement and aberration multipliers
734
816
  MULTIPLIERS: {
@@ -781,11 +863,7 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
781
863
  }
782
864
  }
783
865
  }
784
- }, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateDistance = (pos1, pos2) => {
785
- if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
786
- const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
787
- return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
788
- }, calculateElementCenter = rect => rect ? {
866
+ }, {CONSTANTS: CONSTANTS$2} = ATOMIX_GLASS, calculateElementCenter = rect => rect ? {
789
867
  x: rect.left + rect.width / 2,
790
868
  y: rect.top + rect.height / 2
791
869
  } : {
@@ -857,7 +935,16 @@ const _includesInstanceProperty = getDefaultExportFromCjs((function(it) {
857
935
  // Silently handle errors
858
936
  }
859
937
  return CONSTANTS$2.DEFAULT_CORNER_RADIUS;
860
- }, lerp$1 = (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) => {
938
+ }, smoothstep = t => {
939
+ const clamped = Math.max(0, Math.min(1, t));
940
+ return clamped * clamped * (3 - 2 * clamped);
941
+ }, lerp$1 = (a, b, t) => a + (b - a) * t, softClamp = (value, max) => max <= 0 ? 0 : max * (1 - Math.exp(-value / max)), calculateSpring = (current, target, velocity, stiffness = .1, damping = .8) => {
942
+ const newVelocity = (velocity + (target - current) * stiffness) * damping;
943
+ return {
944
+ value: current + newVelocity,
945
+ velocity: newVelocity
946
+ };
947
+ }, getDisplacementMap = (mode, displacementMap, polarDisplacementMap, prominentDisplacementMap, shaderMapUrl) => {
861
948
  switch (mode) {
862
949
  case "standard":
863
950
  return displacementMap;
@@ -1251,6 +1338,9 @@ shaderTime: shaderTime, withTimeAnimation: withTimeAnimation = !1, animationSpee
1251
1338
  }), jsx("div", {
1252
1339
  ref: contentRef,
1253
1340
  className: ATOMIX_GLASS.CONTENT_CLASS,
1341
+ style: {
1342
+ transform: "var(--atomix-glass-child-parallax, none)"
1343
+ },
1254
1344
  children: children
1255
1345
  }) ]
1256
1346
  })
@@ -1375,51 +1465,26 @@ class {
1375
1465
  }
1376
1466
  }, updateAtomixGlassStyles = (wrapperElement, containerElement, params) => {
1377
1467
  if (!wrapperElement && !containerElement) return;
1378
- const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, directionalScale: directionalScale, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
1468
+ if (!validateGlassSize(params.glassSize)) return;
1469
+ const {mouseOffset: mouseOffset, globalMousePosition: globalMousePosition, glassSize: glassSize, isHovered: isHovered, isActive: isActive, isOverLight: isOverLight, baseOverLightConfig: baseOverLightConfig, effectiveBorderRadius: effectiveBorderRadius, effectiveWithoutEffects: effectiveWithoutEffects, effectiveReducedMotion: effectiveReducedMotion, elasticity: elasticity, elasticTranslation: elasticTranslation, elasticVelocity: elasticVelocity, mouseVelocity: mouseVelocity, directionalScale: directionalScale, scaleBase: scaleBase, onClick: onClick, withLiquidBlur: withLiquidBlur, blurAmount: blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT, saturation: saturation = ATOMIX_GLASS.DEFAULTS.SATURATION, padding: padding = ATOMIX_GLASS.DEFAULTS.PADDING, isFixedOrSticky: isFixedOrSticky = !1} = params, mouseInfluence = calculateMouseInfluence(mouseOffset), hoverIntensity = isHovered ? 1.4 : 1, activeIntensity = isActive ? 1.6 : 1, overLightConfig = {
1379
1470
  opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
1380
1471
  contrast: Math.min(1.6, baseOverLightConfig.contrast + .1 * mouseInfluence),
1381
1472
  brightness: Math.min(1.1, baseOverLightConfig.brightness + .05 * mouseInfluence),
1382
1473
  shadowIntensity: Math.min(1.2, Math.max(.5, baseOverLightConfig.shadowIntensity + .2 * mouseInfluence)),
1383
1474
  borderOpacity: Math.min(1, Math.max(.3, baseOverLightConfig.borderOpacity + .1 * mouseInfluence)),
1384
1475
  saturationBoost: baseOverLightConfig.saturationBoost
1385
- };
1386
- // Calculate mouse influence
1387
- let computedDirectionalScale = directionalScale, elasticTranslation = {
1476
+ }, scaleX = directionalScale.x * scaleBase, scaleY = directionalScale.y * scaleBase, transformStyle = effectiveWithoutEffects ? `scale(${scaleBase})` : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`, stretchMagnitude = ((pos1, pos2) => {
1477
+ if (!pos1 || !pos2 || "number" != typeof pos1.x || "number" != typeof pos1.y || "number" != typeof pos2.x || "number" != typeof pos2.y) return 0;
1478
+ const deltaX = pos1.x - pos2.x, deltaY = pos1.y - pos2.y;
1479
+ return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
1480
+ })({
1388
1481
  x: 0,
1389
1482
  y: 0
1390
- };
1391
- // Calculate elastic translation and directional scale
1392
- if (!effectiveWithoutEffects && wrapperElement) {
1393
- const rect = wrapperElement.getBoundingClientRect(), center = calculateElementCenter(rect);
1394
- // Mouse presence and edge distance logic
1395
- if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
1396
- 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({
1397
- x: edgeDistanceX,
1398
- y: edgeDistanceY
1399
- }, {
1400
- x: 0,
1401
- y: 0
1402
- }), rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE, fadeInFactor = (t => {
1403
- const clamped = Math.max(0, Math.min(1, t));
1404
- return clamped * clamped * (3 - 2 * clamped);
1405
- })(rawT);
1406
- // Directional scale
1407
- if (elasticTranslation = {
1408
- x: deltaX * elasticity * .1 * fadeInFactor,
1409
- y: deltaY * elasticity * .1 * fadeInFactor
1410
- }, !isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
1411
- const centerDistance = calculateDistance(globalMousePosition, center);
1412
- if (centerDistance > 0) {
1413
- 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);
1414
- computedDirectionalScale = `scaleX(${Math.max(.85, softScaleX)}) scaleY(${Math.max(.85, softScaleY)})`;
1415
- }
1416
- }
1417
- }
1418
- }
1419
- 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}`;
1420
- // Update Wrapper Styles (glassVars)
1421
- if (wrapperElement) {
1422
- 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 = {
1483
+ }, elasticTranslation), tensionFactor = smoothstep(stretchMagnitude / 80), lightingContrast = Math.min(1.8, overLightConfig.contrast + .2 * tensionFactor), lightingBrightness = Math.min(1.2, overLightConfig.brightness + .1 * tensionFactor);
1484
+ // Calculate mouse influence
1485
+ // Update Wrapper Styles (glassVars)
1486
+ if (wrapperElement) {
1487
+ const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT, velocityRotation = (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5), borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation, chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5, angleR = borderGradientAngle - chromaticOffset, angleB = borderGradientAngle + chromaticOffset, borderStop1 = Math.max(GRADIENT.BORDER_STOP_1.MIN, GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER), borderStop2 = Math.min(GRADIENT.BORDER_STOP_2.MAX, GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER), tensionGlow = 1 + .5 * tensionFactor, borderOpacities = [ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) * tensionGlow, (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) * tensionGlow ], configBorderOpacity = overLightConfig.borderOpacity, whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, hoverPositions = {
1423
1488
  hover1: {
1424
1489
  x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
1425
1490
  y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1
@@ -1442,10 +1507,16 @@ class {
1442
1507
  base: isOverLight ? overLightConfig.opacity : 0,
1443
1508
  over: isOverLight ? 1.1 * overLightConfig.opacity : 0
1444
1509
  }, style = wrapperElement.style;
1445
- style.setProperty("--atomix-glass-transform", transformStyle || "none"),
1446
- // Gradients
1447
- style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1448
- style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1510
+ style.setProperty("--atomix-glass-transform", transformStyle || "none");
1511
+ // Parallax for content (liquid refraction feel)
1512
+ const parallaxFactor = .38 + .12 * tensionFactor;
1513
+ style.setProperty("--atomix-glass-child-parallax", `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`),
1514
+ style.setProperty("--atomix-glass-contrast", lightingContrast.toString()), style.setProperty("--atomix-glass-brightness", lightingBrightness.toString()),
1515
+ // ── Chromatic Rim Lighting ──────────────────────────────────────
1516
+ // Layer 1: Core White/Blue highlight
1517
+ style.setProperty("--atomix-glass-border-gradient-1", `linear-gradient(${angleB}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[0] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[1] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1518
+ // Layer 2: Subtle Red/Warm highlight (offset angle)
1519
+ style.setProperty("--atomix-glass-border-gradient-2", `linear-gradient(${angleR}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${(borderOpacities[2] ?? 1) * configBorderOpacity}) ${borderStop1}%, rgba(${whiteColor}, ${(borderOpacities[3] ?? 1) * configBorderOpacity}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`),
1449
1520
  // Hover gradients
1450
1521
  style.setProperty("--atomix-glass-hover-1-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.WHITE_STOP}%)`),
1451
1522
  style.setProperty("--atomix-glass-hover-2-gradient", isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_END}%)` : `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.WHITE_STOP}%)`),
@@ -1473,7 +1544,7 @@ class {
1473
1544
  flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER
1474
1545
  };
1475
1546
  if (withLiquidBlur && rect) {
1476
- const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR), edgeIntensity = mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, baseBlur * FLOW_BLUR_MULTIPLIER);
1547
+ const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = blurAmount * MAX_BLUR_RELATIVE, baseBlur = softClamp(blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR, maxBlur), edgeBlur = softClamp(baseBlur * (.8 + mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR * .4), maxBlur), centerBlur = softClamp(baseBlur * (.3 + mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR * .3), maxBlur), flowBlur = softClamp(baseBlur * FLOW_BLUR_MULTIPLIER, maxBlur);
1477
1548
  liquidBlur = {
1478
1549
  baseBlur: clampBlur(baseBlur),
1479
1550
  edgeBlur: clampBlur(edgeBlur),
@@ -1482,9 +1553,10 @@ class {
1482
1553
  };
1483
1554
  }
1484
1555
  // Backdrop filter
1485
- let backdropFilterString = `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`;
1486
- const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), area = rect ? rect.width * rect.height : 0;
1487
- backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
1556
+ const dynamicSaturation = saturation + 40 * tensionFactor + 15 * (liquidBlur.baseBlur || 0);
1557
+ let backdropFilterString = "";
1558
+ const area = rect ? rect.width * rect.height : 0;
1559
+ backdropFilterString = !withLiquidBlur || effectiveReducedMotion || effectiveWithoutEffects || area > 18e4 ? `blur(${clampBlur(Math.max(liquidBlur.baseBlur, .8 * liquidBlur.edgeBlur, 1.1 * liquidBlur.centerBlur, .9 * liquidBlur.flowBlur))}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})` : `blur(${clampBlur(.4 * liquidBlur.baseBlur + .25 * liquidBlur.edgeBlur + .15 * liquidBlur.centerBlur + .2 * liquidBlur.flowBlur)}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
1488
1560
  // Container variables
1489
1561
  const style = containerElement.style;
1490
1562
  style.setProperty("--atomix-glass-container-padding", padding), style.setProperty("--atomix-glass-container-radius", `${effectiveBorderRadius}px`),
@@ -1663,7 +1735,24 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1663
1735
  }), targetGlobalMousePositionRef = useRef({
1664
1736
  x: 0,
1665
1737
  y: 0
1666
- }), 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), animationFrameIdRef = useRef(null), animationStartTimeRef = useRef(0), elapsedTimeRef = useRef(0), shaderTimeRef = useRef(0), fbmConfig = useMemo((() => {
1738
+ }), lerpRafRef = useRef(null), lerpActiveRef = useRef(!1), [dynamicBorderRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), elasticTranslationRef = useRef({
1739
+ x: 0,
1740
+ y: 0
1741
+ }), elasticVelocityRef = useRef({
1742
+ x: 0,
1743
+ y: 0
1744
+ }), directionalScaleRef = useRef({
1745
+ x: 1,
1746
+ y: 1
1747
+ }), scaleVelocityRef = useRef({
1748
+ x: 0,
1749
+ y: 0
1750
+ });
1751
+ useRef(0);
1752
+ const mouseVelocityRef = useRef({
1753
+ x: 0,
1754
+ y: 0
1755
+ }), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), animationFrameIdRef = useRef(null), animationStartTimeRef = useRef(0), elapsedTimeRef = useRef(0), shaderTimeRef = useRef(0), fbmConfig = useMemo((() => {
1667
1756
  // If quality preset is provided, use it as base
1668
1757
  const preset = (quality = distortionQuality, ATOMIX_GLASS.CONSTANTS.DISTORTION_QUALITY_PRESETS[quality]);
1669
1758
  // Override with custom values if provided
@@ -1948,57 +2037,85 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
1948
2037
  return "undefined" == typeof process || process.env, finalConfig;
1949
2038
  }
1950
2039
  return "undefined" == typeof process || process.env, baseConfig;
1951
- }), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.98)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
2040
+ }), [ overLight, getEffectiveOverLight, isHovered, isActive, validateConfigValue, debugOverLight ]), transformStyle = useMemo((() => effectiveWithoutEffects || isActive && Boolean(onClick) ? "scale(0.99)" : "scale(1)"), [ effectiveWithoutEffects, isActive, onClick ]), updateRectRef = useRef(null), stopLerpLoop = useCallback((() => {
1952
2041
  lerpActiveRef.current = !1, null !== lerpRafRef.current && (cancelAnimationFrame(lerpRafRef.current),
1953
2042
  lerpRafRef.current = null);
1954
2043
  }), []), startLerpLoop = useCallback((() => {
1955
2044
  if (lerpActiveRef.current) return;
1956
- lerpActiveRef.current = !0;
1957
- const LERP_T = CONSTANTS.LERP_FACTOR, tick = () => {
2045
+ lerpActiveRef.current = !0, CONSTANTS.LERP_FACTOR;
2046
+ // 0.08 lower = more viscous
2047
+ const tick = () => {
1958
2048
  if (!lerpActiveRef.current) return;
1959
2049
  if (!glassRef.current) return void (lerpActiveRef.current = !1);
1960
- const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, dx = tgt.x - cur.x, dy = tgt.y - cur.y;
1961
- // If we're close enough, snap and park
1962
- if (Math.abs(dx) < .01 && Math.abs(dy) < .01) return internalMouseOffsetRef.current = {
1963
- ...tgt
1964
- }, internalGlobalMousePositionRef.current = {
1965
- ...targetGlobalMousePositionRef.current
1966
- },
1967
- // Final update and stop
1968
- updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
1969
- mouseOffset: internalMouseOffsetRef.current,
1970
- globalMousePosition: internalGlobalMousePositionRef.current,
1971
- glassSize: glassSize,
1972
- isHovered: isHovered,
1973
- isActive: isActive,
1974
- isOverLight: overLightConfig.isOverLight,
1975
- baseOverLightConfig: overLightConfig,
1976
- effectiveBorderRadius: effectiveBorderRadius,
1977
- effectiveWithoutEffects: effectiveWithoutEffects,
1978
- effectiveReducedMotion: effectiveReducedMotion,
1979
- elasticity: elasticity,
1980
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
1981
- onClick: onClick,
1982
- withLiquidBlur: withLiquidBlur,
1983
- blurAmount: blurAmount,
1984
- saturation: saturation,
1985
- padding: padding,
1986
- isFixedOrSticky: isFixedOrSticky
1987
- }), void stopLerpLoop();
1988
- // Smooth step
1989
- internalMouseOffsetRef.current = {
1990
- x: lerp$1(cur.x, tgt.x, LERP_T),
1991
- y: lerp$1(cur.y, tgt.y, LERP_T)
2050
+ const cur = internalMouseOffsetRef.current, tgt = targetMouseOffsetRef.current, springX = calculateSpring(cur.x, tgt.x, mouseVelocityRef.current.x, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING), springY = calculateSpring(cur.y, tgt.y, mouseVelocityRef.current.y, CONSTANTS.LERP_FACTOR, CONSTANTS.ELASTICITY_DAMPING);
2051
+ internalMouseOffsetRef.current = {
2052
+ x: springX.value,
2053
+ y: springY.value
2054
+ }, mouseVelocityRef.current = {
2055
+ x: springX.velocity,
2056
+ y: springY.velocity
1992
2057
  };
1993
2058
  const curG = internalGlobalMousePositionRef.current, tgtG = targetGlobalMousePositionRef.current;
1994
2059
  internalGlobalMousePositionRef.current = {
1995
- x: lerp$1(curG.x, tgtG.x, LERP_T),
1996
- y: lerp$1(curG.y, tgtG.y, LERP_T)
2060
+ x: lerp$1(curG.x, tgtG.x, CONSTANTS.LERP_FACTOR),
2061
+ y: lerp$1(curG.y, tgtG.y, CONSTANTS.LERP_FACTOR)
2062
+ };
2063
+ // ── Calculate Elastic Physics ─────────────────────────────────────
2064
+ let targetElasticTranslation = {
2065
+ x: 0,
2066
+ y: 0
2067
+ }, targetScale = {
2068
+ x: 1,
2069
+ y: 1
2070
+ };
2071
+ if (!effectiveWithoutEffects && glassRef.current) {
2072
+ const rect = cachedRectRef.current || glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), globalPos = internalGlobalMousePositionRef.current;
2073
+ if (globalPos.x && globalPos.y) {
2074
+ const deltaX = globalPos.x - center.x, deltaY = globalPos.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - rect.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - rect.height / 2), edgeDistance = Math.sqrt(edgeDistanceX * edgeDistanceX + edgeDistanceY * edgeDistanceY), activationZone = CONSTANTS.ACTIVATION_ZONE, rawT = edgeDistance > activationZone ? 0 : 1 - edgeDistance / activationZone, fadeInFactor = smoothstep(rawT);
2075
+ // Scale stretch logic (liquid surface tension)
2076
+ if (targetElasticTranslation = {
2077
+ x: deltaX * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor,
2078
+ y: deltaY * elasticity * CONSTANTS.ELASTICITY_TRANSLATION_FACTOR * fadeInFactor
2079
+ }, edgeDistance <= activationZone) {
2080
+ const centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
2081
+ if (centerDistance > 0) {
2082
+ const nx = deltaX / centerDistance, ny = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 350, 1) * elasticity * rawT, mag = 1 + .06 * stretchIntensity;
2083
+ targetScale = {
2084
+ x: mag + Math.abs(nx) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO,
2085
+ y: mag + Math.abs(ny) * stretchIntensity * CONSTANTS.ELASTICITY_STRETCH_RATIO
2086
+ },
2087
+ // Maintain liquid volume by compressing the perpendicular axis
2088
+ targetScale.x -= Math.abs(ny) * stretchIntensity * .15, targetScale.y -= Math.abs(nx) * stretchIntensity * .15;
2089
+ }
2090
+ }
2091
+ }
2092
+ }
2093
+ // Integrate Elastic Translation Spring
2094
+ const springTX = calculateSpring(elasticTranslationRef.current.x, targetElasticTranslation.x, elasticVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springTY = calculateSpring(elasticTranslationRef.current.y, targetElasticTranslation.y, elasticVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
2095
+ elasticTranslationRef.current = {
2096
+ x: springTX.value,
2097
+ y: springTY.value
2098
+ }, elasticVelocityRef.current = {
2099
+ x: springTX.velocity,
2100
+ y: springTY.velocity
2101
+ };
2102
+ // Integrate Scale Spring
2103
+ const springSX = calculateSpring(directionalScaleRef.current.x, targetScale.x, scaleVelocityRef.current.x, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING), springSY = calculateSpring(directionalScaleRef.current.y, targetScale.y, scaleVelocityRef.current.y, CONSTANTS.ELASTICITY_STIFFNESS, CONSTANTS.ELASTICITY_DAMPING);
2104
+ directionalScaleRef.current = {
2105
+ x: springSX.value,
2106
+ y: springSY.value
2107
+ }, scaleVelocityRef.current = {
2108
+ x: springSX.velocity,
2109
+ y: springSY.velocity
1997
2110
  },
1998
2111
  // Imperative style update
1999
2112
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
2000
2113
  mouseOffset: internalMouseOffsetRef.current,
2001
2114
  globalMousePosition: internalGlobalMousePositionRef.current,
2115
+ elasticTranslation: elasticTranslationRef.current,
2116
+ elasticVelocity: elasticVelocityRef.current,
2117
+ mouseVelocity: mouseVelocityRef.current,
2118
+ directionalScale: directionalScaleRef.current,
2002
2119
  glassSize: glassSize,
2003
2120
  isHovered: isHovered,
2004
2121
  isActive: isActive,
@@ -2008,17 +2125,16 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
2008
2125
  effectiveWithoutEffects: effectiveWithoutEffects,
2009
2126
  effectiveReducedMotion: effectiveReducedMotion,
2010
2127
  elasticity: elasticity,
2011
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
2128
+ scaleBase: isActive && Boolean(onClick) ? .99 : 1,
2012
2129
  onClick: onClick,
2013
2130
  withLiquidBlur: withLiquidBlur,
2014
2131
  blurAmount: blurAmount,
2015
2132
  saturation: saturation,
2016
2133
  padding: padding,
2017
2134
  isFixedOrSticky: isFixedOrSticky
2018
- }), lerpRafRef.current = requestAnimationFrame(tick);
2135
+ }), Math.abs(mouseVelocityRef.current.x) < .001 && Math.abs(mouseVelocityRef.current.y) < .001 && Math.abs(elasticVelocityRef.current.x) < .001 && Math.abs(elasticVelocityRef.current.y) < .001 && Math.abs(scaleVelocityRef.current.x) < .001 && Math.abs(scaleVelocityRef.current.y) < .001 && Math.abs(internalMouseOffsetRef.current.x - targetMouseOffsetRef.current.x) < .001 && Math.abs(internalMouseOffsetRef.current.y - targetMouseOffsetRef.current.y) < .001 ? stopLerpLoop() : lerpRafRef.current = requestAnimationFrame(tick);
2019
2136
  };
2020
- // 0.08 – lower = more viscous
2021
- lerpRafRef.current = requestAnimationFrame(tick);
2137
+ lerpRafRef.current = requestAnimationFrame(tick);
2022
2138
  }), [ glassRef, wrapperRef, glassSize, isHovered, isActive, overLightConfig, effectiveBorderRadius, effectiveWithoutEffects, effectiveReducedMotion, elasticity, onClick, withLiquidBlur, blurAmount, saturation, padding, isFixedOrSticky, stopLerpLoop ]), handleGlobalMousePosition = useCallback((globalPos => {
2023
2139
  if (externalGlobalMousePosition && externalMouseOffset) return;
2024
2140
  if (effectiveWithoutEffects) return;
@@ -2065,6 +2181,11 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
2065
2181
  updateAtomixGlassStyles(wrapperRef?.current || null, glassRef.current, {
2066
2182
  mouseOffset: externalMouseOffset || internalMouseOffsetRef.current,
2067
2183
  globalMousePosition: externalGlobalMousePosition || internalGlobalMousePositionRef.current,
2184
+ elasticTranslation: elasticTranslationRef.current,
2185
+ elasticVelocity: elasticVelocityRef.current,
2186
+ mouseVelocity: mouseVelocityRef.current,
2187
+ directionalScale: directionalScaleRef.current,
2188
+ scaleBase: isActive && Boolean(onClick) ? .96 : 1,
2068
2189
  glassSize: glassSize,
2069
2190
  isHovered: isHovered,
2070
2191
  isActive: isActive,
@@ -2074,7 +2195,6 @@ withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION, animationSpeed: a
2074
2195
  effectiveWithoutEffects: effectiveWithoutEffects,
2075
2196
  effectiveReducedMotion: effectiveReducedMotion,
2076
2197
  elasticity: elasticity,
2077
- directionalScale: isActive && Boolean(onClick) ? "scale(0.96)" : "scale(1)",
2078
2198
  onClick: onClick,
2079
2199
  withLiquidBlur: withLiquidBlur,
2080
2200
  blurAmount: blurAmount,
@@ -2971,7 +3091,7 @@ const PERFORMANCE_PRESET = {
2971
3091
  "aria-label": ariaLabel,
2972
3092
  "aria-describedby": ariaDescribedBy,
2973
3093
  "aria-disabled": !(!onClick || !effectiveWithoutEffects) || !onClick && void 0,
2974
- "aria-pressed": void 0,
3094
+ "aria-pressed": onClick ? isActive : void 0,
2975
3095
  onKeyDown: onClick ? handleKeyDown : void 0,
2976
3096
  children: [ jsx(AtomixGlassContainer, {
2977
3097
  ref: glassRef,
@@ -3773,10 +3893,10 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3773
3893
  children: renderSlot(slots?.spinner, {
3774
3894
  className: ThemeNaming.bemClass("btn", "spinner"),
3775
3895
  size: spinnerSize,
3776
- variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
3896
+ variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
3777
3897
  }, jsx(Spinner, {
3778
3898
  size: spinnerSize,
3779
- variant: "link" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "error" : variant
3899
+ variant: "link" === variant || "ghost" === variant || "string" == typeof variant && variant.startsWith("outline-") ? "primary" : "danger" === variant ? "danger" : variant
3780
3900
  }))
3781
3901
  }), iconElement && !loading && jsx("span", {
3782
3902
  className: ThemeNaming.bemClass("btn", "icon"),
@@ -3865,8 +3985,7 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3865
3985
  const defaultGlassProps = {
3866
3986
  displacementScale: 20,
3867
3987
  blurAmount: 0,
3868
- saturation: 200,
3869
- elasticity: 0
3988
+ saturation: 200
3870
3989
  }, glassProps = !0 === glass ? defaultGlassProps : {
3871
3990
  ...defaultGlassProps,
3872
3991
  ...glass
@@ -4054,7 +4173,6 @@ className: className = "", style: style, ...rest}, ref) => {
4054
4173
  children: cardContent
4055
4174
  }), glass ? jsx(AtomixGlass, {
4056
4175
  ...!0 === glass ? {} : glass,
4057
- elasticity: 0,
4058
4176
  children: anchorElement
4059
4177
  }) : anchorElement;
4060
4178
  }
@@ -4066,7 +4184,6 @@ className: className = "", style: style, ...rest}, ref) => {
4066
4184
  });
4067
4185
  return glass ? jsx(AtomixGlass, {
4068
4186
  ...!0 === glass ? {} : glass,
4069
- elasticity: 0,
4070
4187
  children: divElement
4071
4188
  }) : divElement;
4072
4189
  })));