@opensite/ui 1.2.2 → 1.2.4

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 (51) hide show
  1. package/dist/auto-scroll-carousel.cjs +2 -2
  2. package/dist/auto-scroll-carousel.js +2 -2
  3. package/dist/blur-vignette-grid.cjs +13 -17
  4. package/dist/blur-vignette-grid.d.cts +2 -2
  5. package/dist/blur-vignette-grid.d.ts +2 -2
  6. package/dist/blur-vignette-grid.js +13 -17
  7. package/dist/carousel-gradient-text.cjs +8 -10
  8. package/dist/carousel-gradient-text.js +8 -10
  9. package/dist/carousel-icon-sidebar.cjs +48 -29
  10. package/dist/carousel-icon-sidebar.js +48 -29
  11. package/dist/carousel-scale-focus.cjs +27 -1
  12. package/dist/carousel-scale-focus.js +27 -1
  13. package/dist/carousel-tabs-content.cjs +46 -36
  14. package/dist/carousel-tabs-content.js +46 -36
  15. package/dist/expandable-case-study-cards.cjs +1 -0
  16. package/dist/expandable-case-study-cards.js +1 -0
  17. package/dist/feature-capabilities-grid.cjs +525 -54
  18. package/dist/feature-capabilities-grid.d.cts +4 -0
  19. package/dist/feature-capabilities-grid.d.ts +4 -0
  20. package/dist/feature-capabilities-grid.js +525 -54
  21. package/dist/feature-card-grid-linked.cjs +40 -35
  22. package/dist/feature-card-grid-linked.d.cts +9 -1
  23. package/dist/feature-card-grid-linked.d.ts +9 -1
  24. package/dist/feature-card-grid-linked.js +40 -35
  25. package/dist/feature-carousel-progress.cjs +129 -56
  26. package/dist/feature-carousel-progress.d.cts +13 -1
  27. package/dist/feature-carousel-progress.d.ts +13 -1
  28. package/dist/feature-carousel-progress.js +129 -56
  29. package/dist/feature-checklist-image.cjs +61 -105
  30. package/dist/feature-checklist-image.d.cts +1 -1
  31. package/dist/feature-checklist-image.d.ts +1 -1
  32. package/dist/feature-checklist-image.js +61 -105
  33. package/dist/feature-icon-grid-bordered.cjs +457 -35
  34. package/dist/feature-icon-grid-bordered.d.cts +4 -0
  35. package/dist/feature-icon-grid-bordered.d.ts +4 -0
  36. package/dist/feature-icon-grid-bordered.js +457 -35
  37. package/dist/feature-numbered-cards.cjs +519 -35
  38. package/dist/feature-numbered-cards.d.cts +18 -2
  39. package/dist/feature-numbered-cards.d.ts +18 -2
  40. package/dist/feature-numbered-cards.js +520 -36
  41. package/dist/feature-split-image.cjs +1 -1
  42. package/dist/feature-split-image.js +1 -1
  43. package/dist/masonry-motion-grid.cjs +2 -2
  44. package/dist/masonry-motion-grid.js +2 -2
  45. package/dist/registry.cjs +10264 -9952
  46. package/dist/registry.js +10262 -9950
  47. package/dist/testimonial-carousel-cards.cjs +28 -8
  48. package/dist/testimonial-carousel-cards.d.cts +8 -0
  49. package/dist/testimonial-carousel-cards.d.ts +8 -0
  50. package/dist/testimonial-carousel-cards.js +28 -8
  51. package/package.json +1 -1
@@ -4,6 +4,7 @@ import React__default, { useCallback, useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import { cva } from 'class-variance-authority';
7
8
 
8
9
  // components/blocks/features/feature-icon-grid-bordered.tsx
9
10
  function cn(...inputs) {
@@ -493,19 +494,437 @@ var Section = React__default.forwardRef(
493
494
  }
494
495
  );
495
496
  Section.displayName = "Section";
497
+ var baseStyles = [
498
+ // Layout
499
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
500
+ // Typography - using CSS variables with sensible defaults
501
+ "font-[var(--button-font-family,inherit)]",
502
+ "font-[var(--button-font-weight,500)]",
503
+ "tracking-[var(--button-letter-spacing,0)]",
504
+ "leading-[var(--button-line-height,1.25)]",
505
+ "[text-transform:var(--button-text-transform,none)]",
506
+ "text-sm",
507
+ // Border radius
508
+ "rounded-[var(--button-radius,var(--radius,0.375rem))]",
509
+ // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
510
+ "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
511
+ // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
512
+ "[box-shadow:var(--button-shadow,none)]",
513
+ "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
514
+ // Disabled state
515
+ "disabled:pointer-events-none disabled:opacity-50",
516
+ // SVG handling
517
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
518
+ // Focus styles
519
+ "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
520
+ // Invalid state
521
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
522
+ ].join(" ");
523
+ var buttonVariants = cva(baseStyles, {
524
+ variants: {
525
+ variant: {
526
+ // Default (Primary) variant - full customization
527
+ default: [
528
+ "bg-[var(--button-default-bg,hsl(var(--primary)))]",
529
+ "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
530
+ "border-[length:var(--button-default-border-width,0px)]",
531
+ "border-[color:var(--button-default-border,transparent)]",
532
+ "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
533
+ "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
534
+ "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
535
+ "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
536
+ "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
537
+ ].join(" "),
538
+ // Destructive variant - full customization
539
+ destructive: [
540
+ "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
541
+ "text-[var(--button-destructive-fg,white)]",
542
+ "border-[length:var(--button-destructive-border-width,0px)]",
543
+ "border-[color:var(--button-destructive-border,transparent)]",
544
+ "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
545
+ "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
546
+ "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
547
+ "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
548
+ "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
549
+ "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
550
+ "dark:bg-destructive/60"
551
+ ].join(" "),
552
+ // Outline variant - full customization with proper border handling
553
+ outline: [
554
+ "bg-[var(--button-outline-bg,hsl(var(--background)))]",
555
+ "text-[var(--button-outline-fg,inherit)]",
556
+ "border-[length:var(--button-outline-border-width,1px)]",
557
+ "border-[color:var(--button-outline-border,hsl(var(--border)))]",
558
+ "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
559
+ "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
560
+ "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
561
+ "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
562
+ "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
563
+ "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
564
+ ].join(" "),
565
+ // Secondary variant - full customization
566
+ secondary: [
567
+ "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
568
+ "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
569
+ "border-[length:var(--button-secondary-border-width,0px)]",
570
+ "border-[color:var(--button-secondary-border,transparent)]",
571
+ "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
572
+ "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
573
+ "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
574
+ "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
575
+ "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
576
+ ].join(" "),
577
+ // Ghost variant - full customization
578
+ ghost: [
579
+ "bg-[var(--button-ghost-bg,transparent)]",
580
+ "text-[var(--button-ghost-fg,inherit)]",
581
+ "border-[length:var(--button-ghost-border-width,0px)]",
582
+ "border-[color:var(--button-ghost-border,transparent)]",
583
+ "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
584
+ "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
585
+ "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
586
+ "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
587
+ "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
588
+ "dark:hover:bg-accent/50"
589
+ ].join(" "),
590
+ // Link variant - full customization
591
+ link: [
592
+ "bg-[var(--button-link-bg,transparent)]",
593
+ "text-[var(--button-link-fg,hsl(var(--primary)))]",
594
+ "border-[length:var(--button-link-border-width,0px)]",
595
+ "border-[color:var(--button-link-border,transparent)]",
596
+ "[box-shadow:var(--button-link-shadow,none)]",
597
+ "hover:bg-[var(--button-link-hover-bg,transparent)]",
598
+ "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
599
+ "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
600
+ "underline-offset-4 hover:underline"
601
+ ].join(" ")
602
+ },
603
+ size: {
604
+ default: [
605
+ "h-[var(--button-height-md,2.25rem)]",
606
+ "px-[var(--button-padding-x-md,1rem)]",
607
+ "py-[var(--button-padding-y-md,0.5rem)]",
608
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
609
+ ].join(" "),
610
+ sm: [
611
+ "h-[var(--button-height-sm,2rem)]",
612
+ "px-[var(--button-padding-x-sm,0.75rem)]",
613
+ "py-[var(--button-padding-y-sm,0.25rem)]",
614
+ "gap-1.5",
615
+ "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
616
+ ].join(" "),
617
+ md: [
618
+ "h-[var(--button-height-md,2.25rem)]",
619
+ "px-[var(--button-padding-x-md,1rem)]",
620
+ "py-[var(--button-padding-y-md,0.5rem)]",
621
+ "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
622
+ ].join(" "),
623
+ lg: [
624
+ "h-[var(--button-height-lg,2.5rem)]",
625
+ "px-[var(--button-padding-x-lg,1.5rem)]",
626
+ "py-[var(--button-padding-y-lg,0.5rem)]",
627
+ "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
628
+ ].join(" "),
629
+ icon: "size-[var(--button-height-md,2.25rem)]",
630
+ "icon-sm": "size-[var(--button-height-sm,2rem)]",
631
+ "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
632
+ }
633
+ },
634
+ defaultVariants: {
635
+ variant: "default",
636
+ size: "default"
637
+ }
638
+ });
639
+ function normalizePhoneNumber(input) {
640
+ const trimmed = input.trim();
641
+ if (trimmed.toLowerCase().startsWith("tel:")) {
642
+ return trimmed;
643
+ }
644
+ const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
645
+ if (match) {
646
+ const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
647
+ const extension = match[3];
648
+ const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
649
+ const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
650
+ return `tel:${withExtension}`;
651
+ }
652
+ const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
653
+ return `tel:${cleaned}`;
654
+ }
655
+ function normalizeEmail(input) {
656
+ const trimmed = input.trim();
657
+ if (trimmed.toLowerCase().startsWith("mailto:")) {
658
+ return trimmed;
659
+ }
660
+ return `mailto:${trimmed}`;
661
+ }
662
+ function isEmail(input) {
663
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
664
+ return emailRegex.test(input.trim());
665
+ }
666
+ function isPhoneNumber(input) {
667
+ const trimmed = input.trim();
668
+ if (trimmed.toLowerCase().startsWith("tel:")) {
669
+ return true;
670
+ }
671
+ const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
672
+ return phoneRegex.test(trimmed);
673
+ }
674
+ function isInternalUrl(href) {
675
+ if (typeof window === "undefined") {
676
+ return href.startsWith("/") && !href.startsWith("//");
677
+ }
678
+ const trimmed = href.trim();
679
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
680
+ return true;
681
+ }
682
+ try {
683
+ const url = new URL(trimmed, window.location.href);
684
+ const currentOrigin = window.location.origin;
685
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
686
+ return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
687
+ } catch {
688
+ return false;
689
+ }
690
+ }
691
+ function toRelativePath(href) {
692
+ if (typeof window === "undefined") {
693
+ return href;
694
+ }
695
+ const trimmed = href.trim();
696
+ if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
697
+ return trimmed;
698
+ }
699
+ try {
700
+ const url = new URL(trimmed, window.location.href);
701
+ const currentOrigin = window.location.origin;
702
+ const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
703
+ if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
704
+ return url.pathname + url.search + url.hash;
705
+ }
706
+ } catch {
707
+ }
708
+ return trimmed;
709
+ }
710
+ function useNavigation({
711
+ href,
712
+ onClick
713
+ } = {}) {
714
+ const linkType = React.useMemo(() => {
715
+ if (!href || href.trim() === "") {
716
+ return onClick ? "none" : "none";
717
+ }
718
+ const trimmed = href.trim();
719
+ if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
720
+ return "mailto";
721
+ }
722
+ if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
723
+ return "tel";
724
+ }
725
+ if (isInternalUrl(trimmed)) {
726
+ return "internal";
727
+ }
728
+ try {
729
+ new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
730
+ return "external";
731
+ } catch {
732
+ return "internal";
733
+ }
734
+ }, [href, onClick]);
735
+ const normalizedHref = React.useMemo(() => {
736
+ if (!href || href.trim() === "") {
737
+ return void 0;
738
+ }
739
+ const trimmed = href.trim();
740
+ switch (linkType) {
741
+ case "tel":
742
+ return normalizePhoneNumber(trimmed);
743
+ case "mailto":
744
+ return normalizeEmail(trimmed);
745
+ case "internal":
746
+ return toRelativePath(trimmed);
747
+ case "external":
748
+ return trimmed;
749
+ default:
750
+ return trimmed;
751
+ }
752
+ }, [href, linkType]);
753
+ const target = React.useMemo(() => {
754
+ switch (linkType) {
755
+ case "external":
756
+ return "_blank";
757
+ case "internal":
758
+ return "_self";
759
+ case "mailto":
760
+ case "tel":
761
+ return void 0;
762
+ default:
763
+ return void 0;
764
+ }
765
+ }, [linkType]);
766
+ const rel = React.useMemo(() => {
767
+ if (linkType === "external") {
768
+ return "noopener noreferrer";
769
+ }
770
+ return void 0;
771
+ }, [linkType]);
772
+ const isExternal = linkType === "external";
773
+ const isInternal = linkType === "internal";
774
+ const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
775
+ const handleClick = React.useCallback(
776
+ (event) => {
777
+ if (onClick) {
778
+ try {
779
+ onClick(event);
780
+ } catch (error) {
781
+ console.error("Error in user onClick handler:", error);
782
+ }
783
+ }
784
+ if (event.defaultPrevented) {
785
+ return;
786
+ }
787
+ if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
788
+ !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
789
+ if (typeof window !== "undefined") {
790
+ const handler = window.__opensiteNavigationHandler;
791
+ if (typeof handler === "function") {
792
+ try {
793
+ const handled = handler(normalizedHref, event.nativeEvent || event);
794
+ if (handled !== false) {
795
+ event.preventDefault();
796
+ }
797
+ } catch (error) {
798
+ console.error("Error in navigation handler:", error);
799
+ }
800
+ }
801
+ }
802
+ }
803
+ },
804
+ [onClick, shouldUseRouter, normalizedHref]
805
+ );
806
+ return {
807
+ linkType,
808
+ normalizedHref,
809
+ target,
810
+ rel,
811
+ isExternal,
812
+ isInternal,
813
+ shouldUseRouter,
814
+ handleClick
815
+ };
816
+ }
817
+ var Pressable = React.forwardRef(
818
+ ({
819
+ children,
820
+ className,
821
+ href,
822
+ onClick,
823
+ variant,
824
+ size,
825
+ asButton = false,
826
+ fallbackComponentType = "span",
827
+ componentType,
828
+ "aria-label": ariaLabel,
829
+ "aria-describedby": ariaDescribedby,
830
+ id,
831
+ ...props
832
+ }, ref) => {
833
+ const navigation = useNavigation({ href, onClick });
834
+ const {
835
+ normalizedHref,
836
+ target,
837
+ rel,
838
+ linkType,
839
+ isInternal,
840
+ handleClick
841
+ } = navigation;
842
+ const shouldRenderLink = normalizedHref && linkType !== "none";
843
+ const shouldRenderButton = !shouldRenderLink && onClick;
844
+ const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
845
+ const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
846
+ const shouldApplyButtonStyles = asButton || variant || size;
847
+ const combinedClassName = cn(
848
+ shouldApplyButtonStyles && buttonVariants({ variant, size }),
849
+ className
850
+ );
851
+ const dataProps = Object.fromEntries(
852
+ Object.entries(props).filter(([key]) => key.startsWith("data-"))
853
+ );
854
+ const buttonDataAttributes = shouldApplyButtonStyles ? {
855
+ "data-slot": "button",
856
+ "data-variant": variant ?? "default",
857
+ "data-size": size ?? "default"
858
+ } : {};
859
+ const commonProps = {
860
+ className: combinedClassName,
861
+ onClick: handleClick,
862
+ "aria-label": ariaLabel,
863
+ "aria-describedby": ariaDescribedby,
864
+ id,
865
+ ...dataProps,
866
+ ...buttonDataAttributes
867
+ };
868
+ if (finalComponentType === "a" && shouldRenderLink) {
869
+ return /* @__PURE__ */ jsx(
870
+ "a",
871
+ {
872
+ ref,
873
+ href: normalizedHref,
874
+ target,
875
+ rel,
876
+ ...commonProps,
877
+ ...props,
878
+ children
879
+ }
880
+ );
881
+ }
882
+ if (finalComponentType === "button") {
883
+ return /* @__PURE__ */ jsx(
884
+ "button",
885
+ {
886
+ ref,
887
+ type: props.type || "button",
888
+ ...commonProps,
889
+ ...props,
890
+ children
891
+ }
892
+ );
893
+ }
894
+ if (finalComponentType === "div") {
895
+ return /* @__PURE__ */ jsx(
896
+ "div",
897
+ {
898
+ ref,
899
+ ...commonProps,
900
+ children
901
+ }
902
+ );
903
+ }
904
+ return /* @__PURE__ */ jsx(
905
+ "span",
906
+ {
907
+ ref,
908
+ ...commonProps,
909
+ children
910
+ }
911
+ );
912
+ }
913
+ );
914
+ Pressable.displayName = "Pressable";
496
915
  function FeatureIconGridBordered({
497
916
  label,
498
917
  title,
499
918
  features,
500
919
  featuresSlot,
501
920
  className,
502
- containerClassName,
921
+ containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
503
922
  labelClassName,
504
923
  titleClassName,
505
924
  gridClassName,
506
925
  cardClassName,
507
926
  background,
508
- spacing = "py-6 md:py-32",
927
+ spacing = "py-12 md:py-32",
509
928
  pattern,
510
929
  patternOpacity,
511
930
  patternClassName
@@ -524,7 +943,7 @@ function FeatureIconGridBordered({
524
943
  "div",
525
944
  {
526
945
  className: cn(
527
- "relative flex gap-3 rounded-lg border-dashed md:block md:border-l md:p-5",
946
+ "relative flex gap-3 rounded-none border-dashed md:block md:border-l md:p-5",
528
947
  cardClassName,
529
948
  feature.className
530
949
  ),
@@ -533,7 +952,7 @@ function FeatureIconGridBordered({
533
952
  "span",
534
953
  {
535
954
  className: cn(
536
- "mb-8 flex size-10 shrink-0 items-center justify-center rounded-full text-primary-foreground md:size-12",
955
+ "mb-8 flex size-10 shrink-0 items-center justify-center rounded-full text-primary-foreground md:size-16",
537
956
  getAccentColor(background),
538
957
  feature.iconClassName
539
958
  ),
@@ -541,29 +960,24 @@ function FeatureIconGridBordered({
541
960
  }
542
961
  ),
543
962
  /* @__PURE__ */ jsxs("div", { children: [
544
- feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxs(
545
- "h3",
963
+ feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsx(
964
+ Pressable,
546
965
  {
966
+ href: feature.href,
547
967
  className: cn(
548
- "font-medium md:mb-2 md:text-xl",
968
+ "font-medium md:mb-2 text-xl",
549
969
  feature.titleClassName
550
970
  ),
551
- children: [
552
- feature.title,
553
- /* @__PURE__ */ jsx("span", { className: cn("absolute -left-px hidden h-6 w-px md:inline-block", getAccentColor(background)) })
554
- ]
971
+ children: feature.title
555
972
  }
556
- ) : /* @__PURE__ */ jsxs(
973
+ ) : /* @__PURE__ */ jsx(
557
974
  "div",
558
975
  {
559
976
  className: cn(
560
- "font-medium md:mb-2 md:text-xl",
977
+ "font-medium md:mb-2 text-xl",
561
978
  feature.titleClassName
562
979
  ),
563
- children: [
564
- feature.title,
565
- /* @__PURE__ */ jsx("span", { className: cn("absolute -left-px hidden h-6 w-px md:inline-block", getAccentColor(background)) })
566
- ]
980
+ children: feature.title
567
981
  }
568
982
  )),
569
983
  feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx(
@@ -591,7 +1005,7 @@ function FeatureIconGridBordered({
591
1005
  index
592
1006
  ));
593
1007
  }, [featuresSlot, features, cardClassName, renderIcon, background]);
594
- return /* @__PURE__ */ jsxs(
1008
+ return /* @__PURE__ */ jsx(
595
1009
  Section,
596
1010
  {
597
1011
  background,
@@ -601,32 +1015,40 @@ function FeatureIconGridBordered({
601
1015
  patternClassName,
602
1016
  className,
603
1017
  containerClassName,
604
- children: [
605
- label && (typeof label === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mb-4 text-xs ", labelClassName), children: label }) : /* @__PURE__ */ jsx("div", { className: cn("mb-4 text-xs ", labelClassName), children: label })),
606
- title && (typeof title === "string" ? /* @__PURE__ */ jsx(
607
- "h2",
608
- {
609
- className: cn("text-3xl font-medium lg:text-4xl", titleClassName),
610
- children: title
611
- }
612
- ) : /* @__PURE__ */ jsx(
613
- "div",
614
- {
615
- className: cn("text-3xl font-medium lg:text-4xl", titleClassName),
616
- children: title
617
- }
618
- )),
1018
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-6 md:space-y-16", children: [
1019
+ label || title ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
1020
+ label && (typeof label === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mb-4 text-sm", labelClassName), children: label }) : /* @__PURE__ */ jsx("div", { className: cn("mb-4 text-sm", labelClassName), children: label })),
1021
+ title && (typeof title === "string" ? /* @__PURE__ */ jsx(
1022
+ "h2",
1023
+ {
1024
+ className: cn(
1025
+ "text-3xl font-medium lg:text-4xl",
1026
+ titleClassName
1027
+ ),
1028
+ children: title
1029
+ }
1030
+ ) : /* @__PURE__ */ jsx(
1031
+ "div",
1032
+ {
1033
+ className: cn(
1034
+ "text-3xl font-medium lg:text-4xl",
1035
+ titleClassName
1036
+ ),
1037
+ children: title
1038
+ }
1039
+ ))
1040
+ ] }) : null,
619
1041
  (featuresSlot || features && features.length > 0) && /* @__PURE__ */ jsx(
620
1042
  "div",
621
1043
  {
622
1044
  className: cn(
623
- "mt-14 grid gap-6 md:grid-cols-2 lg:mt-20 lg:grid-cols-4",
1045
+ "grid gap-6 md:grid-cols-2 lg:grid-cols-4",
624
1046
  gridClassName
625
1047
  ),
626
1048
  children: featuresContent
627
1049
  }
628
1050
  )
629
- ]
1051
+ ] })
630
1052
  }
631
1053
  );
632
1054
  }