@shohojdhara/atomix 0.6.2 → 0.6.3

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/README.md +510 -106
  2. package/dist/atomix.css +28 -24
  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.spacing.scss +6 -1
  53. package/src/styles/03-generic/_generic.reset.scss +1 -1
  54. package/src/styles/06-components/_components.atomix-glass.scss +20 -29
  55. package/src/styles/06-components/_components.data-table.scss +5 -4
  56. package/src/styles/06-components/_components.dynamic-background.scss +9 -8
  57. package/src/styles/06-components/_components.footer.scss +8 -7
  58. package/src/styles/06-components/_components.hero.scss +2 -2
  59. package/src/styles/06-components/_components.messages.scss +16 -16
  60. package/src/styles/06-components/_components.select.scss +15 -2
  61. package/src/styles/06-components/_components.upload.scss +3 -3
  62. package/CHANGELOG.md +0 -165
@@ -1,5 +1,12 @@
1
1
  import { ATOMIX_GLASS } from '../constants/components';
2
- import { calculateDistance, calculateElementCenter, calculateMouseInfluence, validateGlassSize, clampBlur, smoothstep, softClamp } from '../../components/AtomixGlass/glass-utils';
2
+ import {
3
+ calculateDistance,
4
+ calculateMouseInfluence,
5
+ validateGlassSize,
6
+ clampBlur,
7
+ smoothstep,
8
+ softClamp,
9
+ } from '../../components/AtomixGlass/glass-utils';
3
10
  import type { GlassSize, MousePosition, OverLightObjectConfig } from '../types/components';
4
11
 
5
12
  /**
@@ -28,7 +35,11 @@ export const updateAtomixGlassStyles = (
28
35
  effectiveWithoutEffects: boolean;
29
36
  effectiveReducedMotion: boolean;
30
37
  elasticity: number;
31
- directionalScale: string;
38
+ elasticTranslation: MousePosition;
39
+ directionalScale: { x: number; y: number };
40
+ elasticVelocity: MousePosition;
41
+ mouseVelocity: MousePosition;
42
+ scaleBase: number;
32
43
  onClick?: () => void;
33
44
  withLiquidBlur?: boolean;
34
45
  blurAmount?: number;
@@ -38,7 +49,7 @@ export const updateAtomixGlassStyles = (
38
49
  }
39
50
  ) => {
40
51
  if (!wrapperElement && !containerElement) return;
41
-
52
+ if (!validateGlassSize(params.glassSize)) return;
42
53
  const {
43
54
  mouseOffset,
44
55
  globalMousePosition,
@@ -51,7 +62,11 @@ export const updateAtomixGlassStyles = (
51
62
  effectiveWithoutEffects,
52
63
  effectiveReducedMotion,
53
64
  elasticity,
65
+ elasticTranslation,
66
+ elasticVelocity,
67
+ mouseVelocity,
54
68
  directionalScale,
69
+ scaleBase,
55
70
  onClick,
56
71
  withLiquidBlur,
57
72
  blurAmount = ATOMIX_GLASS.DEFAULTS.BLUR_AMOUNT,
@@ -67,61 +82,34 @@ export const updateAtomixGlassStyles = (
67
82
 
68
83
  // Calculate dynamic OverLight config
69
84
  const overLightConfig = {
70
- opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
71
- contrast: Math.min(1.6, baseOverLightConfig.contrast + mouseInfluence * 0.1),
72
- brightness: Math.min(1.1, baseOverLightConfig.brightness + mouseInfluence * 0.05),
73
- shadowIntensity: Math.min(1.2, Math.max(0.5, baseOverLightConfig.shadowIntensity + mouseInfluence * 0.2)),
74
- borderOpacity: Math.min(1.0, Math.max(0.3, baseOverLightConfig.borderOpacity + mouseInfluence * 0.1)),
75
- saturationBoost: baseOverLightConfig.saturationBoost
85
+ opacity: baseOverLightConfig.opacity * hoverIntensity * activeIntensity,
86
+ contrast: Math.min(1.6, baseOverLightConfig.contrast + mouseInfluence * 0.1),
87
+ brightness: Math.min(1.1, baseOverLightConfig.brightness + mouseInfluence * 0.05),
88
+ shadowIntensity: Math.min(
89
+ 1.2,
90
+ Math.max(0.5, baseOverLightConfig.shadowIntensity + mouseInfluence * 0.2)
91
+ ),
92
+ borderOpacity: Math.min(
93
+ 1.0,
94
+ Math.max(0.3, baseOverLightConfig.borderOpacity + mouseInfluence * 0.1)
95
+ ),
96
+ saturationBoost: baseOverLightConfig.saturationBoost,
76
97
  };
77
98
 
78
- let computedDirectionalScale = directionalScale;
79
-
80
- // Calculate elastic translation and directional scale
81
- let elasticTranslation = { x: 0, y: 0 };
82
- if (!effectiveWithoutEffects && wrapperElement) {
83
- const rect = wrapperElement.getBoundingClientRect();
84
- const center = calculateElementCenter(rect);
85
-
86
- // Mouse presence and edge distance logic
87
- if (globalMousePosition.x && globalMousePosition.y && validateGlassSize(glassSize)) {
88
- const deltaX = globalMousePosition.x - center.x;
89
- const deltaY = globalMousePosition.y - center.y;
90
- const edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2);
91
- const edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2);
92
- const edgeDistance = calculateDistance({ x: edgeDistanceX, y: edgeDistanceY }, { x: 0, y: 0 });
93
-
94
- // Elastic translation
95
- const rawT = edgeDistance > ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE ? 0 : 1 - edgeDistance / ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE;
96
- const fadeInFactor = smoothstep(rawT);
97
- elasticTranslation = {
98
- x: deltaX * elasticity * 0.1 * fadeInFactor,
99
- y: deltaY * elasticity * 0.1 * fadeInFactor,
100
- };
101
-
102
- // Directional scale
103
- if (!isOverLight && edgeDistance <= ATOMIX_GLASS.CONSTANTS.ACTIVATION_ZONE) {
104
- const centerDistance = calculateDistance(globalMousePosition, center);
105
- if (centerDistance > 0) {
106
- const normalizedX = deltaX / centerDistance;
107
- const normalizedY = deltaY / centerDistance;
108
- const stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * rawT;
109
-
110
- const scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * 0.3 - Math.abs(normalizedY) * stretchIntensity * 0.15;
111
- const scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * 0.3 - Math.abs(normalizedX) * stretchIntensity * 0.15;
112
-
113
- const softScaleX = 1 - softClamp(Math.max(0, 1 - scaleX), 0.2);
114
- const softScaleY = 1 - softClamp(Math.max(0, 1 - scaleY), 0.2);
115
-
116
- computedDirectionalScale = `scaleX(${Math.max(0.85, softScaleX)}) scaleY(${Math.max(0.85, softScaleY)})`;
117
- }
118
- }
119
- }
120
- }
99
+ const scaleX = directionalScale.x * scaleBase;
100
+ const scaleY = directionalScale.y * scaleBase;
101
+
102
+ const transformStyle = effectiveWithoutEffects
103
+ ? `scale(${scaleBase})`
104
+ : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) scaleX(${scaleX}) scaleY(${scaleY})`;
105
+
106
+ // ── Apple Liquid Depth Refinements ───────────────────────────────
107
+ const stretchMagnitude = calculateDistance({ x: 0, y: 0 }, elasticTranslation);
108
+ const tensionFactor = smoothstep(stretchMagnitude / 80);
121
109
 
122
- const transformStyle = effectiveWithoutEffects
123
- ? isActive && Boolean(onClick) ? 'scale(0.98)' : 'scale(1)'
124
- : `translate(${elasticTranslation.x}px, ${elasticTranslation.y}px) ${isActive && Boolean(onClick) ? 'scale(0.96)' : computedDirectionalScale}`;
110
+ // Subtle lighting boost on stretch
111
+ const lightingContrast = Math.min(1.8, overLightConfig.contrast + tensionFactor * 0.2);
112
+ const lightingBrightness = Math.min(1.2, overLightConfig.brightness + tensionFactor * 0.1);
125
113
 
126
114
  // Update Wrapper Styles (glassVars)
127
115
  if (wrapperElement) {
@@ -131,7 +119,18 @@ export const updateAtomixGlassStyles = (
131
119
  const absMy = Math.abs(my);
132
120
  const GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
133
121
 
134
- const borderGradientAngle = GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER;
122
+ // ── Velocity-Based Rotation ─────────────────────────────────────
123
+ // Combine mouse offset with velocity for dynamic rotation
124
+ const velocityRotation =
125
+ (mouseVelocity.x + elasticVelocity.x) * (GRADIENT.VELOCITY_ANGLE_MULTIPLIER || 2.5);
126
+ const borderGradientAngle =
127
+ GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER + velocityRotation;
128
+
129
+ // Chromatic offsets for depth
130
+ const chromaticOffset = GRADIENT.CHROMATIC_OFFSET || 1.5;
131
+ const angleR = borderGradientAngle - chromaticOffset;
132
+ const angleB = borderGradientAngle + chromaticOffset;
133
+
135
134
  const borderStop1 = Math.max(
136
135
  GRADIENT.BORDER_STOP_1.MIN,
137
136
  GRADIENT.BORDER_STOP_1.BASE + my * GRADIENT.BORDER_STOP_1.MULTIPLIER
@@ -140,11 +139,18 @@ export const updateAtomixGlassStyles = (
140
139
  GRADIENT.BORDER_STOP_2.MAX,
141
140
  GRADIENT.BORDER_STOP_2.BASE + my * GRADIENT.BORDER_STOP_2.MULTIPLIER
142
141
  );
142
+
143
+ // Modulate border opacity by tension (glow on stretch)
144
+ const tensionGlow = 1 + tensionFactor * 0.5;
143
145
  const borderOpacities = [
144
- GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW,
145
- GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH,
146
- GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW,
147
- GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH,
146
+ (GRADIENT.BORDER_OPACITY.BASE_1 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) *
147
+ tensionGlow,
148
+ (GRADIENT.BORDER_OPACITY.BASE_2 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) *
149
+ tensionGlow,
150
+ (GRADIENT.BORDER_OPACITY.BASE_3 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_LOW) *
151
+ tensionGlow,
152
+ (GRADIENT.BORDER_OPACITY.BASE_4 + absMx * GRADIENT.BORDER_OPACITY.MULTIPLIER_HIGH) *
153
+ tensionGlow,
148
154
  ];
149
155
 
150
156
  const configBorderOpacity = overLightConfig.borderOpacity;
@@ -152,61 +158,93 @@ export const updateAtomixGlassStyles = (
152
158
  const blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK;
153
159
 
154
160
  const hoverPositions = {
155
- hover1: {
156
- x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
157
- y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1,
158
- },
159
- hover2: {
160
- x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
161
- y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2,
162
- },
163
- hover3: {
164
- x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
165
- y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
166
- },
167
- };
161
+ hover1: {
162
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_1,
163
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_1,
164
+ },
165
+ hover2: {
166
+ x: GRADIENT.CENTER_POSITION + mx / GRADIENT.HOVER_POSITION.DIVISOR_2,
167
+ y: GRADIENT.CENTER_POSITION + my / GRADIENT.HOVER_POSITION.DIVISOR_2,
168
+ },
169
+ hover3: {
170
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
171
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.HOVER_POSITION.MULTIPLIER_3,
172
+ },
173
+ };
168
174
 
169
175
  const basePosition = {
170
- x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
171
- y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER,
176
+ x: GRADIENT.CENTER_POSITION + mx * GRADIENT.BASE_LAYER_MULTIPLIER,
177
+ y: GRADIENT.CENTER_POSITION + my * GRADIENT.BASE_LAYER_MULTIPLIER,
172
178
  };
173
179
 
174
180
  const opacityValues = {
175
- hover1: isHovered || isActive ? 0.5 : 0,
176
- hover2: isActive ? 0.5 : 0,
177
- hover3: isHovered ? 0.4 : isActive ? 0.8 : 0,
178
- base: isOverLight ? overLightConfig.opacity : 0,
179
- over: isOverLight ? overLightConfig.opacity * 1.1 : 0,
181
+ hover1: isHovered || isActive ? 0.5 : 0,
182
+ hover2: isActive ? 0.5 : 0,
183
+ hover3: isHovered ? 0.4 : isActive ? 0.8 : 0,
184
+ base: isOverLight ? overLightConfig.opacity : 0,
185
+ over: isOverLight ? overLightConfig.opacity * 1.1 : 0,
180
186
  };
181
187
 
182
188
  const style = wrapperElement.style;
183
-
184
189
  style.setProperty('--atomix-glass-transform', transformStyle || 'none');
185
190
 
186
- // Gradients
187
- 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%)`);
188
- 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%)`);
191
+ // Parallax for content (liquid refraction feel)
192
+ const parallaxFactor = 0.38 + tensionFactor * 0.12;
193
+ style.setProperty(
194
+ '--atomix-glass-child-parallax',
195
+ `translate(${elasticTranslation.x * -parallaxFactor}px, ${elasticTranslation.y * -parallaxFactor}px)`
196
+ );
197
+
198
+ style.setProperty('--atomix-glass-contrast', lightingContrast.toString());
199
+ style.setProperty('--atomix-glass-brightness', lightingBrightness.toString());
200
+
201
+ // ── Chromatic Rim Lighting ──────────────────────────────────────
202
+ // Layer 1: Core White/Blue highlight
203
+ style.setProperty(
204
+ '--atomix-glass-border-gradient-1',
205
+ `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%)`
206
+ );
207
+ // Layer 2: Subtle Red/Warm highlight (offset angle)
208
+ style.setProperty(
209
+ '--atomix-glass-border-gradient-2',
210
+ `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%)`
211
+ );
189
212
 
190
213
  // Hover gradients
191
- style.setProperty('--atomix-glass-hover-1-gradient', isOverLight
214
+ style.setProperty(
215
+ '--atomix-glass-hover-1-gradient',
216
+ isOverLight
192
217
  ? `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}%)`
193
- : `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}%)`);
218
+ : `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}%)`
219
+ );
194
220
 
195
- style.setProperty('--atomix-glass-hover-2-gradient', isOverLight
221
+ style.setProperty(
222
+ '--atomix-glass-hover-2-gradient',
223
+ isOverLight
196
224
  ? `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}%)`
197
- : `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}%)`);
225
+ : `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}%)`
226
+ );
198
227
 
199
- style.setProperty('--atomix-glass-hover-3-gradient', isOverLight
228
+ style.setProperty(
229
+ '--atomix-glass-hover-3-gradient',
230
+ isOverLight
200
231
  ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(${blackColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)`
201
- : `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`);
232
+ : `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_START}) 0%, rgba(${whiteColor}, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.WHITE_STOP}%)`
233
+ );
202
234
 
203
- style.setProperty('--atomix-glass-base-gradient', isOverLight
235
+ style.setProperty(
236
+ '--atomix-glass-base-gradient',
237
+ isOverLight
204
238
  ? `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%)`
205
- : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`);
239
+ : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`
240
+ );
206
241
 
207
- style.setProperty('--atomix-glass-overlay-gradient', isOverLight
242
+ style.setProperty(
243
+ '--atomix-glass-overlay-gradient',
244
+ isOverLight
208
245
  ? `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%)`
209
- : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`);
246
+ : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
247
+ );
210
248
 
211
249
  // Opacities
212
250
  style.setProperty('--atomix-glass-hover-1-opacity', opacityValues.hover1.toString());
@@ -214,7 +252,10 @@ export const updateAtomixGlassStyles = (
214
252
  style.setProperty('--atomix-glass-hover-3-opacity', opacityValues.hover3.toString());
215
253
  style.setProperty('--atomix-glass-base-opacity', opacityValues.base.toString());
216
254
  style.setProperty('--atomix-glass-overlay-opacity', opacityValues.over.toString());
217
- style.setProperty('--atomix-glass-overlay-highlight-opacity', (opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER).toString());
255
+ style.setProperty(
256
+ '--atomix-glass-overlay-highlight-opacity',
257
+ (opacityValues.over * ATOMIX_GLASS.CONSTANTS.OVERLAY_HIGHLIGHT.OPACITY_MULTIPLIER).toString()
258
+ );
218
259
 
219
260
  // Other
220
261
  style.setProperty('--atomix-glass-blend-mode', isOverLight ? 'multiply' : 'overlay');
@@ -238,61 +279,61 @@ export const updateAtomixGlassStyles = (
238
279
  const rect = containerElement.getBoundingClientRect();
239
280
 
240
281
  let liquidBlur = {
241
- baseBlur: blurAmount,
242
- edgeBlur: blurAmount * EDGE_BLUR_MULTIPLIER,
243
- centerBlur: blurAmount * CENTER_BLUR_MULTIPLIER,
244
- flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER,
282
+ baseBlur: blurAmount,
283
+ edgeBlur: blurAmount * EDGE_BLUR_MULTIPLIER,
284
+ centerBlur: blurAmount * CENTER_BLUR_MULTIPLIER,
285
+ flowBlur: blurAmount * FLOW_BLUR_MULTIPLIER,
245
286
  };
246
287
 
247
288
  if (withLiquidBlur && rect) {
248
- const mouseInfluence = calculateMouseInfluence(mouseOffset);
249
- const maxBlur = blurAmount * MAX_BLUR_RELATIVE;
250
-
251
- const baseBlur = Math.min(
252
- maxBlur,
253
- blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR
254
- );
255
- const edgeIntensity = mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR;
256
- const edgeBlur = Math.min(maxBlur, baseBlur * (0.8 + edgeIntensity * 0.4));
257
- const centerIntensity = mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR;
258
- const centerBlur = Math.min(maxBlur, baseBlur * (0.3 + centerIntensity * 0.3));
259
- const flowBlur = Math.min(maxBlur, baseBlur * FLOW_BLUR_MULTIPLIER);
260
-
261
- liquidBlur = {
262
- baseBlur: clampBlur(baseBlur),
263
- edgeBlur: clampBlur(edgeBlur),
264
- centerBlur: clampBlur(centerBlur),
265
- flowBlur: clampBlur(flowBlur),
266
- };
289
+ const mouseInfluence = calculateMouseInfluence(mouseOffset);
290
+ const maxBlur = blurAmount * MAX_BLUR_RELATIVE;
291
+
292
+ const baseBlur = softClamp(
293
+ blurAmount + mouseInfluence * blurAmount * MOUSE_INFLUENCE_BLUR_FACTOR,
294
+ maxBlur
295
+ );
296
+ const edgeIntensity = mouseInfluence * EDGE_INTENSITY_MOUSE_FACTOR;
297
+ const edgeBlur = softClamp(baseBlur * (0.8 + edgeIntensity * 0.4), maxBlur);
298
+ const centerIntensity = mouseInfluence * CENTER_INTENSITY_MOUSE_FACTOR;
299
+ const centerBlur = softClamp(baseBlur * (0.3 + centerIntensity * 0.3), maxBlur);
300
+ const flowBlur = softClamp(baseBlur * FLOW_BLUR_MULTIPLIER, maxBlur);
301
+
302
+ liquidBlur = {
303
+ baseBlur: clampBlur(baseBlur),
304
+ edgeBlur: clampBlur(edgeBlur),
305
+ centerBlur: clampBlur(centerBlur),
306
+ flowBlur: clampBlur(flowBlur),
307
+ };
267
308
  }
268
309
 
269
310
  // Backdrop filter
270
- let backdropFilterString = `blur(${blurAmount}px) saturate(${saturation}%) contrast(1.05) brightness(1.05)`;
271
-
272
- const dynamicSaturation = saturation + (liquidBlur.baseBlur || 0) * 20;
311
+ const tensionSaturation = tensionFactor * 40;
312
+ const dynamicSaturation = saturation + tensionSaturation + (liquidBlur.baseBlur || 0) * 15;
313
+ let backdropFilterString = '';
273
314
  const area = rect ? rect.width * rect.height : 0;
274
315
  const areaIsLarge = area > 180000;
275
316
  const devicePrefersPerformance = effectiveReducedMotion || effectiveWithoutEffects;
276
317
  const useMultiPass = withLiquidBlur && !devicePrefersPerformance && !areaIsLarge;
277
318
 
278
319
  if (useMultiPass) {
279
- const weightedBlur = clampBlur(
280
- liquidBlur.baseBlur * 0.4 +
281
- liquidBlur.edgeBlur * 0.25 +
282
- liquidBlur.centerBlur * 0.15 +
283
- liquidBlur.flowBlur * 0.2
284
- );
285
- backdropFilterString = `blur(${weightedBlur}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
320
+ const weightedBlur = clampBlur(
321
+ liquidBlur.baseBlur * 0.4 +
322
+ liquidBlur.edgeBlur * 0.25 +
323
+ liquidBlur.centerBlur * 0.15 +
324
+ liquidBlur.flowBlur * 0.2
325
+ );
326
+ backdropFilterString = `blur(${weightedBlur}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
286
327
  } else {
287
- const effectiveBlur = clampBlur(
288
- Math.max(
289
- liquidBlur.baseBlur,
290
- liquidBlur.edgeBlur * 0.8,
291
- liquidBlur.centerBlur * 1.1,
292
- liquidBlur.flowBlur * 0.9
293
- )
294
- );
295
- backdropFilterString = `blur(${effectiveBlur}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig.contrast}) brightness(${overLightConfig.brightness})`;
328
+ const effectiveBlur = clampBlur(
329
+ Math.max(
330
+ liquidBlur.baseBlur,
331
+ liquidBlur.edgeBlur * 0.8,
332
+ liquidBlur.centerBlur * 1.1,
333
+ liquidBlur.flowBlur * 0.9
334
+ )
335
+ );
336
+ backdropFilterString = `blur(${effectiveBlur}px) saturate(${Math.min(dynamicSaturation, 250)}%) contrast(${lightingContrast}) brightness(${lightingBrightness})`;
296
337
  }
297
338
 
298
339
  // Container variables
@@ -304,27 +345,38 @@ export const updateAtomixGlassStyles = (
304
345
  style.setProperty('--atomix-glass-container-backdrop', backdropFilterString);
305
346
 
306
347
  // Shadows
307
- style.setProperty('--atomix-glass-container-shadow', isOverLight
348
+ style.setProperty(
349
+ '--atomix-glass-container-shadow',
350
+ isOverLight
308
351
  ? [
309
352
  `inset 0 1px 0 rgba(255, 255, 255, ${(0.4 + mx * 0.002) * (overLightConfig.shadowIntensity || 1)})`,
310
353
  `inset 0 -1px 0 rgba(0, 0, 0, ${(0.2 + Math.abs(my) * 0.001) * (overLightConfig.shadowIntensity || 1)})`,
311
354
  `inset 0 0 20px rgba(0, 0, 0, ${(0.08 + Math.abs(mx + my) * 0.001) * (overLightConfig.shadowIntensity || 1)})`,
312
355
  `0 2px 12px rgba(0, 0, 0, ${(0.12 + Math.abs(my) * 0.002) * (overLightConfig.shadowIntensity || 1)})`,
313
356
  ].join(', ')
314
- : '0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset');
357
+ : '0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset'
358
+ );
315
359
 
316
- style.setProperty('--atomix-glass-container-shadow-opacity', effectiveWithoutEffects ? '0' : '1');
360
+ style.setProperty(
361
+ '--atomix-glass-container-shadow-opacity',
362
+ effectiveWithoutEffects ? '0' : '1'
363
+ );
317
364
 
318
- style.setProperty('--atomix-glass-container-bg', isOverLight
365
+ style.setProperty(
366
+ '--atomix-glass-container-bg',
367
+ isOverLight
319
368
  ? `linear-gradient(${180 + mx * 0.5}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)`
320
- : 'none');
369
+ : 'none'
370
+ );
321
371
 
322
- style.setProperty('--atomix-glass-container-text-shadow', isOverLight
323
- ? '0px 1px 2px rgba(255, 255, 255, 0.15)'
324
- : '0px 2px 12px rgba(0, 0, 0, 0.4)');
372
+ style.setProperty(
373
+ '--atomix-glass-container-text-shadow',
374
+ isOverLight ? '0px 1px 2px rgba(255, 255, 255, 0.15)' : '0px 2px 12px rgba(0, 0, 0, 0.4)'
375
+ );
325
376
 
326
- style.setProperty('--atomix-glass-container-box-shadow', isOverLight
327
- ? '0px 16px 70px rgba(0, 0, 0, 0.75)'
328
- : '0px 12px 40px rgba(0, 0, 0, 0.25)');
377
+ style.setProperty(
378
+ '--atomix-glass-container-box-shadow',
379
+ isOverLight ? '0px 16px 70px rgba(0, 0, 0, 0.75)' : '0px 12px 40px rgba(0, 0, 0, 0.25)'
380
+ );
329
381
  }
330
- };
382
+ };
@@ -1663,11 +1663,19 @@ export const ATOMIX_GLASS = {
1663
1663
  },
1664
1664
  DEFAULTS: {
1665
1665
  DISPLACEMENT_SCALE: 70,
1666
- BLUR_AMOUNT: 0,
1667
- SATURATION: 140,
1668
- ABERRATION_INTENSITY: 2,
1666
+ get BLUR_AMOUNT() {
1667
+ return this.DISPLACEMENT_SCALE * 0.15; // Dynamically computed based on displacement
1668
+ },
1669
+ get SATURATION() {
1670
+ return 100 + (this.DISPLACEMENT_SCALE * 0.5); // Saturate relative to intensity
1671
+ },
1672
+ get ABERRATION_INTENSITY() {
1673
+ return this.DISPLACEMENT_SCALE * 0.03; // Scale aberration with displacement
1674
+ },
1669
1675
  ELASTICITY: 0.15,
1670
- CORNER_RADIUS: 20, // Default border-radius matching design system
1676
+ get CORNER_RADIUS() {
1677
+ return 16; // Use 16 to match SCSS design system (was 20)
1678
+ },
1671
1679
  PADDING: '0',
1672
1680
  MODE: 'standard' as const,
1673
1681
  OVER_LIGHT: false as const,
@@ -1693,6 +1701,11 @@ export const ATOMIX_GLASS = {
1693
1701
  ELASTICITY_TRANSLATION_FACTOR: 0.1,
1694
1702
  ELASTICITY_DISTANCE_THRESHOLD: 200,
1695
1703
  ELASTICITY_COMPRESSION_FACTOR: 0.3,
1704
+ ELASTICITY_STIFFNESS: 0.1,
1705
+ ELASTICITY_DAMPING: 0.76,
1706
+ ELASTICITY_VELOCITY_FACTOR: 0.65,
1707
+ ELASTICITY_STRETCH_RATIO: 0.45,
1708
+ ELASTICITY_MAGNIFICATION_BASE: 1.02,
1696
1709
  // Note: This default must match the SCSS variable --atomix-radius-md
1697
1710
  // @see src/styles/01-settings/_settings.global.scss
1698
1711
  DEFAULT_CORNER_RADIUS: 16,
@@ -1708,58 +1721,60 @@ export const ATOMIX_GLASS = {
1708
1721
  GRADIENT: {
1709
1722
  BASE_ANGLE: 135, // Base angle for border gradients (degrees)
1710
1723
  ANGLE_MULTIPLIER: 1.2, // Multiplier for mouse influence on angle
1724
+ VELOCITY_ANGLE_MULTIPLIER: 2.5, // How much velocity affects gradient rotation
1725
+ CHROMATIC_OFFSET: 1.5, // Degree offset for chromatic rim layers
1711
1726
  BORDER_STOP_1: {
1712
1727
  MIN: 10, // Minimum percentage for border stop 1
1713
1728
  BASE: 33, // Base percentage for border stop 1
1714
- MULTIPLIER: 0.3, // Multiplier for mouse Y influence
1729
+ get MULTIPLIER() { return this.BASE * 0.009; }, // Multiplier for mouse Y influence
1715
1730
  },
1716
1731
  BORDER_STOP_2: {
1717
1732
  MAX: 90, // Maximum percentage for border stop 2
1718
1733
  BASE: 66, // Base percentage for border stop 2
1719
- MULTIPLIER: 0.4, // Multiplier for mouse Y influence
1734
+ get MULTIPLIER() { return this.BASE * 0.006; }, // Multiplier for mouse Y influence
1720
1735
  },
1721
1736
  BORDER_OPACITY: {
1722
1737
  BASE_1: 0.12, // Base opacity for border gradient 1
1723
- BASE_2: 0.4, // Base opacity for border gradient 2
1724
- BASE_3: 0.32, // Base opacity for border gradient 3
1725
- BASE_4: 0.6, // Base opacity for border gradient 4
1726
- MULTIPLIER_LOW: 0.008, // Low multiplier for mouse influence on opacity
1727
- MULTIPLIER_HIGH: 0.012, // High multiplier for mouse influence on opacity
1738
+ get BASE_2() { return this.BASE_1 * 3.33; }, // Base opacity for border gradient 2
1739
+ get BASE_3() { return this.BASE_1 * 2.66; }, // Base opacity for border gradient 3
1740
+ get BASE_4() { return this.BASE_1 * 5; }, // Base opacity for border gradient 4
1741
+ get MULTIPLIER_LOW() { return this.BASE_1 * 0.066; }, // Low multiplier for mouse influence on opacity
1742
+ get MULTIPLIER_HIGH() { return this.BASE_1 * 0.1; }, // High multiplier for mouse influence on opacity
1728
1743
  },
1729
1744
  CENTER_POSITION: 50, // Center position percentage (50%)
1730
1745
  HOVER_POSITION: {
1731
1746
  DIVISOR_1: 2, // Divisor for hover 1 position calculation
1732
- DIVISOR_2: 1.5, // Divisor for hover 2 position calculation
1733
- MULTIPLIER_3: 1, // Direct multiplier for hover 3 (no division)
1747
+ get DIVISOR_2() { return this.DIVISOR_1 * 0.75; }, // Divisor for hover 2 position calculation
1748
+ get MULTIPLIER_3() { return this.DIVISOR_1 * 0.5; }, // Direct multiplier for hover 3 (no division)
1734
1749
  },
1735
- BASE_LAYER_MULTIPLIER: 0.5, // Multiplier for base layer position
1750
+ get BASE_LAYER_MULTIPLIER() { return 0.5; }, // Multiplier for base layer position
1736
1751
  },
1737
1752
 
1738
1753
  // Gradient opacity values for hover effects
1739
1754
  GRADIENT_OPACITY: {
1740
1755
  HOVER_1: {
1741
1756
  BLACK_START: 0.3, // Start opacity for black hover 1
1742
- BLACK_MID: 0.1, // Mid opacity for black hover 1
1757
+ get BLACK_MID() { return this.BLACK_START / 3; }, // Mid opacity for black hover 1
1743
1758
  BLACK_STOP: 30, // Stop percentage for black hover 1
1744
- BLACK_END: 60, // End percentage for black hover 1
1759
+ get BLACK_END() { return this.BLACK_STOP * 2; }, // End percentage for black hover 1
1745
1760
  WHITE_START: 0.5, // Start opacity for white hover 1
1746
- WHITE_STOP: 50, // Stop percentage for white hover 1
1761
+ get WHITE_STOP() { return this.BLACK_END - 10; }, // Stop percentage for white hover 1
1747
1762
  },
1748
1763
  HOVER_2: {
1749
1764
  BLACK_START: 0.4, // Start opacity for black hover 2
1750
- BLACK_MID: 0.15, // Mid opacity for black hover 2
1765
+ get BLACK_MID() { return this.BLACK_START * 0.375; }, // Mid opacity for black hover 2
1751
1766
  BLACK_STOP: 40, // Stop percentage for black hover 2
1752
- BLACK_END: 80, // End percentage for black hover 2
1767
+ get BLACK_END() { return this.BLACK_STOP * 2; }, // End percentage for black hover 2
1753
1768
  WHITE_START: 1, // Start opacity for white hover 2
1754
- WHITE_STOP: 80, // Stop percentage for white hover 2
1769
+ get WHITE_STOP() { return this.BLACK_END; }, // Stop percentage for white hover 2
1755
1770
  },
1756
1771
  HOVER_3: {
1757
1772
  BLACK_START: 0.5, // Start opacity for black hover 3
1758
- BLACK_MID: 0.2, // Mid opacity for black hover 3
1773
+ get BLACK_MID() { return this.BLACK_START * 0.4; }, // Mid opacity for black hover 3
1759
1774
  BLACK_STOP: 50, // Stop percentage for black hover 3
1760
- BLACK_END: 100, // End percentage for black hover 3
1775
+ get BLACK_END() { return this.BLACK_STOP * 2; }, // End percentage for black hover 3
1761
1776
  WHITE_START: 1, // Start opacity for white hover 3
1762
- WHITE_STOP: 100, // Stop percentage for white hover 3
1777
+ get WHITE_STOP() { return this.BLACK_END; }, // Stop percentage for white hover 3
1763
1778
  },
1764
1779
  },
1765
1780
 
@@ -1767,23 +1782,23 @@ export const ATOMIX_GLASS = {
1767
1782
  BASE_GRADIENT: {
1768
1783
  ANGLE: 135, // Gradient angle in degrees
1769
1784
  BLACK_START_BASE: 0.15, // Base start opacity for black
1770
- BLACK_START_MULTIPLIER: 0.003, // Multiplier for mouse X influence on start
1785
+ get BLACK_START_MULTIPLIER() { return this.BLACK_START_BASE * 0.02; }, // Multiplier for mouse X influence on start
1771
1786
  BLACK_MID_BASE: 0.1, // Base mid opacity for black
1772
- BLACK_MID_MULTIPLIER: 0.002, // Multiplier for mouse Y influence on mid
1787
+ get BLACK_MID_MULTIPLIER() { return this.BLACK_MID_BASE * 0.02; }, // Multiplier for mouse Y influence on mid
1773
1788
  BLACK_MID_STOP: 50, // Mid stop percentage
1774
- BLACK_END_BASE: 0.18, // Base end opacity for black
1775
- BLACK_END_MULTIPLIER: 0.004, // Multiplier for mouse X influence on end
1776
- WHITE_OPACITY: 0.1, // White opacity for non-overlight mode
1789
+ get BLACK_END_BASE() { return this.BLACK_START_BASE * 1.2; }, // Base end opacity for black
1790
+ get BLACK_END_MULTIPLIER() { return this.BLACK_END_BASE * 0.022; }, // Multiplier for mouse X influence on end
1791
+ get WHITE_OPACITY() { return this.BLACK_START_BASE * 0.666; }, // White opacity for non-overlight mode
1777
1792
  },
1778
1793
 
1779
1794
  OVERLAY_GRADIENT: {
1780
1795
  BLACK_START_BASE: 0.12, // Base start opacity for black overlay
1781
- BLACK_START_MULTIPLIER: 0.003, // Multiplier for mouse X influence on start
1782
- BLACK_MID: 0.06, // Mid opacity for black overlay
1796
+ get BLACK_START_MULTIPLIER() { return this.BLACK_START_BASE * 0.025; }, // Multiplier for mouse X influence on start
1797
+ get BLACK_MID() { return this.BLACK_START_BASE * 0.5; }, // Mid opacity for black overlay
1783
1798
  BLACK_MID_STOP: 40, // Mid stop percentage
1784
- BLACK_END_BASE: 0.15, // Base end opacity for black overlay
1785
- BLACK_END_MULTIPLIER: 0.003, // Multiplier for mouse Y influence on end
1786
- WHITE_OPACITY: 0.05, // White opacity for non-overlight mode
1799
+ get BLACK_END_BASE() { return this.BLACK_START_BASE * 1.25; }, // Base end opacity for black overlay
1800
+ get BLACK_END_MULTIPLIER() { return this.BLACK_END_BASE * 0.02; }, // Multiplier for mouse Y influence on end
1801
+ get WHITE_OPACITY() { return this.BLACK_START_BASE * 0.416; }, // White opacity for non-overlight mode
1787
1802
  },
1788
1803
 
1789
1804
  // Overlay highlight constants
@@ -1791,8 +1806,8 @@ export const ATOMIX_GLASS = {
1791
1806
  POSITION_X: 20, // X position percentage
1792
1807
  POSITION_Y: 20, // Y position percentage
1793
1808
  WHITE_OPACITY: 0.4, // White opacity in gradient
1794
- STOP: 60, // Stop percentage
1795
- OPACITY_MULTIPLIER: 0.7, // Multiplier for overlay highlight opacity
1809
+ get STOP() { return this.WHITE_OPACITY * 150; }, // Stop percentage
1810
+ get OPACITY_MULTIPLIER() { return this.WHITE_OPACITY * 1.75; }, // Multiplier for overlay highlight opacity
1796
1811
  },
1797
1812
 
1798
1813
  // Displacement and aberration multipliers