@planetaexo/design-system 0.52.3 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { cva } from 'class-variance-authority';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, CopyIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, ArrowRightIcon, LayoutGridIcon } from 'lucide-react';
7
+ import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, ArrowRightIcon, Loader2Icon, SendIcon, CheckCircleIcon, ArrowDownIcon, SparkleIcon, Share2Icon, CopyIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, LayoutGridIcon } from 'lucide-react';
8
8
  import { Separator as Separator$1 } from '@base-ui/react/separator';
9
9
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
10
10
  import { Button as Button$1 } from '@base-ui/react/button';
@@ -1256,16 +1256,47 @@ var VARIANT_STYLES = {
1256
1256
  success: "text-primary border-primary/30 bg-primary/10",
1257
1257
  info: "text-muted-foreground border-primary/25 bg-primary/5"
1258
1258
  };
1259
- function Alert({ variant = "info", children, className }) {
1260
- return /* @__PURE__ */ jsx(
1259
+ function Alert({
1260
+ variant = "info",
1261
+ title,
1262
+ icon,
1263
+ action,
1264
+ role = "status",
1265
+ children,
1266
+ className
1267
+ }) {
1268
+ const isBanner = Boolean(title || icon || action);
1269
+ if (!isBanner) {
1270
+ return /* @__PURE__ */ jsx(
1271
+ "div",
1272
+ {
1273
+ role,
1274
+ className: cn(
1275
+ "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
1276
+ VARIANT_STYLES[variant],
1277
+ className
1278
+ ),
1279
+ children
1280
+ }
1281
+ );
1282
+ }
1283
+ return /* @__PURE__ */ jsxs(
1261
1284
  "div",
1262
1285
  {
1286
+ role,
1263
1287
  className: cn(
1264
- "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
1288
+ "flex items-start gap-3 rounded-lg border px-4 py-3 text-sm font-sans leading-snug",
1265
1289
  VARIANT_STYLES[variant],
1266
1290
  className
1267
1291
  ),
1268
- children
1292
+ children: [
1293
+ icon && /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 [&>svg]:size-4", "aria-hidden": "true", children: icon }),
1294
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
1295
+ title && /* @__PURE__ */ jsx("p", { className: "font-ui font-bold text-current leading-snug", children: title }),
1296
+ children && /* @__PURE__ */ jsx("div", { className: cn(title && "mt-0.5", "text-current/90"), children })
1297
+ ] }),
1298
+ action && /* @__PURE__ */ jsx("div", { className: "shrink-0 self-center", children: action })
1299
+ ]
1269
1300
  }
1270
1301
  );
1271
1302
  }
@@ -11021,7 +11052,12 @@ var badgeVariants = cva(
11021
11052
  destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
11022
11053
  outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
11023
11054
  ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
11024
- link: "text-primary underline-offset-4 hover:underline"
11055
+ link: "text-primary underline-offset-4 hover:underline",
11056
+ // ── Semantic soft tones (added for status surfaces) ────────────────
11057
+ success: "bg-success/10 text-success border-success/20 [a]:hover:bg-success/20",
11058
+ warning: "bg-warning/15 text-warning-foreground border-warning/30 dark:bg-warning/20 dark:text-warning [a]:hover:bg-warning/25",
11059
+ info: "bg-info/10 text-info border-info/20 [a]:hover:bg-info/20",
11060
+ neutral: "bg-muted text-muted-foreground border-border [a]:hover:bg-muted/70"
11025
11061
  }
11026
11062
  },
11027
11063
  defaultVariants: {
@@ -13493,7 +13529,385 @@ function TripPage({
13493
13529
  }
13494
13530
  );
13495
13531
  }
13532
+ function ArrowIcon2() {
13533
+ return /* @__PURE__ */ jsxs(
13534
+ "svg",
13535
+ {
13536
+ width: "13",
13537
+ height: "13",
13538
+ viewBox: "0 0 24 24",
13539
+ fill: "none",
13540
+ stroke: "currentColor",
13541
+ strokeWidth: "2.2",
13542
+ strokeLinecap: "round",
13543
+ strokeLinejoin: "round",
13544
+ children: [
13545
+ /* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
13546
+ /* @__PURE__ */ jsx("polyline", { points: "12 5 19 12 12 19" })
13547
+ ]
13548
+ }
13549
+ );
13550
+ }
13496
13551
  var sizeConfig2 = {
13552
+ sm: {
13553
+ card: "h-72 w-56",
13554
+ title: "text-lg font-bold",
13555
+ meta: "text-xs",
13556
+ excerpt: "text-xs"
13557
+ },
13558
+ md: {
13559
+ card: "h-96 w-72",
13560
+ title: "text-xl font-bold",
13561
+ meta: "text-xs",
13562
+ excerpt: "text-sm"
13563
+ },
13564
+ lg: {
13565
+ card: "h-[28rem] w-96",
13566
+ title: "text-2xl font-bold",
13567
+ meta: "text-sm",
13568
+ excerpt: "text-sm"
13569
+ }
13570
+ };
13571
+ function BlogCard({
13572
+ image,
13573
+ imageAlt = "",
13574
+ category,
13575
+ readingTime,
13576
+ date,
13577
+ title,
13578
+ excerpt,
13579
+ href,
13580
+ cta,
13581
+ size = "md",
13582
+ className
13583
+ }) {
13584
+ var _a;
13585
+ const s = sizeConfig2[size];
13586
+ const meta = [date != null ? date : null, readingTime != null ? readingTime : null].filter(Boolean).join(" | ");
13587
+ const ctaLabel = (_a = cta == null ? void 0 : cta.label) != null ? _a : "Read more";
13588
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
13589
+ /* @__PURE__ */ jsx(
13590
+ "img",
13591
+ {
13592
+ src: image,
13593
+ alt: imageAlt,
13594
+ loading: "lazy",
13595
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
13596
+ }
13597
+ ),
13598
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 to-black/10" }),
13599
+ category ? /* @__PURE__ */ jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsx(Chip, { variant: "glass", children: category }) }) : /* @__PURE__ */ jsx("div", { className: "relative z-10" }),
13600
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
13601
+ meta && /* @__PURE__ */ jsx("p", { className: cn("text-white/70 font-medium font-ui", s.meta), children: meta }),
13602
+ /* @__PURE__ */ jsx("h3", { className: cn("text-white leading-snug", s.title), children: title }),
13603
+ excerpt && /* @__PURE__ */ jsx(
13604
+ "p",
13605
+ {
13606
+ className: cn(
13607
+ "text-white/80 leading-relaxed -mt-1 line-clamp-2",
13608
+ s.excerpt
13609
+ ),
13610
+ children: excerpt
13611
+ }
13612
+ ),
13613
+ /* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center justify-between gap-4", children: /* @__PURE__ */ jsxs(
13614
+ "span",
13615
+ {
13616
+ className: cn(
13617
+ "group/cta inline-flex items-center gap-1.5 border-b border-white/70 pb-0.5",
13618
+ "text-sm font-semibold text-white transition-colors hover:border-white hover:text-white",
13619
+ "font-ui"
13620
+ ),
13621
+ children: [
13622
+ ctaLabel,
13623
+ /* @__PURE__ */ jsx("span", { className: "transition-transform duration-150 group-hover/cta:translate-x-0.5", children: /* @__PURE__ */ jsx(ArrowIcon2, {}) })
13624
+ ]
13625
+ }
13626
+ ) })
13627
+ ] })
13628
+ ] });
13629
+ const baseClasses = cn(
13630
+ "group relative flex flex-col justify-between overflow-hidden rounded-2xl",
13631
+ "shadow-md transition-shadow duration-300 hover:shadow-xl",
13632
+ s.card,
13633
+ className
13634
+ );
13635
+ return href ? /* @__PURE__ */ jsx(
13636
+ "a",
13637
+ {
13638
+ href,
13639
+ onClick: cta == null ? void 0 : cta.onClick,
13640
+ className: baseClasses,
13641
+ "aria-label": title,
13642
+ children: inner
13643
+ }
13644
+ ) : /* @__PURE__ */ jsx("div", { className: baseClasses, children: inner });
13645
+ }
13646
+ function SectionHeading({
13647
+ eyebrow,
13648
+ title,
13649
+ rightSlot
13650
+ }) {
13651
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between gap-4 flex-wrap mb-6", children: [
13652
+ /* @__PURE__ */ jsxs("div", { children: [
13653
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "text-xs font-mono font-semibold text-primary uppercase tracking-widest mb-1", children: eyebrow }),
13654
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading leading-tight", children: title })
13655
+ ] }),
13656
+ rightSlot
13657
+ ] });
13658
+ }
13659
+ function CategoryPage2({
13660
+ title,
13661
+ intro,
13662
+ heroImage,
13663
+ trustpilotMini,
13664
+ breadcrumb,
13665
+ siteHeader,
13666
+ popularTours,
13667
+ popularToursTitle = "More adventures calling your name",
13668
+ popularToursEyebrow = "Popular tours",
13669
+ trips,
13670
+ tripsTitle,
13671
+ tripsEyebrow,
13672
+ filterGroups,
13673
+ sortOptions,
13674
+ defaultSort,
13675
+ tripsInitialCount = 15,
13676
+ trustpilot,
13677
+ reviewsTitle = "Don't just take our word for it",
13678
+ reviewsSubtitle,
13679
+ blogPosts,
13680
+ aboutTitle,
13681
+ aboutContent,
13682
+ blogIntro,
13683
+ travelGuideHref,
13684
+ travelGuideLabel = "Read our Travel Guide",
13685
+ blogPostsTitle,
13686
+ blogPostsViewAllHref,
13687
+ faqs,
13688
+ faqsTitle = "Frequently asked questions",
13689
+ faqInitialCount = 5,
13690
+ gallery,
13691
+ galleryTitle,
13692
+ className
13693
+ }) {
13694
+ var _a;
13695
+ const [faqsExpanded, setFaqsExpanded] = React28.useState(false);
13696
+ const [tripsExpanded, setTripsExpanded] = React28.useState(false);
13697
+ const [filterValue, setFilterValue] = React28.useState({});
13698
+ const [sort, setSort] = React28.useState(
13699
+ defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
13700
+ );
13701
+ const sortedTrips = React28.useMemo(
13702
+ () => [...trips].sort((a, b) => {
13703
+ const af = a.featured ? 1 : 0;
13704
+ const bf = b.featured ? 1 : 0;
13705
+ return bf - af;
13706
+ }),
13707
+ [trips]
13708
+ );
13709
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
13710
+ /* @__PURE__ */ jsxs(
13711
+ "section",
13712
+ {
13713
+ className: cn(
13714
+ "relative w-full",
13715
+ siteHeader ? "min-h-[420px] pt-[140px]" : "min-h-[300px] pt-16",
13716
+ "pb-12 text-white",
13717
+ !heroImage && "bg-gradient-to-br from-primary-900 via-primary-800 to-primary-950"
13718
+ ),
13719
+ children: [
13720
+ heroImage && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 overflow-hidden", children: [
13721
+ /* @__PURE__ */ jsx(
13722
+ "img",
13723
+ {
13724
+ src: heroImage,
13725
+ alt: "",
13726
+ "aria-hidden": true,
13727
+ fetchPriority: "high",
13728
+ className: "absolute inset-0 h-full w-full object-cover"
13729
+ }
13730
+ ),
13731
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-b from-black/55 via-black/40 to-black/65" })
13732
+ ] }),
13733
+ siteHeader && /* @__PURE__ */ jsx(
13734
+ SiteHeader,
13735
+ {
13736
+ links: Array.isArray(siteHeader) ? siteHeader : void 0,
13737
+ position: "overlay"
13738
+ }
13739
+ ),
13740
+ /* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
13741
+ breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
13742
+ i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
13743
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui", children: crumb.label })
13744
+ ] }, i)) }),
13745
+ /* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight max-w-3xl", children: title }),
13746
+ intro && /* @__PURE__ */ jsx("div", { className: "mt-4 text-base sm:text-lg text-white/90 leading-relaxed max-w-2xl [&_strong]:font-semibold [&_a]:underline", children: intro }),
13747
+ trustpilotMini && /* @__PURE__ */ jsx("div", { className: "mt-5 max-w-sm", children: /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) })
13748
+ ] })
13749
+ ]
13750
+ }
13751
+ ),
13752
+ popularTours && popularTours.length > 0 && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
13753
+ /* @__PURE__ */ jsx(
13754
+ SectionHeading,
13755
+ {
13756
+ eyebrow: popularToursEyebrow,
13757
+ title: popularToursTitle
13758
+ }
13759
+ ),
13760
+ /* @__PURE__ */ jsx("div", { className: "-mx-6 sm:-mx-8 px-6 sm:px-8 overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: /* @__PURE__ */ jsx("div", { className: "inline-flex gap-5 min-w-max pb-2", children: popularTours.map((trip, i) => {
13761
+ var _b;
13762
+ const _a2 = trip, { featured: _featured, variant: _variant } = _a2, cardProps = __objRest(_a2, ["featured", "variant"]);
13763
+ return /* @__PURE__ */ jsx(
13764
+ TripCard,
13765
+ __spreadProps(__spreadValues({}, cardProps), {
13766
+ variant: "overlay",
13767
+ size: (_b = cardProps.size) != null ? _b : "md"
13768
+ }),
13769
+ i
13770
+ );
13771
+ }) }) })
13772
+ ] }),
13773
+ /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 pt-6 sm:pt-8 pb-12", children: [
13774
+ (tripsTitle || tripsEyebrow) && /* @__PURE__ */ jsx(SectionHeading, { eyebrow: tripsEyebrow, title: tripsTitle != null ? tripsTitle : "" }),
13775
+ filterGroups && filterGroups.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
13776
+ FilterPanel,
13777
+ {
13778
+ variant: "horizontal",
13779
+ groups: filterGroups,
13780
+ value: filterValue,
13781
+ onChange: setFilterValue,
13782
+ onClearAll: () => setFilterValue({}),
13783
+ sortOptions,
13784
+ sort,
13785
+ onSortChange: setSort
13786
+ }
13787
+ ) }),
13788
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
13789
+ trips.length,
13790
+ " ",
13791
+ trips.length === 1 ? "trip" : "trips",
13792
+ " found"
13793
+ ] }),
13794
+ (() => {
13795
+ const visibleTrips = tripsExpanded ? sortedTrips : sortedTrips.slice(0, tripsInitialCount);
13796
+ const hiddenCount = sortedTrips.length - visibleTrips.length;
13797
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
13798
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-8 lg:gap-x-[35px] lg:gap-y-[38px]", children: visibleTrips.map((trip, i) => {
13799
+ const _a2 = trip, { featured: _featured } = _a2, cardProps = __objRest(_a2, ["featured"]);
13800
+ return /* @__PURE__ */ jsx(
13801
+ TripCard,
13802
+ __spreadProps(__spreadValues({}, cardProps), {
13803
+ className: cn("w-full h-auto", cardProps.className)
13804
+ }),
13805
+ i
13806
+ );
13807
+ }) }),
13808
+ sortedTrips.length > tripsInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsx(
13809
+ "button",
13810
+ {
13811
+ type: "button",
13812
+ onClick: () => setTripsExpanded((v) => !v),
13813
+ className: cn(
13814
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
13815
+ "text-sm font-semibold text-foreground shadow-sm",
13816
+ "hover:bg-muted transition-colors duration-150",
13817
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
13818
+ ),
13819
+ children: tripsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
13820
+ /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
13821
+ "Show less"
13822
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
13823
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
13824
+ "Load more (",
13825
+ hiddenCount,
13826
+ ")"
13827
+ ] })
13828
+ }
13829
+ ) })
13830
+ ] });
13831
+ })()
13832
+ ] }),
13833
+ trustpilot && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12 border-t border-border", children: [
13834
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-2", children: reviewsTitle }),
13835
+ reviewsSubtitle && /* @__PURE__ */ jsx("p", { className: "text-base text-muted-foreground leading-relaxed max-w-3xl mb-6 [&_a]:text-primary [&_a]:underline", children: reviewsSubtitle }),
13836
+ /* @__PURE__ */ jsx("div", { className: "min-h-[400px]", children: /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilot }) })
13837
+ ] }),
13838
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsxs("section", { className: "pt-4", children: [
13839
+ galleryTitle && /* @__PURE__ */ jsx("h2", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 mb-6 text-2xl sm:text-3xl font-bold text-foreground font-heading", children: galleryTitle }),
13840
+ /* @__PURE__ */ jsx(PhotoGallery, { photos: gallery, variant: "gridCompact", initialVisible: 8 })
13841
+ ] }),
13842
+ (aboutTitle || aboutContent || blogPostsTitle || blogPosts && blogPosts.length > 0) && /* @__PURE__ */ jsx("section", { className: "w-full bg-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-14", children: [
13843
+ (aboutTitle || blogPostsTitle) && /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-5", children: aboutTitle != null ? aboutTitle : blogPostsTitle }),
13844
+ aboutContent && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground/85 leading-relaxed space-y-3 max-w-3xl mb-10 [&_strong]:font-semibold [&_a]:text-primary [&_a]:font-bold [&_a]:underline", children: aboutContent }),
13845
+ blogPosts && blogPosts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
13846
+ blogIntro && /* @__PURE__ */ jsx("p", { className: "mb-6 text-base sm:text-lg font-semibold text-foreground font-heading", children: blogIntro }),
13847
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5", children: blogPosts.map((post, i) => /* @__PURE__ */ jsx(
13848
+ BlogCard,
13849
+ {
13850
+ href: post.href,
13851
+ image: post.image,
13852
+ imageAlt: post.imageAlt,
13853
+ title: post.title,
13854
+ excerpt: post.excerpt,
13855
+ category: post.category,
13856
+ readingTime: post.readingTime,
13857
+ className: "w-full"
13858
+ },
13859
+ i
13860
+ )) }),
13861
+ (travelGuideHref || blogPostsViewAllHref) && /* @__PURE__ */ jsx("div", { className: "mt-6 flex justify-end", children: /* @__PURE__ */ jsxs(
13862
+ "a",
13863
+ {
13864
+ href: travelGuideHref != null ? travelGuideHref : blogPostsViewAllHref,
13865
+ className: "inline-flex items-center gap-1.5 text-sm font-semibold text-primary hover:underline",
13866
+ children: [
13867
+ travelGuideHref ? travelGuideLabel : "View all posts",
13868
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4" })
13869
+ ]
13870
+ }
13871
+ ) })
13872
+ ] })
13873
+ ] }) }),
13874
+ faqs && faqs.length > 0 && (() => {
13875
+ const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
13876
+ const hiddenCount = faqs.length - visibleFaqs.length;
13877
+ return /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
13878
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-6", children: faqsTitle }),
13879
+ /* @__PURE__ */ jsx(Accordion, { variant: "faq", children: visibleFaqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
13880
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: faq.question }),
13881
+ /* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
13882
+ ] }, i)) }),
13883
+ faqs.length > faqInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-center", children: /* @__PURE__ */ jsx(
13884
+ "button",
13885
+ {
13886
+ type: "button",
13887
+ onClick: () => setFaqsExpanded((v) => !v),
13888
+ className: cn(
13889
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
13890
+ "text-sm font-semibold text-foreground shadow-sm",
13891
+ "hover:bg-muted transition-colors duration-150",
13892
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
13893
+ ),
13894
+ children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
13895
+ /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
13896
+ "Show less"
13897
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
13898
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
13899
+ "See more (",
13900
+ hiddenCount,
13901
+ ")"
13902
+ ] })
13903
+ }
13904
+ ) })
13905
+ ] });
13906
+ })(),
13907
+ /* @__PURE__ */ jsx(SiteFooter, {})
13908
+ ] });
13909
+ }
13910
+ var sizeConfig3 = {
13497
13911
  sm: {
13498
13912
  card: "w-56",
13499
13913
  image: "h-36",
@@ -13528,7 +13942,7 @@ function ActivityCard({
13528
13942
  size = "md",
13529
13943
  className
13530
13944
  }) {
13531
- const s = sizeConfig2[size];
13945
+ const s = sizeConfig3[size];
13532
13946
  return /* @__PURE__ */ jsxs(
13533
13947
  "div",
13534
13948
  {
@@ -14741,7 +15155,517 @@ function AskExo({
14741
15155
  )
14742
15156
  ] });
14743
15157
  }
15158
+ var STATUS_MAP = {
15159
+ "draft": { label: "Draft", variant: "neutral", dot: "bg-muted-foreground" },
15160
+ "pending-approval": { label: "Pending approval", variant: "warning", dot: "bg-warning" },
15161
+ "pending-group": { label: "Pending group", variant: "info", dot: "bg-info" },
15162
+ "confirmed": { label: "Confirmed", variant: "success", dot: "bg-success" },
15163
+ "payment-pending": { label: "Payment pending", variant: "warning", dot: "bg-warning" },
15164
+ "payment-reconciliation": { label: "Reconciliation", variant: "info", dot: "bg-info" },
15165
+ "fully-paid": { label: "Fully paid", variant: "default", dot: "bg-primary-foreground" },
15166
+ "full": { label: "Full", variant: "secondary", dot: "bg-secondary-foreground" },
15167
+ "waiting-list": { label: "Waiting list", variant: "info", dot: "bg-info" },
15168
+ "operating": { label: "Operating", variant: "default", dot: "bg-primary-foreground" },
15169
+ "cancelled": { label: "Cancelled", variant: "destructive", dot: "bg-destructive" }
15170
+ };
15171
+ function StatusBadge2({ status, dot = true, label, className }) {
15172
+ const config = STATUS_MAP[status];
15173
+ return /* @__PURE__ */ jsxs(Badge, { variant: config.variant, className: cn("gap-1.5", className), children: [
15174
+ dot && /* @__PURE__ */ jsx(
15175
+ "span",
15176
+ {
15177
+ "aria-hidden": "true",
15178
+ className: cn("size-1.5 shrink-0 rounded-full", config.dot)
15179
+ }
15180
+ ),
15181
+ label != null ? label : config.label
15182
+ ] });
15183
+ }
15184
+ function GroupStatusBanner({
15185
+ variant = "info",
15186
+ title,
15187
+ icon,
15188
+ action,
15189
+ urgent = false,
15190
+ children,
15191
+ className
15192
+ }) {
15193
+ return /* @__PURE__ */ jsx(
15194
+ Alert,
15195
+ {
15196
+ variant,
15197
+ title,
15198
+ icon,
15199
+ action,
15200
+ role: urgent ? "alert" : "status",
15201
+ className,
15202
+ children
15203
+ }
15204
+ );
15205
+ }
15206
+ function ParticipantCounter({
15207
+ current,
15208
+ max,
15209
+ label = "Travelers",
15210
+ hideIcon = false,
15211
+ className
15212
+ }) {
15213
+ return /* @__PURE__ */ jsxs(
15214
+ "span",
15215
+ {
15216
+ className: cn(
15217
+ "inline-flex items-center gap-1.5 font-ui text-sm text-foreground",
15218
+ className
15219
+ ),
15220
+ children: [
15221
+ !hideIcon && /* @__PURE__ */ jsx(UsersIcon, { className: "size-4 text-primary", "aria-hidden": "true" }),
15222
+ /* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
15223
+ current,
15224
+ " / ",
15225
+ max
15226
+ ] }),
15227
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label })
15228
+ ]
15229
+ }
15230
+ );
15231
+ }
15232
+ function GroupProgressBar({
15233
+ current,
15234
+ min,
15235
+ max,
15236
+ hideLabels = false,
15237
+ className
15238
+ }) {
15239
+ const pct = Math.max(0, Math.min(100, current / max * 100));
15240
+ const minPct = Math.max(0, Math.min(100, min / max * 100));
15241
+ const quorumMet = current >= min;
15242
+ const isFull = current >= max;
15243
+ const fillTone = isFull ? "bg-success" : quorumMet ? "bg-primary" : "bg-warning";
15244
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
15245
+ /* @__PURE__ */ jsxs(
15246
+ "div",
15247
+ {
15248
+ className: "relative h-3 w-full overflow-visible rounded-full bg-muted",
15249
+ role: "progressbar",
15250
+ "aria-valuenow": current,
15251
+ "aria-valuemin": 0,
15252
+ "aria-valuemax": max,
15253
+ "aria-label": `${current} of ${max} travelers, minimum ${min}${quorumMet ? " met" : " not yet met"}`,
15254
+ children: [
15255
+ /* @__PURE__ */ jsx(
15256
+ "div",
15257
+ {
15258
+ className: cn(
15259
+ "h-full rounded-full transition-[width,background-color] duration-500",
15260
+ fillTone
15261
+ ),
15262
+ style: { width: `${pct}%` }
15263
+ }
15264
+ ),
15265
+ /* @__PURE__ */ jsx(
15266
+ "span",
15267
+ {
15268
+ "aria-hidden": "true",
15269
+ className: "absolute top-1/2 z-10 h-5 w-0.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-foreground/60",
15270
+ style: { left: `${minPct}%` }
15271
+ }
15272
+ )
15273
+ ]
15274
+ }
15275
+ ),
15276
+ !hideLabels && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between font-ui text-[11px] text-muted-foreground", children: [
15277
+ /* @__PURE__ */ jsx("span", { className: cn(quorumMet && "text-success font-semibold"), children: quorumMet ? "Quorum reached" : `Min ${min} to confirm` }),
15278
+ /* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
15279
+ max,
15280
+ " max"
15281
+ ] })
15282
+ ] })
15283
+ ] });
15284
+ }
15285
+ function Card(_a) {
15286
+ var _b = _a, {
15287
+ className,
15288
+ size = "default"
15289
+ } = _b, props = __objRest(_b, [
15290
+ "className",
15291
+ "size"
15292
+ ]);
15293
+ return /* @__PURE__ */ jsx(
15294
+ "div",
15295
+ __spreadValues({
15296
+ "data-slot": "card",
15297
+ "data-size": size,
15298
+ className: cn(
15299
+ "group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
15300
+ className
15301
+ )
15302
+ }, props)
15303
+ );
15304
+ }
15305
+ function CardHeader(_a) {
15306
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15307
+ return /* @__PURE__ */ jsx(
15308
+ "div",
15309
+ __spreadValues({
15310
+ "data-slot": "card-header",
15311
+ className: cn(
15312
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
15313
+ className
15314
+ )
15315
+ }, props)
15316
+ );
15317
+ }
15318
+ function CardTitle(_a) {
15319
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15320
+ return /* @__PURE__ */ jsx(
15321
+ "div",
15322
+ __spreadValues({
15323
+ "data-slot": "card-title",
15324
+ className: cn(
15325
+ "text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
15326
+ className
15327
+ )
15328
+ }, props)
15329
+ );
15330
+ }
15331
+ function CardContent(_a) {
15332
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15333
+ return /* @__PURE__ */ jsx(
15334
+ "div",
15335
+ __spreadValues({
15336
+ "data-slot": "card-content",
15337
+ className: cn("px-4 group-data-[size=sm]/card:px-3", className)
15338
+ }, props)
15339
+ );
15340
+ }
15341
+ function PricingMatrixCard({
15342
+ tiers,
15343
+ currentTravelers,
15344
+ title = "Group pricing",
15345
+ locked = false,
15346
+ className
15347
+ }) {
15348
+ const activeIndex = tiers.reduce(
15349
+ (acc, t, i) => currentTravelers >= t.threshold ? i : acc,
15350
+ -1
15351
+ );
15352
+ const bestIndex = tiers.length - 1;
15353
+ return /* @__PURE__ */ jsxs(Card, { className, children: [
15354
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "font-heading", children: title }) }),
15355
+ /* @__PURE__ */ jsx(CardContent, { className: "px-0", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
15356
+ /* @__PURE__ */ jsx("caption", { className: "sr-only", children: "Price per person by number of travelers" }),
15357
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-y border-border text-left font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: [
15358
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2 font-semibold", children: "Travelers" }),
15359
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2 text-right font-semibold", children: "Price / person" })
15360
+ ] }) }),
15361
+ /* @__PURE__ */ jsx("tbody", { children: tiers.map((tier, i) => {
15362
+ const isActive = !locked && i === activeIndex;
15363
+ const isBest = i === bestIndex;
15364
+ return /* @__PURE__ */ jsxs(
15365
+ "tr",
15366
+ {
15367
+ className: cn(
15368
+ "border-b border-border last:border-0 transition-colors",
15369
+ isActive && "bg-accent",
15370
+ locked && "opacity-60"
15371
+ ),
15372
+ "aria-current": isActive ? "true" : void 0,
15373
+ children: [
15374
+ /* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
15375
+ /* @__PURE__ */ jsx("span", { className: "font-ui font-semibold text-foreground", children: tier.travelers }),
15376
+ isActive && /* @__PURE__ */ jsx(Badge, { variant: "success", className: "h-4 px-1.5 text-[10px]", children: "You are here" }),
15377
+ isBest && !isActive && /* @__PURE__ */ jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: "Best price" })
15378
+ ] }) }),
15379
+ /* @__PURE__ */ jsx(
15380
+ "td",
15381
+ {
15382
+ className: cn(
15383
+ "px-4 py-2.5 text-right font-ui tabular-nums",
15384
+ isActive ? "font-bold text-foreground" : "text-muted-foreground",
15385
+ isBest && "text-primary"
15386
+ ),
15387
+ children: tier.price
15388
+ }
15389
+ )
15390
+ ]
15391
+ },
15392
+ tier.travelers
15393
+ );
15394
+ }) })
15395
+ ] }) })
15396
+ ] });
15397
+ }
15398
+ function PriceProgress({
15399
+ currentPrice,
15400
+ lowestPrice,
15401
+ travelersToLowest,
15402
+ pct,
15403
+ className
15404
+ }) {
15405
+ const reached = travelersToLowest <= 0;
15406
+ const safePct = reached ? 100 : Math.max(0, Math.min(100, pct));
15407
+ return /* @__PURE__ */ jsxs(
15408
+ "div",
15409
+ {
15410
+ className: cn(
15411
+ "flex flex-col gap-3 rounded-xl border border-border bg-card p-4",
15412
+ className
15413
+ ),
15414
+ "aria-live": "polite",
15415
+ children: [
15416
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between gap-4", children: [
15417
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
15418
+ /* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current" }),
15419
+ /* @__PURE__ */ jsx("span", { className: "font-heading text-xl font-bold text-foreground tabular-nums", children: currentPrice })
15420
+ ] }),
15421
+ /* @__PURE__ */ jsx(ArrowDownIcon, { className: "mb-1 size-4 shrink-0 text-success", "aria-hidden": "true" }),
15422
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col text-right", children: [
15423
+ /* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Potential" }),
15424
+ /* @__PURE__ */ jsx("span", { className: "font-heading text-xl font-bold text-primary tabular-nums", children: lowestPrice })
15425
+ ] })
15426
+ ] }),
15427
+ /* @__PURE__ */ jsx("div", { className: "h-2 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx(
15428
+ "div",
15429
+ {
15430
+ className: cn(
15431
+ "h-full rounded-full transition-[width] duration-500",
15432
+ reached ? "bg-success" : "bg-primary"
15433
+ ),
15434
+ style: { width: `${safePct}%` }
15435
+ }
15436
+ ) }),
15437
+ /* @__PURE__ */ jsx(
15438
+ "p",
15439
+ {
15440
+ className: cn(
15441
+ "flex items-center gap-1.5 font-ui text-sm font-semibold",
15442
+ reached ? "text-success" : "text-foreground"
15443
+ ),
15444
+ children: reached ? /* @__PURE__ */ jsxs(Fragment, { children: [
15445
+ /* @__PURE__ */ jsx(SparkleIcon, { className: "size-4", "aria-hidden": "true" }),
15446
+ "Best possible price unlocked"
15447
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15448
+ travelersToLowest,
15449
+ " more ",
15450
+ travelersToLowest === 1 ? "traveler" : "travelers",
15451
+ " for the lowest price"
15452
+ ] })
15453
+ }
15454
+ )
15455
+ ]
15456
+ }
15457
+ );
15458
+ }
15459
+ function ParticipantList({
15460
+ participants,
15461
+ emptySlots = 0,
15462
+ title = "Travelers",
15463
+ leaderLabel = "Leader",
15464
+ emptyMessage = "Be the first to join this adventure.",
15465
+ className
15466
+ }) {
15467
+ if (participants.length === 0 && emptySlots === 0) {
15468
+ return /* @__PURE__ */ jsx("p", { className: cn("font-sans text-sm text-muted-foreground", className), children: emptyMessage });
15469
+ }
15470
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
15471
+ title && /* @__PURE__ */ jsx("h3", { className: "font-heading text-sm font-bold text-foreground", children: title }),
15472
+ /* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-2", children: [
15473
+ participants.map((p, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3", children: [
15474
+ /* @__PURE__ */ jsx(
15475
+ "span",
15476
+ {
15477
+ className: "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-full bg-primary/10 text-primary",
15478
+ "aria-hidden": "true",
15479
+ children: p.avatarUrl ? (
15480
+ // eslint-disable-next-line @next/next/no-img-element
15481
+ /* @__PURE__ */ jsx("img", { src: p.avatarUrl, alt: "", className: "size-full object-cover" })
15482
+ ) : /* @__PURE__ */ jsx(UserIcon, { className: "size-4.5" })
15483
+ }
15484
+ ),
15485
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
15486
+ /* @__PURE__ */ jsx("span", { className: "truncate font-ui text-sm font-medium text-foreground", children: p.firstName }),
15487
+ p.flag && /* @__PURE__ */ jsx("span", { "aria-label": p.country, role: "img", className: "text-base leading-none", children: p.flag }),
15488
+ p.isLeader && /* @__PURE__ */ jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: leaderLabel })
15489
+ ] })
15490
+ ] }, `${p.firstName}-${i}`)),
15491
+ Array.from({ length: emptySlots }).map((_, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3 opacity-60", children: [
15492
+ /* @__PURE__ */ jsx(
15493
+ "span",
15494
+ {
15495
+ "aria-hidden": "true",
15496
+ className: "flex size-9 shrink-0 items-center justify-center rounded-full border border-dashed border-border text-muted-foreground",
15497
+ children: "+"
15498
+ }
15499
+ ),
15500
+ /* @__PURE__ */ jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Open spot" })
15501
+ ] }, `empty-${i}`))
15502
+ ] })
15503
+ ] });
15504
+ }
15505
+ function BrandIcon({ path }) {
15506
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "size-4", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: path }) });
15507
+ }
15508
+ var WHATSAPP = "M.057 24l1.687-6.163a11.867 11.867 0 01-1.587-5.945C.16 5.335 5.495 0 12.05 0a11.82 11.82 0 018.413 3.488 11.82 11.82 0 013.48 8.414c-.003 6.557-5.338 11.892-11.893 11.892a11.9 11.9 0 01-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.82 9.82 0 001.51 5.26l-.999 3.648 3.978-1.945zm5.473-6.231c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.768.967-.941 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.096 3.2 5.077 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414z";
15509
+ var FACEBOOK = "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z";
15510
+ var X = "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z";
15511
+ function ShareWidget({
15512
+ url,
15513
+ message = "Join my adventure and let's unlock a lower price together!",
15514
+ layout = "row",
15515
+ title = "Invite friends & lower the price",
15516
+ className
15517
+ }) {
15518
+ const [copied, setCopied] = React28.useState(false);
15519
+ const [showToast, setShowToast] = React28.useState(false);
15520
+ const encodedUrl = encodeURIComponent(url);
15521
+ const encodedMsg = encodeURIComponent(`${message} ${url}`);
15522
+ const channels = [
15523
+ {
15524
+ key: "whatsapp",
15525
+ label: "WhatsApp",
15526
+ href: `https://wa.me/?text=${encodedMsg}`,
15527
+ path: WHATSAPP,
15528
+ color: "hover:text-[#25D366] hover:border-[#25D366]"
15529
+ },
15530
+ {
15531
+ key: "facebook",
15532
+ label: "Facebook",
15533
+ href: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
15534
+ path: FACEBOOK,
15535
+ color: "hover:text-[#1877F2] hover:border-[#1877F2]"
15536
+ },
15537
+ {
15538
+ key: "x",
15539
+ label: "X",
15540
+ href: `https://twitter.com/intent/tweet?text=${encodeURIComponent(message)}&url=${encodedUrl}`,
15541
+ path: X,
15542
+ color: "hover:text-foreground hover:border-foreground"
15543
+ }
15544
+ ];
15545
+ const copyLink = async () => {
15546
+ try {
15547
+ await navigator.clipboard.writeText(url);
15548
+ } catch (e) {
15549
+ }
15550
+ setCopied(true);
15551
+ setShowToast(true);
15552
+ setTimeout(() => setCopied(false), 2e3);
15553
+ };
15554
+ const isIcons = layout === "icons";
15555
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
15556
+ title && /* @__PURE__ */ jsxs("h3", { className: "flex items-center gap-1.5 font-heading text-sm font-bold text-foreground", children: [
15557
+ /* @__PURE__ */ jsx(Share2Icon, { className: "size-4 text-primary", "aria-hidden": "true" }),
15558
+ title
15559
+ ] }),
15560
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
15561
+ channels.map((c) => /* @__PURE__ */ jsxs(
15562
+ "a",
15563
+ {
15564
+ href: c.href,
15565
+ target: "_blank",
15566
+ rel: "noopener noreferrer",
15567
+ "aria-label": `Share on ${c.label}`,
15568
+ className: cn(
15569
+ "inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors",
15570
+ c.color
15571
+ ),
15572
+ children: [
15573
+ /* @__PURE__ */ jsx(BrandIcon, { path: c.path }),
15574
+ !isIcons && /* @__PURE__ */ jsx("span", { children: c.label })
15575
+ ]
15576
+ },
15577
+ c.key
15578
+ )),
15579
+ /* @__PURE__ */ jsxs(
15580
+ "button",
15581
+ {
15582
+ type: "button",
15583
+ onClick: copyLink,
15584
+ "aria-label": "Copy link",
15585
+ className: cn(
15586
+ "inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors hover:border-primary hover:text-primary",
15587
+ copied && "border-success text-success"
15588
+ ),
15589
+ children: [
15590
+ copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(CopyIcon, { className: "size-4" }),
15591
+ !isIcons && /* @__PURE__ */ jsx("span", { children: copied ? "Copied!" : "Copy link" })
15592
+ ]
15593
+ }
15594
+ )
15595
+ ] }),
15596
+ showToast && /* @__PURE__ */ jsx(
15597
+ Toast,
15598
+ {
15599
+ message: "Link copied to clipboard",
15600
+ variant: "success",
15601
+ onClose: () => setShowToast(false),
15602
+ duration: 2500
15603
+ }
15604
+ )
15605
+ ] });
15606
+ }
15607
+ var MODE_COPY = {
15608
+ joinable: { cta: "Join this adventure", disabled: false },
15609
+ full: { cta: "Join waiting list", disabled: false },
15610
+ closed: { cta: "Booking closed", disabled: true },
15611
+ owner: { cta: "Share your departure", disabled: false }
15612
+ };
15613
+ function StickyBookingCard({
15614
+ currentPrice,
15615
+ deposit,
15616
+ spotsRemaining,
15617
+ mode = "joinable",
15618
+ onPrimary,
15619
+ note,
15620
+ className
15621
+ }) {
15622
+ const { cta, disabled } = MODE_COPY[mode];
15623
+ return /* @__PURE__ */ jsxs(
15624
+ "div",
15625
+ {
15626
+ className: cn(
15627
+ "flex flex-col gap-4 rounded-2xl border border-border bg-card p-5 ring-1 ring-foreground/5",
15628
+ className
15629
+ ),
15630
+ children: [
15631
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between", children: [
15632
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
15633
+ /* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current price" }),
15634
+ /* @__PURE__ */ jsx("span", { className: "font-heading text-2xl font-bold text-foreground tabular-nums", children: currentPrice }),
15635
+ /* @__PURE__ */ jsx("span", { className: "font-sans text-xs text-muted-foreground", children: "per person" })
15636
+ ] }),
15637
+ mode !== "owner" && /* @__PURE__ */ jsx(
15638
+ "span",
15639
+ {
15640
+ className: cn(
15641
+ "font-ui text-xs font-semibold",
15642
+ spotsRemaining <= 2 && spotsRemaining > 0 ? "text-warning" : "text-muted-foreground"
15643
+ ),
15644
+ children: spotsRemaining > 0 ? `${spotsRemaining} spots left` : "Full"
15645
+ }
15646
+ )
15647
+ ] }),
15648
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg bg-muted/60 px-3 py-2", children: [
15649
+ /* @__PURE__ */ jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Deposit today" }),
15650
+ /* @__PURE__ */ jsx("span", { className: "font-ui text-sm font-bold text-foreground tabular-nums", children: deposit })
15651
+ ] }),
15652
+ /* @__PURE__ */ jsx(
15653
+ Button,
15654
+ {
15655
+ variant: "primary",
15656
+ size: "lg",
15657
+ className: "w-full",
15658
+ disabled,
15659
+ onClick: onPrimary,
15660
+ children: cta
15661
+ }
15662
+ ),
15663
+ /* @__PURE__ */ jsx("p", { className: "text-center font-sans text-xs text-muted-foreground", children: note != null ? note : "A hold is placed on your card \u2014 no charge until approved." })
15664
+ ]
15665
+ }
15666
+ );
15667
+ }
14744
15668
 
14745
- export { ActivityCard, AgentContactCard, Alert, AskExo, BirthDateField, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, Picture, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, SiteHeader, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, buttonVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
15669
+ export { ActivityCard, AgentContactCard, Alert, AskExo, BirthDateField, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CategoryPage2, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, STATUS_MAP as DEPARTURE_STATUS_MAP, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, GroupProgressBar, GroupStatusBanner, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, ParticipantCounter, ParticipantList, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, Picture, PriceProgress, PricingMatrixCard, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, ShareWidget, SiteHeader, StatusBadge2 as StatusBadge, StickyBookingCard, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, buttonVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
14746
15670
  //# sourceMappingURL=index.js.map
14747
15671
  //# sourceMappingURL=index.js.map