@opensite/ui 2.8.8 → 2.9.0

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 (147) hide show
  1. package/dist/about-culture-tabs.cjs +174 -174
  2. package/dist/about-culture-tabs.js +174 -174
  3. package/dist/about-developer-profile.cjs +200 -200
  4. package/dist/about-developer-profile.js +198 -198
  5. package/dist/about-developer-story.cjs +142 -142
  6. package/dist/about-developer-story.js +142 -142
  7. package/dist/about-mission-dual-image.cjs +142 -142
  8. package/dist/about-mission-dual-image.js +142 -142
  9. package/dist/about-mission-features.cjs +142 -142
  10. package/dist/about-mission-features.js +142 -142
  11. package/dist/about-network-spotlight.cjs +142 -142
  12. package/dist/about-network-spotlight.js +142 -142
  13. package/dist/about-story-expertise.cjs +142 -142
  14. package/dist/about-story-expertise.js +142 -142
  15. package/dist/about-streamline-team.cjs +142 -142
  16. package/dist/about-streamline-team.js +142 -142
  17. package/dist/carousel-feature-badge.cjs +162 -42
  18. package/dist/carousel-feature-badge.d.cts +14 -1
  19. package/dist/carousel-feature-badge.d.ts +14 -1
  20. package/dist/carousel-feature-badge.js +163 -43
  21. package/dist/community-initiatives.cjs +142 -142
  22. package/dist/community-initiatives.js +142 -142
  23. package/dist/components.cjs +723 -1378
  24. package/dist/components.d.cts +0 -2
  25. package/dist/components.d.ts +0 -2
  26. package/dist/components.js +633 -1287
  27. package/dist/contact-map.cjs +14 -1083
  28. package/dist/contact-map.d.cts +13 -3
  29. package/dist/contact-map.d.ts +13 -3
  30. package/dist/contact-map.js +14 -1083
  31. package/dist/cta-feature-checklist.cjs +142 -142
  32. package/dist/cta-feature-checklist.js +142 -142
  33. package/dist/faq-numbered-grid.cjs +142 -142
  34. package/dist/faq-numbered-grid.js +142 -142
  35. package/dist/feature-animated-carousel.cjs +142 -142
  36. package/dist/feature-animated-carousel.js +142 -142
  37. package/dist/feature-bento-utilities.cjs +142 -142
  38. package/dist/feature-bento-utilities.js +142 -142
  39. package/dist/feature-capabilities-grid.cjs +142 -142
  40. package/dist/feature-capabilities-grid.js +142 -142
  41. package/dist/feature-category-image-cards.cjs +142 -142
  42. package/dist/feature-category-image-cards.js +142 -142
  43. package/dist/feature-icon-grid-bordered.cjs +142 -142
  44. package/dist/feature-icon-grid-bordered.js +142 -142
  45. package/dist/feature-icon-grid-muted.cjs +142 -142
  46. package/dist/feature-icon-grid-muted.js +142 -142
  47. package/dist/feature-numbered-cards.cjs +142 -142
  48. package/dist/feature-numbered-cards.js +142 -142
  49. package/dist/feature-three-column-values.cjs +142 -142
  50. package/dist/feature-three-column-values.js +142 -142
  51. package/dist/hero-ad-campaign-expert.cjs +142 -142
  52. package/dist/hero-ad-campaign-expert.js +142 -142
  53. package/dist/hero-adaptable-product-grid.cjs +142 -142
  54. package/dist/hero-adaptable-product-grid.js +142 -142
  55. package/dist/hero-agency-animated-images.cjs +142 -142
  56. package/dist/hero-agency-animated-images.js +142 -142
  57. package/dist/hero-announcement-badge.cjs +142 -142
  58. package/dist/hero-announcement-badge.js +142 -142
  59. package/dist/hero-badge-image-split.cjs +142 -142
  60. package/dist/hero-badge-image-split.js +142 -142
  61. package/dist/hero-business-carousel-dots.cjs +142 -142
  62. package/dist/hero-business-carousel-dots.js +142 -142
  63. package/dist/hero-business-operations-mosaic.cjs +142 -142
  64. package/dist/hero-business-operations-mosaic.js +142 -142
  65. package/dist/hero-conversation-intelligence.cjs +142 -142
  66. package/dist/hero-conversation-intelligence.js +142 -142
  67. package/dist/hero-creative-studio-stacked.cjs +142 -142
  68. package/dist/hero-creative-studio-stacked.js +142 -142
  69. package/dist/hero-crm-streamlined.cjs +142 -142
  70. package/dist/hero-crm-streamlined.js +142 -142
  71. package/dist/hero-customer-support-layered.cjs +142 -142
  72. package/dist/hero-customer-support-layered.js +142 -142
  73. package/dist/hero-design-showcase-logos.cjs +142 -142
  74. package/dist/hero-design-showcase-logos.js +142 -142
  75. package/dist/hero-design-system-3d.cjs +142 -142
  76. package/dist/hero-design-system-3d.js +142 -142
  77. package/dist/hero-developer-tools-code.cjs +142 -142
  78. package/dist/hero-developer-tools-code.js +142 -142
  79. package/dist/hero-digital-agency-fullscreen.cjs +142 -142
  80. package/dist/hero-digital-agency-fullscreen.js +142 -142
  81. package/dist/hero-ecommerce-product-showcase.cjs +174 -174
  82. package/dist/hero-ecommerce-product-showcase.js +174 -174
  83. package/dist/hero-event-registration.cjs +142 -142
  84. package/dist/hero-event-registration.js +142 -142
  85. package/dist/hero-fullscreen-background-image.cjs +142 -142
  86. package/dist/hero-fullscreen-background-image.js +142 -142
  87. package/dist/hero-gradient-avatars-rating.cjs +142 -142
  88. package/dist/hero-gradient-avatars-rating.js +142 -142
  89. package/dist/hero-gradient-client-focused.cjs +142 -142
  90. package/dist/hero-gradient-client-focused.js +142 -142
  91. package/dist/hero-hiring-animated-text.cjs +142 -142
  92. package/dist/hero-hiring-animated-text.js +142 -142
  93. package/dist/hero-image-left-content.cjs +142 -142
  94. package/dist/hero-image-left-content.js +142 -142
  95. package/dist/hero-innovation-image-grid.cjs +142 -142
  96. package/dist/hero-innovation-image-grid.js +142 -142
  97. package/dist/hero-mental-health-team.cjs +142 -142
  98. package/dist/hero-mental-health-team.js +142 -142
  99. package/dist/hero-minimal-centered-dark.cjs +174 -174
  100. package/dist/hero-minimal-centered-dark.js +174 -174
  101. package/dist/hero-presentation-platform-video.cjs +142 -142
  102. package/dist/hero-presentation-platform-video.js +142 -142
  103. package/dist/hero-product-showcase-floating.cjs +174 -174
  104. package/dist/hero-product-showcase-floating.js +174 -174
  105. package/dist/hero-shared-inbox-layered.cjs +142 -142
  106. package/dist/hero-shared-inbox-layered.js +142 -142
  107. package/dist/hero-software-growth-video-dialog.cjs +142 -142
  108. package/dist/hero-software-growth-video-dialog.js +142 -142
  109. package/dist/hero-spiral-pattern-cards.cjs +174 -174
  110. package/dist/hero-spiral-pattern-cards.js +174 -174
  111. package/dist/hero-split-geometric-shapes.cjs +142 -142
  112. package/dist/hero-split-geometric-shapes.js +142 -142
  113. package/dist/hero-startup-launch-cta.cjs +174 -174
  114. package/dist/hero-startup-launch-cta.js +174 -174
  115. package/dist/hero-stats-social-proof.cjs +174 -174
  116. package/dist/hero-stats-social-proof.js +174 -174
  117. package/dist/hero-task-timer-animated.cjs +142 -142
  118. package/dist/hero-task-timer-animated.js +142 -142
  119. package/dist/hero-testimonial-image-grid.cjs +142 -142
  120. package/dist/hero-testimonial-image-grid.js +142 -142
  121. package/dist/hero-therapy-testimonial-grid.cjs +142 -142
  122. package/dist/hero-therapy-testimonial-grid.js +142 -142
  123. package/dist/hero-ui-library-showcase.cjs +142 -142
  124. package/dist/hero-ui-library-showcase.js +142 -142
  125. package/dist/hero-video-background-dark.cjs +174 -174
  126. package/dist/hero-video-background-dark.js +174 -174
  127. package/dist/hero-video-dialog-gradient.cjs +142 -142
  128. package/dist/hero-video-dialog-gradient.js +142 -142
  129. package/dist/hero-video-overlay-stars.cjs +142 -142
  130. package/dist/hero-video-overlay-stars.js +142 -142
  131. package/dist/hero-welcome-asymmetric-images.cjs +142 -142
  132. package/dist/hero-welcome-asymmetric-images.js +142 -142
  133. package/dist/index.cjs +725 -1380
  134. package/dist/index.d.cts +0 -2
  135. package/dist/index.d.ts +0 -2
  136. package/dist/index.js +634 -1288
  137. package/dist/registry.cjs +2201 -2827
  138. package/dist/registry.js +948 -1574
  139. package/dist/testimonials-masonry-grid.cjs +142 -142
  140. package/dist/testimonials-masonry-grid.js +142 -142
  141. package/dist/testimonials-stats-header.cjs +159 -159
  142. package/dist/testimonials-stats-header.js +159 -159
  143. package/package.json +4 -7
  144. package/dist/geo-map.cjs +0 -1117
  145. package/dist/geo-map.d.cts +0 -92
  146. package/dist/geo-map.d.ts +0 -92
  147. package/dist/geo-map.js +0 -1095
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import * as React6 from 'react';
3
- import React6__default from 'react';
2
+ import * as React8 from 'react';
3
+ import React8__default from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import { cva } from 'class-variance-authority';
8
- import { jsx, jsxs } from 'react/jsx-runtime';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
9
  import { Icon } from '@page-speed/icon';
10
10
  import { Img } from '@page-speed/img';
11
11
  import useEmblaCarousel from 'embla-carousel-react';
@@ -121,7 +121,7 @@ function useNavigation({
121
121
  href,
122
122
  onClick
123
123
  } = {}) {
124
- const linkType = React6.useMemo(() => {
124
+ const linkType = React8.useMemo(() => {
125
125
  if (!href || href.trim() === "") {
126
126
  return onClick ? "none" : "none";
127
127
  }
@@ -142,7 +142,7 @@ function useNavigation({
142
142
  return "internal";
143
143
  }
144
144
  }, [href, onClick]);
145
- const normalizedHref = React6.useMemo(() => {
145
+ const normalizedHref = React8.useMemo(() => {
146
146
  if (!href || href.trim() === "") {
147
147
  return void 0;
148
148
  }
@@ -160,7 +160,7 @@ function useNavigation({
160
160
  return trimmed;
161
161
  }
162
162
  }, [href, linkType]);
163
- const target = React6.useMemo(() => {
163
+ const target = React8.useMemo(() => {
164
164
  switch (linkType) {
165
165
  case "external":
166
166
  return "_blank";
@@ -173,7 +173,7 @@ function useNavigation({
173
173
  return void 0;
174
174
  }
175
175
  }, [linkType]);
176
- const rel = React6.useMemo(() => {
176
+ const rel = React8.useMemo(() => {
177
177
  if (linkType === "external") {
178
178
  return "noopener noreferrer";
179
179
  }
@@ -182,7 +182,7 @@ function useNavigation({
182
182
  const isExternal = linkType === "external";
183
183
  const isInternal = linkType === "internal";
184
184
  const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
185
- const handleClick = React6.useCallback(
185
+ const handleClick = React8.useCallback(
186
186
  (event) => {
187
187
  if (onClick) {
188
188
  try {
@@ -366,7 +366,7 @@ var buttonVariants = cva(baseStyles, {
366
366
  size: "default"
367
367
  }
368
368
  });
369
- var Pressable = React6.forwardRef(
369
+ var Pressable = React8.forwardRef(
370
370
  ({
371
371
  children,
372
372
  className,
@@ -465,7 +465,7 @@ var Pressable = React6.forwardRef(
465
465
  );
466
466
  Pressable.displayName = "Pressable";
467
467
  var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
468
- var DynamicIcon = React6.memo(function DynamicIcon2({
468
+ var DynamicIcon = React8.memo(function DynamicIcon2({
469
469
  apiKey,
470
470
  ...props
471
471
  }) {
@@ -539,7 +539,7 @@ var maxWidthStyles = {
539
539
  "4xl": "max-w-[1536px]",
540
540
  full: "max-w-full"
541
541
  };
542
- var Container = React6__default.forwardRef(
542
+ var Container = React8__default.forwardRef(
543
543
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
544
544
  const Component = as;
545
545
  return /* @__PURE__ */ jsx(
@@ -845,7 +845,7 @@ var spacingStyles = {
845
845
  };
846
846
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl", "hero"];
847
847
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
848
- var Section = React6__default.forwardRef(
848
+ var Section = React8__default.forwardRef(
849
849
  ({
850
850
  id,
851
851
  title,
@@ -906,6 +906,102 @@ var Section = React6__default.forwardRef(
906
906
  }
907
907
  );
908
908
  Section.displayName = "Section";
909
+ function TextInner({ as, className, children, ...props }, ref) {
910
+ const Component = as || "span";
911
+ return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
912
+ }
913
+ var Text = React8.forwardRef(TextInner);
914
+ Text.displayName = "Text";
915
+ function isContentTextItem(item) {
916
+ return item !== null && typeof item === "object" && !React8.isValidElement(item) && "_type" in item && item._type === "text";
917
+ }
918
+ var ContentGroup = React8.forwardRef(
919
+ ({ items, className, children, ...props }, ref) => {
920
+ const hasContent = items && items.length > 0;
921
+ if (!hasContent) {
922
+ return null;
923
+ }
924
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn(className), ...props, children: [
925
+ items.map((item, idx) => {
926
+ if (isContentTextItem(item)) {
927
+ const { _type, ...textProps } = item;
928
+ return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
929
+ }
930
+ const reactNode = item;
931
+ if (React8.isValidElement(reactNode)) {
932
+ return React8.cloneElement(reactNode, { key: reactNode.key ?? idx });
933
+ }
934
+ return /* @__PURE__ */ jsx(React8.Fragment, { children: reactNode }, idx);
935
+ }),
936
+ children
937
+ ] });
938
+ }
939
+ );
940
+ ContentGroup.displayName = "ContentGroup";
941
+ var MOBILE_CLASSES = {
942
+ "fit-left": "items-start md:items-center",
943
+ "fit-center": "items-center",
944
+ "fit-right": "items-end md:items-center",
945
+ "full-left": "items-stretch md:items-center",
946
+ "full-center": "items-stretch md:items-center",
947
+ "full-right": "items-stretch md:items-center"
948
+ };
949
+ function BlockActions({
950
+ mobileConfig,
951
+ actionsClassName,
952
+ verticalSpacing = "mt-4 md:mt-8",
953
+ actions,
954
+ actionsSlot
955
+ }) {
956
+ const width = mobileConfig?.width ?? "full";
957
+ const position = mobileConfig?.position ?? "center";
958
+ const mobileLayoutClass = MOBILE_CLASSES[`${width}-${position}`];
959
+ if (actionsSlot) {
960
+ return /* @__PURE__ */ jsx("div", { children: actionsSlot });
961
+ } else if (actions && actions?.length > 0) {
962
+ return /* @__PURE__ */ jsx(
963
+ "div",
964
+ {
965
+ className: cn(
966
+ "flex flex-col md:flex-row flex-wrap gap-4",
967
+ mobileLayoutClass,
968
+ actionsClassName,
969
+ verticalSpacing
970
+ ),
971
+ children: actions.map((action, index) => /* @__PURE__ */ jsx(ActionComponent, { action }, index))
972
+ }
973
+ );
974
+ } else {
975
+ return null;
976
+ }
977
+ }
978
+ function ActionComponent({ action }) {
979
+ const {
980
+ label,
981
+ icon,
982
+ iconAfter,
983
+ children,
984
+ href,
985
+ onClick,
986
+ className: actionClassName,
987
+ ...pressableProps
988
+ } = action;
989
+ return /* @__PURE__ */ jsx(
990
+ Pressable,
991
+ {
992
+ href,
993
+ onClick,
994
+ asButton: action.asButton ?? true,
995
+ className: actionClassName,
996
+ ...pressableProps,
997
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
998
+ icon,
999
+ label,
1000
+ iconAfter
1001
+ ] })
1002
+ }
1003
+ );
1004
+ }
909
1005
  var SLIDE_LAYOUT_ASPECT_MAP = {
910
1006
  horizontal: "aspect-video",
911
1007
  vertical: "aspect-[9/16]",
@@ -926,28 +1022,31 @@ function CarouselFeatureBadge({
926
1022
  carouselClassName,
927
1023
  carouselItemClassName,
928
1024
  optixFlowConfig,
1025
+ actions,
1026
+ actionsSlot,
1027
+ actionsClassName,
929
1028
  background,
930
- spacing,
1029
+ spacing = "none",
931
1030
  pattern,
932
1031
  patternOpacity,
933
1032
  slideLayoutVariant = "square",
934
1033
  containerMaxWidth = "2xl"
935
1034
  }) {
936
1035
  const [emblaRef, emblaApi] = useEmblaCarousel();
937
- const [canScrollPrev, setCanScrollPrev] = React6.useState(false);
938
- const [canScrollNext, setCanScrollNext] = React6.useState(false);
939
- const scrollPrev = React6.useCallback(() => {
1036
+ const [canScrollPrev, setCanScrollPrev] = React8.useState(false);
1037
+ const [canScrollNext, setCanScrollNext] = React8.useState(false);
1038
+ const scrollPrev = React8.useCallback(() => {
940
1039
  emblaApi?.scrollPrev();
941
1040
  }, [emblaApi]);
942
- const scrollNext = React6.useCallback(() => {
1041
+ const scrollNext = React8.useCallback(() => {
943
1042
  emblaApi?.scrollNext();
944
1043
  }, [emblaApi]);
945
- const onSelect = React6.useCallback(() => {
1044
+ const onSelect = React8.useCallback(() => {
946
1045
  if (!emblaApi) return;
947
1046
  setCanScrollPrev(emblaApi.canScrollPrev());
948
1047
  setCanScrollNext(emblaApi.canScrollNext());
949
1048
  }, [emblaApi]);
950
- React6.useEffect(() => {
1049
+ React8.useEffect(() => {
951
1050
  if (!emblaApi) return;
952
1051
  onSelect();
953
1052
  emblaApi.on("reInit", onSelect);
@@ -990,12 +1089,46 @@ function CarouselFeatureBadge({
990
1089
  index
991
1090
  ));
992
1091
  };
1092
+ const headerItems = React8.useMemo(() => {
1093
+ const items2 = [];
1094
+ if (heading) {
1095
+ if (typeof heading === "string") {
1096
+ items2.push({
1097
+ _type: "text",
1098
+ as: "h2",
1099
+ className: cn(
1100
+ "text-left text-2xl font-semibold md:text-4xl lg:max-w-xl lg:text-6xl text-pretty",
1101
+ headingClassName
1102
+ ),
1103
+ children: heading
1104
+ });
1105
+ } else {
1106
+ items2.push(heading);
1107
+ }
1108
+ }
1109
+ if (description) {
1110
+ if (typeof description === "string") {
1111
+ items2.push({
1112
+ _type: "text",
1113
+ as: "p",
1114
+ className: cn(
1115
+ "max-w-full text-left text-lg leading-snug lg:max-w-sm text-balance text-lg",
1116
+ descriptionClassName
1117
+ ),
1118
+ children: description
1119
+ });
1120
+ } else {
1121
+ items2.push(description);
1122
+ }
1123
+ }
1124
+ return items2;
1125
+ }, [heading, headingClassName, description, descriptionClassName]);
993
1126
  return /* @__PURE__ */ jsx(
994
1127
  Section,
995
1128
  {
996
1129
  background,
997
1130
  spacing,
998
- className: cn(className),
1131
+ className,
999
1132
  pattern,
1000
1133
  patternOpacity,
1001
1134
  containerMaxWidth,
@@ -1005,29 +1138,16 @@ function CarouselFeatureBadge({
1005
1138
  {
1006
1139
  className: cn("flex flex-col items-start gap-4", contentClassName),
1007
1140
  children: [
1008
- badge && /* @__PURE__ */ jsx("div", { className: badgeClassName, children: typeof badge === "string" ? /* @__PURE__ */ jsx(Badge, { children: badge }) : badge }),
1009
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
1010
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
1011
- "h2",
1012
- {
1013
- className: cn(
1014
- "text-left text-xl font-semibold md:text-3xl lg:max-w-xl lg:text-4xl",
1015
- headingClassName
1016
- ),
1017
- children: heading
1018
- }
1019
- ) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
1020
- description && (typeof description === "string" ? /* @__PURE__ */ jsx(
1021
- "p",
1022
- {
1023
- className: cn(
1024
- "max-w-xl text-left text-lg leading-snug lg:max-w-sm",
1025
- descriptionClassName
1026
- ),
1027
- children: description
1028
- }
1029
- ) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
1030
- ] })
1141
+ badge && (typeof badge === "string" ? /* @__PURE__ */ jsx(Badge, { className: badgeClassName, children: badge }) : badge),
1142
+ /* @__PURE__ */ jsx(ContentGroup, { items: headerItems, className: "flex flex-col gap-2" }),
1143
+ /* @__PURE__ */ jsx(
1144
+ BlockActions,
1145
+ {
1146
+ actions,
1147
+ actionsSlot,
1148
+ actionsClassName
1149
+ }
1150
+ )
1031
1151
  ]
1032
1152
  }
1033
1153
  ),
@@ -533,6 +533,148 @@ var Section = React4__namespace.default.forwardRef(
533
533
  }
534
534
  );
535
535
  Section.displayName = "Section";
536
+ var baseStyles = [
537
+ // Layout
538
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
539
+ // Typography - using CSS variables with sensible defaults
540
+ "font-[var(--button-font-family,inherit)]",
541
+ "font-[var(--button-font-weight,500)]",
542
+ "tracking-[var(--button-letter-spacing,0)]",
543
+ "leading-[var(--button-line-height,1.25)]",
544
+ "[text-transform:var(--button-text-transform,none)]",
545
+ "text-sm",
546
+ // Border radius
547
+ "rounded-[var(--button-radius,var(--radius,0.375rem))]",
548
+ // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
549
+ "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
550
+ // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
551
+ "[box-shadow:var(--button-shadow,none)]",
552
+ "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
553
+ // Disabled state
554
+ "disabled:pointer-events-none disabled:opacity-50",
555
+ // SVG handling
556
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
557
+ // Focus styles
558
+ "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
559
+ // Invalid state
560
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
561
+ ].join(" ");
562
+ var buttonVariants = classVarianceAuthority.cva(baseStyles, {
563
+ variants: {
564
+ variant: {
565
+ // Default (Primary) variant - full customization
566
+ default: [
567
+ "bg-[var(--button-default-bg,hsl(var(--primary)))]",
568
+ "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
569
+ "border-[length:var(--button-default-border-width,0px)]",
570
+ "border-[color:var(--button-default-border,transparent)]",
571
+ "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
572
+ "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
573
+ "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
574
+ "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
575
+ "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
576
+ ].join(" "),
577
+ // Destructive variant - full customization
578
+ destructive: [
579
+ "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
580
+ "text-[var(--button-destructive-fg,white)]",
581
+ "border-[length:var(--button-destructive-border-width,0px)]",
582
+ "border-[color:var(--button-destructive-border,transparent)]",
583
+ "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
584
+ "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
585
+ "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
586
+ "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
587
+ "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
588
+ "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
589
+ "dark:bg-destructive/60"
590
+ ].join(" "),
591
+ // Outline variant - full customization with proper border handling
592
+ outline: [
593
+ "bg-[var(--button-outline-bg,hsl(var(--background)))]",
594
+ "text-[var(--button-outline-fg,inherit)]",
595
+ "border-[length:var(--button-outline-border-width,1px)]",
596
+ "border-[color:var(--button-outline-border,hsl(var(--border)))]",
597
+ "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
598
+ "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
599
+ "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
600
+ "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
601
+ "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
602
+ "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
603
+ ].join(" "),
604
+ // Secondary variant - full customization
605
+ secondary: [
606
+ "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
607
+ "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
608
+ "border-[length:var(--button-secondary-border-width,0px)]",
609
+ "border-[color:var(--button-secondary-border,transparent)]",
610
+ "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
611
+ "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
612
+ "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
613
+ "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
614
+ "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
615
+ ].join(" "),
616
+ // Ghost variant - full customization
617
+ ghost: [
618
+ "bg-[var(--button-ghost-bg,transparent)]",
619
+ "text-[var(--button-ghost-fg,inherit)]",
620
+ "border-[length:var(--button-ghost-border-width,0px)]",
621
+ "border-[color:var(--button-ghost-border,transparent)]",
622
+ "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
623
+ "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
624
+ "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
625
+ "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
626
+ "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
627
+ "dark:hover:bg-accent/50"
628
+ ].join(" "),
629
+ // Link variant - full customization
630
+ link: [
631
+ "bg-[var(--button-link-bg,transparent)]",
632
+ "text-[var(--button-link-fg,hsl(var(--primary)))]",
633
+ "border-[length:var(--button-link-border-width,0px)]",
634
+ "border-[color:var(--button-link-border,transparent)]",
635
+ "[box-shadow:var(--button-link-shadow,none)]",
636
+ "hover:bg-[var(--button-link-hover-bg,transparent)]",
637
+ "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
638
+ "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
639
+ "underline-offset-4 hover:underline"
640
+ ].join(" ")
641
+ },
642
+ size: {
643
+ default: [
644
+ "h-[var(--button-height-md,2.25rem)]",
645
+ "px-[var(--button-padding-x-md,1rem)]",
646
+ "py-[var(--button-padding-y-md,0.5rem)]",
647
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
648
+ ].join(" "),
649
+ sm: [
650
+ "h-[var(--button-height-sm,2rem)]",
651
+ "px-[var(--button-padding-x-sm,0.75rem)]",
652
+ "py-[var(--button-padding-y-sm,0.25rem)]",
653
+ "gap-1.5",
654
+ "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
655
+ ].join(" "),
656
+ md: [
657
+ "h-[var(--button-height-md,2.25rem)]",
658
+ "px-[var(--button-padding-x-md,1rem)]",
659
+ "py-[var(--button-padding-y-md,0.5rem)]",
660
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
661
+ ].join(" "),
662
+ lg: [
663
+ "h-[var(--button-height-lg,2.5rem)]",
664
+ "px-[var(--button-padding-x-lg,1.5rem)]",
665
+ "py-[var(--button-padding-y-lg,0.5rem)]",
666
+ "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
667
+ ].join(" "),
668
+ icon: "size-[var(--button-height-md,2.25rem)]",
669
+ "icon-sm": "size-[var(--button-height-sm,2rem)]",
670
+ "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
671
+ }
672
+ },
673
+ defaultVariants: {
674
+ variant: "default",
675
+ size: "default"
676
+ }
677
+ });
536
678
  function normalizePhoneNumber(input) {
537
679
  const trimmed = input.trim();
538
680
  if (trimmed.toLowerCase().startsWith("tel:")) {
@@ -711,148 +853,6 @@ function useNavigation({
711
853
  handleClick
712
854
  };
713
855
  }
714
- var baseStyles = [
715
- // Layout
716
- "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
717
- // Typography - using CSS variables with sensible defaults
718
- "font-[var(--button-font-family,inherit)]",
719
- "font-[var(--button-font-weight,500)]",
720
- "tracking-[var(--button-letter-spacing,0)]",
721
- "leading-[var(--button-line-height,1.25)]",
722
- "[text-transform:var(--button-text-transform,none)]",
723
- "text-sm",
724
- // Border radius
725
- "rounded-[var(--button-radius,var(--radius,0.375rem))]",
726
- // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
727
- "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
728
- // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
729
- "[box-shadow:var(--button-shadow,none)]",
730
- "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
731
- // Disabled state
732
- "disabled:pointer-events-none disabled:opacity-50",
733
- // SVG handling
734
- "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
735
- // Focus styles
736
- "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
737
- // Invalid state
738
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
739
- ].join(" ");
740
- var buttonVariants = classVarianceAuthority.cva(baseStyles, {
741
- variants: {
742
- variant: {
743
- // Default (Primary) variant - full customization
744
- default: [
745
- "bg-[var(--button-default-bg,hsl(var(--primary)))]",
746
- "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
747
- "border-[length:var(--button-default-border-width,0px)]",
748
- "border-[color:var(--button-default-border,transparent)]",
749
- "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
750
- "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
751
- "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
752
- "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
753
- "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
754
- ].join(" "),
755
- // Destructive variant - full customization
756
- destructive: [
757
- "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
758
- "text-[var(--button-destructive-fg,white)]",
759
- "border-[length:var(--button-destructive-border-width,0px)]",
760
- "border-[color:var(--button-destructive-border,transparent)]",
761
- "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
762
- "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
763
- "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
764
- "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
765
- "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
766
- "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
767
- "dark:bg-destructive/60"
768
- ].join(" "),
769
- // Outline variant - full customization with proper border handling
770
- outline: [
771
- "bg-[var(--button-outline-bg,hsl(var(--background)))]",
772
- "text-[var(--button-outline-fg,inherit)]",
773
- "border-[length:var(--button-outline-border-width,1px)]",
774
- "border-[color:var(--button-outline-border,hsl(var(--border)))]",
775
- "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
776
- "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
777
- "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
778
- "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
779
- "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
780
- "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
781
- ].join(" "),
782
- // Secondary variant - full customization
783
- secondary: [
784
- "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
785
- "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
786
- "border-[length:var(--button-secondary-border-width,0px)]",
787
- "border-[color:var(--button-secondary-border,transparent)]",
788
- "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
789
- "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
790
- "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
791
- "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
792
- "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
793
- ].join(" "),
794
- // Ghost variant - full customization
795
- ghost: [
796
- "bg-[var(--button-ghost-bg,transparent)]",
797
- "text-[var(--button-ghost-fg,inherit)]",
798
- "border-[length:var(--button-ghost-border-width,0px)]",
799
- "border-[color:var(--button-ghost-border,transparent)]",
800
- "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
801
- "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
802
- "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
803
- "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
804
- "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
805
- "dark:hover:bg-accent/50"
806
- ].join(" "),
807
- // Link variant - full customization
808
- link: [
809
- "bg-[var(--button-link-bg,transparent)]",
810
- "text-[var(--button-link-fg,hsl(var(--primary)))]",
811
- "border-[length:var(--button-link-border-width,0px)]",
812
- "border-[color:var(--button-link-border,transparent)]",
813
- "[box-shadow:var(--button-link-shadow,none)]",
814
- "hover:bg-[var(--button-link-hover-bg,transparent)]",
815
- "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
816
- "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
817
- "underline-offset-4 hover:underline"
818
- ].join(" ")
819
- },
820
- size: {
821
- default: [
822
- "h-[var(--button-height-md,2.25rem)]",
823
- "px-[var(--button-padding-x-md,1rem)]",
824
- "py-[var(--button-padding-y-md,0.5rem)]",
825
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
826
- ].join(" "),
827
- sm: [
828
- "h-[var(--button-height-sm,2rem)]",
829
- "px-[var(--button-padding-x-sm,0.75rem)]",
830
- "py-[var(--button-padding-y-sm,0.25rem)]",
831
- "gap-1.5",
832
- "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
833
- ].join(" "),
834
- md: [
835
- "h-[var(--button-height-md,2.25rem)]",
836
- "px-[var(--button-padding-x-md,1rem)]",
837
- "py-[var(--button-padding-y-md,0.5rem)]",
838
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
839
- ].join(" "),
840
- lg: [
841
- "h-[var(--button-height-lg,2.5rem)]",
842
- "px-[var(--button-padding-x-lg,1.5rem)]",
843
- "py-[var(--button-padding-y-lg,0.5rem)]",
844
- "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
845
- ].join(" "),
846
- icon: "size-[var(--button-height-md,2.25rem)]",
847
- "icon-sm": "size-[var(--button-height-sm,2rem)]",
848
- "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
849
- }
850
- },
851
- defaultVariants: {
852
- variant: "default",
853
- size: "default"
854
- }
855
- });
856
856
  var Pressable = React4__namespace.forwardRef(
857
857
  ({
858
858
  children,