@opensite/ui 1.2.4 → 1.2.5

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.
@@ -1,12 +1,13 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React4 = require('react');
4
+ var React6 = require('react');
5
5
  var framerMotion = require('framer-motion');
6
6
  var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
8
8
  var img = require('@page-speed/img');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
+ var classVarianceAuthority = require('class-variance-authority');
10
11
 
11
12
  function _interopNamespace(e) {
12
13
  if (e && e.__esModule) return e;
@@ -26,7 +27,7 @@ function _interopNamespace(e) {
26
27
  return Object.freeze(n);
27
28
  }
28
29
 
29
- var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
30
+ var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
30
31
 
31
32
  // components/blocks/features/feature-animated-carousel.tsx
32
33
  function cn(...inputs) {
@@ -70,10 +71,10 @@ function DynamicIcon({
70
71
  className,
71
72
  alt
72
73
  }) {
73
- const [svgContent, setSvgContent] = React4__namespace.useState(null);
74
- const [isLoading, setIsLoading] = React4__namespace.useState(true);
75
- const [error, setError] = React4__namespace.useState(null);
76
- const { url, iconName } = React4__namespace.useMemo(() => {
74
+ const [svgContent, setSvgContent] = React6__namespace.useState(null);
75
+ const [isLoading, setIsLoading] = React6__namespace.useState(true);
76
+ const [error, setError] = React6__namespace.useState(null);
77
+ const { url, iconName } = React6__namespace.useMemo(() => {
77
78
  const separator = name.includes("/") ? "/" : ":";
78
79
  const [prefix, iconName2] = name.split(separator);
79
80
  const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
@@ -82,7 +83,7 @@ function DynamicIcon({
82
83
  iconName: iconName2
83
84
  };
84
85
  }, [name, size]);
85
- React4__namespace.useEffect(() => {
86
+ React6__namespace.useEffect(() => {
86
87
  let isMounted = true;
87
88
  const fetchSvg = async () => {
88
89
  const cached = svgCache.get(url);
@@ -176,7 +177,7 @@ var maxWidthStyles = {
176
177
  "4xl": "max-w-[1536px]",
177
178
  full: "max-w-full"
178
179
  };
179
- var Container = React4__namespace.default.forwardRef(
180
+ var Container = React6__namespace.default.forwardRef(
180
181
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
181
182
  const Component = as;
182
183
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -481,7 +482,7 @@ var spacingStyles = {
481
482
  };
482
483
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
483
484
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
484
- var Section = React4__namespace.default.forwardRef(
485
+ var Section = React6__namespace.default.forwardRef(
485
486
  ({
486
487
  id,
487
488
  title,
@@ -542,271 +543,727 @@ var Section = React4__namespace.default.forwardRef(
542
543
  }
543
544
  );
544
545
  Section.displayName = "Section";
545
- var Controls = React4__namespace.memo(({
546
- handleNext,
547
- handlePrevious,
548
- isPreviousDisabled,
549
- isNextDisabled
550
- }) => {
551
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden flex-col items-start gap-8 lg:flex", children: [
552
- /* @__PURE__ */ jsxRuntime.jsx(
553
- "button",
554
- {
555
- className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
556
- onClick: handlePrevious,
557
- disabled: isPreviousDisabled,
558
- type: "button",
559
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-up", size: 24 })
546
+ var baseStyles = [
547
+ // Layout
548
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
549
+ // Typography - using CSS variables with sensible defaults
550
+ "font-[var(--button-font-family,inherit)]",
551
+ "font-[var(--button-font-weight,500)]",
552
+ "tracking-[var(--button-letter-spacing,0)]",
553
+ "leading-[var(--button-line-height,1.25)]",
554
+ "[text-transform:var(--button-text-transform,none)]",
555
+ "text-sm",
556
+ // Border radius
557
+ "rounded-[var(--button-radius,var(--radius,0.375rem))]",
558
+ // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
559
+ "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
560
+ // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
561
+ "[box-shadow:var(--button-shadow,none)]",
562
+ "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
563
+ // Disabled state
564
+ "disabled:pointer-events-none disabled:opacity-50",
565
+ // SVG handling
566
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
567
+ // Focus styles
568
+ "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
569
+ // Invalid state
570
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
571
+ ].join(" ");
572
+ var buttonVariants = classVarianceAuthority.cva(baseStyles, {
573
+ variants: {
574
+ variant: {
575
+ // Default (Primary) variant - full customization
576
+ default: [
577
+ "bg-[var(--button-default-bg,hsl(var(--primary)))]",
578
+ "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
579
+ "border-[length:var(--button-default-border-width,0px)]",
580
+ "border-[color:var(--button-default-border,transparent)]",
581
+ "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
582
+ "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
583
+ "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
584
+ "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
585
+ "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
586
+ ].join(" "),
587
+ // Destructive variant - full customization
588
+ destructive: [
589
+ "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
590
+ "text-[var(--button-destructive-fg,white)]",
591
+ "border-[length:var(--button-destructive-border-width,0px)]",
592
+ "border-[color:var(--button-destructive-border,transparent)]",
593
+ "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
594
+ "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
595
+ "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
596
+ "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
597
+ "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
598
+ "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
599
+ "dark:bg-destructive/60"
600
+ ].join(" "),
601
+ // Outline variant - full customization with proper border handling
602
+ outline: [
603
+ "bg-[var(--button-outline-bg,hsl(var(--background)))]",
604
+ "text-[var(--button-outline-fg,inherit)]",
605
+ "border-[length:var(--button-outline-border-width,1px)]",
606
+ "border-[color:var(--button-outline-border,hsl(var(--border)))]",
607
+ "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
608
+ "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
609
+ "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
610
+ "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
611
+ "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
612
+ "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
613
+ ].join(" "),
614
+ // Secondary variant - full customization
615
+ secondary: [
616
+ "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
617
+ "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
618
+ "border-[length:var(--button-secondary-border-width,0px)]",
619
+ "border-[color:var(--button-secondary-border,transparent)]",
620
+ "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
621
+ "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
622
+ "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
623
+ "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
624
+ "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
625
+ ].join(" "),
626
+ // Ghost variant - full customization
627
+ ghost: [
628
+ "bg-[var(--button-ghost-bg,transparent)]",
629
+ "text-[var(--button-ghost-fg,inherit)]",
630
+ "border-[length:var(--button-ghost-border-width,0px)]",
631
+ "border-[color:var(--button-ghost-border,transparent)]",
632
+ "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
633
+ "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
634
+ "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
635
+ "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
636
+ "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
637
+ "dark:hover:bg-accent/50"
638
+ ].join(" "),
639
+ // Link variant - full customization
640
+ link: [
641
+ "bg-[var(--button-link-bg,transparent)]",
642
+ "text-[var(--button-link-fg,hsl(var(--primary)))]",
643
+ "border-[length:var(--button-link-border-width,0px)]",
644
+ "border-[color:var(--button-link-border,transparent)]",
645
+ "[box-shadow:var(--button-link-shadow,none)]",
646
+ "hover:bg-[var(--button-link-hover-bg,transparent)]",
647
+ "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
648
+ "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
649
+ "underline-offset-4 hover:underline"
650
+ ].join(" ")
651
+ },
652
+ size: {
653
+ default: [
654
+ "h-[var(--button-height-md,2.25rem)]",
655
+ "px-[var(--button-padding-x-md,1rem)]",
656
+ "py-[var(--button-padding-y-md,0.5rem)]",
657
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
658
+ ].join(" "),
659
+ sm: [
660
+ "h-[var(--button-height-sm,2rem)]",
661
+ "px-[var(--button-padding-x-sm,0.75rem)]",
662
+ "py-[var(--button-padding-y-sm,0.25rem)]",
663
+ "gap-1.5",
664
+ "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
665
+ ].join(" "),
666
+ md: [
667
+ "h-[var(--button-height-md,2.25rem)]",
668
+ "px-[var(--button-padding-x-md,1rem)]",
669
+ "py-[var(--button-padding-y-md,0.5rem)]",
670
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
671
+ ].join(" "),
672
+ lg: [
673
+ "h-[var(--button-height-lg,2.5rem)]",
674
+ "px-[var(--button-padding-x-lg,1.5rem)]",
675
+ "py-[var(--button-padding-y-lg,0.5rem)]",
676
+ "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
677
+ ].join(" "),
678
+ icon: "size-[var(--button-height-md,2.25rem)]",
679
+ "icon-sm": "size-[var(--button-height-sm,2rem)]",
680
+ "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
681
+ }
682
+ },
683
+ defaultVariants: {
684
+ variant: "default",
685
+ size: "default"
686
+ }
687
+ });
688
+ function normalizePhoneNumber(input) {
689
+ const trimmed = input.trim();
690
+ if (trimmed.toLowerCase().startsWith("tel:")) {
691
+ return trimmed;
692
+ }
693
+ const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
694
+ if (match) {
695
+ const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
696
+ const extension = match[3];
697
+ const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
698
+ const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
699
+ return `tel:${withExtension}`;
700
+ }
701
+ const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
702
+ return `tel:${cleaned}`;
703
+ }
704
+ function normalizeEmail(input) {
705
+ const trimmed = input.trim();
706
+ if (trimmed.toLowerCase().startsWith("mailto:")) {
707
+ return trimmed;
708
+ }
709
+ return `mailto:${trimmed}`;
710
+ }
711
+ function isEmail(input) {
712
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
713
+ return emailRegex.test(input.trim());
714
+ }
715
+ function isPhoneNumber(input) {
716
+ const trimmed = input.trim();
717
+ if (trimmed.toLowerCase().startsWith("tel:")) {
718
+ return true;
719
+ }
720
+ const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
721
+ return phoneRegex.test(trimmed);
722
+ }
723
+ function isInternalUrl(href) {
724
+ if (typeof window === "undefined") {
725
+ return href.startsWith("/") && !href.startsWith("//");
726
+ }
727
+ const trimmed = href.trim();
728
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
729
+ return true;
730
+ }
731
+ try {
732
+ const url = new URL(trimmed, window.location.href);
733
+ const currentOrigin = window.location.origin;
734
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
735
+ return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
736
+ } catch {
737
+ return false;
738
+ }
739
+ }
740
+ function toRelativePath(href) {
741
+ if (typeof window === "undefined") {
742
+ return href;
743
+ }
744
+ const trimmed = href.trim();
745
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
746
+ return trimmed;
747
+ }
748
+ try {
749
+ const url = new URL(trimmed, window.location.href);
750
+ const currentOrigin = window.location.origin;
751
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
752
+ if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
753
+ return url.pathname + url.search + url.hash;
754
+ }
755
+ } catch {
756
+ }
757
+ return trimmed;
758
+ }
759
+ function useNavigation({
760
+ href,
761
+ onClick
762
+ } = {}) {
763
+ const linkType = React6__namespace.useMemo(() => {
764
+ if (!href || href.trim() === "") {
765
+ return onClick ? "none" : "none";
766
+ }
767
+ const trimmed = href.trim();
768
+ if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
769
+ return "mailto";
770
+ }
771
+ if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
772
+ return "tel";
773
+ }
774
+ if (isInternalUrl(trimmed)) {
775
+ return "internal";
776
+ }
777
+ try {
778
+ new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
779
+ return "external";
780
+ } catch {
781
+ return "internal";
782
+ }
783
+ }, [href, onClick]);
784
+ const normalizedHref = React6__namespace.useMemo(() => {
785
+ if (!href || href.trim() === "") {
786
+ return void 0;
787
+ }
788
+ const trimmed = href.trim();
789
+ switch (linkType) {
790
+ case "tel":
791
+ return normalizePhoneNumber(trimmed);
792
+ case "mailto":
793
+ return normalizeEmail(trimmed);
794
+ case "internal":
795
+ return toRelativePath(trimmed);
796
+ case "external":
797
+ return trimmed;
798
+ default:
799
+ return trimmed;
800
+ }
801
+ }, [href, linkType]);
802
+ const target = React6__namespace.useMemo(() => {
803
+ switch (linkType) {
804
+ case "external":
805
+ return "_blank";
806
+ case "internal":
807
+ return "_self";
808
+ case "mailto":
809
+ case "tel":
810
+ return void 0;
811
+ default:
812
+ return void 0;
813
+ }
814
+ }, [linkType]);
815
+ const rel = React6__namespace.useMemo(() => {
816
+ if (linkType === "external") {
817
+ return "noopener noreferrer";
818
+ }
819
+ return void 0;
820
+ }, [linkType]);
821
+ const isExternal = linkType === "external";
822
+ const isInternal = linkType === "internal";
823
+ const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
824
+ const handleClick = React6__namespace.useCallback(
825
+ (event) => {
826
+ if (onClick) {
827
+ try {
828
+ onClick(event);
829
+ } catch (error) {
830
+ console.error("Error in user onClick handler:", error);
831
+ }
560
832
  }
561
- ),
562
- /* @__PURE__ */ jsxRuntime.jsx(
563
- "button",
564
- {
565
- className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
566
- onClick: handleNext,
567
- disabled: isNextDisabled,
568
- type: "button",
569
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-down", size: 24 })
833
+ if (event.defaultPrevented) {
834
+ return;
835
+ }
836
+ if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
837
+ !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
838
+ if (typeof window !== "undefined") {
839
+ const handler = window.__opensiteNavigationHandler;
840
+ if (typeof handler === "function") {
841
+ try {
842
+ const handled = handler(normalizedHref, event.nativeEvent || event);
843
+ if (handled !== false) {
844
+ event.preventDefault();
845
+ }
846
+ } catch (error) {
847
+ console.error("Error in navigation handler:", error);
848
+ }
849
+ }
850
+ }
570
851
  }
571
- )
572
- ] });
573
- });
574
- var FeatureCard = React4__namespace.memo(({ feature, isActive, onClick }) => {
575
- const variants = React4.useMemo(() => ({
576
- initial: {
577
- opacity: 0
578
- },
579
- animate: {
580
- opacity: 1
581
852
  },
582
- exit: {
583
- opacity: 0
853
+ [onClick, shouldUseRouter, normalizedHref]
854
+ );
855
+ return {
856
+ linkType,
857
+ normalizedHref,
858
+ target,
859
+ rel,
860
+ isExternal,
861
+ isInternal,
862
+ shouldUseRouter,
863
+ handleClick
864
+ };
865
+ }
866
+ var Pressable = React6__namespace.forwardRef(
867
+ ({
868
+ children,
869
+ className,
870
+ href,
871
+ onClick,
872
+ variant,
873
+ size,
874
+ asButton = false,
875
+ fallbackComponentType = "span",
876
+ componentType,
877
+ "aria-label": ariaLabel,
878
+ "aria-describedby": ariaDescribedby,
879
+ id,
880
+ ...props
881
+ }, ref) => {
882
+ const navigation = useNavigation({ href, onClick });
883
+ const {
884
+ normalizedHref,
885
+ target,
886
+ rel,
887
+ linkType,
888
+ isInternal,
889
+ handleClick
890
+ } = navigation;
891
+ const shouldRenderLink = normalizedHref && linkType !== "none";
892
+ const shouldRenderButton = !shouldRenderLink && onClick;
893
+ const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
894
+ const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
895
+ const shouldApplyButtonStyles = asButton || variant || size;
896
+ const combinedClassName = cn(
897
+ shouldApplyButtonStyles && buttonVariants({ variant, size }),
898
+ className
899
+ );
900
+ const dataProps = Object.fromEntries(
901
+ Object.entries(props).filter(([key]) => key.startsWith("data-"))
902
+ );
903
+ const buttonDataAttributes = shouldApplyButtonStyles ? {
904
+ "data-slot": "button",
905
+ "data-variant": variant ?? "default",
906
+ "data-size": size ?? "default"
907
+ } : {};
908
+ const commonProps = {
909
+ className: combinedClassName,
910
+ onClick: handleClick,
911
+ "aria-label": ariaLabel,
912
+ "aria-describedby": ariaDescribedby,
913
+ id,
914
+ ...dataProps,
915
+ ...buttonDataAttributes
916
+ };
917
+ if (finalComponentType === "a" && shouldRenderLink) {
918
+ return /* @__PURE__ */ jsxRuntime.jsx(
919
+ "a",
920
+ {
921
+ ref,
922
+ href: normalizedHref,
923
+ target,
924
+ rel,
925
+ ...commonProps,
926
+ ...props,
927
+ children
928
+ }
929
+ );
584
930
  }
585
- }), []);
586
- return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsx(
587
- framerMotion.motion.div,
588
- {
589
- layout: true,
590
- transition: {
591
- layout: {
592
- duration: 0.4,
593
- ease: "easeOut"
931
+ if (finalComponentType === "button") {
932
+ return /* @__PURE__ */ jsxRuntime.jsx(
933
+ "button",
934
+ {
935
+ ref,
936
+ type: props.type || "button",
937
+ ...commonProps,
938
+ ...props,
939
+ children
594
940
  }
595
- },
596
- style: {
597
- borderRadius: "24px"
598
- },
599
- className: "flex cursor-pointer items-start gap-4 overflow-hidden bg-background md:w-fit md:max-w-sm",
600
- onClick,
601
- children: isActive ? /* @__PURE__ */ jsxRuntime.jsx(
602
- framerMotion.motion.div,
941
+ );
942
+ }
943
+ if (finalComponentType === "div") {
944
+ return /* @__PURE__ */ jsxRuntime.jsx(
945
+ "div",
603
946
  {
604
- layout: true,
605
- variants,
606
- initial: "initial",
607
- animate: "animate",
608
- exit: "exit",
609
- transition: {
947
+ ref,
948
+ ...commonProps,
949
+ children
950
+ }
951
+ );
952
+ }
953
+ return /* @__PURE__ */ jsxRuntime.jsx(
954
+ "span",
955
+ {
956
+ ref,
957
+ ...commonProps,
958
+ children
959
+ }
960
+ );
961
+ }
962
+ );
963
+ Pressable.displayName = "Pressable";
964
+ var Controls = React6__namespace.memo(
965
+ ({
966
+ handleNext,
967
+ handlePrevious,
968
+ isPreviousDisabled,
969
+ isNextDisabled
970
+ }) => {
971
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden flex-col items-start gap-8 lg:flex", children: [
972
+ /* @__PURE__ */ jsxRuntime.jsx(
973
+ "button",
974
+ {
975
+ className: "rounded-full border p-2 flex items-center justify-center disabled:opacity-50 h-fit w-fit bg-card text-card-foreground",
976
+ onClick: handlePrevious,
977
+ disabled: isPreviousDisabled,
978
+ type: "button",
979
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-up", size: 24 })
980
+ }
981
+ ),
982
+ /* @__PURE__ */ jsxRuntime.jsx(
983
+ "button",
984
+ {
985
+ className: "rounded-full border p-2 flex items-center justify-center disabled:opacity-50 h-fit w-fit bg-card text-card-foreground",
986
+ onClick: handleNext,
987
+ disabled: isNextDisabled,
988
+ type: "button",
989
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-down", size: 24 })
990
+ }
991
+ )
992
+ ] });
993
+ }
994
+ );
995
+ var FeatureCard = React6__namespace.memo(
996
+ ({ feature, isActive, onClick }) => {
997
+ const variants = React6.useMemo(
998
+ () => ({
999
+ initial: {
1000
+ opacity: 0
1001
+ },
1002
+ animate: {
1003
+ opacity: 1
1004
+ },
1005
+ exit: {
1006
+ opacity: 0
1007
+ }
1008
+ }),
1009
+ []
1010
+ );
1011
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsxs(
1012
+ framerMotion.motion.div,
1013
+ {
1014
+ layout: true,
1015
+ transition: {
1016
+ layout: {
610
1017
  duration: 0.4,
611
- delay: 0.3,
612
1018
  ease: "easeOut"
1019
+ }
1020
+ },
1021
+ style: {
1022
+ borderRadius: "24px"
1023
+ },
1024
+ className: cn(
1025
+ "relative flex items-start gap-4 overflow-hidden bg-background text-foreground md:w-fit md:max-w-sm",
1026
+ isActive ? "shadow-xl" : "cursor-pointer shadow-none"
1027
+ ),
1028
+ onClick,
1029
+ children: [
1030
+ isActive && feature.href && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 right-4 bg-background rounded-full h-fit w-fit p-2 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1031
+ Pressable,
1032
+ {
1033
+ href: feature.href,
1034
+ size: "icon-lg",
1035
+ className: "text-foreground",
1036
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-up-right" })
1037
+ }
1038
+ ) }),
1039
+ isActive ? /* @__PURE__ */ jsxRuntime.jsx(
1040
+ framerMotion.motion.div,
1041
+ {
1042
+ layout: true,
1043
+ variants,
1044
+ initial: "initial",
1045
+ animate: "animate",
1046
+ exit: "exit",
1047
+ transition: {
1048
+ duration: 0.4,
1049
+ delay: 0.3,
1050
+ ease: "easeOut"
1051
+ },
1052
+ className: "p-6 text-sm md:p-8 md:text-base",
1053
+ children: (feature.title || feature.description) && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
1054
+ feature.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
1055
+ feature.title,
1056
+ "."
1057
+ ] }),
1058
+ feature.title && feature.description && " ",
1059
+ feature.description && /* @__PURE__ */ jsxRuntime.jsx("span", { children: feature.description })
1060
+ ] })
1061
+ },
1062
+ `feature-description-active-${feature.title}`
1063
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
1064
+ framerMotion.motion.div,
1065
+ {
1066
+ layout: true,
1067
+ variants,
1068
+ initial: "initial",
1069
+ animate: "animate",
1070
+ exit: "exit",
1071
+ transition: {
1072
+ duration: 0.4,
1073
+ delay: 0.2,
1074
+ ease: "easeOut"
1075
+ },
1076
+ className: cn(
1077
+ "flex h-fit shrink-0 items-center gap-4 text-sm md:py-3.5 md:pr-6 md:pl-3 md:text-base",
1078
+ !isActive && "h-0 w-0 md:h-auto md:w-auto"
1079
+ ),
1080
+ style: {
1081
+ height: "auto",
1082
+ lineHeight: "normal"
1083
+ },
1084
+ children: [
1085
+ /* @__PURE__ */ jsxRuntime.jsx(
1086
+ DynamicIcon,
1087
+ {
1088
+ name: "lucide/plus-circle",
1089
+ size: 24,
1090
+ className: "shrink-0"
1091
+ }
1092
+ ),
1093
+ feature.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
1094
+ ]
1095
+ },
1096
+ `feature-description-inactive-${feature.title}`
1097
+ )
1098
+ ]
1099
+ }
1100
+ ) });
1101
+ }
1102
+ );
1103
+ var FeaturesDesktop = React6__namespace.memo(
1104
+ ({
1105
+ features,
1106
+ handleNext,
1107
+ handlePrevious,
1108
+ activeIndex,
1109
+ handleFeatureClick,
1110
+ isPreviousDisabled,
1111
+ isNextDisabled
1112
+ }) => {
1113
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 hidden items-center gap-8 md:flex", children: [
1114
+ /* @__PURE__ */ jsxRuntime.jsx(
1115
+ Controls,
1116
+ {
1117
+ handleNext,
1118
+ handlePrevious,
1119
+ isPreviousDisabled,
1120
+ isNextDisabled
1121
+ }
1122
+ ),
1123
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: features.map((feature, index) => {
1124
+ return /* @__PURE__ */ jsxRuntime.jsx(
1125
+ FeatureCard,
1126
+ {
1127
+ feature,
1128
+ isActive: index === activeIndex,
1129
+ onClick: () => handleFeatureClick(index)
613
1130
  },
614
- className: "p-6 text-sm md:p-8 md:text-base",
615
- children: (feature.title || feature.description) && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
616
- feature.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
617
- feature.title,
618
- "."
619
- ] }),
620
- feature.title && feature.description && " ",
621
- feature.description && /* @__PURE__ */ jsxRuntime.jsx("span", { children: feature.description })
622
- ] })
1131
+ `feature-card-${index}`
1132
+ );
1133
+ }) })
1134
+ ] });
1135
+ }
1136
+ );
1137
+ var FeaturesMobile = React6__namespace.memo(
1138
+ ({
1139
+ features,
1140
+ handleNext,
1141
+ handlePrevious,
1142
+ activeIndex,
1143
+ direction,
1144
+ isPreviousDisabled,
1145
+ isNextDisabled
1146
+ }) => {
1147
+ const variants = React6.useMemo(
1148
+ () => ({
1149
+ enter: (direction2) => ({
1150
+ x: direction2 > 0 ? 100 : -100,
1151
+ opacity: 0
1152
+ }),
1153
+ center: {
1154
+ x: 0,
1155
+ opacity: 1
623
1156
  },
624
- `feature-description-active-${feature.title}`
625
- ) : /* @__PURE__ */ jsxRuntime.jsxs(
1157
+ exit: (direction2) => ({
1158
+ x: direction2 < 0 ? 100 : -100,
1159
+ opacity: 0
1160
+ })
1161
+ }),
1162
+ []
1163
+ );
1164
+ const currentFeature = features[activeIndex];
1165
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex flex-col gap-4 md:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-stretch gap-4", children: [
1166
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
626
1167
  framerMotion.motion.div,
627
1168
  {
628
- layout: true,
1169
+ custom: direction,
629
1170
  variants,
630
- initial: "initial",
631
- animate: "animate",
1171
+ initial: "enter",
1172
+ animate: "center",
632
1173
  exit: "exit",
633
1174
  transition: {
634
- duration: 0.4,
635
- delay: 0.2,
636
- ease: "easeOut"
637
- },
638
- className: cn(
639
- "flex h-fit shrink-0 items-center gap-4 text-sm md:py-3.5 md:pr-6 md:pl-3 md:text-base",
640
- !isActive && "h-0 w-0 md:h-auto md:w-auto"
641
- ),
642
- style: {
643
- height: "auto",
644
- lineHeight: "normal"
1175
+ x: { type: "spring", stiffness: 300, damping: 30 },
1176
+ opacity: { duration: 0.2 }
645
1177
  },
646
- children: [
647
- /* @__PURE__ */ jsxRuntime.jsx(
648
- DynamicIcon,
649
- {
650
- name: "lucide/plus-circle",
651
- size: 24,
652
- className: "shrink-0"
653
- }
654
- ),
655
- feature.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
656
- ]
657
- },
658
- `feature-description-inactive-${feature.title}`
659
- )
660
- }
661
- ) });
662
- });
663
- var FeaturesDesktop = React4__namespace.memo(({
664
- features,
665
- handleNext,
666
- handlePrevious,
667
- activeIndex,
668
- handleFeatureClick,
669
- isPreviousDisabled,
670
- isNextDisabled
671
- }) => {
672
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 hidden items-center gap-8 md:flex", children: [
673
- /* @__PURE__ */ jsxRuntime.jsx(
674
- Controls,
675
- {
676
- handleNext,
677
- handlePrevious,
678
- isPreviousDisabled,
679
- isNextDisabled
680
- }
681
- ),
682
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: features.map((feature, index) => {
683
- return /* @__PURE__ */ jsxRuntime.jsx(
684
- FeatureCard,
685
- {
686
- feature,
687
- isActive: index === activeIndex,
688
- onClick: () => handleFeatureClick(index)
689
- },
690
- `feature-card-${index}`
691
- );
692
- }) })
693
- ] });
694
- });
695
- var FeaturesMobile = React4__namespace.memo(({
696
- features,
697
- handleNext,
698
- handlePrevious,
699
- activeIndex,
700
- direction,
701
- isPreviousDisabled,
702
- isNextDisabled
703
- }) => {
704
- const variants = React4.useMemo(() => ({
705
- enter: (direction2) => ({
706
- x: direction2 > 0 ? 100 : -100,
707
- opacity: 0
708
- }),
709
- center: {
710
- x: 0,
711
- opacity: 1
712
- },
713
- exit: (direction2) => ({
714
- x: direction2 < 0 ? 100 : -100,
715
- opacity: 0
716
- })
717
- }), []);
718
- const currentFeature = features[activeIndex];
719
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex flex-col items-center gap-6 md:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-between gap-4", children: [
720
- /* @__PURE__ */ jsxRuntime.jsx(
721
- "button",
722
- {
723
- className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
724
- onClick: handlePrevious,
725
- disabled: isPreviousDisabled,
726
- type: "button",
727
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-left", size: 24 })
728
- }
729
- ),
730
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-24 w-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
731
- framerMotion.motion.div,
732
- {
733
- custom: direction,
734
- variants,
735
- initial: "enter",
736
- animate: "center",
737
- exit: "exit",
738
- transition: {
739
- x: { type: "spring", stiffness: 300, damping: 30 },
740
- opacity: { duration: 0.2 }
1178
+ className: "rounded-3xl bg-background p-4 text-left",
1179
+ children: (currentFeature?.title || currentFeature?.description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm", children: [
1180
+ currentFeature.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: currentFeature.title }),
1181
+ currentFeature.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1", children: currentFeature.description })
1182
+ ] })
741
1183
  },
742
- className: "absolute inset-0 flex items-center justify-center rounded-3xl bg-background p-4",
743
- children: (currentFeature?.title || currentFeature?.description) && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm", children: [
744
- currentFeature.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
745
- currentFeature.title,
746
- "."
747
- ] }),
748
- currentFeature.title && currentFeature.description && " ",
749
- currentFeature.description && /* @__PURE__ */ jsxRuntime.jsx("span", { children: currentFeature.description })
750
- ] })
751
- },
752
- activeIndex
753
- ) }) }),
754
- /* @__PURE__ */ jsxRuntime.jsx(
755
- "button",
756
- {
757
- className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
758
- onClick: handleNext,
759
- disabled: isNextDisabled,
760
- type: "button",
761
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24 })
762
- }
763
- )
764
- ] }) });
765
- });
1184
+ activeIndex
1185
+ ) }) }),
1186
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center gap-2", children: [
1187
+ /* @__PURE__ */ jsxRuntime.jsx(
1188
+ "button",
1189
+ {
1190
+ className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
1191
+ onClick: handlePrevious,
1192
+ disabled: isPreviousDisabled,
1193
+ type: "button",
1194
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-up", size: 20 })
1195
+ }
1196
+ ),
1197
+ /* @__PURE__ */ jsxRuntime.jsx(
1198
+ "button",
1199
+ {
1200
+ className: "rounded-full border bg-background/50 p-2 hover:bg-background disabled:opacity-50",
1201
+ onClick: handleNext,
1202
+ disabled: isNextDisabled,
1203
+ type: "button",
1204
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-down", size: 20 })
1205
+ }
1206
+ )
1207
+ ] })
1208
+ ] }) });
1209
+ }
1210
+ );
766
1211
  function FeatureAnimatedCarousel({
1212
+ title,
1213
+ description,
1214
+ titleClassName,
1215
+ descriptionClassName,
767
1216
  features,
768
1217
  className,
769
1218
  optixFlowConfig,
770
1219
  background,
771
- spacing,
772
1220
  pattern,
773
1221
  patternOpacity,
774
- patternClassName
1222
+ patternClassName,
1223
+ headerClassName,
1224
+ spacing = "py-12 md:py-32",
1225
+ containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8"
775
1226
  }) {
776
- const [activeIndex, setActiveIndex] = React4__namespace.useState(0);
777
- const [direction, setDirection] = React4__namespace.useState(1);
778
- const handleNext = React4.useCallback(() => {
1227
+ const [activeIndex, setActiveIndex] = React6__namespace.useState(0);
1228
+ const [direction, setDirection] = React6__namespace.useState(1);
1229
+ const handleNext = React6.useCallback(() => {
779
1230
  if (features && activeIndex < features.length - 1) {
780
1231
  setDirection(1);
781
1232
  setActiveIndex(activeIndex + 1);
782
1233
  }
783
1234
  }, [activeIndex, features]);
784
- const handlePrevious = React4.useCallback(() => {
1235
+ const handlePrevious = React6.useCallback(() => {
785
1236
  if (activeIndex > 0) {
786
1237
  setDirection(-1);
787
1238
  setActiveIndex(activeIndex - 1);
788
1239
  }
789
1240
  }, [activeIndex]);
790
- const handleFeatureClick = React4.useCallback((index) => {
791
- setDirection(index > activeIndex ? 1 : -1);
792
- setActiveIndex(index);
793
- }, [activeIndex]);
1241
+ const handleFeatureClick = React6.useCallback(
1242
+ (index) => {
1243
+ setDirection(index > activeIndex ? 1 : -1);
1244
+ setActiveIndex(index);
1245
+ },
1246
+ [activeIndex]
1247
+ );
794
1248
  const isPreviousDisabled = activeIndex === 0;
795
1249
  const isNextDisabled = !features || activeIndex === features.length - 1;
796
- const imageVariants = React4.useMemo(() => ({
797
- enter: (direction2) => ({
798
- x: direction2 > 0 ? 300 : -300,
799
- opacity: 0
1250
+ const imageVariants = React6.useMemo(
1251
+ () => ({
1252
+ enter: (direction2) => ({
1253
+ x: direction2 > 0 ? 300 : -300,
1254
+ opacity: 0
1255
+ }),
1256
+ center: {
1257
+ x: 0,
1258
+ opacity: 1
1259
+ },
1260
+ exit: (direction2) => ({
1261
+ x: direction2 < 0 ? 300 : -300,
1262
+ opacity: 0
1263
+ })
800
1264
  }),
801
- center: {
802
- x: 0,
803
- opacity: 1
804
- },
805
- exit: (direction2) => ({
806
- x: direction2 < 0 ? 300 : -300,
807
- opacity: 0
808
- })
809
- }), []);
1265
+ []
1266
+ );
810
1267
  if (!features || features.length === 0) {
811
1268
  return /* @__PURE__ */ jsxRuntime.jsx(
812
1269
  Section,
@@ -817,11 +1274,17 @@ function FeatureAnimatedCarousel({
817
1274
  patternOpacity,
818
1275
  patternClassName,
819
1276
  className,
820
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
821
- "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]",
822
- getNestedCardBg(background),
823
- getNestedCardTextColor(background)
824
- ) })
1277
+ containerClassName,
1278
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1279
+ "div",
1280
+ {
1281
+ className: cn(
1282
+ "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]",
1283
+ getNestedCardBg(background),
1284
+ getNestedCardTextColor(background)
1285
+ )
1286
+ }
1287
+ )
825
1288
  }
826
1289
  );
827
1290
  }
@@ -835,60 +1298,105 @@ function FeatureAnimatedCarousel({
835
1298
  patternOpacity,
836
1299
  patternClassName,
837
1300
  className,
838
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
839
- "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]",
840
- getNestedCardBg(background),
841
- getNestedCardTextColor(background)
842
- ), children: [
843
- /* @__PURE__ */ jsxRuntime.jsx(
844
- FeaturesDesktop,
845
- {
846
- features,
847
- handleNext,
848
- handlePrevious,
849
- activeIndex,
850
- handleFeatureClick,
851
- isPreviousDisabled,
852
- isNextDisabled
853
- }
854
- ),
855
- /* @__PURE__ */ jsxRuntime.jsx(
856
- FeaturesMobile,
1301
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-6 md:space-y-16", children: [
1302
+ title || description ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-6 text-left", headerClassName), children: [
1303
+ title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1304
+ "h2",
1305
+ {
1306
+ className: cn(
1307
+ "text-xl font-semibold text-balance md:text-2xl lg:text-3xl max-w-lg md:max-w-md",
1308
+ titleClassName
1309
+ ),
1310
+ children: title
1311
+ }
1312
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1313
+ "div",
1314
+ {
1315
+ className: cn(
1316
+ "text-xl font-semibold text-balance md:text-2xl lg:text-3xl max-w-lg md:max-w-md",
1317
+ titleClassName
1318
+ ),
1319
+ children: title
1320
+ }
1321
+ )),
1322
+ description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("max-w-lg md:max-w-md", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx(
1323
+ "div",
1324
+ {
1325
+ className: cn("max-w-lg md:max-w-md", descriptionClassName),
1326
+ children: description
1327
+ }
1328
+ ))
1329
+ ] }) : null,
1330
+ /* @__PURE__ */ jsxRuntime.jsxs(
1331
+ "div",
857
1332
  {
858
- features,
859
- handleNext,
860
- handlePrevious,
861
- activeIndex,
862
- direction,
863
- isPreviousDisabled,
864
- isNextDisabled
1333
+ className: cn(
1334
+ "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]"
1335
+ ),
1336
+ children: [
1337
+ /* @__PURE__ */ jsxRuntime.jsx(
1338
+ FeaturesDesktop,
1339
+ {
1340
+ features,
1341
+ handleNext,
1342
+ handlePrevious,
1343
+ activeIndex,
1344
+ handleFeatureClick,
1345
+ isPreviousDisabled,
1346
+ isNextDisabled
1347
+ }
1348
+ ),
1349
+ /* @__PURE__ */ jsxRuntime.jsx(
1350
+ FeaturesMobile,
1351
+ {
1352
+ features,
1353
+ handleNext,
1354
+ handlePrevious,
1355
+ activeIndex,
1356
+ direction,
1357
+ isPreviousDisabled,
1358
+ isNextDisabled
1359
+ }
1360
+ ),
1361
+ currentFeature?.image && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-[250px] md:h-auto overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2 shadow-xl", children: [
1362
+ currentFeature.href && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-4 right-4 z-10 bg-background rounded-full h-fit w-fit p-2 flex items-center justify-center md:hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
1363
+ Pressable,
1364
+ {
1365
+ href: currentFeature.href,
1366
+ size: "icon-lg",
1367
+ className: "text-foreground",
1368
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-up-right" })
1369
+ }
1370
+ ) }),
1371
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
1372
+ framerMotion.motion.div,
1373
+ {
1374
+ custom: direction,
1375
+ variants: imageVariants,
1376
+ initial: "enter",
1377
+ animate: "center",
1378
+ exit: "exit",
1379
+ transition: {
1380
+ x: { type: "spring", stiffness: 300, damping: 30 },
1381
+ opacity: { duration: 0.2 }
1382
+ },
1383
+ className: "h-full w-full",
1384
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1385
+ img.Img,
1386
+ {
1387
+ src: currentFeature.image,
1388
+ alt: currentFeature.imageAlt || (typeof currentFeature.title === "string" ? currentFeature.title : "Feature image"),
1389
+ className: "h-full w-full object-cover",
1390
+ optixFlowConfig
1391
+ }
1392
+ )
1393
+ },
1394
+ activeIndex
1395
+ ) })
1396
+ ] })
1397
+ ]
865
1398
  }
866
- ),
867
- currentFeature?.image && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
868
- framerMotion.motion.div,
869
- {
870
- custom: direction,
871
- variants: imageVariants,
872
- initial: "enter",
873
- animate: "center",
874
- exit: "exit",
875
- transition: {
876
- x: { type: "spring", stiffness: 300, damping: 30 },
877
- opacity: { duration: 0.2 }
878
- },
879
- className: "h-full w-full",
880
- children: /* @__PURE__ */ jsxRuntime.jsx(
881
- img.Img,
882
- {
883
- src: currentFeature.image,
884
- alt: currentFeature.imageAlt || (typeof currentFeature.title === "string" ? currentFeature.title : "Feature image"),
885
- className: "h-full w-full object-cover",
886
- optixFlowConfig
887
- }
888
- )
889
- },
890
- activeIndex
891
- ) }) })
1399
+ )
892
1400
  ] })
893
1401
  }
894
1402
  );