@shohojdhara/atomix 0.3.13 → 0.3.15

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 (249) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +2 -0
  3. package/build-tools/EXAMPLES.md +372 -0
  4. package/build-tools/README.md +242 -0
  5. package/build-tools/__tests__/error-handler.test.js +230 -0
  6. package/build-tools/__tests__/index.test.js +141 -0
  7. package/build-tools/__tests__/rollup-plugin.test.js +194 -0
  8. package/build-tools/__tests__/utils.test.js +161 -0
  9. package/build-tools/__tests__/vite-plugin.test.js +129 -0
  10. package/build-tools/__tests__/webpack-loader.test.js +190 -0
  11. package/build-tools/error-handler.js +308 -0
  12. package/build-tools/index.d.ts +43 -0
  13. package/build-tools/index.js +88 -0
  14. package/build-tools/package.json +67 -0
  15. package/build-tools/rollup-plugin.js +236 -0
  16. package/build-tools/types.d.ts +163 -0
  17. package/build-tools/utils.js +203 -0
  18. package/build-tools/vite-plugin.js +161 -0
  19. package/build-tools/webpack-loader.js +123 -0
  20. package/dist/atomix.css +298 -167
  21. package/dist/atomix.css.map +1 -1
  22. package/dist/atomix.min.css +3 -3
  23. package/dist/atomix.min.css.map +1 -1
  24. package/dist/build-tools/EXAMPLES.md +372 -0
  25. package/dist/build-tools/README.md +242 -0
  26. package/dist/build-tools/__tests__/error-handler.test.js +230 -0
  27. package/dist/build-tools/__tests__/index.test.js +141 -0
  28. package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
  29. package/dist/build-tools/__tests__/utils.test.js +161 -0
  30. package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
  31. package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
  32. package/dist/build-tools/error-handler.js +308 -0
  33. package/dist/build-tools/index.d.ts +43 -0
  34. package/dist/build-tools/index.js +88 -0
  35. package/dist/build-tools/package.json +67 -0
  36. package/dist/build-tools/rollup-plugin.js +236 -0
  37. package/dist/build-tools/types.d.ts +163 -0
  38. package/dist/build-tools/utils.js +203 -0
  39. package/dist/build-tools/vite-plugin.js +161 -0
  40. package/dist/build-tools/webpack-loader.js +123 -0
  41. package/dist/charts.d.ts +2 -2
  42. package/dist/charts.js +87 -58
  43. package/dist/charts.js.map +1 -1
  44. package/dist/core.d.ts +42 -12
  45. package/dist/core.js +175 -135
  46. package/dist/core.js.map +1 -1
  47. package/dist/forms.d.ts +30 -16
  48. package/dist/forms.js +146 -131
  49. package/dist/forms.js.map +1 -1
  50. package/dist/heavy.d.ts +2 -2
  51. package/dist/heavy.js +151 -118
  52. package/dist/heavy.js.map +1 -1
  53. package/dist/index.d.ts +130 -106
  54. package/dist/index.esm.js +1083 -465
  55. package/dist/index.esm.js.map +1 -1
  56. package/dist/index.js +1102 -483
  57. package/dist/index.js.map +1 -1
  58. package/dist/index.min.js +1 -1
  59. package/dist/index.min.js.map +1 -1
  60. package/dist/theme.d.ts +27 -2
  61. package/dist/theme.js +721 -108
  62. package/dist/theme.js.map +1 -1
  63. package/package.json +23 -8
  64. package/scripts/atomix-cli.js +749 -1153
  65. package/scripts/cli/__tests__/README.md +81 -0
  66. package/scripts/cli/__tests__/basic.test.js +115 -0
  67. package/scripts/cli/__tests__/component-generator.test.js +332 -0
  68. package/scripts/cli/__tests__/integration.test.js +327 -0
  69. package/scripts/cli/__tests__/test-setup.js +133 -0
  70. package/scripts/cli/__tests__/token-manager.test.js +251 -0
  71. package/scripts/cli/__tests__/utils.test.js +78 -118
  72. package/scripts/cli/component-generator.js +564 -0
  73. package/scripts/cli/dependency-checker.js +355 -0
  74. package/scripts/cli/documentation-sync.js +542 -0
  75. package/scripts/cli/interactive-init.js +129 -292
  76. package/scripts/cli/mappings.js +211 -0
  77. package/scripts/cli/migration-tools.js +95 -288
  78. package/scripts/cli/template-manager.js +105 -0
  79. package/scripts/cli/templates/README.md +123 -0
  80. package/scripts/cli/templates/common-templates.js +636 -0
  81. package/scripts/cli/templates/composable-templates.js +171 -0
  82. package/scripts/cli/templates/config-templates.js +126 -0
  83. package/scripts/cli/templates/index.js +102 -0
  84. package/scripts/cli/templates/project-templates.js +342 -0
  85. package/scripts/cli/templates/react-templates.js +331 -0
  86. package/scripts/cli/templates/scss-templates.js +155 -0
  87. package/scripts/cli/templates/storybook-templates.js +236 -0
  88. package/scripts/cli/templates/testing-templates.js +224 -0
  89. package/scripts/cli/templates/testing-utils.js +278 -0
  90. package/scripts/cli/templates/token-templates.js +447 -0
  91. package/scripts/cli/templates/types-templates.js +147 -0
  92. package/scripts/cli/templates.js +35 -0
  93. package/scripts/cli/theme-bridge.js +28 -16
  94. package/scripts/cli/token-manager.js +432 -247
  95. package/scripts/cli/utils.js +37 -26
  96. package/src/components/Accordion/Accordion.stories.tsx +369 -870
  97. package/src/components/Accordion/Accordion.test.tsx +57 -0
  98. package/src/components/Accordion/Accordion.tsx +4 -0
  99. package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
  100. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
  101. package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
  102. package/src/components/AtomixGlass/glass-utils.ts +2 -2
  103. package/src/components/AtomixGlass/shader-utils.ts +5 -0
  104. package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
  105. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2965 -2861
  106. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
  107. package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
  108. package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
  109. package/src/components/AtomixGlass/stories/Playground.stories.tsx +73 -59
  110. package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +1 -1
  111. package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
  112. package/src/components/Avatar/Avatar.stories.tsx +239 -27
  113. package/src/components/Badge/Badge.stories.tsx +132 -373
  114. package/src/components/Badge/Badge.test.tsx +51 -0
  115. package/src/components/Badge/Badge.tsx +20 -1
  116. package/src/components/Block/Block.stories.tsx +26 -17
  117. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +141 -23
  118. package/src/components/Breadcrumb/Breadcrumb.tsx +2 -2
  119. package/src/components/Button/Button.stories.tsx +463 -1126
  120. package/src/components/Button/Button.test.tsx +107 -0
  121. package/src/components/Button/Button.tsx +50 -54
  122. package/src/components/Button/ButtonGroup.stories.tsx +373 -217
  123. package/src/components/Button/README.md +5 -0
  124. package/src/components/Callout/Callout.stories.tsx +299 -644
  125. package/src/components/Callout/Callout.test.tsx +10 -10
  126. package/src/components/Callout/Callout.tsx +7 -7
  127. package/src/components/Callout/README.md +9 -8
  128. package/src/components/Card/Card.stories.tsx +248 -68
  129. package/src/components/Card/Card.tsx +2 -2
  130. package/src/components/Chart/Chart.stories.tsx +156 -14
  131. package/src/components/Chart/Chart.tsx +1 -1
  132. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +151 -69
  133. package/src/components/Countdown/Countdown.stories.tsx +115 -8
  134. package/src/components/DataTable/DataTable.stories.tsx +346 -146
  135. package/src/components/DataTable/DataTable.tsx +14 -12
  136. package/src/components/DatePicker/DatePicker.stories.tsx +325 -1066
  137. package/src/components/Dropdown/Dropdown.stories.tsx +157 -37
  138. package/src/components/EdgePanel/EdgePanel.stories.tsx +230 -21
  139. package/src/components/Footer/Footer.stories.tsx +392 -328
  140. package/src/components/Form/Checkbox.stories.tsx +143 -9
  141. package/src/components/Form/Checkbox.test.tsx +63 -0
  142. package/src/components/Form/Checkbox.tsx +90 -52
  143. package/src/components/Form/Form.stories.tsx +121 -22
  144. package/src/components/Form/FormGroup.stories.tsx +128 -5
  145. package/src/components/Form/Input.stories.tsx +28 -16
  146. package/src/components/Form/Input.test.tsx +59 -0
  147. package/src/components/Form/Input.tsx +97 -95
  148. package/src/components/Form/Radio.stories.tsx +232 -97
  149. package/src/components/Form/Radio.tsx +2 -2
  150. package/src/components/Form/Select.stories.tsx +144 -12
  151. package/src/components/Form/Select.tsx +2 -2
  152. package/src/components/Form/Textarea.stories.tsx +171 -13
  153. package/src/components/Form/Textarea.test.tsx +45 -0
  154. package/src/components/Form/Textarea.tsx +88 -86
  155. package/src/components/Hero/Hero.stories.tsx +333 -32
  156. package/src/components/List/List.stories.tsx +143 -5
  157. package/src/components/Modal/Modal.stories.tsx +185 -46
  158. package/src/components/Navigation/Navbar/Navbar.stories.tsx +5 -5
  159. package/src/components/Navigation/Navbar/Navbar.tsx +1 -1
  160. package/src/components/Navigation/README.md +1 -1
  161. package/src/components/Pagination/Pagination.stories.tsx +5 -2
  162. package/src/components/Pagination/Pagination.tsx +1 -1
  163. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -10
  164. package/src/components/Popover/Popover.stories.tsx +449 -99
  165. package/src/components/ProductReview/ProductReview.tsx +1 -1
  166. package/src/components/Progress/Progress.stories.tsx +167 -5
  167. package/src/components/Progress/Progress.tsx +46 -46
  168. package/src/components/Rating/Rating.stories.tsx +4 -4
  169. package/src/components/Rating/Rating.tsx +8 -8
  170. package/src/components/River/River.stories.tsx +1 -1
  171. package/src/components/SectionIntro/SectionIntro.stories.tsx +240 -48
  172. package/src/components/Slider/Slider.stories.tsx +63 -63
  173. package/src/components/Spinner/Spinner.stories.tsx +104 -10
  174. package/src/components/Spinner/Spinner.test.tsx +35 -0
  175. package/src/components/Spinner/Spinner.tsx +9 -2
  176. package/src/components/Steps/Steps.stories.tsx +172 -43
  177. package/src/components/Tabs/Tabs.stories.tsx +136 -10
  178. package/src/components/Testimonial/Testimonial.stories.tsx +121 -4
  179. package/src/components/Todo/Todo.stories.tsx +198 -9
  180. package/src/components/Toggle/Toggle.stories.tsx +153 -43
  181. package/src/components/Toggle/Toggle.test.tsx +91 -0
  182. package/src/components/Toggle/Toggle.tsx +44 -27
  183. package/src/components/Tooltip/Tooltip.stories.tsx +194 -104
  184. package/src/components/Tooltip/Tooltip.tsx +1 -1
  185. package/src/components/Upload/Upload.stories.tsx +113 -24
  186. package/src/layouts/Grid/Grid.stories.tsx +49 -49
  187. package/src/layouts/MasonryGrid/MasonryGrid.stories.tsx +2 -2
  188. package/src/lib/README.md +2 -2
  189. package/src/lib/__tests__/theme-tools.test.ts +193 -0
  190. package/src/lib/composables/index.ts +2 -2
  191. package/src/lib/composables/useAccordion.ts +12 -3
  192. package/src/lib/composables/useAtomixGlass.ts +28 -56
  193. package/src/lib/composables/useBreadcrumb.ts +2 -2
  194. package/src/lib/composables/useCallout.ts +7 -7
  195. package/src/lib/composables/useChartExport.ts +2 -7
  196. package/src/lib/composables/useDataTable.ts +46 -29
  197. package/src/lib/composables/useNavbar.ts +1 -1
  198. package/src/lib/constants/components.ts +10 -33
  199. package/src/lib/storybook/InteractiveDemo.tsx +113 -0
  200. package/src/lib/storybook/PreviewContainer.tsx +36 -0
  201. package/src/lib/storybook/VariantsGrid.tsx +21 -0
  202. package/src/lib/storybook/index.ts +3 -0
  203. package/src/lib/theme/core/createThemeObject.ts +9 -5
  204. package/src/lib/theme/devtools/CLI.ts +155 -0
  205. package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +213 -0
  206. package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +566 -0
  207. package/src/lib/theme/devtools/LiveEditor.tsx +2 -1
  208. package/src/lib/theme/devtools/index.ts +3 -0
  209. package/src/lib/theme/errors/errors.ts +8 -0
  210. package/src/lib/theme/runtime/ThemeProvider.tsx +117 -57
  211. package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +305 -0
  212. package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +588 -0
  213. package/src/lib/theme/utils/__tests__/themeValidation.test.ts +264 -0
  214. package/src/lib/theme/utils/index.ts +1 -0
  215. package/src/lib/theme/utils/themeValidation.ts +501 -0
  216. package/src/lib/theme-tools.ts +32 -3
  217. package/src/lib/types/components.ts +82 -27
  218. package/src/lib/utils/__tests__/csv.test.ts +45 -0
  219. package/src/lib/utils/csv.ts +17 -0
  220. package/src/lib/utils/dataTableExport.ts +1 -10
  221. package/src/lib/utils/themeNaming.ts +1 -1
  222. package/src/styles/01-settings/_index.scss +2 -1
  223. package/src/styles/01-settings/_settings.accordion.scss +28 -7
  224. package/src/styles/01-settings/_settings.colors.scss +11 -11
  225. package/src/styles/01-settings/_settings.typography.scss +5 -5
  226. package/src/styles/02-tools/_tools.utility-api.scss +14 -0
  227. package/src/styles/06-components/_components.accordion.scss +56 -14
  228. package/src/styles/06-components/_components.callout.scss +29 -33
  229. package/src/styles/06-components/_components.checkbox.scss +23 -17
  230. package/src/styles/06-components/_index.scss +1 -1
  231. package/src/styles/99-utilities/_index.scss +2 -0
  232. package/src/styles/99-utilities/_utilities.display.scss +14 -3
  233. package/src/styles/99-utilities/_utilities.flex.scss +10 -10
  234. package/src/styles/99-utilities/_utilities.scss +3 -1
  235. package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
  236. package/src/styles/99-utilities/_utilities.text.scss +28 -8
  237. package/themes/dark-complementary/README.md +98 -0
  238. package/themes/dark-complementary/index.scss +158 -0
  239. package/themes/default-light/README.md +81 -0
  240. package/themes/default-light/index.scss +154 -0
  241. package/themes/high-contrast/README.md +105 -0
  242. package/themes/high-contrast/index.scss +172 -0
  243. package/themes/test-theme/README.md +38 -0
  244. package/themes/test-theme/index.scss +47 -0
  245. package/scripts/cli/__tests__/cli-commands.test.js +0 -204
  246. package/scripts/cli/__tests__/vitest.config.js +0 -26
  247. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
  248. package/src/lib/composables/useButton.ts +0 -93
  249. package/src/lib/composables/useCheckbox.ts +0 -70
package/dist/heavy.js CHANGED
@@ -80,10 +80,16 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
80
80
  MIN_BLUR: .1,
81
81
  MOUSE_INFLUENCE_DIVISOR: 100,
82
82
  EDGE_FADE_PIXELS: 2,
83
+ // Note: This default must match the SCSS variable --atomix-radius-md
84
+ // @see src/styles/01-settings/_settings.global.scss
83
85
  DEFAULT_CORNER_RADIUS: 16,
84
- // Fallback value matching design system
85
86
  MAX_SIZE: 4096,
86
87
  // Maximum width/height for glass size
88
+ // Palette for internal calculations (matches design system base colors)
89
+ PALETTE: {
90
+ WHITE: "255, 255, 255",
91
+ BLACK: "0, 0, 0"
92
+ },
87
93
  // Gradient calculation constants
88
94
  GRADIENT: {
89
95
  BASE_ANGLE: 135,
@@ -242,10 +248,10 @@ import { Pause, Play, SkipBack, SkipForward, SpeakerX, SpeakerHigh, Gear, Downlo
242
248
  y: 0
243
249
  }, calculateMouseInfluence = mouseOffset => {
244
250
  if (!mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y) return 0;
245
- // More responsive calculation for overlight effects
251
+ // Bounded calculation keeps the glass effect subtle and stable
246
252
  const influence = Math.sqrt(mouseOffset.x * mouseOffset.x + mouseOffset.y * mouseOffset.y) / CONSTANTS$1.MOUSE_INFLUENCE_DIVISOR;
247
- return Math.min(1.5, influence);
248
- // Cap influence for better control
253
+ return Math.min(.8, influence);
254
+ // Tighter cap to prevent blur/filter blow-out
249
255
  }, clampBlur = value => "number" != typeof value || isNaN(value) ? CONSTANTS$1.MIN_BLUR : Math.max(CONSTANTS$1.MIN_BLUR, Math.min(50, value)), validateGlassSize = size => size && "number" == typeof size.width && "number" == typeof size.height && size.width > 0 && size.height > 0 && size.width <= CONSTANTS$1.MAX_SIZE && size.height <= CONSTANTS$1.MAX_SIZE, parseBorderRadiusValue = value => {
250
256
  if ("number" == typeof value) return Math.max(0, value);
251
257
  if ("string" != typeof value || !value.trim()) return CONSTANTS$1.DEFAULT_CORNER_RADIUS;
@@ -474,7 +480,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
474
480
  }, globalMousePosition: globalMousePosition = {
475
481
  x: 0,
476
482
  y: 0
477
- }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, active: active = !1, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, cornerRadius: cornerRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
483
+ }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, onMouseUp: onMouseUp, isHovered: isHovered = !1, isActive: isActive = !1, overLight: overLight = !1, overLightConfig: overLightConfig = {}, cornerRadius: cornerRadius = 0, padding: padding = "0 0", glassSize: glassSize = {
478
484
  width: 0,
479
485
  height: 0
480
486
  }, onClick: onClick, mode: mode = "standard", effectiveDisableEffects: effectiveDisableEffects = !1, effectiveReducedMotion: effectiveReducedMotion = !1, shaderVariant: shaderVariant = "liquidGlass", enableLiquidBlur: enableLiquidBlur = !1, elasticity: elasticity = 0, contentRef: contentRef}, ref) => {
@@ -587,28 +593,29 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
587
593
  flowBlur: 1.2 * blurAmount
588
594
  };
589
595
  // Enhanced validation for liquid blur
590
- if (!enableLiquidBlur || !rectCache || !globalMousePosition || "number" != typeof globalMousePosition.x || "number" != typeof globalMousePosition.y || isNaN(globalMousePosition.x) || isNaN(globalMousePosition.y)) return defaultBlur;
596
+ if (!enableLiquidBlur || !rectCache || !mouseOffset || "number" != typeof mouseOffset.x || "number" != typeof mouseOffset.y || isNaN(mouseOffset.x) || isNaN(mouseOffset.y)) return defaultBlur;
591
597
  try {
592
- // Cache center and distance calculations
593
- const center = calculateElementCenter(rectCache), distance = calculateDistance(globalMousePosition, center), maxDistance = Math.sqrt(rectCache.width * rectCache.width + rectCache.height * rectCache.height) / 2, normalizedDistance = Math.min(distance / maxDistance, 1), mouseInfluence = calculateMouseInfluence(mouseOffset), baseBlur = blurAmount + mouseInfluence * blurAmount * .4, edgeBlur = baseBlur * (.8 + .6 * (1.5 * normalizedDistance + .3 * mouseInfluence)), centerBlur = baseBlur * (.3 + .4 * (.3 * (1 - normalizedDistance) + .2 * mouseInfluence)), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, flowDirection = Math.atan2(deltaY, deltaX), flowBlur = baseBlur * (.4 + .6 * (.5 * Math.sin(flowDirection + mouseInfluence * Math.PI) + .5)), stateMultiplier = (isHovered ? 1.2 : 1) * (isActive ? 1.4 : 1);
598
+ const mouseInfluence = calculateMouseInfluence(mouseOffset), maxBlur = 2 * blurAmount, baseBlur = Math.min(maxBlur, blurAmount + mouseInfluence * blurAmount * .15), edgeIntensity = .15 * mouseInfluence, edgeBlur = Math.min(maxBlur, baseBlur * (.8 + .4 * edgeIntensity)), centerIntensity = .1 * mouseInfluence, centerBlur = Math.min(maxBlur, baseBlur * (.3 + .3 * centerIntensity)), flowBlur = Math.min(maxBlur, 1.2 * baseBlur);
599
+ // NOTE: hover/active multipliers intentionally omitted here
600
+ // they belong on opacity layers, not the blur filter itself.
594
601
  return {
595
- baseBlur: clampBlur(baseBlur * stateMultiplier),
596
- edgeBlur: clampBlur(edgeBlur * stateMultiplier),
597
- centerBlur: clampBlur(centerBlur * stateMultiplier),
598
- flowBlur: clampBlur(flowBlur * stateMultiplier)
602
+ baseBlur: clampBlur(baseBlur),
603
+ edgeBlur: clampBlur(edgeBlur),
604
+ centerBlur: clampBlur(centerBlur),
605
+ flowBlur: clampBlur(flowBlur)
599
606
  };
600
607
  } catch (error) {
601
608
  return console.warn("AtomixGlassContainer: Error calculating liquid blur", error),
602
609
  defaultBlur;
603
610
  }
604
- }), [ enableLiquidBlur, blurAmount, globalMousePosition, mouseOffset, isHovered, isActive, rectCache, style, glassSize ]), backdropStyle = useMemo((() => {
611
+ }), [ enableLiquidBlur, blurAmount, mouseOffset, rectCache ]), backdropStyle = useMemo((() => {
605
612
  try {
606
613
  const dynamicSaturation = saturation + 20 * (liquidBlur.baseBlur || 0), validatedBaseBlur = "number" != typeof liquidBlur.baseBlur || isNaN(liquidBlur.baseBlur) ? 0 : liquidBlur.baseBlur, validatedEdgeBlur = "number" != typeof liquidBlur.edgeBlur || isNaN(liquidBlur.edgeBlur) ? 0 : liquidBlur.edgeBlur, validatedCenterBlur = "number" != typeof liquidBlur.centerBlur || isNaN(liquidBlur.centerBlur) ? 0 : liquidBlur.centerBlur, validatedFlowBlur = "number" != typeof liquidBlur.flowBlur || isNaN(liquidBlur.flowBlur) ? 0 : liquidBlur.flowBlur, area = rectCache ? rectCache.width * rectCache.height : 0;
607
614
  // Validate blur values before using them
608
615
  return !enableLiquidBlur || effectiveReducedMotion || effectiveDisableEffects || area > 18e4 ? {
609
- backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(1.05) brightness(1.05)`
616
+ backdropFilter: `blur(${clampBlur(Math.max(validatedBaseBlur, .8 * validatedEdgeBlur, 1.1 * validatedCenterBlur, .9 * validatedFlowBlur))}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
610
617
  } : {
611
- backdropFilter: `${[ `blur(${validatedBaseBlur}px)`, `blur(${validatedEdgeBlur}px)`, `blur(${validatedCenterBlur}px)`, `blur(${validatedFlowBlur}px)` ].join(" ")} saturate(${Math.min(dynamicSaturation, 200)}%) contrast(1.05) brightness(1.05)`
618
+ backdropFilter: `blur(${clampBlur(.4 * validatedBaseBlur + .25 * validatedEdgeBlur + .15 * validatedCenterBlur + .2 * validatedFlowBlur)}px) saturate(${Math.min(dynamicSaturation, 200)}%) contrast(${overLightConfig?.contrast || 1.05}) brightness(${overLightConfig?.brightness || 1.05})`
612
619
  };
613
620
  // Single-pass fallback: stronger radius to match perceived blur of multi-pass
614
621
  } catch (error) {
@@ -627,7 +634,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
627
634
  "--atomix-glass-container-padding": padding || "0 0",
628
635
  "--atomix-glass-container-radius": `${"number" != typeof cornerRadius || isNaN(cornerRadius) ? 0 : cornerRadius}px`,
629
636
  "--atomix-glass-container-backdrop": backdropStyle?.backdropFilter || "none",
630
- "--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${.4 + .002 * mx})`, `inset 0 -1px 0 rgba(0, 0, 0, ${.2 + .001 * Math.abs(my)})`, `inset 0 0 20px rgba(0, 0, 0, ${.08 + .001 * Math.abs(mx + my)})`, `0 2px 12px rgba(0, 0, 0, ${.12 + .002 * Math.abs(my)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
637
+ "--atomix-glass-container-shadow": overLight ? [ `inset 0 1px 0 rgba(255, 255, 255, ${(.4 + .002 * mx) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 -1px 0 rgba(0, 0, 0, ${(.2 + .001 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})`, `inset 0 0 20px rgba(0, 0, 0, ${(.08 + .001 * Math.abs(mx + my)) * (overLightConfig?.shadowIntensity || 1)})`, `0 2px 12px rgba(0, 0, 0, ${(.12 + .002 * Math.abs(my)) * (overLightConfig?.shadowIntensity || 1)})` ].join(", ") : "0 0 20px rgba(0, 0, 0, 0.15) inset, 0 4px 8px rgba(0, 0, 0, 0.08) inset",
631
638
  "--atomix-glass-container-shadow-opacity": effectiveDisableEffects ? 0 : 1,
632
639
  // Background and shadow values use design token-aligned RGB values
633
640
  "--atomix-glass-container-bg": overLight ? `linear-gradient(${180 + .5 * mx}deg, rgba(255, 255, 255, 0.1) 0%, transparent 20%, transparent 80%, rgba(0, 0, 0, 0.05) 100%)` : "none",
@@ -646,10 +653,18 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
646
653
  "--atomix-glass-container-text-shadow": "none"
647
654
  };
648
655
  }
649
- }), [ glassSize, padding, cornerRadius, backdropStyle, mouseOffset, overLight, effectiveDisableEffects ]);
656
+ }), [ glassSize, padding, cornerRadius, backdropStyle, mouseOffset, overLight, effectiveDisableEffects ]), setForceNoTransition = el => {
657
+ el && (el.style.setProperty("transition-duration", "0s", "important"), el.style.setProperty("animation-duration", "0s", "important"),
658
+ el.style.setProperty("transition-delay", "0s", "important"));
659
+ };
650
660
  return jsx("div", {
651
- ref: ref,
652
- className: `${ATOMIX_GLASS.CONTAINER_CLASS} ${className} ${active ? ATOMIX_GLASS.CLASSES.ACTIVE : ""} ${overLight ? ATOMIX_GLASS.CLASSES.OVER_LIGHT : ""}`,
661
+ ref: el => {
662
+ // Apply force no-transition
663
+ setForceNoTransition(el),
664
+ // Handle forwarded ref
665
+ "function" == typeof ref ? ref(el) : ref && (ref.current = el);
666
+ },
667
+ className: `${ATOMIX_GLASS.CONTAINER_CLASS} ${className} ${isActive ? ATOMIX_GLASS.CLASSES.ACTIVE : ""} ${overLight ? ATOMIX_GLASS.CLASSES.OVER_LIGHT : ""}`,
653
668
  style: {
654
669
  ...style,
655
670
  ...containerVars
@@ -667,6 +682,11 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
667
682
  onMouseUp: onMouseUp,
668
683
  children: [ jsxs("div", {
669
684
  className: ATOMIX_GLASS.FILTER_CLASS,
685
+ style: {
686
+ zIndex: 1,
687
+ position: "absolute",
688
+ inset: 0
689
+ },
670
690
  children: [ jsx(GlassFilter, {
671
691
  blurAmount: blurAmount,
672
692
  mode: mode,
@@ -675,6 +695,7 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
675
695
  aberrationIntensity: "number" != typeof aberrationIntensity || isNaN(aberrationIntensity) ? 0 : aberrationIntensity,
676
696
  shaderMapUrl: shaderMapUrl
677
697
  }), jsx("div", {
698
+ ref: setForceNoTransition,
678
699
  className: ATOMIX_GLASS.FILTER_OVERLAY_CLASS,
679
700
  style: {
680
701
  filter: `url(#${filterId})`,
@@ -696,9 +717,8 @@ const sharedShaderCache = new Map, AtomixGlassContainer = forwardRef((({childre
696
717
  style: {
697
718
  position: "relative",
698
719
  textShadow: "var(--atomix-glass-container-text-shadow)",
699
- ...elasticity > 0 ? {
700
- zIndex: 100
701
- } : {}
720
+ // Ensure content is always above the filter layer (zIndex 1)
721
+ zIndex: elasticity > 0 ? 100 : 2
702
722
  },
703
723
  children: children
704
724
  }) ]
@@ -816,12 +836,12 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
816
836
  }), [internalMouseOffset, setInternalMouseOffset] = useState({
817
837
  x: 0,
818
838
  y: 0
819
- }), [dynamicCornerRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveCornerRadius = useMemo((() => void 0 !== cornerRadius ? Math.max(0, cornerRadius) : Math.max(0, dynamicCornerRadius)), [ cornerRadius, dynamicCornerRadius, debugCornerRadius ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveDisableEffects = useMemo((() => disableEffects || effectiveReducedMotion), [ disableEffects, effectiveReducedMotion ]), globalMousePosition = useMemo((() => externalGlobalMousePosition || internalGlobalMousePosition), [ externalGlobalMousePosition, internalGlobalMousePosition ]), mouseOffset = useMemo((() => externalMouseOffset || internalMouseOffset), [ externalMouseOffset, internalMouseOffset ]);
839
+ }), [dynamicCornerRadius, setDynamicCornerRadius] = useState(CONSTANTS.DEFAULT_CORNER_RADIUS), [userPrefersReducedMotion, setUserPrefersReducedMotion] = useState(!1), [userPrefersHighContrast, setUserPrefersHighContrast] = useState(!1), [detectedOverLight, setDetectedOverLight] = useState(!1), effectiveCornerRadius = useMemo((() => void 0 !== cornerRadius ? Math.max(0, cornerRadius) : Math.max(0, dynamicCornerRadius)), [ cornerRadius, dynamicCornerRadius ]), effectiveReducedMotion = useMemo((() => reducedMotion || userPrefersReducedMotion), [ reducedMotion, userPrefersReducedMotion ]), effectiveHighContrast = useMemo((() => highContrast || userPrefersHighContrast), [ highContrast, userPrefersHighContrast ]), effectiveDisableEffects = useMemo((() => disableEffects || effectiveReducedMotion), [ disableEffects, effectiveReducedMotion ]), globalMousePosition = useMemo((() => externalGlobalMousePosition || internalGlobalMousePosition), [ externalGlobalMousePosition, internalGlobalMousePosition ]), mouseOffset = useMemo((() => externalMouseOffset || internalMouseOffset), [ externalMouseOffset, internalMouseOffset ]);
820
840
  // Extract border-radius from children
821
841
  useEffect((() => {
822
842
  const extractRadius = () => {
823
843
  try {
824
- let extractedRadius = null, extractionSource = "default";
844
+ let extractedRadius = null;
825
845
  if (contentRef.current) {
826
846
  const firstChild = contentRef.current.firstElementChild;
827
847
  if (firstChild) {
@@ -838,15 +858,14 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
838
858
  return null;
839
859
  }
840
860
  })(firstChild);
841
- null !== domRadius && domRadius > 0 && (extractedRadius = domRadius, extractionSource = "DOM element");
861
+ null !== domRadius && domRadius > 0 && (extractedRadius = domRadius);
842
862
  }
843
863
  }
844
864
  if (null === extractedRadius) {
845
865
  const childRadius = extractBorderRadiusFromChildren(children);
846
- childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius,
847
- extractionSource = "React children");
866
+ childRadius > 0 && childRadius !== CONSTANTS.DEFAULT_CORNER_RADIUS && (extractedRadius = childRadius);
848
867
  }
849
- null !== extractedRadius && extractedRadius > 0 ? setDynamicCornerRadius(extractedRadius) : "undefined" == typeof process || process.env;
868
+ null !== extractedRadius && extractedRadius > 0 && setDynamicCornerRadius(extractedRadius);
850
869
  } catch (error) {
851
870
  "undefined" != typeof process && "production" === process.env?.NODE_ENV || !debugCornerRadius || console.error("[AtomixGlass] Error extracting corner radius:", error);
852
871
  }
@@ -975,7 +994,6 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
975
994
  }
976
995
  if ("boolean" == typeof overLight &&
977
996
  // For boolean values, disable auto-detection
978
- // Cache is automatically managed by WeakMap (no manual clearing needed)
979
997
  setDetectedOverLight(!1), "function" == typeof window.matchMedia) try {
980
998
  const mediaQueryReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"), mediaQueryHighContrast = window.matchMedia("(prefers-contrast: high)");
981
999
  setUserPrefersReducedMotion(mediaQueryReducedMotion.matches), setUserPrefersHighContrast(mediaQueryHighContrast.matches);
@@ -1045,6 +1063,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1045
1063
  }), [ handleGlobalMousePosition, mouseContainer, glassRef, externalGlobalMousePosition, externalMouseOffset, effectiveDisableEffects ]);
1046
1064
  // Transform calculations
1047
1065
  const calculateDirectionalScale = useCallback((() => {
1066
+ if (!0 === overLight || "auto" === overLight && detectedOverLight || "object" == typeof overLight && null !== overLight && detectedOverLight) return "scale(1)";
1048
1067
  if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return "scale(1)";
1049
1068
  const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), deltaX = globalMousePosition.x - center.x, deltaY = globalMousePosition.y - center.y, edgeDistanceX = Math.max(0, Math.abs(deltaX) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(deltaY) - glassSize.height / 2), edgeDistance = calculateDistance({
1050
1069
  x: edgeDistanceX,
@@ -1058,7 +1077,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1058
1077
  if (0 === centerDistance) return "scale(1)";
1059
1078
  const normalizedX = deltaX / centerDistance, normalizedY = deltaY / centerDistance, stretchIntensity = Math.min(centerDistance / 300, 1) * elasticity * fadeInFactor, scaleX = 1 + Math.abs(normalizedX) * stretchIntensity * .3 - Math.abs(normalizedY) * stretchIntensity * .15, scaleY = 1 + Math.abs(normalizedY) * stretchIntensity * .3 - Math.abs(normalizedX) * stretchIntensity * .15;
1060
1079
  return `scaleX(${Math.max(.8, scaleX)}) scaleY(${Math.max(.8, scaleY)})`;
1061
- }), [ globalMousePosition, elasticity, glassSize, glassRef ]), calculateFadeInFactor = useCallback((() => {
1080
+ }), [ globalMousePosition, elasticity, glassSize, glassRef, overLight, detectedOverLight ]), calculateFadeInFactor = useCallback((() => {
1062
1081
  if (!(globalMousePosition.x && globalMousePosition.y && glassRef.current && validateGlassSize(glassSize))) return 0;
1063
1082
  const rect = glassRef.current.getBoundingClientRect(), center = calculateElementCenter(rect), edgeDistanceX = Math.max(0, Math.abs(globalMousePosition.x - center.x) - glassSize.width / 2), edgeDistanceY = Math.max(0, Math.abs(globalMousePosition.y - center.y) - glassSize.height / 2), edgeDistance = calculateDistance({
1064
1083
  x: edgeDistanceX,
@@ -1143,20 +1162,21 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1143
1162
  isOverLight: isOverLight,
1144
1163
  threshold: .7,
1145
1164
  opacity: isOverLight ? Math.min(.6, Math.max(.2, .5 * hoverIntensity * activeIntensity)) : 0,
1146
- contrast: Math.min(1.8, Math.max(1, 1.4 + .3 * mouseInfluence)),
1147
- brightness: Math.min(1.2, Math.max(.7, .85 + .15 * mouseInfluence)),
1148
- saturationBoost: Math.min(2, Math.max(1, 1.3 + .4 * mouseInfluence)),
1149
- shadowIntensity: Math.min(1.5, Math.max(.5, .9 + .5 * mouseInfluence)),
1150
- borderOpacity: Math.min(1, Math.max(.3, .7 + .3 * mouseInfluence))
1165
+ contrast: Math.min(1.6, Math.max(1, 1.4 + .1 * mouseInfluence)),
1166
+ brightness: Math.min(1.1, Math.max(.8, .9 + .05 * mouseInfluence)),
1167
+ saturationBoost: 1.3,
1168
+ // Fixed value dynamic saturation amplifies perceived displacement
1169
+ shadowIntensity: Math.min(1.2, Math.max(.5, .9 + .2 * mouseInfluence)),
1170
+ borderOpacity: Math.min(1, Math.max(.3, .7 + .1 * mouseInfluence))
1151
1171
  };
1152
1172
  if ("object" == typeof overLight && null !== overLight) {
1153
1173
  const objConfig = overLight, validatedThreshold = validateConfigValue(objConfig.threshold, .1, 1, baseConfig.threshold), validatedOpacity = validateConfigValue(objConfig.opacity, .1, 1, baseConfig.opacity), validatedContrast = validateConfigValue(objConfig.contrast, .5, 2.5, baseConfig.contrast), validatedBrightness = validateConfigValue(objConfig.brightness, .5, 2, baseConfig.brightness), validatedSaturationBoost = validateConfigValue(objConfig.saturationBoost, .5, 3, baseConfig.saturationBoost), finalConfig = {
1154
1174
  ...baseConfig,
1155
1175
  threshold: validatedThreshold,
1156
1176
  opacity: validatedOpacity * hoverIntensity * activeIntensity,
1157
- contrast: validatedContrast + .3 * mouseInfluence,
1158
- brightness: validatedBrightness + .15 * mouseInfluence,
1159
- saturationBoost: validatedSaturationBoost + .4 * mouseInfluence
1177
+ contrast: Math.min(1.6, validatedContrast + .1 * mouseInfluence),
1178
+ brightness: Math.min(1.1, validatedBrightness + .05 * mouseInfluence),
1179
+ saturationBoost: validatedSaturationBoost
1160
1180
  };
1161
1181
  // Validate and apply object config values with proper clamping
1162
1182
  return "undefined" == typeof process || process.env, finalConfig;
@@ -1290,19 +1310,19 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1290
1310
  debugOverLight: debugOverLight,
1291
1311
  enablePerformanceMonitoring: enablePerformanceMonitoring,
1292
1312
  children: children
1293
- }), isOverLight = overLightConfig.isOverLight, shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
1313
+ }), isOverLight = useMemo((() => overLightConfig?.isOverLight), [ overLight ]), shouldRenderOverLightLayers = enableOverLightLayers && isOverLight, baseStyle = {
1294
1314
  ...style,
1295
- ...0 !== elasticity && !effectiveDisableEffects && {
1315
+ ...!effectiveDisableEffects && {
1296
1316
  transform: transformStyle
1297
1317
  }
1298
- }, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = {
1318
+ }, componentClassName = [ ATOMIX_GLASS.BASE_CLASS, effectiveReducedMotion && `${ATOMIX_GLASS.BASE_CLASS}--reduced-motion`, effectiveHighContrast && `${ATOMIX_GLASS.BASE_CLASS}--high-contrast`, effectiveDisableEffects && `${ATOMIX_GLASS.BASE_CLASS}--disabled-effects`, className ].filter(Boolean).join(" "), positionStyles = useMemo((() => ({
1299
1319
  position: style.position || "absolute",
1300
1320
  top: style.top || 0,
1301
1321
  left: style.left || 0
1302
- }, adjustedSize = {
1322
+ })), [ style.position, style.top, style.left ]), adjustedSize = useMemo((() => ({
1303
1323
  width: "fixed" !== style.position ? "100%" : style.width ? style.width : Math.max(glassSize.width, 0),
1304
1324
  height: "fixed" !== style.position ? "100%" : style.height ? style.height : Math.max(glassSize.height, 0)
1305
- }, gradientValues = useMemo((() => {
1325
+ })), [ style.position, style.width, style.height, glassSize.width, glassSize.height ]), gradientValues = useMemo((() => {
1306
1326
  const mx = mouseOffset.x, my = mouseOffset.y, absMx = Math.abs(mx), absMy = Math.abs(my), GRADIENT = ATOMIX_GLASS.CONSTANTS.GRADIENT;
1307
1327
  return {
1308
1328
  borderGradientAngle: GRADIENT.BASE_ANGLE + mx * GRADIENT.ANGLE_MULTIPLIER,
@@ -1342,7 +1362,7 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1342
1362
  over: isOverLight ? 1.1 * (overLightOpacity || .4) : 0
1343
1363
  };
1344
1364
  }), [ isHovered, isActive, isOverLight, overLightConfig.opacity ]), glassVars = useMemo((() => {
1345
- const whiteColor = "255, 255, 255", {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues;
1365
+ const whiteColor = ATOMIX_GLASS.CONSTANTS.PALETTE.WHITE, blackColor = ATOMIX_GLASS.CONSTANTS.PALETTE.BLACK, {borderGradientAngle: borderGradientAngle, borderStop1: borderStop1, borderStop2: borderStop2, borderOpacities: borderOpacities, hoverPositions: hoverPositions, basePosition: basePosition, mx: mx, my: my, absMx: absMx, absMy: absMy} = gradientValues, configBorderOpacity = overLightConfig?.borderOpacity ?? 1;
1346
1366
  return {
1347
1367
  "--atomix-glass-radius": `${effectiveCornerRadius}px`,
1348
1368
  "--atomix-glass-transform": transformStyle || "none",
@@ -1353,20 +1373,20 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1353
1373
  "--atomix-glass-height": "fixed" !== style.position ? adjustedSize.height : `${adjustedSize.height}px`,
1354
1374
  "--atomix-glass-border-width": "var(--atomix-spacing-0-5, 0.09375rem)",
1355
1375
  "--atomix-glass-blend-mode": isOverLight ? "multiply" : "overlay",
1356
- "--atomix-glass-border-gradient-1": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacities[0]}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacities[1]}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1357
- "--atomix-glass-border-gradient-2": `linear-gradient(${borderGradientAngle}deg, rgba(${whiteColor}, 0) 0%, rgba(${whiteColor}, ${borderOpacities[2]}) ${borderStop1}%, rgba(${whiteColor}, ${borderOpacities[3]}) ${borderStop2}%, rgba(${whiteColor}, 0) 100%)`,
1376
+ "--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%)`,
1377
+ "--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%)`,
1358
1378
  "--atomix-glass-hover-1-opacity": opacityValues.hover1,
1359
- "--atomix-glass-hover-1-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover1.x}% ${hoverPositions.hover1.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_1.BLACK_STOP}%, rgba(0, 0, 0, 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}%)`,
1379
+ "--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}%)`,
1360
1380
  "--atomix-glass-hover-2-opacity": opacityValues.hover2,
1361
- "--atomix-glass-hover-2-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover2.x}% ${hoverPositions.hover2.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_2.BLACK_STOP}%, rgba(0, 0, 0, 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}%)`,
1381
+ "--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}%)`,
1362
1382
  "--atomix-glass-hover-3-opacity": opacityValues.hover3,
1363
- "--atomix-glass-hover-3-gradient": isOverLight ? `radial-gradient(circle at ${hoverPositions.hover3.x}% ${hoverPositions.hover3.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_START}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_STOP}%, rgba(0, 0, 0, 0) ${ATOMIX_GLASS.CONSTANTS.GRADIENT_OPACITY.HOVER_3.BLACK_END}%)` : `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}%)`,
1383
+ "--atomix-glass-hover-3-gradient": isOverLight ? `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}%)` : `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}%)`,
1364
1384
  "--atomix-glass-base-opacity": opacityValues.base,
1365
- "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${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(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
1385
+ "--atomix-glass-base-gradient": isOverLight ? `linear-gradient(${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.ANGLE}deg, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_BASE + mx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_BASE + my * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_MULTIPLIER}) ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_BASE + absMx * ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.BASE_GRADIENT.WHITE_OPACITY})`,
1366
1386
  "--atomix-glass-overlay-opacity": opacityValues.over,
1367
- "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(0, 0, 0, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
1387
+ "--atomix-glass-overlay-gradient": isOverLight ? `radial-gradient(circle at ${basePosition.x}% ${basePosition.y}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_BASE + absMx * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_START_MULTIPLIER}) 0%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID}) ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_MID_STOP}%, rgba(${blackColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_BASE + absMy * ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.BLACK_END_MULTIPLIER}) 100%)` : `rgba(${whiteColor}, ${ATOMIX_GLASS.CONSTANTS.OVERLAY_GRADIENT.WHITE_OPACITY})`
1368
1388
  };
1369
- }), [ gradientValues, opacityValues, effectiveCornerRadius, transformStyle, positionStyles, adjustedSize, style.position, isOverLight ]), renderBackgroundLayer = layerType => jsx("div", {
1389
+ }), [ gradientValues, opacityValues, effectiveCornerRadius, transformStyle, positionStyles, adjustedSize, style.position, isOverLight, overLightConfig.borderOpacity ]), renderBackgroundLayer = layerType => jsx("div", {
1370
1390
  className: [ ATOMIX_GLASS.BACKGROUND_LAYER_CLASS, "dark" === layerType ? ATOMIX_GLASS.BACKGROUND_LAYER_DARK_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_BLACK_CLASS, isOverLight ? ATOMIX_GLASS.BACKGROUND_LAYER_OVER_LIGHT_CLASS : ATOMIX_GLASS.BACKGROUND_LAYER_HIDDEN_CLASS ].filter(Boolean).join(" "),
1371
1391
  style: {
1372
1392
  ...positionStyles,
@@ -1392,9 +1412,9 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1392
1412
  className: className,
1393
1413
  style: baseStyle,
1394
1414
  cornerRadius: effectiveCornerRadius,
1395
- displacementScale: effectiveDisableEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : overLightConfig.isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1415
+ displacementScale: effectiveDisableEffects ? 0 : "shader" === mode ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_DISPLACEMENT : isOverLight ? displacementScale * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.OVER_LIGHT_DISPLACEMENT : displacementScale,
1396
1416
  blurAmount: effectiveDisableEffects ? 0 : blurAmount,
1397
- saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : overLightConfig.isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
1417
+ saturation: effectiveHighContrast ? ATOMIX_GLASS.CONSTANTS.SATURATION.HIGH_CONTRAST : isOverLight ? saturation * overLightConfig.saturationBoost : saturation,
1398
1418
  aberrationIntensity: effectiveDisableEffects ? 0 : "shader" === mode ? aberrationIntensity * ATOMIX_GLASS.CONSTANTS.MULTIPLIERS.SHADER_ABERRATION : aberrationIntensity,
1399
1419
  glassSize: glassSize,
1400
1420
  padding: padding,
@@ -1410,10 +1430,15 @@ function useAtomixGlass({glassRef: glassRef, contentRef: contentRef, cornerRadiu
1410
1430
  onMouseLeave: handleMouseLeave,
1411
1431
  onMouseDown: handleMouseDown,
1412
1432
  onMouseUp: handleMouseUp,
1413
- active: isActive,
1414
1433
  isHovered: isHovered,
1415
1434
  isActive: isActive,
1416
- overLight: overLightConfig.isOverLight,
1435
+ overLight: isOverLight,
1436
+ overLightConfig: {
1437
+ contrast: overLightConfig.contrast,
1438
+ brightness: overLightConfig.brightness,
1439
+ shadowIntensity: overLightConfig.shadowIntensity,
1440
+ borderOpacity: overLightConfig.borderOpacity
1441
+ },
1417
1442
  onClick: onClick,
1418
1443
  mode: mode,
1419
1444
  transform: baseStyle.transform,
@@ -1661,7 +1686,11 @@ const smoothStep = (a, b, t) => {
1661
1686
  // Add input validation
1662
1687
  "number" != typeof x || "number" != typeof y || "number" != typeof time || isNaN(x) || isNaN(y) || isNaN(time) ? .5 : .5 * (.7 * fbm(40 * x + .3 * time, 40 * y - .3 * time, 6) + .3 * fbm(80 * x, 80 * y, 4)))(ix, iy, time), microDetailX = .008 * (microSurface - .5), microDetailY = .008 * (microSurface - .5), centerDistance = calculateLength(ix, iy), dynamicRefraction = .35 * Math.pow(Math.min(centerDistance, 1), 1.8) * (1 + mouseFalloff * mouseDistance * .8), refractionX = Math.cos(refractionAngle) * dynamicRefraction, refractionY = Math.sin(refractionAngle) * dynamicRefraction, vortexAngle = Math.atan2(iy - mouseY, ix - mouseX), vortexDistance = calculateLength(ix - mouseX, iy - mouseY), vortexStrength = mouseFalloff * Math.sin(10 * vortexDistance - 3 * time) * .025, vortexX = Math.cos(vortexAngle + 2 * time) * vortexStrength, vortexY = Math.sin(vortexAngle + 2 * time) * vortexStrength, fluidX = Math.sin(10 * ix + 5 * mouseX + 2.5 * time) * Math.cos(8 * iy - 2 * time) * .018, fluidY = Math.cos(8 * ix - 2 * time) * Math.sin(10 * iy + 5 * mouseY + 2.5 * time) * .018, rippleEffect = (.012 * Math.sin(15 * Math.min(centerDistance, 10) - 4 * time) + .008 * Math.cos(20 * Math.min(centerDistance, 10) + 3 * time)) * mouseFalloff, rippleX = Math.cos(refractionAngle) * rippleEffect, rippleY = Math.sin(refractionAngle) * rippleEffect, distanceToEdge = roundedRectSDF(ix, iy, .44, .34, .39), edgeMask = smoothStep(.92, -.12, distanceToEdge), edgeSoftness = smoothStep(.85, .1, distanceToEdge), finalY = iy + (1.2 * refractionY + .8 * spectralY + 1.5 * parallaxY + .9 * scatteringY + 1 * turbulenceY + .6 * microDetailY + 1.3 * vortexY + 1.1 * fluidY + .7 * rippleY + .8 * causticDistortion) * edgeMask * edgeSoftness * .85;
1663
1688
  return createTexture(clampValue(ix + (1.2 * refractionX + .8 * spectralX + 1.5 * parallaxX + .9 * scatteringX + 1 * turbulenceX + .6 * microDetailX + 1.3 * vortexX + 1.1 * fluidX + .7 * rippleX + causticDistortion) * edgeMask * edgeSoftness * .85 + .5, 0, 1), clampValue(finalY + .5, 0, 1));
1664
- }
1689
+ },
1690
+ // Aliases for compatibility
1691
+ plasma: (uv, mousePosition) => fragmentShaders.premiumGlass(uv, mousePosition),
1692
+ waves: (uv, mousePosition) => fragmentShaders.liquidMetal(uv, mousePosition),
1693
+ noise: (uv, mousePosition) => fragmentShaders.appleFluid(uv, mousePosition)
1665
1694
  }, shaderUtils = Object.freeze( Object.defineProperty({
1666
1695
  __proto__: null,
1667
1696
  ShaderDisplacementGenerator: class {
@@ -3000,7 +3029,7 @@ MasonryGrid.displayName = "MasonryGrid", forwardRef((({children: children, clas
3000
3029
  });
3001
3030
  })).displayName = "MasonryGridItem";
3002
3031
 
3003
- const Badge = memo((({label: label, variant: variant = "primary", size: size = "md", disabled: disabled = !1, icon: icon, className: className = "", glass: glass, style: style}) => {
3032
+ const Badge = memo((({label: label, variant: variant = "primary", size: size = "md", disabled: disabled = !1, icon: icon, onRemove: onRemove, "aria-label": ariaLabel, className: className = "", glass: glass, style: style}) => {
3004
3033
  const {generateBadgeClass: generateBadgeClass} =
3005
3034
  /**
3006
3035
  * Badge state and functionality
@@ -3038,6 +3067,7 @@ const Badge = memo((({label: label, variant: variant = "primary", size: size =
3038
3067
  }), badgeElement = jsxs("span", {
3039
3068
  className: badgeClass,
3040
3069
  "aria-disabled": disabled,
3070
+ "aria-label": ariaLabel,
3041
3071
  ref: ref,
3042
3072
  style: style,
3043
3073
  children: [ icon && jsx("span", {
@@ -3045,6 +3075,13 @@ const Badge = memo((({label: label, variant: variant = "primary", size: size =
3045
3075
  children: icon
3046
3076
  }), jsx("span", {
3047
3077
  children: label
3078
+ }), onRemove && jsx("button", {
3079
+ type: "button",
3080
+ className: "c-badge__close",
3081
+ onClick: onRemove,
3082
+ "aria-label": "Remove badge",
3083
+ disabled: disabled,
3084
+ children: "×"
3048
3085
  }) ]
3049
3086
  });
3050
3087
  if (glass) {
@@ -3068,7 +3105,7 @@ const Badge = memo((({label: label, variant: variant = "primary", size: size =
3068
3105
 
3069
3106
  Badge.displayName = "Badge";
3070
3107
 
3071
- const Spinner = memo((({size: size = "md", variant: variant = "primary", fullscreen: fullscreen = !1, className: className = "", style: style, glass: glass}) => {
3108
+ const Spinner = memo((({size: size = "md", variant: variant = "primary", fullscreen: fullscreen = !1, className: className = "", style: style, glass: glass, "aria-label": ariaLabel, role: role = "status"}) => {
3072
3109
  const {generateSpinnerClass: generateSpinnerClass} =
3073
3110
  /**
3074
3111
  * Spinner state and functionality
@@ -3106,10 +3143,11 @@ const Spinner = memo((({size: size = "md", variant: variant = "primary", fullsc
3106
3143
  }), spinnerContent = jsx("div", {
3107
3144
  className: spinnerClass,
3108
3145
  style: style,
3109
- role: "status",
3146
+ role: role,
3147
+ "aria-label": ariaLabel || "Loading",
3110
3148
  children: jsx("span", {
3111
3149
  className: "u-visually-hidden",
3112
- children: "Loading..."
3150
+ children: ariaLabel || "Loading..."
3113
3151
  })
3114
3152
  });
3115
3153
  if (glass) {
@@ -3190,7 +3228,7 @@ class ThemeNaming {
3190
3228
  * Convert kebab-case to camelCase for JavaScript properties
3191
3229
  * @param str - String to convert
3192
3230
  */ static kebabToCamel(str) {
3193
- return str.replace(/-([a-z])/g, (g => g[1].toUpperCase()));
3231
+ return str.replace(/-([a-z])/g, (g => g[1]?.toUpperCase() ?? ""));
3194
3232
  }
3195
3233
  /**
3196
3234
  * Create a CSS variable name
@@ -3251,13 +3289,11 @@ class ThemeNaming {
3251
3289
 
3252
3290
  ThemeNaming.prefix = "atomix";
3253
3291
 
3254
- const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, ariaLabel: ariaLabel, ariaDescribedBy: ariaDescribedBy, ariaExpanded: ariaExpanded, ariaControls: ariaControls, tabIndex: tabIndex, style: style, LinkComponent: LinkComponent, ...props}, ref) => {
3292
+ const Button = React.memo( forwardRef((({label: label, children: children, onClick: onClick, variant: variant = "primary", size: size = "md", disabled: disabled = !1, loading: loading = !1, loadingText: loadingText, icon: icon, iconName: iconName, iconSize: iconSize = "sm", iconPosition: iconPosition = "start", iconOnly: iconOnly = !1, rounded: rounded = !1, fullWidth: fullWidth = !1, block: block = !1, active: active = !1, selected: selected = !1, type: type = "button", className: className = "", as: Component = "button", href: href, target: target, glass: glass, onHover: onHover, onFocus: onFocus, onBlur: onBlur, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, tabIndex: tabIndex, style: style, LinkComponent: LinkComponent, ...props}, ref) => {
3255
3293
  const isDisabled = disabled || loading, shouldRenderAsLink = Boolean(href && !isDisabled), iconElement = iconName ? jsx(Icon, {
3256
3294
  name: iconName,
3257
3295
  size: iconSize
3258
- }) : icon;
3259
- // Determine if we should render as a link
3260
- const buttonClass = [ BUTTON.BASE_CLASS, ThemeNaming.variantClass("btn", variant), "md" !== size ? ThemeNaming.sizeClass("btn", size) : "", iconOnly ? ThemeNaming.stateClass("btn", "icon") : "", rounded ? ThemeNaming.stateClass("btn", "rounded") : "", isDisabled ? ThemeNaming.stateClass("btn", "disabled") : "", glass ? ThemeNaming.stateClass("btn", "glass") : "", loading ? BUTTON.CLASSES.LOADING : "", fullWidth ? BUTTON.CLASSES.FULL_WIDTH : "", block ? BUTTON.CLASSES.BLOCK : "", active ? BUTTON.CLASSES.ACTIVE : "", selected ? BUTTON.CLASSES.SELECTED : "", className ].filter(Boolean).join(" "), handleClickEvent = useCallback((event => {
3296
+ }) : icon, buttonClass = [ BUTTON.BASE_CLASS, ThemeNaming.variantClass("btn", variant), "md" !== size ? ThemeNaming.sizeClass("btn", size) : "", iconOnly ? ThemeNaming.stateClass("btn", "icon") : "", rounded ? ThemeNaming.stateClass("btn", "rounded") : "", isDisabled ? ThemeNaming.stateClass("btn", "disabled") : "", glass ? ThemeNaming.stateClass("btn", "glass") : "", loading ? BUTTON.CLASSES.LOADING : "", fullWidth ? BUTTON.CLASSES.FULL_WIDTH : "", block ? BUTTON.CLASSES.BLOCK : "", active ? BUTTON.CLASSES.ACTIVE : "", selected ? BUTTON.CLASSES.SELECTED : "", className ].filter(Boolean).join(" "), handleClickEvent = useCallback((event => {
3261
3297
  isDisabled ? event.preventDefault() : onClick?.(event);
3262
3298
  }), [ isDisabled, onClick ]), handleMouseEnter = useCallback((event => {
3263
3299
  isDisabled || onHover?.(event);
@@ -3265,7 +3301,7 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3265
3301
  isDisabled || onFocus?.(event);
3266
3302
  }), [ isDisabled, onFocus ]), handleBlurEvent = useCallback((event => {
3267
3303
  isDisabled || onBlur?.(event);
3268
- }), [ isDisabled, onBlur ]), buttonText = loading && loadingText ? loadingText : label || children, spinnerSize = "sm" === size ? "sm" : "lg" === size ? "md" : "sm", buttonContent = jsxs(Fragment, {
3304
+ }), [ isDisabled, onBlur ]), buttonText = loading && loadingText ? loadingText : label || children, spinnerSize = "sm" === size ? "sm" : "lg" === size ? "md" : "sm", safeAriaLabel = ariaLabel || (iconOnly ? "string" == typeof label ? label : "string" == typeof children ? children : void 0 : void 0), buttonContent = jsxs(Fragment, {
3269
3305
  children: [ loading && jsx("span", {
3270
3306
  className: ThemeNaming.bemClass("btn", "spinner"),
3271
3307
  "aria-hidden": "true",
@@ -3282,80 +3318,77 @@ const Button = React.memo( forwardRef((({label: label, children: children, onCl
3282
3318
  children: buttonText
3283
3319
  }) ]
3284
3320
  }), buttonProps = {
3285
- ref: ref,
3286
3321
  className: buttonClass,
3287
- type: "button" !== Component || shouldRenderAsLink ? void 0 : type,
3288
3322
  onClick: handleClickEvent,
3289
3323
  onMouseEnter: onHover ? handleMouseEnter : void 0,
3290
3324
  onFocus: onFocus ? handleFocusEvent : void 0,
3291
3325
  onBlur: onBlur ? handleBlurEvent : void 0,
3292
- disabled: isDisabled && "button" === Component && !shouldRenderAsLink,
3293
3326
  "aria-disabled": isDisabled,
3294
3327
  "aria-busy": loading,
3295
- "aria-label": ariaLabel || (iconOnly ? label || children : void 0),
3328
+ "aria-label": safeAriaLabel,
3296
3329
  "aria-describedby": ariaDescribedBy,
3297
3330
  "aria-expanded": ariaExpanded,
3298
3331
  "aria-controls": ariaControls,
3299
3332
  tabIndex: void 0 !== tabIndex ? tabIndex : isDisabled ? -1 : 0,
3300
3333
  style: style,
3301
3334
  ...props
3302
- }, defaultGlassProps = {
3303
- displacementScale: 20,
3304
- blurAmount: 0,
3305
- saturation: 200,
3306
- elasticity: 0
3307
- }, glassProps = !0 === glass ? defaultGlassProps : {
3308
- ...defaultGlassProps,
3309
- ...glass
3310
3335
  };
3311
- // Handle click with loading check
3312
- // Render as anchor if href is provided
3313
- if (shouldRenderAsLink) {
3314
- const {ref: _, ...buttonPropsWithoutRef} = buttonProps, anchorButtonProps = {
3315
- ...buttonPropsWithoutRef,
3316
- type: void 0,
3317
- disabled: void 0
3318
- };
3319
- // Use custom LinkComponent if provided (e.g., Next.js Link)
3320
- if (LinkComponent) {
3321
- const LinkComp = LinkComponent, linkProps = {
3322
- ...anchorButtonProps,
3323
- ref: ref,
3324
- href: href,
3325
- target: target,
3326
- rel: "_blank" === target ? "noopener noreferrer" : void 0
3327
- }, linkElement = jsx(LinkComp, {
3328
- ...linkProps,
3329
- children: buttonContent
3330
- });
3331
- return glass ? jsx(AtomixGlass, {
3332
- ...glassProps,
3333
- children: linkElement
3334
- }) : linkElement;
3335
- }
3336
- // Fallback to regular anchor tag
3337
- const anchorElement = jsx("a", {
3338
- ...anchorButtonProps,
3336
+ // Determine if we should render as a link
3337
+ // If disabled, we still check href, but we might want to render as button or anchor with aria-disabled
3338
+ // The previous logic was Boolean(href && !isDisabled). This meant if disabled, it renders as <button>.
3339
+ // This is a safe fallback for disabled links.
3340
+ let content;
3341
+ // Render as anchor if href is provided
3342
+ if (shouldRenderAsLink)
3343
+ // Use custom LinkComponent if provided (e.g., Next.js Link)
3344
+ if (LinkComponent) {
3345
+ const LinkComp = LinkComponent, linkProps = {
3346
+ ...buttonProps,
3339
3347
  ref: ref,
3348
+ // LinkComponent usually forwards ref to anchor
3340
3349
  href: href,
3341
3350
  target: target,
3342
- rel: "_blank" === target ? "noopener noreferrer" : void 0,
3351
+ rel: "_blank" === target ? "noopener noreferrer" : void 0
3352
+ };
3353
+ content = jsx(LinkComp, {
3354
+ ...linkProps,
3343
3355
  children: buttonContent
3344
3356
  });
3345
- return glass ? jsx(AtomixGlass, {
3346
- ...glassProps,
3347
- children: anchorElement
3348
- }) : anchorElement;
3349
- }
3357
+ } else
3358
+ // Fallback to regular anchor tag
3359
+ content = jsx("a", {
3360
+ ...buttonProps,
3361
+ ref: ref,
3362
+ href: href,
3363
+ target: target,
3364
+ rel: "_blank" === target ? "noopener noreferrer" : void 0,
3365
+ children: buttonContent
3366
+ }); else
3350
3367
  // Default button rendering
3351
- const buttonElement = jsx(Component, {
3368
+ content = jsx(Component, {
3352
3369
  ...buttonProps,
3370
+ ref: ref,
3371
+ type: "button" === Component ? type : void 0,
3372
+ disabled: isDisabled,
3353
3373
  children: buttonContent
3354
3374
  });
3355
- return glass ? jsx(AtomixGlass, {
3356
- ...glassProps,
3357
- children: buttonElement
3358
- }) : buttonElement;
3375
+ if (glass) {
3376
+ // Default glass props
3377
+ const defaultGlassProps = {
3378
+ displacementScale: 20,
3379
+ blurAmount: 0,
3380
+ saturation: 200,
3381
+ elasticity: 0
3382
+ }, glassProps = !0 === glass ? defaultGlassProps : {
3383
+ ...defaultGlassProps,
3384
+ ...glass
3385
+ };
3386
+ return jsx(AtomixGlass, {
3387
+ ...glassProps,
3388
+ children: content
3389
+ });
3390
+ }
3391
+ return content;
3359
3392
  })));
3360
3393
 
3361
3394
  Button.displayName = "Button";