@shohojdhara/atomix 0.6.4 → 0.6.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 (83) hide show
  1. package/dist/atomix.css +117 -38
  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/atomix.umd.js +1 -1
  6. package/dist/atomix.umd.js.map +1 -1
  7. package/dist/atomix.umd.min.js +1 -1
  8. package/dist/charts.d.ts +30 -1
  9. package/dist/charts.js +625 -846
  10. package/dist/charts.js.map +1 -1
  11. package/dist/core.d.ts +30 -1
  12. package/dist/core.js +659 -873
  13. package/dist/core.js.map +1 -1
  14. package/dist/forms.d.ts +30 -1
  15. package/dist/forms.js +1171 -1402
  16. package/dist/forms.js.map +1 -1
  17. package/dist/heavy.d.ts +31 -89
  18. package/dist/heavy.js +975 -1195
  19. package/dist/heavy.js.map +1 -1
  20. package/dist/index.d.ts +383 -140
  21. package/dist/index.esm.js +1567 -1679
  22. package/dist/index.esm.js.map +1 -1
  23. package/dist/index.js +1556 -1667
  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/package.json +1 -1
  28. package/src/components/Accordion/Accordion.tsx +2 -5
  29. package/src/components/AtomixGlass/AtomixGlass.test.tsx +14 -16
  30. package/src/components/AtomixGlass/AtomixGlass.tsx +137 -364
  31. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +32 -251
  32. package/src/components/AtomixGlass/GlassFilter.tsx +62 -68
  33. package/src/components/AtomixGlass/README.md +2 -1
  34. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +19 -18
  35. package/src/components/AtomixGlass/glass-border-styles.test.ts +58 -0
  36. package/src/components/AtomixGlass/glass-border-styles.ts +136 -0
  37. package/src/components/AtomixGlass/glass-utils.ts +456 -22
  38. package/src/components/AtomixGlass/shader-utils.ts +19 -77
  39. package/src/components/AtomixGlass/stories/AnimationFeatures.stories.tsx +158 -537
  40. package/src/components/AtomixGlass/stories/Border.stories.tsx +149 -0
  41. package/src/components/AtomixGlass/stories/Examples.stories.tsx +229 -89
  42. package/src/components/AtomixGlass/stories/Playground.stories.tsx +29 -340
  43. package/src/components/AtomixGlass/stories/argTypes.ts +30 -13
  44. package/src/components/AtomixGlass/stories/premium-presets.ts +206 -0
  45. package/src/components/AtomixGlass/stories/shared-components.tsx +52 -8
  46. package/src/components/Badge/Badge.tsx +4 -4
  47. package/src/components/Button/Button.tsx +2 -6
  48. package/src/components/Callout/Callout.test.tsx +4 -3
  49. package/src/components/Callout/Callout.tsx +2 -5
  50. package/src/components/Dropdown/Dropdown.tsx +3 -7
  51. package/src/components/Form/Checkbox.tsx +2 -8
  52. package/src/components/Form/Input.tsx +2 -9
  53. package/src/components/Form/Radio.tsx +2 -9
  54. package/src/components/Form/Select.test.tsx +6 -6
  55. package/src/components/Form/Select.tsx +2 -7
  56. package/src/components/Form/Textarea.stories.tsx +5 -5
  57. package/src/components/Form/Textarea.tsx +2 -9
  58. package/src/components/Messages/Messages.tsx +2 -8
  59. package/src/components/Modal/Modal.tsx +4 -5
  60. package/src/components/Navigation/Nav/Nav.tsx +2 -6
  61. package/src/components/Navigation/Navbar/Navbar.tsx +2 -9
  62. package/src/components/Navigation/SideMenu/SideMenu.tsx +2 -6
  63. package/src/components/Pagination/Pagination.tsx +2 -10
  64. package/src/components/Popover/Popover.tsx +2 -9
  65. package/src/components/Progress/Progress.tsx +2 -7
  66. package/src/components/Rating/Rating.tsx +2 -10
  67. package/src/components/Spinner/Spinner.tsx +2 -7
  68. package/src/components/Steps/Steps.tsx +2 -10
  69. package/src/components/Tabs/Tabs.tsx +2 -9
  70. package/src/components/Toggle/Toggle.tsx +2 -10
  71. package/src/components/Tooltip/Tooltip.tsx +2 -5
  72. package/src/lib/composables/useAtomixGlass.ts +42 -143
  73. package/src/lib/composables/useAtomixGlassStyles.ts +61 -77
  74. package/src/lib/composables/usePerformanceMonitor.ts +5 -66
  75. package/src/lib/constants/components.ts +363 -46
  76. package/src/lib/types/components.ts +33 -1
  77. package/src/styles/01-settings/_settings.atomix-glass.scss +66 -28
  78. package/src/styles/02-tools/_tools.button.scss +51 -42
  79. package/src/styles/02-tools/_tools.glass.scss +45 -3
  80. package/src/styles/06-components/_components.atomix-glass.scss +116 -79
  81. package/src/components/AtomixGlass/PerformanceDashboard.tsx +0 -171
  82. package/src/components/AtomixGlass/animation-system.ts +0 -578
  83. package/src/components/AtomixGlass/deprecated/AtomixGlass.deprecated.tsx +0 -390
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect, useRef, forwardRef } from 'react';
2
2
  import { NavbarProps } from '../../../lib/types/components';
3
3
  import { useNavbar } from '../../../lib/composables/useNavbar';
4
- import { NAVBAR } from '../../../lib/constants/components';
4
+ import { NAVBAR, GLASS_DEFAULTS } from '../../../lib/constants/components';
5
5
  import { AtomixGlass } from '../../AtomixGlass/AtomixGlass';
6
6
 
7
7
  /**
@@ -187,14 +187,7 @@ export const Navbar = forwardRef<HTMLElement, NavbarProps>(
187
187
  );
188
188
 
189
189
  if (glass) {
190
- const defaultGlassProps = {
191
- displacementScale: 30,
192
- blurAmount: 2,
193
- borderRadius: 0,
194
- elasticity: 0,
195
- mode: 'shader' as const,
196
- shaderVariant: 'premiumGlass' as const,
197
- };
190
+ const defaultGlassProps = GLASS_DEFAULTS.NAVBAR;
198
191
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
199
192
 
200
193
  // AtomixGlass hoists layout props (position/top/left/right/zIndex) to its
@@ -6,6 +6,7 @@ import { AtomixGlass } from '../../AtomixGlass/AtomixGlass';
6
6
  import useForkRef from '../../../lib/utils/useForkRef';
7
7
  import SideMenuList from './SideMenuList';
8
8
  import SideMenuItem from './SideMenuItem';
9
+ import { GLASS_DEFAULTS } from '../../../lib/constants/components';
9
10
 
10
11
  /**
11
12
  * SideMenu component provides a collapsible navigation menu with title and menu items.
@@ -305,12 +306,7 @@ export const SideMenu = forwardRef<HTMLDivElement, SideMenuProps>(
305
306
  );
306
307
 
307
308
  if (glass) {
308
- const defaultGlassProps = {
309
- displacementScale: 70,
310
- blurAmount: 2,
311
- borderRadius: 12,
312
- mode: 'shader' as const,
313
- };
309
+ const defaultGlassProps = GLASS_DEFAULTS.SIDE_MENU;
314
310
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
315
311
  return (
316
312
  <AtomixGlass {...glassProps}>
@@ -1,7 +1,7 @@
1
1
  import React, { memo, useState, FormEvent } from 'react';
2
2
  import { PaginationProps } from '../../lib/types/components';
3
3
  import { usePagination, DOTS } from '../../lib/composables/usePagination';
4
- import { PAGINATION_DEFAULTS } from '../../lib/constants/components';
4
+ import { PAGINATION_DEFAULTS, GLASS_DEFAULTS } from '../../lib/constants/components';
5
5
  import { Icon, IconProps } from '../Icon/Icon';
6
6
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
7
7
 
@@ -238,15 +238,7 @@ export const Pagination: React.FC<PaginationProps> = memo(
238
238
  );
239
239
 
240
240
  if (glass) {
241
- // Default glass settings for pagination
242
- const defaultGlassProps = {
243
- displacementScale: 60,
244
- blurAmount: 1,
245
- saturation: 160,
246
- aberrationIntensity: 0.5,
247
- borderRadius: 8,
248
- mode: 'shader' as const,
249
- };
241
+ const defaultGlassProps = GLASS_DEFAULTS.PAGINATION;
250
242
 
251
243
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
252
244
 
@@ -1,6 +1,6 @@
1
1
  import React, { ReactNode, forwardRef, createContext } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
- import { POPOVER } from '../../lib/constants/components';
3
+ import { POPOVER, GLASS_DEFAULTS } from '../../lib/constants/components';
4
4
  import { usePopover } from '../../lib/composables/usePopover';
5
5
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
6
6
  import type { PopoverProps, PopoverTriggerProps } from '../../lib/types/components';
@@ -81,14 +81,7 @@ export const Popover: React.FC<PopoverProps> = ({
81
81
  {glass ? (
82
82
  // Default glass settings for popovers
83
83
  (() => {
84
- const defaultGlassProps = {
85
- displacementScale: 50,
86
- blurAmount: 1,
87
- saturation: 160,
88
- aberrationIntensity: 0.5,
89
- borderRadius: 8,
90
- mode: 'shader' as const,
91
- };
84
+ const defaultGlassProps = GLASS_DEFAULTS.POPOVER;
92
85
 
93
86
  const glassProps =
94
87
  glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, memo } from 'react';
2
2
  import { ProgressProps } from '../../lib/types/components';
3
3
  import { useProgress } from '../../lib/composables/useProgress';
4
- import { PROGRESS } from '../../lib/constants/components';
4
+ import { PROGRESS, GLASS_DEFAULTS } from '../../lib/constants/components';
5
5
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
6
6
 
7
7
  export const Progress = memo(
@@ -43,12 +43,7 @@ export const Progress = memo(
43
43
  );
44
44
 
45
45
  if (glass) {
46
- const defaultGlassProps = {
47
- displacementScale: 30,
48
- blurAmount: 0.5,
49
- borderRadius: 8,
50
- mode: 'shader' as const,
51
- };
46
+ const defaultGlassProps = GLASS_DEFAULTS.PROGRESS;
52
47
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
53
48
  return <AtomixGlass {...glassProps}>{progressContent}</AtomixGlass>;
54
49
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useRef, useEffect, useCallback, forwardRef } from 'react';
2
- import { THEME_COLORS, SIZES, RATING } from '../../lib/constants/components';
2
+ import { THEME_COLORS, SIZES, RATING, GLASS_DEFAULTS } from '../../lib/constants/components';
3
3
  import { useRating } from '../../lib/composables/useRating';
4
4
  import type { RatingProps } from '../../lib/types/components';
5
5
  import useForkRef from '../../lib/utils/useForkRef';
@@ -275,15 +275,7 @@ export const Rating = forwardRef<HTMLDivElement, RatingProps>(
275
275
  );
276
276
 
277
277
  if (glass) {
278
- // Default glass settings for ratings
279
- const defaultGlassProps = {
280
- displacementScale: 60,
281
- blurAmount: 1,
282
- saturation: 160,
283
- aberrationIntensity: 0.5,
284
- borderRadius: 8,
285
- mode: 'shader' as const,
286
- };
278
+ const defaultGlassProps = GLASS_DEFAULTS.RATING;
287
279
 
288
280
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
289
281
 
@@ -1,7 +1,7 @@
1
1
  import React, { memo, forwardRef } from 'react';
2
2
  import { SpinnerProps } from '../../lib/types/components';
3
3
  import { useSpinner } from '../../lib/composables/useSpinner';
4
- import { SPINNER } from '../../lib/constants/components';
4
+ import { SPINNER, GLASS_DEFAULTS } from '../../lib/constants/components';
5
5
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
6
6
 
7
7
  export const Spinner = memo(
@@ -51,12 +51,7 @@ export const Spinner = memo(
51
51
  );
52
52
 
53
53
  if (glass) {
54
- const defaultGlassProps = {
55
- displacementScale: 20,
56
- blurAmount: 1,
57
- borderRadius: 999,
58
- mode: 'shader' as const,
59
- };
54
+ const defaultGlassProps = GLASS_DEFAULTS.SPINNER;
60
55
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
61
56
  return <AtomixGlass {...glassProps}>{spinnerContent}</AtomixGlass>;
62
57
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState, ReactNode, forwardRef, Children, cloneElement, isValidElement } from 'react';
2
- import { STEPS } from '../../lib/constants/components';
2
+ import { STEPS, GLASS_DEFAULTS } from '../../lib/constants/components';
3
3
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
4
4
  import { AtomixGlassProps } from '../../lib/types/components';
5
5
 
@@ -225,15 +225,7 @@ const StepsComp: React.FC<StepsProps> = ({
225
225
  );
226
226
 
227
227
  if (glass) {
228
- // Default glass settings for steps
229
- const defaultGlassProps = {
230
- displacementScale: 60,
231
- blurAmount: 1,
232
- saturation: 160,
233
- aberrationIntensity: 0.5,
234
- borderRadius: 8,
235
- mode: 'shader' as const,
236
- };
228
+ const defaultGlassProps = GLASS_DEFAULTS.STEPS;
237
229
 
238
230
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
239
231
 
@@ -7,7 +7,7 @@ import React, {
7
7
  forwardRef,
8
8
  ComponentType,
9
9
  } from 'react';
10
- import { TAB } from '../../lib/constants/components';
10
+ import { TAB, GLASS_DEFAULTS } from '../../lib/constants/components';
11
11
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
12
12
  import { AtomixGlassProps } from '../../lib/types/components';
13
13
 
@@ -354,14 +354,7 @@ const TabsComponentBase = ({
354
354
 
355
355
  if (glass) {
356
356
  // Default glass settings for tabs
357
- const defaultGlassProps = {
358
- displacementScale: 60,
359
- blurAmount: 1,
360
- saturation: 160,
361
- aberrationIntensity: 0.5,
362
- borderRadius: 8,
363
- mode: 'shader' as const,
364
- };
357
+ const defaultGlassProps = GLASS_DEFAULTS.TABS;
365
358
 
366
359
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
367
360
 
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useCallback, useEffect } from 'react';
2
- import { TOGGLE } from '../../lib/constants/components';
2
+ import { TOGGLE, GLASS_DEFAULTS } from '../../lib/constants/components';
3
3
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
4
4
  import { AtomixGlassProps, BaseComponentProps } from '../../lib/types/components';
5
5
 
@@ -115,15 +115,7 @@ export const Toggle: React.FC<ToggleProps> = ({
115
115
  );
116
116
 
117
117
  if (glass) {
118
- // Default glass settings for toggles
119
- const defaultGlassProps = {
120
- displacementScale: 60,
121
- blurAmount: 1,
122
- saturation: 160,
123
- aberrationIntensity: 0.5,
124
- borderRadius: 8,
125
- mode: 'shader' as const,
126
- };
118
+ const defaultGlassProps = GLASS_DEFAULTS.TOGGLE;
127
119
 
128
120
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
129
121
 
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode, memo } from 'react';
2
- import { TOOLTIP } from '../../lib/constants/components';
2
+ import { TOOLTIP, GLASS_DEFAULTS } from '../../lib/constants/components';
3
3
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
4
4
  import { AtomixGlassProps } from '../../lib/types/components';
5
5
  import {
@@ -118,10 +118,7 @@ export const Tooltip: React.FC<TooltipProps> = memo(
118
118
  );
119
119
 
120
120
  if (glass) {
121
- const defaultGlassProps = {
122
- displacementScale: 100,
123
- blurAmount: 3,
124
- };
121
+ const defaultGlassProps = GLASS_DEFAULTS.TOOLTIP;
125
122
 
126
123
  const glassProps = glass === true ? defaultGlassProps : { ...defaultGlassProps, ...glass };
127
124
 
@@ -10,23 +10,18 @@ import { ATOMIX_GLASS } from '../constants/components';
10
10
  import { globalMouseTracker } from './shared-mouse-tracker';
11
11
  import {
12
12
  calculateElementCenter,
13
- calculateMouseInfluence,
14
13
  extractBorderRadiusFromChildren,
15
14
  extractBorderRadiusFromDOMElement,
16
- validateGlassSize,
15
+ getInteractionIntensity,
17
16
  lerp,
18
17
  calculateSpring,
19
- calculateVelocity,
20
18
  smoothstep,
21
19
  } from '../../components/AtomixGlass/glass-utils';
22
- import { updateAtomixGlassStyles } from './useAtomixGlassStyles';
23
- // Phase 1: Time-Based Animation System
24
20
  import {
25
- createAnimationLoop,
26
- createFBMEngine,
27
- getFBMConfigForQuality,
28
- liquidGlassWithTime,
29
- } from '../../components/AtomixGlass/animation-system';
21
+ normalizeBorderConfig,
22
+ type ResolvedGlassBorderConfig,
23
+ } from '../../components/AtomixGlass/glass-border-styles';
24
+ import { updateAtomixGlassStyles } from './useAtomixGlassStyles';
30
25
 
31
26
  const { CONSTANTS } = ATOMIX_GLASS;
32
27
 
@@ -153,13 +148,7 @@ interface UseAtomixGlassOptions extends Omit<AtomixGlassProps, 'children'> {
153
148
  children?: React.ReactNode;
154
149
  isFixedOrSticky?: boolean;
155
150
  priority?: number; // Priority for z-index ordering
156
- // Phase 1: Time-Based Animation System
157
151
  withLiquidBlur?: boolean;
158
- animationQuality?: 'low' | 'medium' | 'high';
159
- timeSpeed?: number;
160
- noiseAmplitude?: number;
161
- noiseFrequency?: number;
162
- displacementStrength?: number;
163
152
  }
164
153
 
165
154
  interface UseAtomixGlassReturn {
@@ -191,9 +180,8 @@ interface UseAtomixGlassReturn {
191
180
  // Transform calculations
192
181
  transformStyle: string;
193
182
 
194
- // Phase 1: Animation System - Shader time control
195
- getShaderTime: () => number;
196
- applyTimeBasedDistortion: (uv: { x: number; y: number }) => { x: number; y: number };
183
+ /** Resolved liquid glass rim configuration */
184
+ resolvedBorder: ResolvedGlassBorderConfig;
197
185
 
198
186
  // Event handlers
199
187
  handleMouseEnter: () => void;
@@ -221,6 +209,8 @@ export function useAtomixGlass({
221
209
  reducedMotion = false,
222
210
  highContrast = false,
223
211
  withoutEffects = false,
212
+ border,
213
+ withBorder = true,
224
214
  elasticity = ATOMIX_GLASS.DEFAULTS.ELASTICITY,
225
215
  onClick,
226
216
  debugBorderRadius = false,
@@ -228,23 +218,20 @@ export function useAtomixGlass({
228
218
  children,
229
219
  blurAmount,
230
220
  saturation,
231
- padding,
221
+
232
222
  withLiquidBlur,
233
223
  isFixedOrSticky = false,
234
224
  priority = 1, // Default priority
235
- // Phase 1: Animation System Props
236
- withTimeAnimation = ATOMIX_GLASS.DEFAULTS.WITH_TIME_ANIMATION,
237
- animationSpeed = ATOMIX_GLASS.DEFAULTS.ANIMATION_SPEED,
238
- withMultiLayerDistortion = ATOMIX_GLASS.DEFAULTS.WITH_MULTI_LAYER_DISTORTION,
239
- distortionOctaves = ATOMIX_GLASS.DEFAULTS.DISTORTION_OCTAVES,
240
- distortionLacunarity = ATOMIX_GLASS.DEFAULTS.DISTORTION_LACUNARITY,
241
- distortionGain = ATOMIX_GLASS.DEFAULTS.DISTORTION_GAIN,
242
- distortionQuality = ATOMIX_GLASS.DEFAULTS.DISTORTION_QUALITY,
243
225
  }: UseAtomixGlassOptions): UseAtomixGlassReturn {
244
226
  // State
245
227
  const [isHovered, setIsHovered] = useState(false);
246
228
  const [isActive, setIsActive] = useState(false);
247
229
 
230
+ const resolvedBorder = useMemo(
231
+ () => normalizeBorderConfig(border, withBorder),
232
+ [border, withBorder]
233
+ );
234
+
248
235
  // Mouse tracking refs
249
236
  const cachedRectRef = useRef<DOMRect | null>(null);
250
237
  const internalGlobalMousePositionRef = useRef<MousePosition>({ x: 0, y: 0 });
@@ -267,46 +254,12 @@ export function useAtomixGlass({
267
254
  const elasticVelocityRef = useRef<MousePosition>({ x: 0, y: 0 });
268
255
  const directionalScaleRef = useRef<{ x: number; y: number }>({ x: 1, y: 1 });
269
256
  const scaleVelocityRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
270
- const lastMouseTimeRef = useRef<number>(0);
271
257
  const mouseVelocityRef = useRef<MousePosition>({ x: 0, y: 0 });
272
258
 
273
259
  const [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(false);
274
260
  const [userPrefersHighContrast, setUserPrefersHighContrast] = useState(false);
275
261
  const [detectedOverLight, setDetectedOverLight] = useState(false);
276
262
 
277
- // ============================================================================
278
- // Phase 1: Time-Based Animation System (Feature 1.1)
279
- // ============================================================================
280
-
281
- // Animation state refs
282
- const animationFrameIdRef = useRef<number | null>(null);
283
- const animationStartTimeRef = useRef<number>(0);
284
- const elapsedTimeRef = useRef<number>(0);
285
- const shaderTimeRef = useRef<number>(0);
286
-
287
- /**
288
- * Get FBM configuration based on quality preset or custom values
289
- */
290
- const fbmConfig = useMemo(() => {
291
- // If quality preset is provided, use it as base
292
- const preset = getFBMConfigForQuality(distortionQuality);
293
-
294
- // Override with custom values if provided
295
- return {
296
- octaves: distortionOctaves ?? preset.octaves,
297
- lacunarity: distortionLacunarity ?? preset.lacunarity,
298
- gain: distortionGain ?? preset.gain,
299
- };
300
- }, [distortionQuality, distortionOctaves, distortionLacunarity, distortionGain]);
301
-
302
- /**
303
- * Create FBM engine for multi-layer distortion
304
- */
305
- const fbmEngine = useMemo(() => {
306
- if (!withMultiLayerDistortion) return null;
307
- return createFBMEngine(fbmConfig);
308
- }, [withMultiLayerDistortion, fbmConfig]);
309
-
310
263
  /**
311
264
  * Determine effective animation settings
312
265
  */
@@ -315,74 +268,6 @@ export function useAtomixGlass({
315
268
  [reducedMotion, userPrefersReducedMotion]
316
269
  );
317
270
 
318
- const effectiveWithTimeAnimation = useMemo(() => {
319
- return withTimeAnimation && !effectiveReducedMotion;
320
- }, [withTimeAnimation, effectiveReducedMotion]);
321
-
322
- /**
323
- * Animation loop for time-based effects
324
- */
325
- useEffect(() => {
326
- if (!effectiveWithTimeAnimation || typeof window === 'undefined') {
327
- return undefined;
328
- }
329
-
330
- let lastFrameTime = performance.now();
331
-
332
- /**
333
- * Animation frame handler
334
- */
335
- const animate = (currentTime: number) => {
336
- // Calculate delta time
337
- const deltaTime = currentTime - lastFrameTime;
338
- lastFrameTime = currentTime;
339
-
340
- // Apply animation speed multiplier
341
- const scaledDelta = deltaTime * animationSpeed;
342
- elapsedTimeRef.current += scaledDelta;
343
- shaderTimeRef.current = elapsedTimeRef.current;
344
-
345
- // Continue animation loop
346
- animationFrameIdRef.current = requestAnimationFrame(animate);
347
- };
348
-
349
- // Start animation
350
- animationStartTimeRef.current = performance.now();
351
- animationFrameIdRef.current = requestAnimationFrame(animate);
352
-
353
- // Cleanup
354
- return () => {
355
- if (animationFrameIdRef.current !== null) {
356
- cancelAnimationFrame(animationFrameIdRef.current);
357
- animationFrameIdRef.current = null;
358
- }
359
- };
360
- }, [effectiveWithTimeAnimation, animationSpeed]);
361
-
362
- /**
363
- * Get current shader time for animations
364
- */
365
- const getShaderTime = useCallback(() => {
366
- return shaderTimeRef.current;
367
- }, []);
368
-
369
- /**
370
- * Apply time-based distortion to UV coordinates
371
- */
372
- const applyTimeBasedDistortion = useCallback(
373
- (uv: { x: number; y: number }): { x: number; y: number } => {
374
- if (!effectiveWithTimeAnimation || !fbmEngine) {
375
- return uv;
376
- }
377
-
378
- const time = shaderTimeRef.current;
379
-
380
- // Apply liquid glass distortion with time
381
- return liquidGlassWithTime(uv, time, fbmConfig);
382
- },
383
- [effectiveWithTimeAnimation, fbmEngine, fbmConfig]
384
- );
385
-
386
271
  // Memoized derived values
387
272
  const effectiveBorderRadius = useMemo(() => {
388
273
  if (borderRadius !== undefined) {
@@ -666,8 +551,7 @@ export function useAtomixGlass({
666
551
 
667
552
  const overLightConfig = useMemo(() => {
668
553
  const isOverLight = getEffectiveOverLight();
669
- const hoverIntensity = isHovered ? 1.4 : 1;
670
- const activeIntensity = isActive ? 1.6 : 1;
554
+ const { hoverIntensity, activeIntensity } = getInteractionIntensity(isHovered, isActive);
671
555
 
672
556
  // More robust overlight configuration with better defaults and clamping
673
557
  const baseOpacity = isOverLight
@@ -678,11 +562,14 @@ export function useAtomixGlass({
678
562
  isOverLight,
679
563
  threshold: 0.7,
680
564
  opacity: baseOpacity,
681
- contrast: 1.4,
682
- brightness: 0.9,
683
- saturationBoost: 1.3, // Fixed value — dynamic saturation amplifies perceived displacement
684
- shadowIntensity: 0.9,
685
- borderOpacity: 0.7,
565
+ // Dark UI (Apple Music): neutral contrast + slight brightness lift
566
+ contrast: isOverLight ? 1.4 : 1.02,
567
+ brightness: isOverLight ? 0.9 : 1.02,
568
+ saturationBoost: isOverLight ? 1.3 : 1.0,
569
+ shadowIntensity: isOverLight ? 0.9 : 1.0,
570
+ borderOpacity: isOverLight
571
+ ? ATOMIX_GLASS.BORDER.OVER_LIGHT.opacity
572
+ : ATOMIX_GLASS.BORDER.DARK.opacity,
686
573
  };
687
574
 
688
575
  if (typeof overLight === 'object' && overLight !== null) {
@@ -713,6 +600,12 @@ export function useAtomixGlass({
713
600
  3.0,
714
601
  baseConfig.saturationBoost
715
602
  );
603
+ const validatedBorderOpacity = validateConfigValue(
604
+ objConfig.borderOpacity,
605
+ 0.1,
606
+ 1.0,
607
+ baseConfig.borderOpacity
608
+ );
716
609
 
717
610
  const finalConfig = {
718
611
  ...baseConfig,
@@ -721,6 +614,7 @@ export function useAtomixGlass({
721
614
  contrast: validatedContrast,
722
615
  brightness: validatedBrightness,
723
616
  saturationBoost: validatedSaturationBoost,
617
+ borderOpacity: validatedBorderOpacity,
724
618
  };
725
619
 
726
620
  if (
@@ -958,8 +852,10 @@ export function useAtomixGlass({
958
852
  withLiquidBlur,
959
853
  blurAmount,
960
854
  saturation,
961
- padding,
855
+
962
856
  isFixedOrSticky,
857
+ borderAnimated: resolvedBorder.animated,
858
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier,
963
859
  });
964
860
 
965
861
  // ── Stop check ──────────────────────────────────────────────────
@@ -1000,8 +896,10 @@ export function useAtomixGlass({
1000
896
  withLiquidBlur,
1001
897
  blurAmount,
1002
898
  saturation,
1003
- padding,
899
+
1004
900
  isFixedOrSticky,
901
+ resolvedBorder.animated,
902
+ resolvedBorder.opacityMultiplier,
1005
903
  stopLerpLoop,
1006
904
  ]);
1007
905
 
@@ -1140,7 +1038,8 @@ export function useAtomixGlass({
1140
1038
  withLiquidBlur,
1141
1039
  blurAmount,
1142
1040
  saturation,
1143
- padding,
1041
+ borderAnimated: resolvedBorder.animated,
1042
+ borderOpacityMultiplier: resolvedBorder.opacityMultiplier,
1144
1043
  });
1145
1044
  }, [
1146
1045
  isHovered,
@@ -1158,7 +1057,8 @@ export function useAtomixGlass({
1158
1057
  withLiquidBlur,
1159
1058
  blurAmount,
1160
1059
  saturation,
1161
- padding,
1060
+ resolvedBorder.animated,
1061
+ resolvedBorder.opacityMultiplier,
1162
1062
  onClick,
1163
1063
  ]);
1164
1064
 
@@ -1191,9 +1091,8 @@ export function useAtomixGlass({
1191
1091
  globalMousePosition, // This is now static (refs or props) unless prop changes
1192
1092
  mouseOffset, // This is now static (refs or props) unless prop changes
1193
1093
  overLightConfig,
1094
+ resolvedBorder,
1194
1095
  transformStyle,
1195
- getShaderTime,
1196
- applyTimeBasedDistortion,
1197
1096
  handleMouseEnter,
1198
1097
  handleMouseLeave,
1199
1098
  handleMouseDown,