@opensite/ui 0.7.7 → 0.7.8

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.
@@ -32,6 +32,16 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
32
32
  function cn(...inputs) {
33
33
  return tailwindMerge.twMerge(clsx.clsx(inputs));
34
34
  }
35
+ var BRIGHTNESS_CLASS_MAP = {
36
+ "10": "brightness-[.1]",
37
+ "20": "brightness-[.2]",
38
+ "25": "brightness-[.25]",
39
+ "30": "brightness-[.3]",
40
+ "40": "brightness-[.4]",
41
+ "50": "brightness-50",
42
+ "75": "brightness-75",
43
+ "100": "brightness-100"
44
+ };
35
45
  function normalizePhoneNumber(input) {
36
46
  const trimmed = input.trim();
37
47
  if (trimmed.toLowerCase().startsWith("tel:")) {
@@ -947,7 +957,8 @@ function CarouselGalleryThumbnails({
947
957
  background = "white",
948
958
  spacing = "xl",
949
959
  pattern,
950
- patternOpacity
960
+ patternOpacity,
961
+ slideMediaBrightness = "50"
951
962
  }) {
952
963
  const [currentIndex, setCurrentIndex] = React__namespace.useState(0);
953
964
  const prevSlide = React__namespace.useCallback(() => {
@@ -1001,7 +1012,11 @@ function CarouselGalleryThumbnails({
1001
1012
  {
1002
1013
  src: image.src,
1003
1014
  alt: typeof image.alt === "string" ? image.alt : `Image ${index + 1}`,
1004
- className: cn("h-full w-full object-cover", image.imageClassName),
1015
+ className: cn(
1016
+ "h-full w-full object-cover",
1017
+ BRIGHTNESS_CLASS_MAP[slideMediaBrightness],
1018
+ image.imageClassName
1019
+ ),
1005
1020
  optixFlowConfig
1006
1021
  }
1007
1022
  )
@@ -116,7 +116,11 @@ interface CarouselGalleryThumbnailsProps {
116
116
  * Pattern overlay opacity (0-1)
117
117
  */
118
118
  patternOpacity?: number;
119
+ /**
120
+ * Brightness level for slide images (controls overlay visibility)
121
+ */
122
+ slideMediaBrightness?: "10" | "20" | "25" | "30" | "40" | "50" | "75" | "100";
119
123
  }
120
- declare function CarouselGalleryThumbnails({ images, imagesSlot, autoPlay, autoPlayInterval, showThumbnails, className, containerClassName, slideClassName, navigationClassName, captionClassName, thumbnailsClassName, thumbnailClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, }: CarouselGalleryThumbnailsProps): React.JSX.Element;
124
+ declare function CarouselGalleryThumbnails({ images, imagesSlot, autoPlay, autoPlayInterval, showThumbnails, className, containerClassName, slideClassName, navigationClassName, captionClassName, thumbnailsClassName, thumbnailClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, slideMediaBrightness, }: CarouselGalleryThumbnailsProps): React.JSX.Element;
121
125
 
122
126
  export { CarouselGalleryThumbnails, type CarouselGalleryThumbnailsProps, type GalleryImage };
@@ -116,7 +116,11 @@ interface CarouselGalleryThumbnailsProps {
116
116
  * Pattern overlay opacity (0-1)
117
117
  */
118
118
  patternOpacity?: number;
119
+ /**
120
+ * Brightness level for slide images (controls overlay visibility)
121
+ */
122
+ slideMediaBrightness?: "10" | "20" | "25" | "30" | "40" | "50" | "75" | "100";
119
123
  }
120
- declare function CarouselGalleryThumbnails({ images, imagesSlot, autoPlay, autoPlayInterval, showThumbnails, className, containerClassName, slideClassName, navigationClassName, captionClassName, thumbnailsClassName, thumbnailClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, }: CarouselGalleryThumbnailsProps): React.JSX.Element;
124
+ declare function CarouselGalleryThumbnails({ images, imagesSlot, autoPlay, autoPlayInterval, showThumbnails, className, containerClassName, slideClassName, navigationClassName, captionClassName, thumbnailsClassName, thumbnailClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, slideMediaBrightness, }: CarouselGalleryThumbnailsProps): React.JSX.Element;
121
125
 
122
126
  export { CarouselGalleryThumbnails, type CarouselGalleryThumbnailsProps, type GalleryImage };
@@ -11,6 +11,16 @@ import { Img } from '@page-speed/img';
11
11
  function cn(...inputs) {
12
12
  return twMerge(clsx(inputs));
13
13
  }
14
+ var BRIGHTNESS_CLASS_MAP = {
15
+ "10": "brightness-[.1]",
16
+ "20": "brightness-[.2]",
17
+ "25": "brightness-[.25]",
18
+ "30": "brightness-[.3]",
19
+ "40": "brightness-[.4]",
20
+ "50": "brightness-50",
21
+ "75": "brightness-75",
22
+ "100": "brightness-100"
23
+ };
14
24
  function normalizePhoneNumber(input) {
15
25
  const trimmed = input.trim();
16
26
  if (trimmed.toLowerCase().startsWith("tel:")) {
@@ -926,7 +936,8 @@ function CarouselGalleryThumbnails({
926
936
  background = "white",
927
937
  spacing = "xl",
928
938
  pattern,
929
- patternOpacity
939
+ patternOpacity,
940
+ slideMediaBrightness = "50"
930
941
  }) {
931
942
  const [currentIndex, setCurrentIndex] = React.useState(0);
932
943
  const prevSlide = React.useCallback(() => {
@@ -980,7 +991,11 @@ function CarouselGalleryThumbnails({
980
991
  {
981
992
  src: image.src,
982
993
  alt: typeof image.alt === "string" ? image.alt : `Image ${index + 1}`,
983
- className: cn("h-full w-full object-cover", image.imageClassName),
994
+ className: cn(
995
+ "h-full w-full object-cover",
996
+ BRIGHTNESS_CLASS_MAP[slideMediaBrightness],
997
+ image.imageClassName
998
+ ),
984
999
  optixFlowConfig
985
1000
  }
986
1001
  )
@@ -988,7 +988,7 @@ function CarouselHorizontalCards({
988
988
  return items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
989
989
  framerMotion.motion.div,
990
990
  {
991
- className: cn("group w-[280px] shrink-0", item.className),
991
+ className: cn("group w-[320px] shrink-0 sm:w-[360px] lg:w-[400px]", item.className),
992
992
  initial: { opacity: 0, y: 20 },
993
993
  animate: { opacity: 1, y: 0 },
994
994
  transition: { duration: 0.5, delay: index * 0.1 },
@@ -1024,7 +1024,7 @@ function CarouselHorizontalCards({
1024
1024
  patternOpacity,
1025
1025
  "aria-labelledby": "carousel-title",
1026
1026
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("container mx-auto px-4 md:px-6", containerClassName), children: [
1027
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mb-6 flex items-center justify-between", headerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1027
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mb-8 flex items-center justify-between gap-4", headerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1028
1028
  heading && /* @__PURE__ */ jsxRuntime.jsxs("a", { href: headingHref, className: "group inline-flex items-center", children: [
1029
1029
  typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1030
1030
  "h2",
@@ -1039,7 +1039,7 @@ function CarouselHorizontalCards({
1039
1039
  {
1040
1040
  name: "lucide/chevron-right",
1041
1041
  size: 24,
1042
- className: "ml-2 transition-transform group-hover:translate-x-1"
1042
+ className: "ml-2 flex-shrink-0 self-center transition-transform group-hover:translate-x-1"
1043
1043
  }
1044
1044
  )
1045
1045
  ] }),
@@ -1058,20 +1058,20 @@ function CarouselHorizontalCards({
1058
1058
  Pressable,
1059
1059
  {
1060
1060
  onClick: () => scroll("left"),
1061
- className: cn("absolute left-0 top-1/2 z-10 -translate-y-1/2 rounded-full border bg-background/60 p-2 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1061
+ className: cn("absolute left-0 top-1/2 z-10 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full border bg-background/60 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1062
1062
  "aria-label": "Scroll left",
1063
1063
  asButton: true,
1064
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-left", size: 24 })
1064
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-left", size: 20 })
1065
1065
  }
1066
1066
  ),
1067
1067
  !isAtEnd && /* @__PURE__ */ jsxRuntime.jsx(
1068
1068
  Pressable,
1069
1069
  {
1070
1070
  onClick: () => scroll("right"),
1071
- className: cn("absolute right-0 top-1/2 z-10 -translate-y-1/2 rounded-full border bg-background/60 p-2 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1071
+ className: cn("absolute right-0 top-1/2 z-10 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full border bg-background/60 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1072
1072
  "aria-label": "Scroll right",
1073
1073
  asButton: true,
1074
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24 })
1074
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 20 })
1075
1075
  }
1076
1076
  )
1077
1077
  ] })
@@ -967,7 +967,7 @@ function CarouselHorizontalCards({
967
967
  return items.map((item, index) => /* @__PURE__ */ jsx(
968
968
  motion.div,
969
969
  {
970
- className: cn("group w-[280px] shrink-0", item.className),
970
+ className: cn("group w-[320px] shrink-0 sm:w-[360px] lg:w-[400px]", item.className),
971
971
  initial: { opacity: 0, y: 20 },
972
972
  animate: { opacity: 1, y: 0 },
973
973
  transition: { duration: 0.5, delay: index * 0.1 },
@@ -1003,7 +1003,7 @@ function CarouselHorizontalCards({
1003
1003
  patternOpacity,
1004
1004
  "aria-labelledby": "carousel-title",
1005
1005
  children: /* @__PURE__ */ jsxs("div", { className: cn("container mx-auto px-4 md:px-6", containerClassName), children: [
1006
- /* @__PURE__ */ jsx("div", { className: cn("mb-6 flex items-center justify-between", headerClassName), children: /* @__PURE__ */ jsxs("div", { children: [
1006
+ /* @__PURE__ */ jsx("div", { className: cn("mb-8 flex items-center justify-between gap-4", headerClassName), children: /* @__PURE__ */ jsxs("div", { children: [
1007
1007
  heading && /* @__PURE__ */ jsxs("a", { href: headingHref, className: "group inline-flex items-center", children: [
1008
1008
  typeof heading === "string" ? /* @__PURE__ */ jsx(
1009
1009
  "h2",
@@ -1018,7 +1018,7 @@ function CarouselHorizontalCards({
1018
1018
  {
1019
1019
  name: "lucide/chevron-right",
1020
1020
  size: 24,
1021
- className: "ml-2 transition-transform group-hover:translate-x-1"
1021
+ className: "ml-2 flex-shrink-0 self-center transition-transform group-hover:translate-x-1"
1022
1022
  }
1023
1023
  )
1024
1024
  ] }),
@@ -1037,20 +1037,20 @@ function CarouselHorizontalCards({
1037
1037
  Pressable,
1038
1038
  {
1039
1039
  onClick: () => scroll("left"),
1040
- className: cn("absolute left-0 top-1/2 z-10 -translate-y-1/2 rounded-full border bg-background/60 p-2 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1040
+ className: cn("absolute left-0 top-1/2 z-10 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full border bg-background/60 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1041
1041
  "aria-label": "Scroll left",
1042
1042
  asButton: true,
1043
- children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-left", size: 24 })
1043
+ children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-left", size: 20 })
1044
1044
  }
1045
1045
  ),
1046
1046
  !isAtEnd && /* @__PURE__ */ jsx(
1047
1047
  Pressable,
1048
1048
  {
1049
1049
  onClick: () => scroll("right"),
1050
- className: cn("absolute right-0 top-1/2 z-10 -translate-y-1/2 rounded-full border bg-background/60 p-2 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1050
+ className: cn("absolute right-0 top-1/2 z-10 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full border bg-background/60 text-foreground shadow-md backdrop-blur-sm transition-opacity hover:bg-background/80", navigationClassName),
1051
1051
  "aria-label": "Scroll right",
1052
1052
  asButton: true,
1053
- children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24 })
1053
+ children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 20 })
1054
1054
  }
1055
1055
  )
1056
1056
  ] })
@@ -978,7 +978,7 @@ function CarouselImageHero({
978
978
  Pressable,
979
979
  {
980
980
  asButton: true,
981
- className: cn("bg-primary-foreground text-primary dark:bg-primary dark:text-primary-foreground", actionClassName),
981
+ className: actionClassName,
982
982
  ...pressableProps,
983
983
  children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
984
984
  icon,
@@ -1046,12 +1046,12 @@ function CarouselImageHero({
1046
1046
  children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24, className: "text-white" })
1047
1047
  }
1048
1048
  ),
1049
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-2", indicatorsClassName), children: images?.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
1049
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-3", indicatorsClassName), children: images?.map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
1050
1050
  "button",
1051
1051
  {
1052
1052
  onClick: () => setCurrentImageIndex(index),
1053
1053
  className: cn(
1054
- "h-2.5 w-2.5 rounded-full transition-colors",
1054
+ "flex h-3 w-3 items-center justify-center rounded-full transition-colors",
1055
1055
  index === currentImageIndex ? "bg-white" : "bg-white/50 hover:bg-white/80"
1056
1056
  ),
1057
1057
  "aria-label": `Go to image ${index + 1}`
@@ -1059,7 +1059,7 @@ function CarouselImageHero({
1059
1059
  index
1060
1060
  )) })
1061
1061
  ] }),
1062
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("container relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-24 text-center md:px-6 md:py-32 2xl:max-w-[1400px]", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-3xl space-y-8", contentClassName), children: [
1062
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("container relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-16 text-center md:px-6 md:py-20", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-4xl space-y-6", contentClassName), children: [
1063
1063
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
1064
1064
  badge && (typeof badge === "string" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-sm font-medium text-white backdrop-blur-sm", badgeClassName), children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: badge }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: badgeClassName, children: badge })),
1065
1065
  heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-bold tracking-tight text-primary-foreground dark:text-primary sm:text-5xl md:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: headingClassName, children: heading })),
@@ -957,7 +957,7 @@ function CarouselImageHero({
957
957
  Pressable,
958
958
  {
959
959
  asButton: true,
960
- className: cn("bg-primary-foreground text-primary dark:bg-primary dark:text-primary-foreground", actionClassName),
960
+ className: actionClassName,
961
961
  ...pressableProps,
962
962
  children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
963
963
  icon,
@@ -1025,12 +1025,12 @@ function CarouselImageHero({
1025
1025
  children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24, className: "text-white" })
1026
1026
  }
1027
1027
  ),
1028
- /* @__PURE__ */ jsx("div", { className: cn("absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-2", indicatorsClassName), children: images?.map((_, index) => /* @__PURE__ */ jsx(
1028
+ /* @__PURE__ */ jsx("div", { className: cn("absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-3", indicatorsClassName), children: images?.map((_, index) => /* @__PURE__ */ jsx(
1029
1029
  "button",
1030
1030
  {
1031
1031
  onClick: () => setCurrentImageIndex(index),
1032
1032
  className: cn(
1033
- "h-2.5 w-2.5 rounded-full transition-colors",
1033
+ "flex h-3 w-3 items-center justify-center rounded-full transition-colors",
1034
1034
  index === currentImageIndex ? "bg-white" : "bg-white/50 hover:bg-white/80"
1035
1035
  ),
1036
1036
  "aria-label": `Go to image ${index + 1}`
@@ -1038,7 +1038,7 @@ function CarouselImageHero({
1038
1038
  index
1039
1039
  )) })
1040
1040
  ] }),
1041
- /* @__PURE__ */ jsx("div", { className: cn("container relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-24 text-center md:px-6 md:py-32 2xl:max-w-[1400px]", containerClassName), children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-3xl space-y-8", contentClassName), children: [
1041
+ /* @__PURE__ */ jsx("div", { className: cn("container relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-16 text-center md:px-6 md:py-20", containerClassName), children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-4xl space-y-6", contentClassName), children: [
1042
1042
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1043
1043
  badge && (typeof badge === "string" ? /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-sm font-medium text-white backdrop-blur-sm", badgeClassName), children: /* @__PURE__ */ jsx("span", { children: badge }) }) : /* @__PURE__ */ jsx("div", { className: badgeClassName, children: badge })),
1044
1044
  heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("text-4xl font-bold tracking-tight text-primary-foreground dark:text-primary sm:text-5xl md:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
@@ -1055,38 +1055,42 @@ function CarouselMultiStepShowcase({
1055
1055
  }
1056
1056
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: subheadingClassName, children: subheading }))
1057
1057
  ] }),
1058
- stepsSlot ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: stepNavigationClassName, children: stepsSlot }) : /* @__PURE__ */ jsxRuntime.jsx(
1058
+ stepsSlot ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("hidden sm:block", stepNavigationClassName), children: stepsSlot }) : /* @__PURE__ */ jsxRuntime.jsx(
1059
1059
  "div",
1060
1060
  {
1061
1061
  className: cn(
1062
- "mb-8 flex flex-wrap justify-center gap-2",
1062
+ "mb-8 hidden flex-wrap justify-center gap-2 sm:flex",
1063
1063
  stepNavigationClassName
1064
1064
  ),
1065
- children: steps?.map((step, index) => /* @__PURE__ */ jsxRuntime.jsxs(
1066
- "button",
1067
- {
1068
- onClick: () => goToStep(index),
1069
- className: cn(
1070
- "flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all",
1071
- activeStep === index ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:bg-muted/80",
1072
- step.className
1073
- ),
1074
- children: [
1075
- /* @__PURE__ */ jsxRuntime.jsx(
1076
- "span",
1077
- {
1078
- className: cn(
1079
- "flex h-6 w-6 items-center justify-center rounded-full text-xs",
1080
- activeStep === index ? "bg-primary-foreground text-primary" : "bg-background"
1081
- ),
1082
- children: step.step
1083
- }
1065
+ children: steps?.map((step, index) => {
1066
+ const isCompleted = index < activeStep;
1067
+ const isActive = index === activeStep;
1068
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1069
+ "button",
1070
+ {
1071
+ onClick: () => goToStep(index),
1072
+ className: cn(
1073
+ "flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all",
1074
+ isActive ? "bg-primary text-primary-foreground" : isCompleted ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:bg-muted/80",
1075
+ step.className
1084
1076
  ),
1085
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: typeof step.title === "string" ? step.title.split(":")[0] : step.title })
1086
- ]
1087
- },
1088
- step.id
1089
- ))
1077
+ children: [
1078
+ /* @__PURE__ */ jsxRuntime.jsx(
1079
+ "span",
1080
+ {
1081
+ className: cn(
1082
+ "flex h-6 w-6 items-center justify-center rounded-full text-xs",
1083
+ isActive ? "bg-primary-foreground text-primary" : isCompleted ? "bg-primary-foreground text-primary" : "bg-background"
1084
+ ),
1085
+ children: isCompleted ? /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/check", size: 14 }) : step.step
1086
+ }
1087
+ ),
1088
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: typeof step.title === "string" ? step.title.split(":")[0] : step.title })
1089
+ ]
1090
+ },
1091
+ step.id
1092
+ );
1093
+ })
1090
1094
  }
1091
1095
  ),
1092
1096
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1034,38 +1034,42 @@ function CarouselMultiStepShowcase({
1034
1034
  }
1035
1035
  ) : /* @__PURE__ */ jsx("div", { className: subheadingClassName, children: subheading }))
1036
1036
  ] }),
1037
- stepsSlot ? /* @__PURE__ */ jsx("div", { className: stepNavigationClassName, children: stepsSlot }) : /* @__PURE__ */ jsx(
1037
+ stepsSlot ? /* @__PURE__ */ jsx("div", { className: cn("hidden sm:block", stepNavigationClassName), children: stepsSlot }) : /* @__PURE__ */ jsx(
1038
1038
  "div",
1039
1039
  {
1040
1040
  className: cn(
1041
- "mb-8 flex flex-wrap justify-center gap-2",
1041
+ "mb-8 hidden flex-wrap justify-center gap-2 sm:flex",
1042
1042
  stepNavigationClassName
1043
1043
  ),
1044
- children: steps?.map((step, index) => /* @__PURE__ */ jsxs(
1045
- "button",
1046
- {
1047
- onClick: () => goToStep(index),
1048
- className: cn(
1049
- "flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all",
1050
- activeStep === index ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:bg-muted/80",
1051
- step.className
1052
- ),
1053
- children: [
1054
- /* @__PURE__ */ jsx(
1055
- "span",
1056
- {
1057
- className: cn(
1058
- "flex h-6 w-6 items-center justify-center rounded-full text-xs",
1059
- activeStep === index ? "bg-primary-foreground text-primary" : "bg-background"
1060
- ),
1061
- children: step.step
1062
- }
1044
+ children: steps?.map((step, index) => {
1045
+ const isCompleted = index < activeStep;
1046
+ const isActive = index === activeStep;
1047
+ return /* @__PURE__ */ jsxs(
1048
+ "button",
1049
+ {
1050
+ onClick: () => goToStep(index),
1051
+ className: cn(
1052
+ "flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all",
1053
+ isActive ? "bg-primary text-primary-foreground" : isCompleted ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:bg-muted/80",
1054
+ step.className
1063
1055
  ),
1064
- /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: typeof step.title === "string" ? step.title.split(":")[0] : step.title })
1065
- ]
1066
- },
1067
- step.id
1068
- ))
1056
+ children: [
1057
+ /* @__PURE__ */ jsx(
1058
+ "span",
1059
+ {
1060
+ className: cn(
1061
+ "flex h-6 w-6 items-center justify-center rounded-full text-xs",
1062
+ isActive ? "bg-primary-foreground text-primary" : isCompleted ? "bg-primary-foreground text-primary" : "bg-background"
1063
+ ),
1064
+ children: isCompleted ? /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/check", size: 14 }) : step.step
1065
+ }
1066
+ ),
1067
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: typeof step.title === "string" ? step.title.split(":")[0] : step.title })
1068
+ ]
1069
+ },
1070
+ step.id
1071
+ );
1072
+ })
1069
1073
  }
1070
1074
  ),
1071
1075
  /* @__PURE__ */ jsx(
@@ -32,6 +32,16 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
32
32
  function cn(...inputs) {
33
33
  return tailwindMerge.twMerge(clsx.clsx(inputs));
34
34
  }
35
+ var BRIGHTNESS_CLASS_MAP = {
36
+ "10": "brightness-[.1]",
37
+ "20": "brightness-[.2]",
38
+ "25": "brightness-[.25]",
39
+ "30": "brightness-[.3]",
40
+ "40": "brightness-[.4]",
41
+ "50": "brightness-50",
42
+ "75": "brightness-75",
43
+ "100": "brightness-100"
44
+ };
35
45
  function normalizePhoneNumber(input) {
36
46
  const trimmed = input.trim();
37
47
  if (trimmed.toLowerCase().startsWith("tel:")) {
@@ -946,10 +956,11 @@ function CarouselPortfolioHero({
946
956
  navigationClassName,
947
957
  counterClassName,
948
958
  optixFlowConfig,
949
- background = "white",
950
- spacing = "xl",
959
+ background = "dark",
960
+ spacing = "none",
951
961
  pattern,
952
- patternOpacity
962
+ patternOpacity,
963
+ slideMediaBrightness = "50"
953
964
  }) {
954
965
  const [currentIndex, setCurrentIndex] = React__namespace.useState(0);
955
966
  const goToNext = React__namespace.useCallback(() => {
@@ -995,7 +1006,7 @@ function CarouselPortfolioHero({
995
1006
  pattern,
996
1007
  patternOpacity,
997
1008
  children: [
998
- slidesSlot ? slidesSlot : slides?.map((slide, index) => /* @__PURE__ */ jsxRuntime.jsxs(
1009
+ slidesSlot ? slidesSlot : slides?.map((slide, index) => /* @__PURE__ */ jsxRuntime.jsx(
999
1010
  "div",
1000
1011
  {
1001
1012
  className: cn(
@@ -1003,22 +1014,23 @@ function CarouselPortfolioHero({
1003
1014
  index === currentIndex ? "opacity-100" : "opacity-0",
1004
1015
  slide.className
1005
1016
  ),
1006
- children: [
1007
- /* @__PURE__ */ jsxRuntime.jsx(
1008
- img.Img,
1009
- {
1010
- src: slide.image,
1011
- alt: typeof slide.title === "string" ? slide.title : `Slide ${index + 1}`,
1012
- className: cn("h-full w-full object-cover", slide.imageClassName),
1013
- optixFlowConfig
1014
- }
1015
- ),
1016
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent" })
1017
- ]
1017
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1018
+ img.Img,
1019
+ {
1020
+ src: slide.image,
1021
+ alt: typeof slide.title === "string" ? slide.title : `Slide ${index + 1}`,
1022
+ className: cn(
1023
+ "h-full w-full object-cover",
1024
+ BRIGHTNESS_CLASS_MAP[slideMediaBrightness],
1025
+ slide.imageClassName
1026
+ ),
1027
+ optixFlowConfig
1028
+ }
1029
+ )
1018
1030
  },
1019
1031
  slide.id
1020
1032
  )),
1021
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative z-10 flex h-full w-full flex-col justify-end p-4 pb-16 text-white sm:p-8 md:p-12", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-3xl", contentClassName), children: [
1033
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative z-10 flex h-full w-full flex-col justify-end px-6 pb-16 text-white md:px-8 lg:px-12", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-4xl", contentClassName), children: [
1022
1034
  currentSlide?.tag && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: typeof currentSlide.tag === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-block rounded-full bg-primary px-3 py-1 text-sm font-medium", tagClassName), children: currentSlide.tag }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagClassName, children: currentSlide.tag }) }),
1023
1035
  currentSlide?.title && (typeof currentSlide.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-bold sm:text-5xl md:text-6xl", titleClassName), children: currentSlide.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: titleClassName, children: currentSlide.title })),
1024
1036
  currentSlide?.description && (typeof currentSlide.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-4 text-lg text-white/80 sm:text-xl md:max-w-2xl", descriptionClassName), children: currentSlide.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: currentSlide.description })),
@@ -128,7 +128,11 @@ interface CarouselPortfolioHeroProps {
128
128
  * Pattern overlay opacity (0-1)
129
129
  */
130
130
  patternOpacity?: number;
131
+ /**
132
+ * Brightness level for slide images (controls overlay visibility)
133
+ */
134
+ slideMediaBrightness?: "10" | "20" | "25" | "30" | "40" | "50" | "75" | "100";
131
135
  }
132
- declare function CarouselPortfolioHero({ slides, slidesSlot, actions, actionsSlot, autoPlayInterval, className, containerClassName, contentClassName, tagClassName, titleClassName, descriptionClassName, actionsClassName, navigationClassName, counterClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, }: CarouselPortfolioHeroProps): React.JSX.Element;
136
+ declare function CarouselPortfolioHero({ slides, slidesSlot, actions, actionsSlot, autoPlayInterval, className, containerClassName, contentClassName, tagClassName, titleClassName, descriptionClassName, actionsClassName, navigationClassName, counterClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, slideMediaBrightness, }: CarouselPortfolioHeroProps): React.JSX.Element;
133
137
 
134
138
  export { CarouselPortfolioHero, type CarouselPortfolioHeroProps, type PortfolioSlide };
@@ -128,7 +128,11 @@ interface CarouselPortfolioHeroProps {
128
128
  * Pattern overlay opacity (0-1)
129
129
  */
130
130
  patternOpacity?: number;
131
+ /**
132
+ * Brightness level for slide images (controls overlay visibility)
133
+ */
134
+ slideMediaBrightness?: "10" | "20" | "25" | "30" | "40" | "50" | "75" | "100";
131
135
  }
132
- declare function CarouselPortfolioHero({ slides, slidesSlot, actions, actionsSlot, autoPlayInterval, className, containerClassName, contentClassName, tagClassName, titleClassName, descriptionClassName, actionsClassName, navigationClassName, counterClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, }: CarouselPortfolioHeroProps): React.JSX.Element;
136
+ declare function CarouselPortfolioHero({ slides, slidesSlot, actions, actionsSlot, autoPlayInterval, className, containerClassName, contentClassName, tagClassName, titleClassName, descriptionClassName, actionsClassName, navigationClassName, counterClassName, optixFlowConfig, background, spacing, pattern, patternOpacity, slideMediaBrightness, }: CarouselPortfolioHeroProps): React.JSX.Element;
133
137
 
134
138
  export { CarouselPortfolioHero, type CarouselPortfolioHeroProps, type PortfolioSlide };
@@ -11,6 +11,16 @@ import { Img } from '@page-speed/img';
11
11
  function cn(...inputs) {
12
12
  return twMerge(clsx(inputs));
13
13
  }
14
+ var BRIGHTNESS_CLASS_MAP = {
15
+ "10": "brightness-[.1]",
16
+ "20": "brightness-[.2]",
17
+ "25": "brightness-[.25]",
18
+ "30": "brightness-[.3]",
19
+ "40": "brightness-[.4]",
20
+ "50": "brightness-50",
21
+ "75": "brightness-75",
22
+ "100": "brightness-100"
23
+ };
14
24
  function normalizePhoneNumber(input) {
15
25
  const trimmed = input.trim();
16
26
  if (trimmed.toLowerCase().startsWith("tel:")) {
@@ -925,10 +935,11 @@ function CarouselPortfolioHero({
925
935
  navigationClassName,
926
936
  counterClassName,
927
937
  optixFlowConfig,
928
- background = "white",
929
- spacing = "xl",
938
+ background = "dark",
939
+ spacing = "none",
930
940
  pattern,
931
- patternOpacity
941
+ patternOpacity,
942
+ slideMediaBrightness = "50"
932
943
  }) {
933
944
  const [currentIndex, setCurrentIndex] = React.useState(0);
934
945
  const goToNext = React.useCallback(() => {
@@ -974,7 +985,7 @@ function CarouselPortfolioHero({
974
985
  pattern,
975
986
  patternOpacity,
976
987
  children: [
977
- slidesSlot ? slidesSlot : slides?.map((slide, index) => /* @__PURE__ */ jsxs(
988
+ slidesSlot ? slidesSlot : slides?.map((slide, index) => /* @__PURE__ */ jsx(
978
989
  "div",
979
990
  {
980
991
  className: cn(
@@ -982,22 +993,23 @@ function CarouselPortfolioHero({
982
993
  index === currentIndex ? "opacity-100" : "opacity-0",
983
994
  slide.className
984
995
  ),
985
- children: [
986
- /* @__PURE__ */ jsx(
987
- Img,
988
- {
989
- src: slide.image,
990
- alt: typeof slide.title === "string" ? slide.title : `Slide ${index + 1}`,
991
- className: cn("h-full w-full object-cover", slide.imageClassName),
992
- optixFlowConfig
993
- }
994
- ),
995
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent" })
996
- ]
996
+ children: /* @__PURE__ */ jsx(
997
+ Img,
998
+ {
999
+ src: slide.image,
1000
+ alt: typeof slide.title === "string" ? slide.title : `Slide ${index + 1}`,
1001
+ className: cn(
1002
+ "h-full w-full object-cover",
1003
+ BRIGHTNESS_CLASS_MAP[slideMediaBrightness],
1004
+ slide.imageClassName
1005
+ ),
1006
+ optixFlowConfig
1007
+ }
1008
+ )
997
1009
  },
998
1010
  slide.id
999
1011
  )),
1000
- /* @__PURE__ */ jsx("div", { className: cn("relative z-10 flex h-full w-full flex-col justify-end p-4 pb-16 text-white sm:p-8 md:p-12", containerClassName), children: /* @__PURE__ */ jsx("div", { className: "container mx-auto", children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-3xl", contentClassName), children: [
1012
+ /* @__PURE__ */ jsx("div", { className: cn("relative z-10 flex h-full w-full flex-col justify-end px-6 pb-16 text-white md:px-8 lg:px-12", containerClassName), children: /* @__PURE__ */ jsx("div", { className: "container mx-auto", children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-4xl", contentClassName), children: [
1001
1013
  currentSlide?.tag && /* @__PURE__ */ jsx("div", { className: "mb-4", children: typeof currentSlide.tag === "string" ? /* @__PURE__ */ jsx("span", { className: cn("inline-block rounded-full bg-primary px-3 py-1 text-sm font-medium", tagClassName), children: currentSlide.tag }) : /* @__PURE__ */ jsx("div", { className: tagClassName, children: currentSlide.tag }) }),
1002
1014
  currentSlide?.title && (typeof currentSlide.title === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("text-4xl font-bold sm:text-5xl md:text-6xl", titleClassName), children: currentSlide.title }) : /* @__PURE__ */ jsx("div", { className: titleClassName, children: currentSlide.title })),
1003
1015
  currentSlide?.description && (typeof currentSlide.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mt-4 text-lg text-white/80 sm:text-xl md:max-w-2xl", descriptionClassName), children: currentSlide.description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: currentSlide.description })),