@planetaexo/design-system 0.63.0 → 0.65.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
@@ -1,10 +1,10 @@
1
- import * as React31 from 'react';
1
+ import * as React32 from 'react';
2
2
  import { useState, useRef, useCallback, useEffect, useId } from 'react';
3
3
  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, 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';
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, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, ArrowRightIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, ArrowDownIcon, SparkleIcon, Share2Icon, CopyIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon, 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';
@@ -81,7 +81,7 @@ var buttonVariants = cva(
81
81
  }
82
82
  }
83
83
  );
84
- var Button = React31.forwardRef(
84
+ var Button = React32.forwardRef(
85
85
  (_a, ref) => {
86
86
  var _b = _a, { className, variant, size } = _b, props = __objRest(_b, ["className", "variant", "size"]);
87
87
  return /* @__PURE__ */ jsx(
@@ -310,10 +310,10 @@ function DialogDescription(_a) {
310
310
  }, props)
311
311
  );
312
312
  }
313
- var FloatingInput = React31.forwardRef(
313
+ var FloatingInput = React32.forwardRef(
314
314
  (_a, ref) => {
315
315
  var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
316
- const inputId = id != null ? id : React31.useId();
316
+ const inputId = id != null ? id : React32.useId();
317
317
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
318
318
  /* @__PURE__ */ jsx(
319
319
  "input",
@@ -353,10 +353,10 @@ var FloatingInput = React31.forwardRef(
353
353
  }
354
354
  );
355
355
  FloatingInput.displayName = "FloatingInput";
356
- var FloatingSelect = React31.forwardRef(
356
+ var FloatingSelect = React32.forwardRef(
357
357
  (_a, ref) => {
358
358
  var _b = _a, { label, error, id, className, required, children, value } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children", "value"]);
359
- const inputId = id != null ? id : React31.useId();
359
+ const inputId = id != null ? id : React32.useId();
360
360
  const hasValue = typeof value === "string" ? value !== "" : value !== void 0 && value !== null;
361
361
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
362
362
  /* @__PURE__ */ jsx(
@@ -617,14 +617,15 @@ function PhoneCountrySelect({
617
617
  value,
618
618
  onChange,
619
619
  className,
620
- disabled
620
+ disabled,
621
+ showDial = true
621
622
  }) {
622
623
  var _a;
623
- const [open, setOpen] = React31.useState(false);
624
- const containerRef = React31.useRef(null);
625
- const listRef = React31.useRef(null);
624
+ const [open, setOpen] = React32.useState(false);
625
+ const containerRef = React32.useRef(null);
626
+ const listRef = React32.useRef(null);
626
627
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
627
- React31.useEffect(() => {
628
+ React32.useEffect(() => {
628
629
  if (!open) return;
629
630
  const handler = (e) => {
630
631
  var _a2;
@@ -635,7 +636,7 @@ function PhoneCountrySelect({
635
636
  document.addEventListener("mousedown", handler);
636
637
  return () => document.removeEventListener("mousedown", handler);
637
638
  }, [open]);
638
- React31.useEffect(() => {
639
+ React32.useEffect(() => {
639
640
  if (!open || !listRef.current) return;
640
641
  const activeEl = listRef.current.querySelector("[data-selected=true]");
641
642
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -666,7 +667,7 @@ function PhoneCountrySelect({
666
667
  ),
667
668
  children: [
668
669
  /* @__PURE__ */ jsx("span", { className: "text-base leading-none", children: selected.flag }),
669
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: selected.dial }),
670
+ showDial && /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: selected.dial }),
670
671
  /* @__PURE__ */ jsx(
671
672
  ChevronDownIcon,
672
673
  {
@@ -905,8 +906,8 @@ function CalendarDayButton(_a) {
905
906
  "locale"
906
907
  ]);
907
908
  const defaultClassNames = getDefaultClassNames();
908
- const ref = React31.useRef(null);
909
- React31.useEffect(() => {
909
+ const ref = React32.useRef(null);
910
+ React32.useEffect(() => {
910
911
  var _a2;
911
912
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
912
913
  }, [modifiers.focused]);
@@ -937,16 +938,16 @@ function BirthDateField({
937
938
  className,
938
939
  disabled
939
940
  }) {
940
- const [open, setOpen] = React31.useState(false);
941
- const [text, setText] = React31.useState(
941
+ const [open, setOpen] = React32.useState(false);
942
+ const [text, setText] = React32.useState(
942
943
  value ? format(value, "dd/MM/yyyy") : ""
943
944
  );
944
- const containerRef = React31.useRef(null);
945
- const inputId = React31.useId();
946
- React31.useEffect(() => {
945
+ const containerRef = React32.useRef(null);
946
+ const inputId = React32.useId();
947
+ React32.useEffect(() => {
947
948
  setText(value ? format(value, "dd/MM/yyyy") : "");
948
949
  }, [value]);
949
- React31.useEffect(() => {
950
+ React32.useEffect(() => {
950
951
  if (!open) return;
951
952
  const handler = (e) => {
952
953
  var _a;
@@ -1155,14 +1156,14 @@ function CountrySearchField({
1155
1156
  }) {
1156
1157
  var _a;
1157
1158
  const list = countries != null ? countries : COUNTRIES;
1158
- const [query, setQuery] = React31.useState("");
1159
- const [open, setOpen] = React31.useState(false);
1160
- const containerRef = React31.useRef(null);
1161
- const searchRef = React31.useRef(null);
1159
+ const [query, setQuery] = React32.useState("");
1160
+ const [open, setOpen] = React32.useState(false);
1161
+ const containerRef = React32.useRef(null);
1162
+ const searchRef = React32.useRef(null);
1162
1163
  const selected = list.find((c) => c.code === value);
1163
1164
  const isFloated = open || !!selected;
1164
1165
  const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
1165
- React31.useEffect(() => {
1166
+ React32.useEffect(() => {
1166
1167
  if (!open) return;
1167
1168
  const handler = (e) => {
1168
1169
  var _a2;
@@ -1307,10 +1308,10 @@ function AdventureCard({
1307
1308
  }) {
1308
1309
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
1309
1310
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1310
- const [checkedInternal, setCheckedInternal] = React31.useState(
1311
+ const [checkedInternal, setCheckedInternal] = React32.useState(
1311
1312
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
1312
1313
  );
1313
- const [openDescriptionId, setOpenDescriptionId] = React31.useState(null);
1314
+ const [openDescriptionId, setOpenDescriptionId] = React32.useState(null);
1314
1315
  const openDescriptionOptional = openDescriptionId ? (_e = adventure.optionals) == null ? void 0 : _e.find((o) => o.id === openDescriptionId) : void 0;
1315
1316
  const isChecked = (opt) => {
1316
1317
  var _a2;
@@ -1766,7 +1767,7 @@ function BookingShell({
1766
1767
  return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1767
1768
  /* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1768
1769
  /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1769
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
1770
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
1770
1771
  /* @__PURE__ */ jsx(
1771
1772
  "span",
1772
1773
  {
@@ -1965,7 +1966,7 @@ function TermsSection({
1965
1966
  termsContent
1966
1967
  }) {
1967
1968
  var _a;
1968
- const [modalOpen, setModalOpen] = React31.useState(false);
1969
+ const [modalOpen, setModalOpen] = React32.useState(false);
1969
1970
  const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
1970
1971
  return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1971
1972
  /* @__PURE__ */ jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
@@ -2103,9 +2104,9 @@ function BookingWizard({
2103
2104
  }) {
2104
2105
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T;
2105
2106
  const wizardSteps = WIZARD_STEPS_FN(labels);
2106
- const [step, setStep] = React31.useState("responsible");
2107
- const [error, setError] = React31.useState(null);
2108
- const [responsible, setResponsible] = React31.useState({
2107
+ const [step, setStep] = React32.useState("responsible");
2108
+ const [error, setError] = React32.useState(null);
2109
+ const [responsible, setResponsible] = React32.useState({
2109
2110
  firstName: "",
2110
2111
  lastName: "",
2111
2112
  email: "",
@@ -2124,7 +2125,7 @@ function BookingWizard({
2124
2125
  return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
2125
2126
  }, 0);
2126
2127
  const totalPax = totalAdults + totalChildren;
2127
- const [travellers, setTravellers] = React31.useState(
2128
+ const [travellers, setTravellers] = React32.useState(
2128
2129
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
2129
2130
  firstName: "",
2130
2131
  lastName: "",
@@ -2132,9 +2133,9 @@ function BookingWizard({
2132
2133
  email: ""
2133
2134
  }))
2134
2135
  );
2135
- const [payAmount, setPayAmount] = React31.useState("full");
2136
- const [payMethod, setPayMethod] = React31.useState("stripe");
2137
- const [termsAccepted, setTermsAccepted] = React31.useState(false);
2136
+ const [payAmount, setPayAmount] = React32.useState("full");
2137
+ const [payMethod, setPayMethod] = React32.useState("stripe");
2138
+ const [termsAccepted, setTermsAccepted] = React32.useState(false);
2138
2139
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
2139
2140
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
2140
2141
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -2362,7 +2363,7 @@ function Offer({
2362
2363
  className
2363
2364
  }) {
2364
2365
  var _a, _b, _c;
2365
- const [showBooking, setShowBooking] = React31.useState(false);
2366
+ const [showBooking, setShowBooking] = React32.useState(false);
2366
2367
  const isShowingCheckout = !confirmedState && (!!checkoutSlot || internalDemoCheckout && showBooking);
2367
2368
  const handleBook = () => {
2368
2369
  if (!checkoutSlot && !externalBookingFlow && internalDemoCheckout) {
@@ -2729,7 +2730,7 @@ function AdventureSection({
2729
2730
  labels
2730
2731
  }) {
2731
2732
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
2732
- const [detailsOpen, setDetailsOpen] = React31.useState(false);
2733
+ const [detailsOpen, setDetailsOpen] = React32.useState(false);
2733
2734
  const handleCopyUrl = (url) => {
2734
2735
  if (onCopyFormLink) {
2735
2736
  onCopyFormLink(url);
@@ -3268,8 +3269,8 @@ function AddTravellerDialog({
3268
3269
  errorMessage
3269
3270
  }) {
3270
3271
  var _a, _b, _c, _d, _e;
3271
- const [form, setForm] = React31.useState(() => createInitialAddFormData(config));
3272
- React31.useEffect(() => {
3272
+ const [form, setForm] = React32.useState(() => createInitialAddFormData(config));
3273
+ React32.useEffect(() => {
3273
3274
  if (open) {
3274
3275
  setForm(createInitialAddFormData(config));
3275
3276
  }
@@ -3329,7 +3330,7 @@ function EditTravellerDialog({
3329
3330
  errorMessage
3330
3331
  }) {
3331
3332
  var _a, _b, _c, _d, _e;
3332
- const [form, setForm] = React31.useState(() => ({
3333
+ const [form, setForm] = React32.useState(() => ({
3333
3334
  firstName: "",
3334
3335
  lastName: "",
3335
3336
  email: "",
@@ -3338,7 +3339,7 @@ function EditTravellerDialog({
3338
3339
  birthDate: "",
3339
3340
  personType: "ADULT"
3340
3341
  }));
3341
- React31.useEffect(() => {
3342
+ React32.useEffect(() => {
3342
3343
  var _a2, _b2, _c2, _d2, _e2, _f;
3343
3344
  if (open && traveller) {
3344
3345
  setForm({
@@ -3674,48 +3675,48 @@ function BookingDetails({
3674
3675
  const hasSubmitAddTraveller = !!onSubmitAddTraveller;
3675
3676
  const hasSubmitEditTraveller = !!onSubmitEditTraveller;
3676
3677
  const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
3677
- const [addModalState, setAddModalState] = React31.useState({
3678
+ const [addModalState, setAddModalState] = React32.useState({
3678
3679
  open: false,
3679
3680
  adventureId: null
3680
3681
  });
3681
- const [editModalState, setEditModalState] = React31.useState({ open: false, adventureId: null, traveller: null });
3682
- const [deleteModalState, setDeleteModalState] = React31.useState({ open: false, adventureId: null, traveller: null });
3683
- const [resendInviteDialogState, setResendInviteDialogState] = React31.useState({ open: false, traveller: null });
3684
- const handleRequestOpenAddModal = React31.useCallback((adventureId) => {
3682
+ const [editModalState, setEditModalState] = React32.useState({ open: false, adventureId: null, traveller: null });
3683
+ const [deleteModalState, setDeleteModalState] = React32.useState({ open: false, adventureId: null, traveller: null });
3684
+ const [resendInviteDialogState, setResendInviteDialogState] = React32.useState({ open: false, traveller: null });
3685
+ const handleRequestOpenAddModal = React32.useCallback((adventureId) => {
3685
3686
  setAddModalState({ open: true, adventureId });
3686
3687
  }, []);
3687
- const handleRequestOpenEditModal = React31.useCallback(
3688
+ const handleRequestOpenEditModal = React32.useCallback(
3688
3689
  (adventureId, traveller) => {
3689
3690
  setEditModalState({ open: true, adventureId, traveller });
3690
3691
  },
3691
3692
  []
3692
3693
  );
3693
- const handleRequestOpenDeleteModal = React31.useCallback(
3694
+ const handleRequestOpenDeleteModal = React32.useCallback(
3694
3695
  (adventureId, traveller) => {
3695
3696
  setDeleteModalState({ open: true, adventureId, traveller });
3696
3697
  },
3697
3698
  []
3698
3699
  );
3699
- const handleRequestOpenResendInviteDialog = React31.useCallback(
3700
+ const handleRequestOpenResendInviteDialog = React32.useCallback(
3700
3701
  (traveller) => {
3701
3702
  setResendInviteDialogState({ open: true, traveller });
3702
3703
  },
3703
3704
  []
3704
3705
  );
3705
- const closeAddModal = React31.useCallback(() => {
3706
+ const closeAddModal = React32.useCallback(() => {
3706
3707
  setAddModalState({ open: false, adventureId: null });
3707
3708
  }, []);
3708
- const closeEditModal = React31.useCallback(() => {
3709
+ const closeEditModal = React32.useCallback(() => {
3709
3710
  setEditModalState({ open: false, adventureId: null, traveller: null });
3710
3711
  }, []);
3711
- const closeDeleteModal = React31.useCallback(() => {
3712
+ const closeDeleteModal = React32.useCallback(() => {
3712
3713
  setDeleteModalState({ open: false, adventureId: null, traveller: null });
3713
3714
  }, []);
3714
- const closeResendInviteDialog = React31.useCallback(() => {
3715
+ const closeResendInviteDialog = React32.useCallback(() => {
3715
3716
  setResendInviteDialogState({ open: false, traveller: null });
3716
3717
  }, []);
3717
- const submitInFlightRef = React31.useRef(false);
3718
- const handleAddSubmit = React31.useCallback(
3718
+ const submitInFlightRef = React32.useRef(false);
3719
+ const handleAddSubmit = React32.useCallback(
3719
3720
  async (adventureId, data) => {
3720
3721
  if (!onSubmitAddTraveller) return;
3721
3722
  if (submitInFlightRef.current) return;
@@ -3730,7 +3731,7 @@ function BookingDetails({
3730
3731
  },
3731
3732
  [onSubmitAddTraveller, closeAddModal]
3732
3733
  );
3733
- const handleEditSubmit = React31.useCallback(
3734
+ const handleEditSubmit = React32.useCallback(
3734
3735
  async (adventureId, travellerId, data) => {
3735
3736
  if (!onSubmitEditTraveller) return;
3736
3737
  if (submitInFlightRef.current) return;
@@ -3745,7 +3746,7 @@ function BookingDetails({
3745
3746
  },
3746
3747
  [onSubmitEditTraveller, closeEditModal]
3747
3748
  );
3748
- const handleDeleteConfirm = React31.useCallback(
3749
+ const handleDeleteConfirm = React32.useCallback(
3749
3750
  async (adventureId, travellerId) => {
3750
3751
  if (!onConfirmRemoveTraveller) return;
3751
3752
  if (submitInFlightRef.current) return;
@@ -5542,7 +5543,7 @@ function BookingCreatedEmail({
5542
5543
  }, children: i + 1 }) }),
5543
5544
  /* @__PURE__ */ jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
5544
5545
  ] }) }) }, i)) }),
5545
- nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
5546
+ nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
5546
5547
  idx === 0 ? /* @__PURE__ */ jsx("strong", { children: line }) : line,
5547
5548
  idx < arr.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
5548
5549
  ] }, idx)) })
@@ -7909,13 +7910,14 @@ function DatePickerField({
7909
7910
  placeholder = "Select a date",
7910
7911
  disabled,
7911
7912
  fromDate,
7912
- className
7913
+ className,
7914
+ error
7913
7915
  }) {
7914
- const [open, setOpen] = React31.useState(false);
7915
- const containerRef = React31.useRef(null);
7916
- const [calendarWidth, setCalendarWidth] = React31.useState();
7916
+ const [open, setOpen] = React32.useState(false);
7917
+ const containerRef = React32.useRef(null);
7918
+ const [calendarWidth, setCalendarWidth] = React32.useState();
7917
7919
  const hasValue = !!value;
7918
- React31.useEffect(() => {
7920
+ React32.useEffect(() => {
7919
7921
  if (!containerRef.current) return;
7920
7922
  const observer = new ResizeObserver(([entry]) => {
7921
7923
  setCalendarWidth(entry.contentRect.width);
@@ -7923,78 +7925,91 @@ function DatePickerField({
7923
7925
  observer.observe(containerRef.current);
7924
7926
  return () => observer.disconnect();
7925
7927
  }, []);
7926
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cn("w-full", className), children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
7927
- /* @__PURE__ */ jsxs(
7928
- PopoverTrigger,
7929
- {
7930
- disabled,
7931
- className: cn(
7932
- "relative flex w-full items-center rounded-lg border border-border bg-background",
7933
- "px-3 text-left text-base font-ui transition-colors h-14",
7934
- "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
7935
- "disabled:pointer-events-none disabled:opacity-50",
7936
- open && "border-primary ring-1 ring-primary"
7937
- ),
7938
- children: [
7939
- /* @__PURE__ */ jsxs(
7940
- "span",
7941
- {
7942
- className: cn(
7943
- "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
7944
- hasValue || open ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
7945
- ),
7946
- children: [
7947
- label,
7948
- required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
7949
- ]
7950
- }
7928
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("w-full", className), children: [
7929
+ /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
7930
+ /* @__PURE__ */ jsxs(
7931
+ PopoverTrigger,
7932
+ {
7933
+ disabled,
7934
+ className: cn(
7935
+ "relative flex w-full items-center rounded-lg border border-border bg-background",
7936
+ "px-3 text-left text-base font-ui transition-colors h-14",
7937
+ "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
7938
+ "disabled:pointer-events-none disabled:opacity-50",
7939
+ open && "border-primary ring-1 ring-primary",
7940
+ error && "border-destructive focus:border-destructive focus:ring-destructive"
7951
7941
  ),
7952
- /* @__PURE__ */ jsx(
7953
- "span",
7942
+ children: [
7943
+ /* @__PURE__ */ jsxs(
7944
+ "span",
7945
+ {
7946
+ className: cn(
7947
+ "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
7948
+ hasValue || open ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
7949
+ ),
7950
+ children: [
7951
+ label,
7952
+ required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
7953
+ ]
7954
+ }
7955
+ ),
7956
+ /* @__PURE__ */ jsx(
7957
+ "span",
7958
+ {
7959
+ className: cn(
7960
+ "flex-1 truncate mt-3",
7961
+ hasValue ? "text-foreground" : "invisible"
7962
+ ),
7963
+ children: hasValue ? format(value, "dd MMM yyyy") : placeholder
7964
+ }
7965
+ ),
7966
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "ml-2 h-4 w-4 shrink-0 text-muted-foreground" })
7967
+ ]
7968
+ }
7969
+ ),
7970
+ /* @__PURE__ */ jsx(
7971
+ PopoverContent,
7972
+ {
7973
+ className: "p-0",
7974
+ align: "start",
7975
+ style: calendarWidth ? { width: calendarWidth } : void 0,
7976
+ children: /* @__PURE__ */ jsx(
7977
+ Calendar,
7954
7978
  {
7955
- className: cn(
7956
- "flex-1 truncate mt-3",
7957
- hasValue ? "text-foreground" : "invisible"
7958
- ),
7959
- children: hasValue ? format(value, "dd MMM yyyy") : placeholder
7979
+ mode: "single",
7980
+ selected: value,
7981
+ onSelect: (date) => {
7982
+ onChange == null ? void 0 : onChange(date);
7983
+ setOpen(false);
7984
+ },
7985
+ fromDate: fromDate != null ? fromDate : /* @__PURE__ */ new Date(),
7986
+ className: "font-ui w-full",
7987
+ autoFocus: true
7960
7988
  }
7961
- ),
7962
- /* @__PURE__ */ jsx(CalendarIcon, { className: "ml-2 h-4 w-4 shrink-0 text-muted-foreground" })
7963
- ]
7964
- }
7965
- ),
7966
- /* @__PURE__ */ jsx(
7967
- PopoverContent,
7968
- {
7969
- className: "p-0",
7970
- align: "start",
7971
- style: calendarWidth ? { width: calendarWidth } : void 0,
7972
- children: /* @__PURE__ */ jsx(
7973
- Calendar,
7974
- {
7975
- mode: "single",
7976
- selected: value,
7977
- onSelect: (date) => {
7978
- onChange == null ? void 0 : onChange(date);
7979
- setOpen(false);
7980
- },
7981
- fromDate: fromDate != null ? fromDate : /* @__PURE__ */ new Date(),
7982
- className: "font-ui w-full",
7983
- autoFocus: true
7984
- }
7985
- )
7986
- }
7987
- )
7988
- ] }) });
7989
+ )
7990
+ }
7991
+ )
7992
+ ] }),
7993
+ error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive font-ui", children: error })
7994
+ ] });
7995
+ }
7996
+ function dialFor(iso) {
7997
+ var _a, _b;
7998
+ return (_b = (_a = PHONE_COUNTRIES.find((c) => c.code === iso)) == null ? void 0 : _a.dial) != null ? _b : "";
7989
7999
  }
8000
+ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7990
8001
  function FormSection({
7991
8002
  title,
8003
+ required,
7992
8004
  children,
7993
8005
  className
7994
8006
  }) {
7995
8007
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
7996
8008
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
7997
- /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground whitespace-nowrap font-heading", children: title }),
8009
+ /* @__PURE__ */ jsxs("h3", { className: "text-base font-bold text-foreground whitespace-nowrap font-heading", children: [
8010
+ title,
8011
+ required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
8012
+ ] }),
7998
8013
  /* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-border" })
7999
8014
  ] }),
8000
8015
  children
@@ -8010,24 +8025,67 @@ var defaultInitial = {
8010
8025
  phoneCountry: "BR",
8011
8026
  lastName: "",
8012
8027
  firstName: "",
8013
- country: "France",
8028
+ country: "",
8014
8029
  phone: "",
8015
- email: ""
8030
+ email: "",
8031
+ contactVia: "Email"
8016
8032
  };
8017
8033
  function BookingForm({
8018
8034
  defaultValues,
8019
8035
  onSubmit,
8020
- submitLabel = "Send my request",
8036
+ submitLabel,
8021
8037
  loading = false,
8022
8038
  showHeader = true,
8023
- title = "Check availability for your trip",
8024
- subtitle = "Free enquiry \u2013 no commitment",
8039
+ title,
8040
+ subtitle,
8041
+ labels,
8025
8042
  className
8026
8043
  }) {
8027
- const [values, setValues] = React31.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
8028
- const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
8044
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
8045
+ const L = labels != null ? labels : {};
8046
+ const titleText = (_a = title != null ? title : L.title) != null ? _a : "Check availability for your trip";
8047
+ const subtitleText = (_b = subtitle != null ? subtitle : L.subtitle) != null ? _b : "Free enquiry \u2013 no commitment";
8048
+ const submitText = (_c = submitLabel != null ? submitLabel : L.submit) != null ? _c : "Send my request";
8049
+ const [values, setValues] = React32.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
8050
+ const [errors, setErrors] = React32.useState({});
8051
+ const set = (key, value) => {
8052
+ setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
8053
+ setErrors(
8054
+ (prev) => prev[key] ? __spreadProps(__spreadValues({}, prev), { [key]: void 0 }) : prev
8055
+ );
8056
+ };
8057
+ React32.useEffect(() => {
8058
+ if (!defaultValues) return;
8059
+ setValues((prev) => {
8060
+ let changed = false;
8061
+ const next = __spreadValues({}, prev);
8062
+ Object.keys(defaultValues).forEach(
8063
+ (k) => {
8064
+ const incoming = defaultValues[k];
8065
+ if (incoming === void 0 || incoming === "") return;
8066
+ if (prev[k] === defaultInitial[k]) {
8067
+ next[k] = incoming;
8068
+ changed = true;
8069
+ }
8070
+ }
8071
+ );
8072
+ return changed ? next : prev;
8073
+ });
8074
+ }, [defaultValues]);
8075
+ const reqMsg = (_d = L.errorRequired) != null ? _d : "This field is required";
8076
+ const emailMsg = (_e = L.errorEmail) != null ? _e : "Enter a valid email address";
8029
8077
  const handleSubmit = (e) => {
8030
8078
  e.preventDefault();
8079
+ const next = {};
8080
+ if (!values.firstName.trim()) next.firstName = reqMsg;
8081
+ if (!values.lastName.trim()) next.lastName = reqMsg;
8082
+ if (!values.email.trim()) next.email = reqMsg;
8083
+ else if (!EMAIL_RE.test(values.email.trim())) next.email = emailMsg;
8084
+ if (!values.travelDate) next.travelDate = reqMsg;
8085
+ if (!values.phone.trim()) next.phone = reqMsg;
8086
+ if (!values.contactVia) next.contactVia = reqMsg;
8087
+ setErrors(next);
8088
+ if (Object.keys(next).length > 0) return;
8031
8089
  onSubmit == null ? void 0 : onSubmit(values);
8032
8090
  };
8033
8091
  return /* @__PURE__ */ jsxs(
@@ -8038,15 +8096,14 @@ function BookingForm({
8038
8096
  noValidate: true,
8039
8097
  children: [
8040
8098
  showHeader && /* @__PURE__ */ jsxs("div", { children: [
8041
- /* @__PURE__ */ jsx("h2", { className: "text-2xl font-black uppercase tracking-wide text-foreground font-heading leading-tight", children: title }),
8042
- /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground font-ui", children: subtitle })
8099
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl font-black uppercase tracking-wide text-foreground font-heading leading-tight", children: titleText }),
8100
+ /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground font-ui", children: subtitleText })
8043
8101
  ] }),
8044
- /* @__PURE__ */ jsx(FormSection, { title: "Who's joining the adventure?", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
8102
+ /* @__PURE__ */ jsx(FormSection, { title: (_f = L.travelersSection) != null ? _f : "Who's joining the adventure?", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
8045
8103
  /* @__PURE__ */ jsx(
8046
8104
  CounterField,
8047
8105
  {
8048
- label: "Adults",
8049
- required: true,
8106
+ label: (_g = L.adults) != null ? _g : "Adults",
8050
8107
  value: values.adults,
8051
8108
  min: 1,
8052
8109
  onChange: (v) => set("adults", v)
@@ -8055,30 +8112,30 @@ function BookingForm({
8055
8112
  /* @__PURE__ */ jsx(
8056
8113
  CounterField,
8057
8114
  {
8058
- label: "Children",
8059
- sublabel: "(under 12)",
8115
+ label: (_h = L.children) != null ? _h : "Children",
8116
+ sublabel: (_i = L.childrenSublabel) != null ? _i : "(under 12)",
8060
8117
  value: values.children,
8061
8118
  min: 0,
8062
8119
  onChange: (v) => set("children", v)
8063
8120
  }
8064
8121
  )
8065
8122
  ] }) }),
8066
- /* @__PURE__ */ jsx(FormSection, { title: "Your next trip", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
8123
+ /* @__PURE__ */ jsx(FormSection, { title: (_j = L.tripSection) != null ? _j : "Your next trip", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
8067
8124
  /* @__PURE__ */ jsx(
8068
8125
  DatePickerField,
8069
8126
  {
8070
- label: "Travel date",
8127
+ label: (_k = L.travelDate) != null ? _k : "Travel date",
8071
8128
  required: true,
8072
8129
  value: values.travelDate,
8073
8130
  onChange: (d) => set("travelDate", d),
8074
- placeholder: "Pick a date"
8131
+ placeholder: (_l = L.pickDate) != null ? _l : "Pick a date",
8132
+ error: errors.travelDate
8075
8133
  }
8076
8134
  ),
8077
8135
  /* @__PURE__ */ jsx(
8078
8136
  FloatingInput,
8079
8137
  {
8080
- label: "Budget (per person)",
8081
- required: true,
8138
+ label: (_m = L.budget) != null ? _m : "Budget (per person)",
8082
8139
  type: "number",
8083
8140
  min: 0,
8084
8141
  value: values.budget,
@@ -8086,7 +8143,7 @@ function BookingForm({
8086
8143
  }
8087
8144
  )
8088
8145
  ] }) }),
8089
- /* @__PURE__ */ jsx(FormSection, { title: "Tell us about your trip", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
8146
+ /* @__PURE__ */ jsx(FormSection, { title: (_n = L.projectSection) != null ? _n : "Tell us about your trip", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
8090
8147
  /* @__PURE__ */ jsx(
8091
8148
  "textarea",
8092
8149
  {
@@ -8114,140 +8171,184 @@ function BookingForm({
8114
8171
  "peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
8115
8172
  ),
8116
8173
  children: [
8117
- "Your trip in a few words",
8174
+ (_o = L.projectLabel) != null ? _o : "Your trip in a few words",
8118
8175
  " ",
8119
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
8176
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: (_p = L.optional) != null ? _p : "(optional)" })
8120
8177
  ]
8121
8178
  }
8122
8179
  )
8123
8180
  ] }) }),
8124
- /* @__PURE__ */ jsxs(FormSection, { title: "Contact details", children: [
8181
+ /* @__PURE__ */ jsxs(FormSection, { title: (_q = L.contactSection) != null ? _q : "Contact details", children: [
8125
8182
  /* @__PURE__ */ jsx(
8126
8183
  "div",
8127
8184
  {
8128
8185
  role: "radiogroup",
8129
- "aria-label": "Title",
8186
+ "aria-label": (_r = L.titleAria) != null ? _r : "Title",
8130
8187
  className: "flex flex-wrap items-center gap-x-6 gap-y-3",
8131
- children: ["ms", "mr"].map((c) => /* @__PURE__ */ jsxs(
8132
- "label",
8133
- {
8134
- className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground",
8135
- children: [
8136
- /* @__PURE__ */ jsx(
8137
- "input",
8138
- {
8139
- type: "radio",
8140
- name: "civility",
8141
- value: c,
8142
- checked: values.civility === c,
8143
- onChange: () => set("civility", c),
8144
- className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
8145
- }
8146
- ),
8147
- c === "ms" ? "Ms." : "Mr."
8148
- ]
8149
- },
8150
- c
8151
- ))
8188
+ children: ["ms", "mr"].map((c) => {
8189
+ var _a2, _b2;
8190
+ return /* @__PURE__ */ jsxs(
8191
+ "label",
8192
+ {
8193
+ className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground",
8194
+ children: [
8195
+ /* @__PURE__ */ jsx(
8196
+ "input",
8197
+ {
8198
+ type: "radio",
8199
+ name: "civility",
8200
+ value: c,
8201
+ checked: values.civility === c,
8202
+ onChange: () => set("civility", c),
8203
+ className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
8204
+ }
8205
+ ),
8206
+ c === "ms" ? (_a2 = L.ms) != null ? _a2 : "Ms." : (_b2 = L.mr) != null ? _b2 : "Mr."
8207
+ ]
8208
+ },
8209
+ c
8210
+ );
8211
+ })
8152
8212
  }
8153
8213
  ),
8154
8214
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 min-w-0", children: [
8155
8215
  /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
8156
8216
  FloatingInput,
8157
8217
  {
8158
- label: "Last name",
8218
+ label: (_s = L.lastName) != null ? _s : "Last name",
8159
8219
  required: true,
8160
8220
  value: values.lastName,
8161
- onChange: (e) => set("lastName", e.target.value)
8221
+ onChange: (e) => set("lastName", e.target.value),
8222
+ error: errors.lastName
8162
8223
  }
8163
8224
  ) }),
8164
8225
  /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
8165
8226
  FloatingInput,
8166
8227
  {
8167
- label: "First name",
8228
+ label: (_t = L.firstName) != null ? _t : "First name",
8168
8229
  required: true,
8169
8230
  value: values.firstName,
8170
- onChange: (e) => set("firstName", e.target.value)
8231
+ onChange: (e) => set("firstName", e.target.value),
8232
+ error: errors.firstName
8171
8233
  }
8172
8234
  ) }),
8173
- /* @__PURE__ */ jsx("div", { className: "min-w-0 sm:col-span-2 lg:col-span-1", children: /* @__PURE__ */ jsxs(
8174
- FloatingSelect,
8235
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 sm:col-span-2 lg:col-span-1", children: /* @__PURE__ */ jsx(
8236
+ CountrySearchField,
8175
8237
  {
8176
- label: "Country of residence",
8177
- required: true,
8238
+ label: (_u = L.country) != null ? _u : "Country of residence",
8178
8239
  value: values.country,
8179
- onChange: (e) => set("country", e.target.value),
8180
- children: [
8181
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, hidden: true }),
8182
- /* @__PURE__ */ jsx("option", { value: "France", children: "France" }),
8183
- /* @__PURE__ */ jsx("option", { value: "Belgium", children: "Belgium" }),
8184
- /* @__PURE__ */ jsx("option", { value: "Switzerland", children: "Switzerland" }),
8185
- /* @__PURE__ */ jsx("option", { value: "Canada", children: "Canada" }),
8186
- /* @__PURE__ */ jsx("option", { value: "Luxembourg", children: "Luxembourg" }),
8187
- /* @__PURE__ */ jsx("option", { value: "United Kingdom", children: "United Kingdom" }),
8188
- /* @__PURE__ */ jsx("option", { value: "United States", children: "United States" }),
8189
- /* @__PURE__ */ jsx("option", { value: "Other", children: "Other" })
8190
- ]
8240
+ onChange: (code) => set("country", code),
8241
+ countries: COUNTRIES
8191
8242
  }
8192
8243
  ) })
8193
8244
  ] }),
8194
8245
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-2", children: [
8195
- /* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0", children: [
8196
- /* @__PURE__ */ jsx(
8197
- PhoneCountrySelect,
8198
- {
8199
- value: values.phoneCountry,
8200
- onChange: (code) => set("phoneCountry", code),
8201
- className: "shrink-0"
8202
- }
8203
- ),
8204
- /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
8246
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
8247
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0", children: [
8205
8248
  /* @__PURE__ */ jsx(
8206
- "input",
8249
+ PhoneCountrySelect,
8207
8250
  {
8208
- id: "phone",
8209
- type: "tel",
8210
- placeholder: " ",
8211
- value: values.phone,
8212
- onChange: (e) => set("phone", e.target.value),
8213
- className: cn(
8214
- "peer block h-14 w-full rounded-r-lg border border-border bg-background",
8215
- "px-3 pt-5 pb-2 text-base text-foreground font-ui",
8216
- "transition-colors placeholder-transparent",
8217
- "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
8218
- )
8251
+ value: values.phoneCountry,
8252
+ onChange: (code) => set("phoneCountry", code),
8253
+ className: "shrink-0",
8254
+ showDial: false
8219
8255
  }
8220
8256
  ),
8221
- /* @__PURE__ */ jsxs(
8222
- "label",
8223
- {
8224
- htmlFor: "phone",
8225
- className: cn(
8226
- "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
8227
- "text-base text-muted-foreground font-ui transition-all duration-150",
8228
- "peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
8229
- "peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
8230
- ),
8231
- children: [
8232
- "Phone ",
8233
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: "*" })
8234
- ]
8235
- }
8236
- )
8237
- ] })
8257
+ /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
8258
+ /* @__PURE__ */ jsx(
8259
+ "input",
8260
+ {
8261
+ id: "phone",
8262
+ type: "tel",
8263
+ placeholder: " ",
8264
+ value: `${dialFor(values.phoneCountry)} ${values.phone}`,
8265
+ onChange: (e) => {
8266
+ const dial = dialFor(values.phoneCountry);
8267
+ let national = e.target.value;
8268
+ if (national.startsWith(dial)) national = national.slice(dial.length);
8269
+ national = national.replace(/^\s+/, "");
8270
+ set("phone", national);
8271
+ },
8272
+ className: cn(
8273
+ "peer block h-14 w-full rounded-r-lg border border-border bg-background",
8274
+ "px-3 pt-5 pb-2 text-base text-foreground font-ui",
8275
+ "transition-colors placeholder-transparent",
8276
+ "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
8277
+ errors.phone && "border-destructive focus:border-destructive focus:ring-destructive"
8278
+ )
8279
+ }
8280
+ ),
8281
+ /* @__PURE__ */ jsxs(
8282
+ "label",
8283
+ {
8284
+ htmlFor: "phone",
8285
+ className: cn(
8286
+ "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
8287
+ "text-base text-muted-foreground font-ui transition-all duration-150",
8288
+ "peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
8289
+ "peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
8290
+ ),
8291
+ children: [
8292
+ (_v = L.phone) != null ? _v : "Phone",
8293
+ " ",
8294
+ /* @__PURE__ */ jsx("span", { className: "text-primary", children: "*" })
8295
+ ]
8296
+ }
8297
+ )
8298
+ ] })
8299
+ ] }),
8300
+ errors.phone && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive font-ui", children: errors.phone })
8238
8301
  ] }),
8239
8302
  /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
8240
8303
  FloatingInput,
8241
8304
  {
8242
- label: "Email",
8305
+ label: (_w = L.email) != null ? _w : "Email",
8243
8306
  required: true,
8244
8307
  type: "email",
8245
8308
  value: values.email,
8246
- onChange: (e) => set("email", e.target.value)
8309
+ onChange: (e) => set("email", e.target.value),
8310
+ error: errors.email
8247
8311
  }
8248
8312
  ) })
8249
8313
  ] })
8250
8314
  ] }),
8315
+ /* @__PURE__ */ jsxs(
8316
+ FormSection,
8317
+ {
8318
+ title: (_x = L.contactViaSection) != null ? _x : "How should we contact you?",
8319
+ required: true,
8320
+ children: [
8321
+ /* @__PURE__ */ jsx(
8322
+ "div",
8323
+ {
8324
+ role: "radiogroup",
8325
+ "aria-label": (_y = L.contactViaSection) != null ? _y : "How should we contact you?",
8326
+ className: "inline-flex flex-wrap rounded-full border border-border bg-background p-1",
8327
+ children: [
8328
+ ["WhatsApp", (_z = L.contactViaWhatsApp) != null ? _z : "WhatsApp"],
8329
+ ["Email", (_A = L.contactViaEmail) != null ? _A : "Email"],
8330
+ ["Phone", (_B = L.contactViaPhone) != null ? _B : "Phone"]
8331
+ ].map(([value, label]) => /* @__PURE__ */ jsx(
8332
+ "button",
8333
+ {
8334
+ type: "button",
8335
+ role: "radio",
8336
+ "aria-checked": values.contactVia === value,
8337
+ onClick: () => set("contactVia", value),
8338
+ className: cn(
8339
+ "whitespace-nowrap rounded-full px-5 py-2 font-heading text-[13px] font-semibold transition-colors",
8340
+ values.contactVia === value ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
8341
+ ),
8342
+ children: label
8343
+ },
8344
+ value
8345
+ ))
8346
+ }
8347
+ ),
8348
+ errors.contactVia && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive font-ui", children: errors.contactVia })
8349
+ ]
8350
+ }
8351
+ ),
8251
8352
  /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-2", children: /* @__PURE__ */ jsx(
8252
8353
  "button",
8253
8354
  {
@@ -8282,8 +8383,8 @@ function BookingForm({
8282
8383
  }
8283
8384
  )
8284
8385
  ] }),
8285
- "Sending\u2026"
8286
- ] }) : submitLabel
8386
+ (_C = L.sending) != null ? _C : "Sending\u2026"
8387
+ ] }) : submitText
8287
8388
  }
8288
8389
  ) })
8289
8390
  ]
@@ -8592,11 +8693,11 @@ function FloatingTextarea({
8592
8693
  }
8593
8694
  function SelectField({ field, value, onChange, error, disabled }) {
8594
8695
  var _a, _b, _c;
8595
- const [open, setOpen] = React31.useState(false);
8596
- const containerRef = React31.useRef(null);
8696
+ const [open, setOpen] = React32.useState(false);
8697
+ const containerRef = React32.useRef(null);
8597
8698
  const options = (_a = field.options) != null ? _a : [];
8598
8699
  const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
8599
- React31.useEffect(() => {
8700
+ React32.useEffect(() => {
8600
8701
  if (!open) return;
8601
8702
  const handleOutside = (e) => {
8602
8703
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -9064,11 +9165,11 @@ function RegistrationForm({
9064
9165
  readOnly = false
9065
9166
  }) {
9066
9167
  var _a;
9067
- const L = React31.useMemo(
9168
+ const L = React32.useMemo(
9068
9169
  () => __spreadValues(__spreadValues({}, DEFAULT_LABELS12), labels != null ? labels : {}),
9069
9170
  [labels]
9070
9171
  );
9071
- const sortedFields = React31.useMemo(
9172
+ const sortedFields = React32.useMemo(
9072
9173
  () => [...fields].sort((a, b) => {
9073
9174
  var _a2, _b;
9074
9175
  return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
@@ -9076,7 +9177,7 @@ function RegistrationForm({
9076
9177
  [fields]
9077
9178
  );
9078
9179
  const isControlled = values !== void 0;
9079
- const [internal, setInternal] = React31.useState(
9180
+ const [internal, setInternal] = React32.useState(
9080
9181
  () => initializeValues(
9081
9182
  sortedFields,
9082
9183
  defaultValues != null ? defaultValues : {},
@@ -9084,9 +9185,9 @@ function RegistrationForm({
9084
9185
  includeTerms
9085
9186
  )
9086
9187
  );
9087
- const [submitAttempted, setSubmitAttempted] = React31.useState(false);
9088
- const [validationErrors, setValidationErrors] = React31.useState({});
9089
- React31.useEffect(() => {
9188
+ const [submitAttempted, setSubmitAttempted] = React32.useState(false);
9189
+ const [validationErrors, setValidationErrors] = React32.useState({});
9190
+ React32.useEffect(() => {
9090
9191
  if (isControlled) return;
9091
9192
  setInternal((prev) => {
9092
9193
  const next = initializeValues(
@@ -9143,7 +9244,7 @@ function RegistrationForm({
9143
9244
  const termsError = submitAttempted && termsEnabled && !termsAccepted;
9144
9245
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
9145
9246
  const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
9146
- React31.useEffect(() => {
9247
+ React32.useEffect(() => {
9147
9248
  if (!submitAttempted || !scrollTargetId) return;
9148
9249
  const timer = setTimeout(() => {
9149
9250
  const elem = document.getElementById(scrollTargetId);
@@ -9596,60 +9697,335 @@ function RegistrationSuccessCard({
9596
9697
  }
9597
9698
  );
9598
9699
  }
9599
- var OTPCodeInput = ({
9600
- value,
9601
- onChange,
9602
- label,
9700
+ var OTHER = "OTHER";
9701
+ function SectionHeading({ children }) {
9702
+ return /* @__PURE__ */ jsx("h2", { className: "text-lg font-heading font-bold text-foreground mb-3", children });
9703
+ }
9704
+ function FieldError({ children }) {
9705
+ if (!children) return null;
9706
+ return /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive font-ui", children });
9707
+ }
9708
+ function CancellationForm({
9709
+ adventures,
9710
+ identity,
9711
+ labels,
9712
+ onSubmit,
9713
+ submitting = false,
9603
9714
  error,
9604
- disabled = false,
9605
- length = 6,
9606
- className,
9607
- id,
9608
- required
9609
- }) => {
9610
- const baseId = id != null ? id : React31.useId();
9611
- const inputRef = React31.useRef(null);
9612
- const [focused, setFocused] = React31.useState(false);
9613
- const digits = React31.useMemo(() => {
9614
- const arr = value.split("").slice(0, length);
9615
- while (arr.length < length) arr.push("");
9616
- return arr;
9617
- }, [value, length]);
9618
- const handleChange = (e) => {
9619
- const numeric = e.target.value.replace(/\D/g, "").slice(0, length);
9620
- onChange(numeric);
9621
- };
9622
- const activeIndex = Math.min(value.length, length - 1);
9623
- const errorId = error ? `${baseId}-error` : void 0;
9624
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
9625
- /* @__PURE__ */ jsx(
9626
- "label",
9627
- {
9628
- htmlFor: baseId,
9629
- className: cn(
9630
- "self-start text-sm text-muted-foreground font-ui mb-2",
9631
- required && "after:content-['*'] after:text-primary after:ml-0.5"
9632
- ),
9633
- children: label
9715
+ className
9716
+ }) {
9717
+ var _a, _b, _c;
9718
+ const [selectedAdventureIds, setSelectedAdventureIds] = React32.useState(/* @__PURE__ */ new Set());
9719
+ const [participantsByAdventure, setParticipantsByAdventure] = React32.useState({});
9720
+ const [reasonCode, setReasonCode] = React32.useState("");
9721
+ const [reasonOther, setReasonOther] = React32.useState("");
9722
+ const [refundPreference, setRefundPreference] = React32.useState("");
9723
+ const [refundOther, setRefundOther] = React32.useState("");
9724
+ const [agreedToPolicy, setAgreedToPolicy] = React32.useState(false);
9725
+ const [contactName, setContactName] = React32.useState((_a = identity == null ? void 0 : identity.name) != null ? _a : "");
9726
+ const [contactEmail, setContactEmail] = React32.useState((_b = identity == null ? void 0 : identity.email) != null ? _b : "");
9727
+ const [contactPhone, setContactPhone] = React32.useState((_c = identity == null ? void 0 : identity.phone) != null ? _c : "");
9728
+ const [errors, setErrors] = React32.useState({});
9729
+ const allParticipantsOf = React32.useCallback(
9730
+ (advId) => {
9731
+ var _a2, _b2;
9732
+ return new Set(((_b2 = (_a2 = adventures.find((a) => a.id === advId)) == null ? void 0 : _a2.participants) != null ? _b2 : []).map((p) => p.id));
9733
+ },
9734
+ [adventures]
9735
+ );
9736
+ function toggleAdventure(advId, on) {
9737
+ setSelectedAdventureIds((prev) => {
9738
+ const next = new Set(prev);
9739
+ if (on) next.add(advId);
9740
+ else next.delete(advId);
9741
+ return next;
9742
+ });
9743
+ setParticipantsByAdventure((prev) => {
9744
+ const next = __spreadValues({}, prev);
9745
+ if (on) next[advId] = allParticipantsOf(advId);
9746
+ else delete next[advId];
9747
+ return next;
9748
+ });
9749
+ }
9750
+ function toggleParticipant(advId, travellerId, on) {
9751
+ setParticipantsByAdventure((prev) => {
9752
+ var _a2;
9753
+ const set = new Set((_a2 = prev[advId]) != null ? _a2 : []);
9754
+ if (on) set.add(travellerId);
9755
+ else set.delete(travellerId);
9756
+ return __spreadProps(__spreadValues({}, prev), { [advId]: set });
9757
+ });
9758
+ }
9759
+ function selectAll() {
9760
+ const allAdv = new Set(adventures.map((a) => a.id));
9761
+ const byAdv = {};
9762
+ for (const a of adventures) byAdv[a.id] = new Set(a.participants.map((p) => p.id));
9763
+ setSelectedAdventureIds(allAdv);
9764
+ setParticipantsByAdventure(byAdv);
9765
+ }
9766
+ const allSelected = adventures.length > 0 && adventures.every((a) => selectedAdventureIds.has(a.id));
9767
+ function validate() {
9768
+ var _a2;
9769
+ const next = {};
9770
+ const selAdvIds = adventures.filter((a) => selectedAdventureIds.has(a.id)).map((a) => a.id);
9771
+ if (selAdvIds.length === 0) next.adventures = labels.errorSelectAdventure;
9772
+ for (const advId of selAdvIds) {
9773
+ const set = participantsByAdventure[advId];
9774
+ if (!set || set.size === 0) next.participants = labels.errorSelectParticipants;
9775
+ }
9776
+ if (!reasonCode) next.reason = labels.errorReasonRequired;
9777
+ else if (reasonCode === OTHER && !reasonOther.trim()) next.reason = labels.errorReasonOtherRequired;
9778
+ if (!refundPreference) next.refund = labels.errorRefundRequired;
9779
+ else if (refundPreference === OTHER && !refundOther.trim())
9780
+ next.refund = labels.errorRefundOtherRequired;
9781
+ if (!agreedToPolicy) next.agreement = labels.errorAgreementRequired;
9782
+ setErrors(next);
9783
+ if (Object.keys(next).length > 0) return { ok: false };
9784
+ const travellerIds = /* @__PURE__ */ new Set();
9785
+ for (const advId of selAdvIds) {
9786
+ for (const tid of (_a2 = participantsByAdventure[advId]) != null ? _a2 : []) travellerIds.add(tid);
9787
+ }
9788
+ return {
9789
+ ok: true,
9790
+ values: {
9791
+ selectedBookingAdventureIds: selAdvIds,
9792
+ selectedTravellerIds: [...travellerIds],
9793
+ reasonCode,
9794
+ reasonOther: reasonCode === OTHER ? reasonOther.trim() : "",
9795
+ refundPreference,
9796
+ refundOther: refundPreference === OTHER ? refundOther.trim() : "",
9797
+ agreedToPolicy,
9798
+ contact: { name: contactName.trim(), email: contactEmail.trim(), phone: contactPhone.trim() }
9634
9799
  }
9635
- ),
9636
- /* @__PURE__ */ jsxs(
9637
- "div",
9638
- {
9639
- className: cn(
9640
- "relative",
9641
- disabled && "opacity-50 pointer-events-none"
9800
+ };
9801
+ }
9802
+ function handleSubmit(e) {
9803
+ e.preventDefault();
9804
+ const r = validate();
9805
+ if (r.ok && r.values) void onSubmit(r.values);
9806
+ }
9807
+ return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: cn("space-y-8", className), noValidate: true, children: [
9808
+ /* @__PURE__ */ jsxs("section", { children: [
9809
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.identityHeading }),
9810
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-3", children: [
9811
+ /* @__PURE__ */ jsx(
9812
+ FloatingInput,
9813
+ {
9814
+ label: labels.contactNameLabel,
9815
+ value: contactName,
9816
+ onChange: (e) => setContactName(e.target.value)
9817
+ }
9642
9818
  ),
9643
- children: [
9644
- /* @__PURE__ */ jsx(
9645
- "input",
9646
- {
9647
- ref: inputRef,
9648
- id: baseId,
9649
- type: "text",
9650
- inputMode: "numeric",
9651
- pattern: "\\d*",
9652
- maxLength: length,
9819
+ /* @__PURE__ */ jsx(
9820
+ FloatingInput,
9821
+ {
9822
+ label: labels.contactEmailLabel,
9823
+ type: "email",
9824
+ value: contactEmail,
9825
+ onChange: (e) => setContactEmail(e.target.value)
9826
+ }
9827
+ ),
9828
+ /* @__PURE__ */ jsx(
9829
+ FloatingInput,
9830
+ {
9831
+ label: labels.contactPhoneLabel,
9832
+ value: contactPhone,
9833
+ onChange: (e) => setContactPhone(e.target.value)
9834
+ }
9835
+ )
9836
+ ] })
9837
+ ] }),
9838
+ /* @__PURE__ */ jsxs("section", { children: [
9839
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 mb-3", children: [
9840
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.adventuresHeading }),
9841
+ adventures.length > 1 && /* @__PURE__ */ jsx(Button, { type: "button", variant: "link", size: "sm", onClick: selectAll, disabled: allSelected, children: labels.selectAllLabel })
9842
+ ] }),
9843
+ labels.adventuresHint && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: labels.adventuresHint }),
9844
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: adventures.map((adv) => {
9845
+ var _a2;
9846
+ const selected = selectedAdventureIds.has(adv.id);
9847
+ const partSet = (_a2 = participantsByAdventure[adv.id]) != null ? _a2 : /* @__PURE__ */ new Set();
9848
+ return /* @__PURE__ */ jsxs(
9849
+ "div",
9850
+ {
9851
+ className: cn(
9852
+ "rounded-lg border p-4 transition-colors",
9853
+ selected ? "border-primary bg-primary/5" : "border-border bg-card"
9854
+ ),
9855
+ children: [
9856
+ /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-3 cursor-pointer", children: [
9857
+ /* @__PURE__ */ jsx(
9858
+ "input",
9859
+ {
9860
+ type: "checkbox",
9861
+ className: "mt-1 h-4 w-4 accent-primary",
9862
+ checked: selected,
9863
+ onChange: (e) => toggleAdventure(adv.id, e.target.checked)
9864
+ }
9865
+ ),
9866
+ /* @__PURE__ */ jsxs("span", { className: "flex-1", children: [
9867
+ /* @__PURE__ */ jsx("span", { className: "block font-ui font-medium text-foreground", children: adv.name }),
9868
+ adv.dateRange && /* @__PURE__ */ jsx("span", { className: "block text-sm text-muted-foreground", children: adv.dateRange })
9869
+ ] })
9870
+ ] }),
9871
+ selected && /* @__PURE__ */ jsxs("div", { className: "mt-4 pl-7 space-y-4", children: [
9872
+ adv.cancellationPolicy && /* @__PURE__ */ jsxs("div", { className: "rounded-md bg-muted/50 border border-border p-3", children: [
9873
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-ui font-semibold uppercase tracking-wide text-muted-foreground mb-1", children: labels.policyHeading }),
9874
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground whitespace-pre-line", children: adv.cancellationPolicy })
9875
+ ] }),
9876
+ adv.participants.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
9877
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-ui font-semibold uppercase tracking-wide text-muted-foreground mb-2", children: labels.participantsHeading }),
9878
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: adv.participants.map((p) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
9879
+ /* @__PURE__ */ jsx(
9880
+ "input",
9881
+ {
9882
+ type: "checkbox",
9883
+ className: "h-4 w-4 accent-primary",
9884
+ checked: partSet.has(p.id),
9885
+ onChange: (e) => toggleParticipant(adv.id, p.id, e.target.checked)
9886
+ }
9887
+ ),
9888
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: p.name })
9889
+ ] }, p.id)) })
9890
+ ] })
9891
+ ] })
9892
+ ]
9893
+ },
9894
+ adv.id
9895
+ );
9896
+ }) }),
9897
+ /* @__PURE__ */ jsx(FieldError, { children: errors.adventures }),
9898
+ /* @__PURE__ */ jsx(FieldError, { children: errors.participants })
9899
+ ] }),
9900
+ /* @__PURE__ */ jsxs("section", { children: [
9901
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.reasonHeading }),
9902
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: labels.reasonOptions.map((opt) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
9903
+ /* @__PURE__ */ jsx(
9904
+ "input",
9905
+ {
9906
+ type: "radio",
9907
+ name: "cancellation-reason",
9908
+ className: "h-4 w-4 accent-primary",
9909
+ checked: reasonCode === opt.value,
9910
+ onChange: () => setReasonCode(opt.value)
9911
+ }
9912
+ ),
9913
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: opt.label })
9914
+ ] }, opt.value)) }),
9915
+ reasonCode === OTHER && /* @__PURE__ */ jsx(
9916
+ "textarea",
9917
+ {
9918
+ className: "mt-3 w-full rounded-lg border border-border bg-background px-3 py-2 text-base text-foreground font-ui focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
9919
+ rows: 3,
9920
+ placeholder: labels.reasonOtherLabel,
9921
+ value: reasonOther,
9922
+ onChange: (e) => setReasonOther(e.target.value),
9923
+ maxLength: 1e3
9924
+ }
9925
+ ),
9926
+ /* @__PURE__ */ jsx(FieldError, { children: errors.reason })
9927
+ ] }),
9928
+ /* @__PURE__ */ jsxs("section", { children: [
9929
+ /* @__PURE__ */ jsx(SectionHeading, { children: labels.refundHeading }),
9930
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: labels.refundOptions.map((opt) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
9931
+ /* @__PURE__ */ jsx(
9932
+ "input",
9933
+ {
9934
+ type: "radio",
9935
+ name: "cancellation-refund",
9936
+ className: "h-4 w-4 accent-primary",
9937
+ checked: refundPreference === opt.value,
9938
+ onChange: () => setRefundPreference(opt.value)
9939
+ }
9940
+ ),
9941
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: opt.label })
9942
+ ] }, opt.value)) }),
9943
+ refundPreference === OTHER && /* @__PURE__ */ jsx(
9944
+ "textarea",
9945
+ {
9946
+ className: "mt-3 w-full rounded-lg border border-border bg-background px-3 py-2 text-base text-foreground font-ui focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
9947
+ rows: 3,
9948
+ placeholder: labels.refundOtherLabel,
9949
+ value: refundOther,
9950
+ onChange: (e) => setRefundOther(e.target.value),
9951
+ maxLength: 1e3
9952
+ }
9953
+ ),
9954
+ /* @__PURE__ */ jsx(FieldError, { children: errors.refund })
9955
+ ] }),
9956
+ /* @__PURE__ */ jsxs("section", { children: [
9957
+ /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-3 cursor-pointer", children: [
9958
+ /* @__PURE__ */ jsx(
9959
+ "input",
9960
+ {
9961
+ type: "checkbox",
9962
+ className: "mt-1 h-4 w-4 accent-primary",
9963
+ checked: agreedToPolicy,
9964
+ onChange: (e) => setAgreedToPolicy(e.target.checked)
9965
+ }
9966
+ ),
9967
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: labels.agreementLabel })
9968
+ ] }),
9969
+ /* @__PURE__ */ jsx(FieldError, { children: errors.agreement })
9970
+ ] }),
9971
+ error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive font-ui", role: "alert", children: error }),
9972
+ /* @__PURE__ */ jsx(Button, { type: "submit", variant: "destructive", size: "lg", disabled: submitting, className: "w-full", children: submitting ? labels.submittingLabel : labels.submitLabel })
9973
+ ] });
9974
+ }
9975
+ var OTPCodeInput = ({
9976
+ value,
9977
+ onChange,
9978
+ label,
9979
+ error,
9980
+ disabled = false,
9981
+ length = 6,
9982
+ className,
9983
+ id,
9984
+ required
9985
+ }) => {
9986
+ const baseId = id != null ? id : React32.useId();
9987
+ const inputRef = React32.useRef(null);
9988
+ const [focused, setFocused] = React32.useState(false);
9989
+ const digits = React32.useMemo(() => {
9990
+ const arr = value.split("").slice(0, length);
9991
+ while (arr.length < length) arr.push("");
9992
+ return arr;
9993
+ }, [value, length]);
9994
+ const handleChange = (e) => {
9995
+ const numeric = e.target.value.replace(/\D/g, "").slice(0, length);
9996
+ onChange(numeric);
9997
+ };
9998
+ const activeIndex = Math.min(value.length, length - 1);
9999
+ const errorId = error ? `${baseId}-error` : void 0;
10000
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
10001
+ /* @__PURE__ */ jsx(
10002
+ "label",
10003
+ {
10004
+ htmlFor: baseId,
10005
+ className: cn(
10006
+ "self-start text-sm text-muted-foreground font-ui mb-2",
10007
+ required && "after:content-['*'] after:text-primary after:ml-0.5"
10008
+ ),
10009
+ children: label
10010
+ }
10011
+ ),
10012
+ /* @__PURE__ */ jsxs(
10013
+ "div",
10014
+ {
10015
+ className: cn(
10016
+ "relative",
10017
+ disabled && "opacity-50 pointer-events-none"
10018
+ ),
10019
+ children: [
10020
+ /* @__PURE__ */ jsx(
10021
+ "input",
10022
+ {
10023
+ ref: inputRef,
10024
+ id: baseId,
10025
+ type: "text",
10026
+ inputMode: "numeric",
10027
+ pattern: "\\d*",
10028
+ maxLength: length,
9653
10029
  value,
9654
10030
  autoComplete: "one-time-code",
9655
10031
  "aria-label": label,
@@ -9723,7 +10099,7 @@ function Checkbox(_a) {
9723
10099
  })
9724
10100
  );
9725
10101
  }
9726
- var AccordionVariantContext = React31.createContext("default");
10102
+ var AccordionVariantContext = React32.createContext("default");
9727
10103
  function Accordion(_a) {
9728
10104
  var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
9729
10105
  return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
@@ -9741,7 +10117,7 @@ function Accordion(_a) {
9741
10117
  }
9742
10118
  function AccordionItem(_a) {
9743
10119
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
9744
- const variant = React31.useContext(AccordionVariantContext);
10120
+ const variant = React32.useContext(AccordionVariantContext);
9745
10121
  return /* @__PURE__ */ jsx(
9746
10122
  Accordion$1.Item,
9747
10123
  __spreadValues({
@@ -9757,56 +10133,66 @@ function AccordionItem(_a) {
9757
10133
  function AccordionTrigger(_a) {
9758
10134
  var _b = _a, {
9759
10135
  className,
9760
- children
10136
+ children,
10137
+ headingLevel
9761
10138
  } = _b, props = __objRest(_b, [
9762
10139
  "className",
9763
- "children"
10140
+ "children",
10141
+ "headingLevel"
9764
10142
  ]);
9765
- const variant = React31.useContext(AccordionVariantContext);
9766
- return /* @__PURE__ */ jsx(Accordion$1.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
9767
- Accordion$1.Trigger,
10143
+ const variant = React32.useContext(AccordionVariantContext);
10144
+ const headingRender = headingLevel === 2 ? /* @__PURE__ */ jsx("h2", {}) : headingLevel === 4 ? /* @__PURE__ */ jsx("h4", {}) : headingLevel === 5 ? /* @__PURE__ */ jsx("h5", {}) : headingLevel === 6 ? /* @__PURE__ */ jsx("h6", {}) : void 0;
10145
+ return /* @__PURE__ */ jsx(
10146
+ Accordion$1.Header,
9768
10147
  __spreadProps(__spreadValues({
9769
- "data-slot": "accordion-trigger",
9770
- className: cn(
9771
- "group/accordion-trigger relative flex flex-1 items-center justify-between text-left transition-all outline-none",
9772
- "focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
9773
- variant === "default" && [
9774
- "rounded-lg border border-transparent py-2.5 text-sm font-medium",
9775
- "hover:underline focus-visible:border-ring",
9776
- "**:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground"
9777
- ],
9778
- variant === "faq" && [
9779
- "px-5 py-4 text-base font-bold",
9780
- "hover:bg-muted/30 rounded-lg"
9781
- ],
9782
- className
9783
- )
9784
- }, props), {
9785
- children: [
9786
- children,
9787
- variant === "default" && /* @__PURE__ */ jsxs(Fragment, { children: [
9788
- /* @__PURE__ */ jsx(
9789
- ChevronDownIcon,
9790
- {
9791
- "data-slot": "accordion-trigger-icon",
9792
- className: "pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
9793
- }
9794
- ),
9795
- /* @__PURE__ */ jsx(
9796
- ChevronUpIcon,
9797
- {
9798
- "data-slot": "accordion-trigger-icon",
9799
- className: "pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
9800
- }
10148
+ className: "flex"
10149
+ }, headingRender ? { render: headingRender } : {}), {
10150
+ children: /* @__PURE__ */ jsxs(
10151
+ Accordion$1.Trigger,
10152
+ __spreadProps(__spreadValues({
10153
+ "data-slot": "accordion-trigger",
10154
+ className: cn(
10155
+ "group/accordion-trigger relative flex flex-1 items-center justify-between text-left transition-all outline-none",
10156
+ "focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
10157
+ variant === "default" && [
10158
+ "rounded-lg border border-transparent py-2.5 text-sm font-medium",
10159
+ "hover:underline focus-visible:border-ring",
10160
+ "**:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground"
10161
+ ],
10162
+ variant === "faq" && [
10163
+ "px-5 py-4 text-base font-bold",
10164
+ "hover:bg-muted/30 rounded-lg"
10165
+ ],
10166
+ className
9801
10167
  )
9802
- ] }),
9803
- variant === "faq" && /* @__PURE__ */ jsxs(Fragment, { children: [
9804
- /* @__PURE__ */ jsx(PlusIcon, { className: "pointer-events-none shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:hidden" }),
9805
- /* @__PURE__ */ jsx(MinusIcon, { className: "pointer-events-none hidden shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:inline" })
9806
- ] })
9807
- ]
10168
+ }, props), {
10169
+ children: [
10170
+ children,
10171
+ variant === "default" && /* @__PURE__ */ jsxs(Fragment, { children: [
10172
+ /* @__PURE__ */ jsx(
10173
+ ChevronDownIcon,
10174
+ {
10175
+ "data-slot": "accordion-trigger-icon",
10176
+ className: "pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
10177
+ }
10178
+ ),
10179
+ /* @__PURE__ */ jsx(
10180
+ ChevronUpIcon,
10181
+ {
10182
+ "data-slot": "accordion-trigger-icon",
10183
+ className: "pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
10184
+ }
10185
+ )
10186
+ ] }),
10187
+ variant === "faq" && /* @__PURE__ */ jsxs(Fragment, { children: [
10188
+ /* @__PURE__ */ jsx(PlusIcon, { className: "pointer-events-none shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:hidden" }),
10189
+ /* @__PURE__ */ jsx(MinusIcon, { className: "pointer-events-none hidden shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:inline" })
10190
+ ] })
10191
+ ]
10192
+ })
10193
+ )
9808
10194
  })
9809
- ) });
10195
+ );
9810
10196
  }
9811
10197
  function AccordionContent(_a) {
9812
10198
  var _b = _a, {
@@ -9816,7 +10202,7 @@ function AccordionContent(_a) {
9816
10202
  "className",
9817
10203
  "children"
9818
10204
  ]);
9819
- const variant = React31.useContext(AccordionVariantContext);
10205
+ const variant = React32.useContext(AccordionVariantContext);
9820
10206
  return /* @__PURE__ */ jsx(
9821
10207
  Accordion$1.Panel,
9822
10208
  __spreadProps(__spreadValues({
@@ -10031,18 +10417,19 @@ function FilterPanel({
10031
10417
  variant = "sidebar",
10032
10418
  sortOptions,
10033
10419
  sort,
10034
- onSortChange
10420
+ onSortChange,
10421
+ labels
10035
10422
  }) {
10036
- var _a, _b;
10037
- const resolvedGroups = React31.useMemo(() => resolveGroups(groups), [groups]);
10038
- const [internalValue, setInternalValue] = React31.useState(
10423
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10424
+ const resolvedGroups = React32.useMemo(() => resolveGroups(groups), [groups]);
10425
+ const [internalValue, setInternalValue] = React32.useState(
10039
10426
  () => Object.fromEntries(groups.map((g) => [g.id, []]))
10040
10427
  );
10041
10428
  const selected = value != null ? value : internalValue;
10042
- const [expandedItems, setExpandedItems] = React31.useState(
10429
+ const [expandedItems, setExpandedItems] = React32.useState(
10043
10430
  () => new Set(groups.flatMap((g) => getDefaultExpandedIds(g.items)))
10044
10431
  );
10045
- const toggleExpanded = React31.useCallback((id) => {
10432
+ const toggleExpanded = React32.useCallback((id) => {
10046
10433
  setExpandedItems((prev) => {
10047
10434
  const next = new Set(prev);
10048
10435
  if (next.has(id)) next.delete(id);
@@ -10171,7 +10558,7 @@ function FilterPanel({
10171
10558
  type: "button",
10172
10559
  onClick: handleClearAll,
10173
10560
  className: "text-sm font-ui font-semibold text-muted-foreground underline underline-offset-2 hover:text-foreground",
10174
- children: "Clear all"
10561
+ children: (_b = labels == null ? void 0 : labels.clearAll) != null ? _b : "Clear all"
10175
10562
  }
10176
10563
  ),
10177
10564
  /* @__PURE__ */ jsxs(
@@ -10185,9 +10572,8 @@ function FilterPanel({
10185
10572
  }
10186
10573
  ),
10187
10574
  children: [
10188
- "Show ",
10189
- totalSelected > 0 ? `(${totalSelected})` : "",
10190
- " results"
10575
+ (_c = labels == null ? void 0 : labels.showResults) != null ? _c : "Show results",
10576
+ totalSelected > 0 ? ` (${totalSelected})` : ""
10191
10577
  ]
10192
10578
  }
10193
10579
  )
@@ -10212,7 +10598,7 @@ function FilterPanel({
10212
10598
  }
10213
10599
  ),
10214
10600
  children: [
10215
- "Sort",
10601
+ (_d = labels == null ? void 0 : labels.sortLabel) != null ? _d : "Sort",
10216
10602
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" })
10217
10603
  ]
10218
10604
  }
@@ -10322,14 +10708,15 @@ function FilterPanel({
10322
10708
  className: "inline-flex items-center gap-1 rounded-full px-3 py-1.5 text-xs font-ui font-semibold text-muted-foreground hover:text-foreground transition-colors",
10323
10709
  children: [
10324
10710
  /* @__PURE__ */ jsx(XIcon, { className: "h-3 w-3" }),
10325
- "Clear all (",
10711
+ (_e = labels == null ? void 0 : labels.clearAll) != null ? _e : "Clear all",
10712
+ " (",
10326
10713
  totalSelected,
10327
10714
  ")"
10328
10715
  ]
10329
10716
  }
10330
10717
  ),
10331
10718
  sortOptions && sortOptions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
10332
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-ui hidden sm:inline", children: "Sort by" }),
10719
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground font-ui hidden sm:inline", children: (_f = labels == null ? void 0 : labels.sortByLabel) != null ? _f : "Sort by" }),
10333
10720
  /* @__PURE__ */ jsxs(Popover, { children: [
10334
10721
  /* @__PURE__ */ jsxs(
10335
10722
  PopoverTrigger,
@@ -10346,7 +10733,7 @@ function FilterPanel({
10346
10733
  }
10347
10734
  ),
10348
10735
  children: [
10349
- (_b = activeSort == null ? void 0 : activeSort.label) != null ? _b : "Default",
10736
+ (_g = activeSort == null ? void 0 : activeSort.label) != null ? _g : "Default",
10350
10737
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-3.5 w-3.5 text-muted-foreground" })
10351
10738
  ]
10352
10739
  }
@@ -10418,7 +10805,7 @@ function FilterPanel({
10418
10805
  {
10419
10806
  onClick: handleClearAll,
10420
10807
  className: "self-start text-sm text-muted-foreground underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring font-ui",
10421
- children: "Remove all filters"
10808
+ children: (_h = labels == null ? void 0 : labels.removeAllFilters) != null ? _h : "Remove all filters"
10422
10809
  }
10423
10810
  )
10424
10811
  ] });
@@ -10426,11 +10813,11 @@ function FilterPanel({
10426
10813
  var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
10427
10814
  function TrustpilotEmbed({ config }) {
10428
10815
  var _a, _b, _c, _d, _e, _f;
10429
- const ref = React31.useRef(null);
10430
- const [widgetReady, setWidgetReady] = React31.useState(false);
10431
- const [delayPassed, setDelayPassed] = React31.useState(false);
10816
+ const ref = React32.useRef(null);
10817
+ const [widgetReady, setWidgetReady] = React32.useState(false);
10818
+ const [delayPassed, setDelayPassed] = React32.useState(false);
10432
10819
  const showFallback = delayPassed && !widgetReady;
10433
- React31.useEffect(() => {
10820
+ React32.useEffect(() => {
10434
10821
  var _a2;
10435
10822
  if (typeof document === "undefined" || !ref.current) return;
10436
10823
  const node = ref.current;
@@ -10618,7 +11005,7 @@ function webpVariantUrl(src) {
10618
11005
  return `${withoutQuery}.webp${query}`;
10619
11006
  }
10620
11007
  function PictureLoader() {
10621
- const gradientId = React31.useId();
11008
+ const gradientId = React32.useId();
10622
11009
  return /* @__PURE__ */ jsx(
10623
11010
  "span",
10624
11011
  {
@@ -10687,11 +11074,11 @@ function Picture(_a) {
10687
11074
  "onLoad",
10688
11075
  "onError"
10689
11076
  ]);
10690
- var _a2;
10691
- const ref = React31.useRef(null);
10692
- const [visible, setVisible] = React31.useState(eager);
10693
- const [loaded, setLoaded] = React31.useState(false);
10694
- React31.useEffect(() => {
11077
+ var _a2, _b2;
11078
+ const ref = React32.useRef(null);
11079
+ const [visible, setVisible] = React32.useState(eager);
11080
+ const [loaded, setLoaded] = React32.useState(false);
11081
+ React32.useEffect(() => {
10695
11082
  if (eager || visible) return;
10696
11083
  const el = ref.current;
10697
11084
  if (!el || typeof IntersectionObserver === "undefined") {
@@ -10710,13 +11097,14 @@ function Picture(_a) {
10710
11097
  io.observe(el);
10711
11098
  return () => io.disconnect();
10712
11099
  }, [eager, visible, rootMargin]);
10713
- React31.useEffect(() => {
11100
+ React32.useEffect(() => {
10714
11101
  setLoaded(false);
10715
11102
  }, [src]);
10716
11103
  const webp = webpVariantUrl(src);
10717
11104
  const realSrc = visible ? src : PLACEHOLDER_SRC;
11105
+ const resolvedTitle = (_a2 = imgProps.title) != null ? _a2 : typeof imgProps.alt === "string" && imgProps.alt.trim() ? imgProps.alt : void 0;
10718
11106
  const decodingResolved = decoding != null ? decoding : eager ? void 0 : "async";
10719
- const fetchPriorityResolved = (_a2 = imgProps.fetchPriority) != null ? _a2 : eager ? void 0 : "low";
11107
+ const fetchPriorityResolved = (_b2 = imgProps.fetchPriority) != null ? _b2 : eager ? void 0 : "low";
10720
11108
  const handleLoad = (e) => {
10721
11109
  if (visible) setLoaded(true);
10722
11110
  onLoad == null ? void 0 : onLoad(e);
@@ -10742,6 +11130,7 @@ function Picture(_a) {
10742
11130
  onLoad: handleLoad,
10743
11131
  onError: handleError
10744
11132
  }, imgProps), {
11133
+ title: resolvedTitle,
10745
11134
  fetchPriority: fetchPriorityResolved,
10746
11135
  style: mergedStyle
10747
11136
  })
@@ -10765,6 +11154,7 @@ function Picture(_a) {
10765
11154
  onLoad: handleLoad,
10766
11155
  onError: handleError
10767
11156
  }, imgProps), {
11157
+ title: resolvedTitle,
10768
11158
  fetchPriority: fetchPriorityResolved,
10769
11159
  style: mergedStyle
10770
11160
  })
@@ -10838,11 +11228,11 @@ function ItineraryModal({
10838
11228
  onNext
10839
11229
  }) {
10840
11230
  var _a, _b, _c;
10841
- const [imgIndex, setImgIndex] = React31.useState(0);
11231
+ const [imgIndex, setImgIndex] = React32.useState(0);
10842
11232
  const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
10843
11233
  const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
10844
11234
  const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
10845
- React31.useEffect(() => {
11235
+ React32.useEffect(() => {
10846
11236
  setImgIndex(0);
10847
11237
  }, [stop == null ? void 0 : stop.dayNumber]);
10848
11238
  if (!stop) return null;
@@ -10969,8 +11359,8 @@ function ItineraryModal({
10969
11359
  ) });
10970
11360
  }
10971
11361
  function Itinerary({ title, subtitle, stops, className }) {
10972
- const [activeIndex, setActiveIndex] = React31.useState(null);
10973
- const scrollRef = React31.useRef(null);
11362
+ const [activeIndex, setActiveIndex] = React32.useState(null);
11363
+ const scrollRef = React32.useRef(null);
10974
11364
  const activeStop = activeIndex !== null ? stops[activeIndex] : null;
10975
11365
  const scrollBy = (dir) => {
10976
11366
  if (!scrollRef.current) return;
@@ -11059,21 +11449,22 @@ function gridCols(total) {
11059
11449
  function Lightbox({
11060
11450
  photos,
11061
11451
  initialIndex,
11062
- onClose
11452
+ onClose,
11453
+ labels
11063
11454
  }) {
11064
- var _a;
11065
- const [index, setIndex] = React31.useState(initialIndex);
11455
+ var _a, _b, _c, _d;
11456
+ const [index, setIndex] = React32.useState(initialIndex);
11066
11457
  const total = photos.length;
11067
11458
  const photo = photos[index];
11068
- const prev = React31.useCallback(
11459
+ const prev = React32.useCallback(
11069
11460
  () => setIndex((i) => (i - 1 + total) % total),
11070
11461
  [total]
11071
11462
  );
11072
- const next = React31.useCallback(
11463
+ const next = React32.useCallback(
11073
11464
  () => setIndex((i) => (i + 1) % total),
11074
11465
  [total]
11075
11466
  );
11076
- React31.useEffect(() => {
11467
+ React32.useEffect(() => {
11077
11468
  const onKey = (e) => {
11078
11469
  if (e.key === "Escape") onClose();
11079
11470
  if (e.key === "ArrowLeft") prev();
@@ -11094,7 +11485,7 @@ function Lightbox({
11094
11485
  type: "button",
11095
11486
  onClick: onClose,
11096
11487
  className: "absolute top-5 right-5 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors z-10",
11097
- "aria-label": "Close lightbox",
11488
+ "aria-label": (_a = labels == null ? void 0 : labels.close) != null ? _a : "Close lightbox",
11098
11489
  children: /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5" })
11099
11490
  }
11100
11491
  ),
@@ -11107,7 +11498,7 @@ function Lightbox({
11107
11498
  prev();
11108
11499
  },
11109
11500
  className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
11110
- "aria-label": "Previous photo",
11501
+ "aria-label": (_b = labels == null ? void 0 : labels.previous) != null ? _b : "Previous photo",
11111
11502
  children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
11112
11503
  }
11113
11504
  ),
@@ -11120,7 +11511,7 @@ function Lightbox({
11120
11511
  next();
11121
11512
  },
11122
11513
  className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
11123
- "aria-label": "Next photo",
11514
+ "aria-label": (_c = labels == null ? void 0 : labels.next) != null ? _c : "Next photo",
11124
11515
  children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
11125
11516
  }
11126
11517
  ),
@@ -11128,7 +11519,8 @@ function Lightbox({
11128
11519
  Picture,
11129
11520
  {
11130
11521
  src: photo.src,
11131
- alt: (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
11522
+ alt: (_d = photo.alt) != null ? _d : `Photo ${index + 1}`,
11523
+ title: photo.caption,
11132
11524
  className: "max-w-[calc(100%-6rem)] max-h-[calc(100vh-11rem)] object-contain rounded-lg shadow-2xl",
11133
11525
  onClick: (e) => e.stopPropagation()
11134
11526
  }
@@ -11198,6 +11590,7 @@ function PhotoTile({
11198
11590
  {
11199
11591
  src: photo.src,
11200
11592
  alt: (_b = photo.alt) != null ? _b : `Photo ${index + 1}`,
11593
+ title: photo.caption,
11201
11594
  className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105",
11202
11595
  loading: "lazy"
11203
11596
  }
@@ -11211,8 +11604,10 @@ function PhotoTile({
11211
11604
  function ShowMoreButton({
11212
11605
  count,
11213
11606
  expanded,
11214
- onClick
11607
+ onClick,
11608
+ labels
11215
11609
  }) {
11610
+ var _a, _b;
11216
11611
  return /* @__PURE__ */ jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsx(
11217
11612
  "button",
11218
11613
  {
@@ -11226,10 +11621,11 @@ function ShowMoreButton({
11226
11621
  ),
11227
11622
  children: expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
11228
11623
  /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
11229
- "Show less"
11624
+ (_a = labels == null ? void 0 : labels.showLess) != null ? _a : "Show less"
11230
11625
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
11231
11626
  /* @__PURE__ */ jsx(LayoutGridIcon, { className: "h-4 w-4 text-muted-foreground" }),
11232
- "See more (",
11627
+ (_b = labels == null ? void 0 : labels.seeMore) != null ? _b : "See more",
11628
+ " (",
11233
11629
  count,
11234
11630
  ")"
11235
11631
  ] })
@@ -11239,9 +11635,10 @@ function ShowMoreButton({
11239
11635
  function GridGallery({
11240
11636
  photos,
11241
11637
  initialVisible,
11242
- onOpen
11638
+ onOpen,
11639
+ labels
11243
11640
  }) {
11244
- const [expanded, setExpanded] = React31.useState(false);
11641
+ const [expanded, setExpanded] = React32.useState(false);
11245
11642
  const cols = gridCols(photos.length);
11246
11643
  const hasMore = photos.length > initialVisible;
11247
11644
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
@@ -11261,7 +11658,8 @@ function GridGallery({
11261
11658
  {
11262
11659
  count: photos.length - initialVisible,
11263
11660
  expanded,
11264
- onClick: () => setExpanded((v) => !v)
11661
+ onClick: () => setExpanded((v) => !v),
11662
+ labels
11265
11663
  }
11266
11664
  )
11267
11665
  ] });
@@ -11269,9 +11667,10 @@ function GridGallery({
11269
11667
  function CompactGridGallery({
11270
11668
  photos,
11271
11669
  initialVisible,
11272
- onOpen
11670
+ onOpen,
11671
+ labels
11273
11672
  }) {
11274
- const [expanded, setExpanded] = React31.useState(false);
11673
+ const [expanded, setExpanded] = React32.useState(false);
11275
11674
  const hasMore = photos.length > initialVisible;
11276
11675
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
11277
11676
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -11290,7 +11689,8 @@ function CompactGridGallery({
11290
11689
  {
11291
11690
  count: photos.length - initialVisible,
11292
11691
  expanded,
11293
- onClick: () => setExpanded((v) => !v)
11692
+ onClick: () => setExpanded((v) => !v),
11693
+ labels
11294
11694
  }
11295
11695
  )
11296
11696
  ] });
@@ -11298,9 +11698,10 @@ function CompactGridGallery({
11298
11698
  function MasonryGallery({
11299
11699
  photos,
11300
11700
  initialVisible,
11301
- onOpen
11701
+ onOpen,
11702
+ labels
11302
11703
  }) {
11303
- const [expanded, setExpanded] = React31.useState(false);
11704
+ const [expanded, setExpanded] = React32.useState(false);
11304
11705
  const hasMore = photos.length > initialVisible;
11305
11706
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
11306
11707
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -11319,6 +11720,7 @@ function MasonryGallery({
11319
11720
  {
11320
11721
  src: p.src,
11321
11722
  alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
11723
+ title: p.caption,
11322
11724
  className: "w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105",
11323
11725
  loading: "lazy"
11324
11726
  }
@@ -11334,7 +11736,8 @@ function MasonryGallery({
11334
11736
  {
11335
11737
  count: photos.length - initialVisible,
11336
11738
  expanded,
11337
- onClick: () => setExpanded((v) => !v)
11739
+ onClick: () => setExpanded((v) => !v),
11740
+ labels
11338
11741
  }
11339
11742
  )
11340
11743
  ] });
@@ -11358,6 +11761,7 @@ function FilmstripGallery({
11358
11761
  {
11359
11762
  src: p.src,
11360
11763
  alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
11764
+ title: p.caption,
11361
11765
  className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
11362
11766
  loading: "lazy"
11363
11767
  }
@@ -11371,9 +11775,10 @@ function FilmstripGallery({
11371
11775
  }
11372
11776
  function FeaturedGallery({
11373
11777
  photos,
11374
- onOpen
11778
+ onOpen,
11779
+ labels
11375
11780
  }) {
11376
- const [expanded, setExpanded] = React31.useState(false);
11781
+ const [expanded, setExpanded] = React32.useState(false);
11377
11782
  const featured = photos.slice(0, 3);
11378
11783
  const extra = photos.slice(3);
11379
11784
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -11423,6 +11828,7 @@ function FeaturedGallery({
11423
11828
  {
11424
11829
  src: p.src,
11425
11830
  alt: (_b = p.alt) != null ? _b : `Photo ${i + 4}`,
11831
+ title: p.caption,
11426
11832
  className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
11427
11833
  loading: "lazy"
11428
11834
  }
@@ -11438,7 +11844,8 @@ function FeaturedGallery({
11438
11844
  {
11439
11845
  count: extra.length,
11440
11846
  expanded,
11441
- onClick: () => setExpanded((v) => !v)
11847
+ onClick: () => setExpanded((v) => !v),
11848
+ labels
11442
11849
  }
11443
11850
  )
11444
11851
  ] });
@@ -11506,6 +11913,7 @@ function CarouselGallery({
11506
11913
  {
11507
11914
  src: photo.src,
11508
11915
  alt: (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
11916
+ title: photo.caption,
11509
11917
  className: "h-full w-full object-cover transition-transform duration-500 group-hover/photo:scale-[1.02]",
11510
11918
  loading: "lazy"
11511
11919
  },
@@ -11569,11 +11977,12 @@ function PhotoGallery({
11569
11977
  variant = "grid",
11570
11978
  initialVisible = 6,
11571
11979
  onPhotoClick,
11980
+ labels,
11572
11981
  className
11573
11982
  }) {
11574
- const [lightboxIndex, setLightboxIndex] = React31.useState(null);
11575
- const [carouselIndex, setCarouselIndex] = React31.useState(0);
11576
- const normalised = React31.useMemo(() => photos.map(normalise), [photos]);
11983
+ const [lightboxIndex, setLightboxIndex] = React32.useState(null);
11984
+ const [carouselIndex, setCarouselIndex] = React32.useState(0);
11985
+ const normalised = React32.useMemo(() => photos.map(normalise), [photos]);
11577
11986
  const handleOpen = (index) => {
11578
11987
  setLightboxIndex(index);
11579
11988
  onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
@@ -11584,7 +11993,8 @@ function PhotoGallery({
11584
11993
  {
11585
11994
  photos: normalised,
11586
11995
  initialIndex: lightboxIndex,
11587
- onClose: () => setLightboxIndex(null)
11996
+ onClose: () => setLightboxIndex(null),
11997
+ labels
11588
11998
  }
11589
11999
  );
11590
12000
  if (variant === "carousel" || variant === "fullBleed") {
@@ -11612,7 +12022,8 @@ function PhotoGallery({
11612
12022
  {
11613
12023
  photos: normalised,
11614
12024
  initialVisible,
11615
- onOpen: handleOpen
12025
+ onOpen: handleOpen,
12026
+ labels
11616
12027
  }
11617
12028
  ),
11618
12029
  variant === "gridCompact" && /* @__PURE__ */ jsx(
@@ -11620,7 +12031,8 @@ function PhotoGallery({
11620
12031
  {
11621
12032
  photos: normalised,
11622
12033
  initialVisible,
11623
- onOpen: handleOpen
12034
+ onOpen: handleOpen,
12035
+ labels
11624
12036
  }
11625
12037
  ),
11626
12038
  variant === "masonry" && /* @__PURE__ */ jsx(
@@ -11628,11 +12040,12 @@ function PhotoGallery({
11628
12040
  {
11629
12041
  photos: normalised,
11630
12042
  initialVisible,
11631
- onOpen: handleOpen
12043
+ onOpen: handleOpen,
12044
+ labels
11632
12045
  }
11633
12046
  ),
11634
12047
  variant === "filmstrip" && /* @__PURE__ */ jsx(FilmstripGallery, { photos: normalised, onOpen: handleOpen }),
11635
- variant === "featured" && /* @__PURE__ */ jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen }),
12048
+ variant === "featured" && /* @__PURE__ */ jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen, labels }),
11636
12049
  variant === "collage" && /* @__PURE__ */ jsx(CollageGallery, { photos: normalised, onOpen: handleOpen }),
11637
12050
  variant === "collageTight" && /* @__PURE__ */ jsx(CollageGallery, { photos: normalised, onOpen: handleOpen, seamless: true }),
11638
12051
  lightbox
@@ -11659,7 +12072,7 @@ function ItineraryDay({
11659
12072
  photoLayout = "rounded",
11660
12073
  className
11661
12074
  }) {
11662
- const photoList = React31.useMemo(() => normalisePhotos(photos), [photos]);
12075
+ const photoList = React32.useMemo(() => normalisePhotos(photos), [photos]);
11663
12076
  const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
11664
12077
  const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
11665
12078
  const gallery = photoList.length > 0 && /* @__PURE__ */ jsx(
@@ -11714,8 +12127,8 @@ function MenuTrip({
11714
12127
  bold = true,
11715
12128
  className
11716
12129
  }) {
11717
- const scrollRef = React31.useRef(null);
11718
- React31.useEffect(() => {
12130
+ const scrollRef = React32.useRef(null);
12131
+ React32.useEffect(() => {
11719
12132
  if (!scrollRef.current || !activeSection) return;
11720
12133
  const container = scrollRef.current;
11721
12134
  const btn = container.querySelector(
@@ -11902,6 +12315,8 @@ function PricingTrip({
11902
12315
  departureTimes,
11903
12316
  onBook,
11904
12317
  bookLabel = "Check availability",
12318
+ fromLabel = "From",
12319
+ perPersonLabel = "per person",
11905
12320
  variant = "card",
11906
12321
  sharp = false,
11907
12322
  belowPrice,
@@ -11911,8 +12326,8 @@ function PricingTrip({
11911
12326
  className
11912
12327
  }) {
11913
12328
  const rOuter = sharp ? "rounded-none" : "rounded-2xl";
11914
- const [showEstimates, setShowEstimates] = React31.useState(false);
11915
- const [showPriceInfo, setShowPriceInfo] = React31.useState(false);
12329
+ const [showEstimates, setShowEstimates] = React32.useState(false);
12330
+ const [showPriceInfo, setShowPriceInfo] = React32.useState(false);
11916
12331
  if (variant === "compact") {
11917
12332
  const showOverlay = showPriceInfo && (!!priceInfo || !!currencyEstimates && currencyEstimates.length > 0);
11918
12333
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -11928,13 +12343,16 @@ function PricingTrip({
11928
12343
  ),
11929
12344
  /* @__PURE__ */ jsxs("div", { className: "relative flex items-center gap-3", children: [
11930
12345
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
11931
- /* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
12346
+ /* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: fromLabel }),
11932
12347
  /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-1.5 flex-wrap", children: [
11933
12348
  /* @__PURE__ */ jsxs("p", { className: "text-lg font-bold text-foreground font-heading leading-none", children: [
11934
12349
  currency,
11935
12350
  " ",
11936
12351
  priceFrom,
11937
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-normal text-muted-foreground font-ui ml-1", children: "/ per person" })
12352
+ /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-normal text-muted-foreground font-ui ml-1", children: [
12353
+ "/ ",
12354
+ perPersonLabel
12355
+ ] })
11938
12356
  ] }),
11939
12357
  (priceInfo || currencyEstimates && currencyEstimates.length > 0) && /* @__PURE__ */ jsx(
11940
12358
  "button",
@@ -12046,7 +12464,7 @@ function PricingTrip({
12046
12464
  ] }),
12047
12465
  /* @__PURE__ */ jsx("div", { className: "flex-1" }),
12048
12466
  /* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right", children: [
12049
- /* @__PURE__ */ jsx("span", { className: "block text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
12467
+ /* @__PURE__ */ jsx("span", { className: "block text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: fromLabel }),
12050
12468
  /* @__PURE__ */ jsxs("span", { className: "text-xl font-bold text-foreground font-heading leading-none", children: [
12051
12469
  currency,
12052
12470
  " ",
@@ -12075,13 +12493,16 @@ function PricingTrip({
12075
12493
  }
12076
12494
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
12077
12495
  /* @__PURE__ */ jsxs("div", { children: [
12078
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide", children: "From" }),
12496
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide", children: fromLabel }),
12079
12497
  /* @__PURE__ */ jsxs("p", { className: "text-2xl font-bold text-foreground font-heading flex items-center gap-2 flex-wrap", children: [
12080
12498
  /* @__PURE__ */ jsxs("span", { children: [
12081
12499
  currency,
12082
12500
  " ",
12083
12501
  priceFrom,
12084
- /* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground font-ui", children: " / per person" })
12502
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-normal text-muted-foreground font-ui", children: [
12503
+ " / ",
12504
+ perPersonLabel
12505
+ ] })
12085
12506
  ] }),
12086
12507
  priceInfo && /* @__PURE__ */ jsx(
12087
12508
  "button",
@@ -12348,18 +12769,20 @@ function SiteHeader({
12348
12769
  onSearch,
12349
12770
  onAccount,
12350
12771
  position = variant === "transparent" ? "overlay" : "fixed",
12772
+ labels,
12351
12773
  className
12352
12774
  }) {
12775
+ var _a, _b, _c, _d, _e, _f, _g;
12353
12776
  const t = VARIANT[variant];
12354
12777
  const resolvedLogo = logoSrc != null ? logoSrc : variant === "white" ? logoSrcDark : logoSrcLight;
12355
- const [openMenu, setOpenMenu] = React31.useState(null);
12356
- const [langOpen, setLangOpen] = React31.useState(false);
12357
- const [mobileOpen, setMobileOpen] = React31.useState(false);
12358
- const [openMobileSection, setOpenMobileSection] = React31.useState(null);
12359
- const [activeLang, setActiveLang] = React31.useState(currentLanguage);
12778
+ const [openMenu, setOpenMenu] = React32.useState(null);
12779
+ const [langOpen, setLangOpen] = React32.useState(false);
12780
+ const [mobileOpen, setMobileOpen] = React32.useState(false);
12781
+ const [openMobileSection, setOpenMobileSection] = React32.useState(null);
12782
+ const [activeLang, setActiveLang] = React32.useState(currentLanguage);
12360
12783
  const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
12361
- const menuCloseTimer = React31.useRef(void 0);
12362
- const langCloseTimer = React31.useRef(void 0);
12784
+ const menuCloseTimer = React32.useRef(void 0);
12785
+ const langCloseTimer = React32.useRef(void 0);
12363
12786
  const handleMenuEnter = (label) => {
12364
12787
  clearTimeout(menuCloseTimer.current);
12365
12788
  setOpenMenu(label);
@@ -12380,7 +12803,7 @@ function SiteHeader({
12380
12803
  setOpenMenu(null);
12381
12804
  setLangOpen(false);
12382
12805
  };
12383
- React31.useEffect(() => () => {
12806
+ React32.useEffect(() => () => {
12384
12807
  clearTimeout(menuCloseTimer.current);
12385
12808
  clearTimeout(langCloseTimer.current);
12386
12809
  }, []);
@@ -12407,7 +12830,7 @@ function SiteHeader({
12407
12830
  {
12408
12831
  type: "button",
12409
12832
  onClick: () => setMobileOpen(true),
12410
- "aria-label": "Open menu",
12833
+ "aria-label": (_a = labels == null ? void 0 : labels.openMenu) != null ? _a : "Open menu",
12411
12834
  className: cn(
12412
12835
  "flex lg:hidden h-9 w-9 items-center justify-center rounded-full transition-colors -ml-1.5",
12413
12836
  t.mobileTrigger
@@ -12436,8 +12859,8 @@ function SiteHeader({
12436
12859
  }
12437
12860
  ),
12438
12861
  /* @__PURE__ */ jsx("nav", { className: "hidden lg:flex items-center gap-0.5 mx-auto", children: links.map((link) => {
12439
- var _a, _b;
12440
- const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
12862
+ var _a2, _b2;
12863
+ const hasDropdown = !!((_a2 = link.items) == null ? void 0 : _a2.length);
12441
12864
  const isOpen = openMenu === link.label;
12442
12865
  return /* @__PURE__ */ jsxs(
12443
12866
  "div",
@@ -12449,7 +12872,7 @@ function SiteHeader({
12449
12872
  /* @__PURE__ */ jsxs(
12450
12873
  "a",
12451
12874
  {
12452
- href: (_b = link.href) != null ? _b : "#",
12875
+ href: (_b2 = link.href) != null ? _b2 : "#",
12453
12876
  onClick: hasDropdown ? (e) => e.preventDefault() : void 0,
12454
12877
  className: cn(
12455
12878
  "flex items-center gap-1 px-3.5 py-1.5 rounded-full",
@@ -12498,7 +12921,7 @@ function SiteHeader({
12498
12921
  "button",
12499
12922
  {
12500
12923
  type: "button",
12501
- "aria-label": "Language",
12924
+ "aria-label": (_b = labels == null ? void 0 : labels.language) != null ? _b : "Language",
12502
12925
  className: cn(
12503
12926
  "flex items-center gap-0.5 px-2.5 py-1.5 rounded-full",
12504
12927
  "text-sm font-ui transition-colors",
@@ -12538,7 +12961,7 @@ function SiteHeader({
12538
12961
  {
12539
12962
  type: "button",
12540
12963
  onClick: onSearch,
12541
- "aria-label": "Search",
12964
+ "aria-label": (_c = labels == null ? void 0 : labels.search) != null ? _c : "Search",
12542
12965
  className: cn(
12543
12966
  "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
12544
12967
  t.icon
@@ -12551,7 +12974,7 @@ function SiteHeader({
12551
12974
  {
12552
12975
  type: "button",
12553
12976
  onClick: onAccount,
12554
- "aria-label": "Account",
12977
+ "aria-label": (_d = labels == null ? void 0 : labels.account) != null ? _d : "Account",
12555
12978
  className: cn(
12556
12979
  "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
12557
12980
  t.icon
@@ -12584,7 +13007,7 @@ function SiteHeader({
12584
13007
  {
12585
13008
  type: "button",
12586
13009
  onClick: () => setMobileOpen(false),
12587
- "aria-label": "Close menu",
13010
+ "aria-label": (_e = labels == null ? void 0 : labels.closeMenu) != null ? _e : "Close menu",
12588
13011
  className: cn(
12589
13012
  "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
12590
13013
  t.mobileTrigger
@@ -12594,8 +13017,8 @@ function SiteHeader({
12594
13017
  )
12595
13018
  ] }),
12596
13019
  /* @__PURE__ */ jsx("nav", { className: "flex-1 overflow-y-auto px-6 py-6 flex flex-col gap-1", children: links.map((link) => {
12597
- var _a, _b;
12598
- const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
13020
+ var _a2, _b2;
13021
+ const hasDropdown = !!((_a2 = link.items) == null ? void 0 : _a2.length);
12599
13022
  const isExpanded = openMobileSection === link.label;
12600
13023
  return /* @__PURE__ */ jsxs("div", { children: [
12601
13024
  hasDropdown ? /* @__PURE__ */ jsxs(
@@ -12623,7 +13046,7 @@ function SiteHeader({
12623
13046
  ) : /* @__PURE__ */ jsx(
12624
13047
  "a",
12625
13048
  {
12626
- href: (_b = link.href) != null ? _b : "#",
13049
+ href: (_b2 = link.href) != null ? _b2 : "#",
12627
13050
  onClick: () => setMobileOpen(false),
12628
13051
  className: cn(
12629
13052
  "flex items-center py-4 text-xl font-ui font-black transition-colors border-b border-white/8",
@@ -12633,11 +13056,11 @@ function SiteHeader({
12633
13056
  }
12634
13057
  ),
12635
13058
  hasDropdown && isExpanded && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0 pl-4 pb-2", children: link.items.map((item) => {
12636
- var _a2;
13059
+ var _a3;
12637
13060
  return /* @__PURE__ */ jsx(
12638
13061
  "a",
12639
13062
  {
12640
- href: (_a2 = item.href) != null ? _a2 : "#",
13063
+ href: (_a3 = item.href) != null ? _a3 : "#",
12641
13064
  onClick: () => setMobileOpen(false),
12642
13065
  className: cn(
12643
13066
  "py-3 text-base font-ui font-bold transition-colors border-b",
@@ -12656,7 +13079,7 @@ function SiteHeader({
12656
13079
  ), children: [
12657
13080
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
12658
13081
  const isActive = lang.code === activeLang;
12659
- return /* @__PURE__ */ jsxs(React31.Fragment, { children: [
13082
+ return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
12660
13083
  i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
12661
13084
  "text-xs select-none",
12662
13085
  variant === "white" ? "text-border" : "text-white/15"
@@ -12690,7 +13113,7 @@ function SiteHeader({
12690
13113
  onSearch == null ? void 0 : onSearch();
12691
13114
  setMobileOpen(false);
12692
13115
  },
12693
- "aria-label": "Search",
13116
+ "aria-label": (_f = labels == null ? void 0 : labels.search) != null ? _f : "Search",
12694
13117
  className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
12695
13118
  children: /* @__PURE__ */ jsx(SearchIcon, { className: "h-[18px] w-[18px]" })
12696
13119
  }
@@ -12703,7 +13126,7 @@ function SiteHeader({
12703
13126
  onAccount == null ? void 0 : onAccount();
12704
13127
  setMobileOpen(false);
12705
13128
  },
12706
- "aria-label": "Account",
13129
+ "aria-label": (_g = labels == null ? void 0 : labels.account) != null ? _g : "Account",
12707
13130
  className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
12708
13131
  children: /* @__PURE__ */ jsx(UserIcon, { className: "h-[18px] w-[18px]" })
12709
13132
  }
@@ -12718,8 +13141,8 @@ function SiteHeader({
12718
13141
  );
12719
13142
  }
12720
13143
  function ThemeToggle({ className }) {
12721
- const [dark, setDark] = React31.useState(false);
12722
- React31.useEffect(() => {
13144
+ const [dark, setDark] = React32.useState(false);
13145
+ React32.useEffect(() => {
12723
13146
  const saved = localStorage.getItem("theme");
12724
13147
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
12725
13148
  const isDark = saved === "dark" || !saved && prefersDark;
@@ -12769,7 +13192,7 @@ var chipVariants = cva(
12769
13192
  }
12770
13193
  }
12771
13194
  );
12772
- var Chip = React31.forwardRef(function Chip2(_a, ref) {
13195
+ var Chip = React32.forwardRef(function Chip2(_a, ref) {
12773
13196
  var _b = _a, { className, variant, size, href, children } = _b, props = __objRest(_b, ["className", "variant", "size", "href", "children"]);
12774
13197
  const classes = cn(chipVariants({ variant, size }), className);
12775
13198
  if (href) {
@@ -12853,9 +13276,11 @@ function HeartIcon({ filled = false }) {
12853
13276
  );
12854
13277
  }
12855
13278
  function TripCardEditorial(props) {
13279
+ var _a, _b, _c, _d;
12856
13280
  const {
12857
13281
  image,
12858
13282
  imageAlt = "",
13283
+ labels,
12859
13284
  title,
12860
13285
  description,
12861
13286
  nights,
@@ -12871,7 +13296,7 @@ function TripCardEditorial(props) {
12871
13296
  tag,
12872
13297
  tagHref
12873
13298
  } = props;
12874
- const [internalFav, setInternalFav] = React31.useState(false);
13299
+ const [internalFav, setInternalFav] = React32.useState(false);
12875
13300
  const favorited = favoritedProp != null ? favoritedProp : internalFav;
12876
13301
  const handleFav = (e) => {
12877
13302
  e.preventDefault();
@@ -12913,7 +13338,7 @@ function TripCardEditorial(props) {
12913
13338
  "button",
12914
13339
  {
12915
13340
  type: "button",
12916
- "aria-label": favorited ? "Remove from favorites" : "Add to favorites",
13341
+ "aria-label": favorited ? (_a = labels == null ? void 0 : labels.removeFromFavorites) != null ? _a : "Remove from favorites" : (_b = labels == null ? void 0 : labels.addToFavorites) != null ? _b : "Add to favorites",
12917
13342
  "aria-pressed": favorited,
12918
13343
  onClick: handleFav,
12919
13344
  className: cn(
@@ -12957,7 +13382,7 @@ function TripCardEditorial(props) {
12957
13382
  /* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
12958
13383
  nights,
12959
13384
  " ",
12960
- nights === 1 ? "night" : "nights"
13385
+ nights === 1 ? (_c = labels == null ? void 0 : labels.night) != null ? _c : "night" : (_d = labels == null ? void 0 : labels.nights) != null ? _d : "nights"
12961
13386
  ] })
12962
13387
  ] }) : /* @__PURE__ */ jsx("span", {}),
12963
13388
  price && /* @__PURE__ */ jsx("p", { className: "text-base font-bold text-foreground font-ui", children: price })
@@ -12982,12 +13407,14 @@ function TripCardEditorial(props) {
12982
13407
  ] });
12983
13408
  }
12984
13409
  function TripCard(props) {
13410
+ var _a, _b;
12985
13411
  if (props.variant === "editorial") {
12986
13412
  return /* @__PURE__ */ jsx(TripCardEditorial, __spreadValues({}, props));
12987
13413
  }
12988
13414
  const {
12989
13415
  image,
12990
13416
  imageAlt = "",
13417
+ labels,
12991
13418
  status,
12992
13419
  nights,
12993
13420
  period,
@@ -13000,6 +13427,7 @@ function TripCard(props) {
13000
13427
  } = props;
13001
13428
  const s = sizeConfig[size];
13002
13429
  const statusInfo = status ? statusConfig[status] : null;
13430
+ const statusLabel = statusInfo ? status === "sold-out" ? (_a = labels == null ? void 0 : labels.soldOut) != null ? _a : statusInfo.label : status === "trending" ? (_b = labels == null ? void 0 : labels.trending) != null ? _b : statusInfo.label : statusInfo.label : null;
13003
13431
  const meta = [
13004
13432
  nights ? `${nights} nights` : null,
13005
13433
  period != null ? period : null
@@ -13025,7 +13453,7 @@ function TripCard(props) {
13025
13453
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent" }),
13026
13454
  statusInfo && /* @__PURE__ */ jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-xl bg-card/90 px-3 py-1.5 backdrop-blur-sm shadow-sm", children: [
13027
13455
  /* @__PURE__ */ jsx("span", { className: "text-primary", children: statusInfo.icon }),
13028
- /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground font-ui", children: statusInfo.label })
13456
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground font-ui", children: statusLabel })
13029
13457
  ] }) }),
13030
13458
  !statusInfo && /* @__PURE__ */ jsx("div", { className: "relative z-10" }),
13031
13459
  /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
@@ -13119,6 +13547,7 @@ function BlogCard({
13119
13547
  {
13120
13548
  src: image,
13121
13549
  alt: imageAlt,
13550
+ title: imageAlt || void 0,
13122
13551
  loading: "lazy",
13123
13552
  className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
13124
13553
  }
@@ -13382,7 +13811,7 @@ function BlogPost({
13382
13811
  ) }),
13383
13812
  /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/90 via-black/45 to-transparent" }),
13384
13813
  /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 bottom-0", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-3xl px-6 sm:px-8 pb-9 sm:pb-11", children: [
13385
- 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(React31.Fragment, { children: [
13814
+ 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(React32.Fragment, { children: [
13386
13815
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
13387
13816
  crumb.href ? /* @__PURE__ */ jsx(
13388
13817
  "a",
@@ -13436,7 +13865,7 @@ function BlogPost({
13436
13865
  ] });
13437
13866
  }
13438
13867
  function useHlsVideo(videoRef, src) {
13439
- React31.useEffect(() => {
13868
+ React32.useEffect(() => {
13440
13869
  if (!src || !videoRef.current) return;
13441
13870
  const video = videoRef.current;
13442
13871
  if (!src.includes(".m3u8")) return;
@@ -13472,6 +13901,8 @@ function TripHeader({
13472
13901
  breadcrumb,
13473
13902
  destination,
13474
13903
  duration,
13904
+ groupSize,
13905
+ labels,
13475
13906
  tagline,
13476
13907
  chips,
13477
13908
  belowMeta,
@@ -13479,12 +13910,12 @@ function TripHeader({
13479
13910
  uiVariant = "v1",
13480
13911
  className
13481
13912
  }) {
13482
- var _a;
13483
- const [heroIndex, setHeroIndex] = React31.useState(0);
13484
- const [videoReady, setVideoReady] = React31.useState(false);
13485
- const videoRef = React31.useRef(null);
13913
+ var _a, _b, _c, _d, _e, _f, _g;
13914
+ const [heroIndex, setHeroIndex] = React32.useState(0);
13915
+ const [videoReady, setVideoReady] = React32.useState(false);
13916
+ const videoRef = React32.useRef(null);
13486
13917
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
13487
- const validImages = React31.useMemo(
13918
+ const validImages = React32.useMemo(
13488
13919
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
13489
13920
  [images]
13490
13921
  );
@@ -13497,9 +13928,9 @@ function TripHeader({
13497
13928
  const currentSrc = heroSrc(safeIndex);
13498
13929
  const showCarousel = !videoUrl && validImages.length > 1;
13499
13930
  const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
13500
- const hasMeta = !!(destination || duration);
13931
+ const hasMeta = !!(destination || duration || groupSize);
13501
13932
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
13502
- React31.useEffect(() => {
13933
+ React32.useEffect(() => {
13503
13934
  if (!videoUrl) return;
13504
13935
  const el = videoRef.current;
13505
13936
  if (!el) return;
@@ -13604,7 +14035,7 @@ function TripHeader({
13604
14035
  (i) => (i - 1 + validImages.length) % validImages.length
13605
14036
  ),
13606
14037
  className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
13607
- "aria-label": "Imagem anterior",
14038
+ "aria-label": (_b = labels == null ? void 0 : labels.previousImage) != null ? _b : "Previous image",
13608
14039
  children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
13609
14040
  }
13610
14041
  ),
@@ -13614,7 +14045,7 @@ function TripHeader({
13614
14045
  type: "button",
13615
14046
  onClick: () => setHeroIndex((i) => (i + 1) % validImages.length),
13616
14047
  className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
13617
- "aria-label": "Pr\xF3xima imagem",
14048
+ "aria-label": (_c = labels == null ? void 0 : labels.nextImage) != null ? _c : "Next image",
13618
14049
  children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
13619
14050
  }
13620
14051
  ),
@@ -13642,7 +14073,7 @@ function TripHeader({
13642
14073
  chips && chips.length > 0 ? siteHeader ? "-mt-[200px] sm:-mt-[214px]" : "-mt-[168px] sm:-mt-[182px]" : siteHeader ? "-mt-44" : "-mt-36"
13643
14074
  ),
13644
14075
  children: [
13645
- 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(React31.Fragment, { children: [
14076
+ 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(React32.Fragment, { children: [
13646
14077
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
13647
14078
  /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
13648
14079
  ] }, i)) }),
@@ -13657,15 +14088,19 @@ function TripHeader({
13657
14088
  /* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
13658
14089
  nights,
13659
14090
  " ",
13660
- nights === 1 ? "noite" : "noites"
14091
+ nights === 1 ? (_d = labels == null ? void 0 : labels.night) != null ? _d : "night" : (_e = labels == null ? void 0 : labels.nights) != null ? _e : "nights"
13661
14092
  ] }),
13662
14093
  /* @__PURE__ */ jsx("span", { className: "text-white/40", children: "\xB7" }),
13663
14094
  /* @__PURE__ */ jsx(SunIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
13664
14095
  /* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
13665
14096
  duration.days,
13666
14097
  " ",
13667
- duration.days === 1 ? "dia" : "dias"
14098
+ duration.days === 1 ? (_f = labels == null ? void 0 : labels.day) != null ? _f : "day" : (_g = labels == null ? void 0 : labels.days) != null ? _g : "days"
13668
14099
  ] })
14100
+ ] }),
14101
+ groupSize && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-white/85", children: [
14102
+ /* @__PURE__ */ jsx(UsersIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
14103
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-ui font-semibold", children: groupSize })
13669
14104
  ] })
13670
14105
  ] }) : tagline ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm sm:text-base text-white/80 font-ui", children: tagline }) : null,
13671
14106
  chips && chips.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap items-center gap-1.5", children: chips.map((chip, i) => /* @__PURE__ */ jsx(Chip, { href: chip.href, children: chip.label }, i)) }),
@@ -13808,10 +14243,10 @@ function LanguagePicker({
13808
14243
  }) {
13809
14244
  var _a;
13810
14245
  const t = VARIANT2[variant];
13811
- const [open, setOpen] = React31.useState(false);
13812
- const ref = React31.useRef(null);
14246
+ const [open, setOpen] = React32.useState(false);
14247
+ const ref = React32.useRef(null);
13813
14248
  const active = (_a = languages.find((l) => l.code === currentLanguage)) != null ? _a : languages[0];
13814
- React31.useEffect(() => {
14249
+ React32.useEffect(() => {
13815
14250
  if (!open) return;
13816
14251
  const onDocClick = (e) => {
13817
14252
  if (ref.current && !ref.current.contains(e.target)) {
@@ -14012,7 +14447,7 @@ function SiteFooter({
14012
14447
  children: wrapper
14013
14448
  },
14014
14449
  b.alt + i
14015
- ) : /* @__PURE__ */ jsx(React31.Fragment, { children: wrapper }, b.alt + i);
14450
+ ) : /* @__PURE__ */ jsx(React32.Fragment, { children: wrapper }, b.alt + i);
14016
14451
  }) })
14017
14452
  ] }),
14018
14453
  themes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "lg:col-span-3", children: [
@@ -14110,7 +14545,10 @@ function Stars({ count = 5 }) {
14110
14545
  i
14111
14546
  )) });
14112
14547
  }
14113
- function ItineraryTimeline({ steps }) {
14548
+ function ItineraryTimeline({
14549
+ steps,
14550
+ transferLabel
14551
+ }) {
14114
14552
  return /* @__PURE__ */ jsx("ol", { className: "relative flex flex-col gap-0", children: steps.map((step, i) => /* @__PURE__ */ jsxs("li", { className: "relative flex gap-4 pb-8 last:pb-0", children: [
14115
14553
  i < steps.length - 1 && /* @__PURE__ */ jsx("div", { className: "absolute left-3.5 top-7 bottom-0 w-px bg-border" }),
14116
14554
  /* @__PURE__ */ jsx("div", { className: "relative z-10 mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border-2 border-primary bg-background", children: /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold text-primary font-ui", children: i + 1 }) }),
@@ -14121,7 +14559,7 @@ function ItineraryTimeline({ steps }) {
14121
14559
  /* @__PURE__ */ jsx(ClockIcon, { className: "h-3 w-3 mr-1" }),
14122
14560
  step.duration
14123
14561
  ] }),
14124
- step.isTransfer && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs font-ui h-5 px-2", children: "Transfer" })
14562
+ step.isTransfer && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs font-ui h-5 px-2", children: transferLabel != null ? transferLabel : "Transfer" })
14125
14563
  ] }),
14126
14564
  /* @__PURE__ */ jsx("div", { className: "text-base text-muted-foreground leading-relaxed [&_p:not(:last-child)]:mb-2 [&_strong]:text-foreground [&_strong]:font-semibold", children: step.description })
14127
14565
  ] })
@@ -14138,6 +14576,7 @@ function TripPage({
14138
14576
  tagline,
14139
14577
  destination,
14140
14578
  duration,
14579
+ groupSize,
14141
14580
  images,
14142
14581
  videoUrl,
14143
14582
  breadcrumb,
@@ -14161,6 +14600,7 @@ function TripPage({
14161
14600
  whenItOperates,
14162
14601
  food,
14163
14602
  foodGallery,
14603
+ foodGalleryVariant = "gridCompact",
14164
14604
  termsAndConditions,
14165
14605
  meetingPoints,
14166
14606
  meetingPoint,
@@ -14180,17 +14620,23 @@ function TripPage({
14180
14620
  currencyEstimates,
14181
14621
  priceInfo,
14182
14622
  onBook,
14623
+ onBookingSubmit,
14624
+ bookingLoading,
14625
+ bookingDefaults,
14626
+ bookingLabels,
14183
14627
  bookLabel,
14628
+ fromLabel,
14629
+ perPersonLabel,
14184
14630
  siteHeader,
14185
14631
  uiVariant = "v1",
14186
14632
  features,
14187
14633
  className
14188
14634
  }) {
14189
14635
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
14190
- const [activeSection, setActiveSection] = React31.useState("");
14191
- const [accordionValue, setAccordionValue] = React31.useState([]);
14192
- const [faqsExpanded, setFaqsExpanded] = React31.useState(false);
14193
- const accordionSectionIds = React31.useMemo(
14636
+ const [activeSection, setActiveSection] = React32.useState("");
14637
+ const [accordionValue, setAccordionValue] = React32.useState([]);
14638
+ const [faqsExpanded, setFaqsExpanded] = React32.useState(false);
14639
+ const accordionSectionIds = React32.useMemo(
14194
14640
  () => /* @__PURE__ */ new Set([
14195
14641
  "when-it-operates",
14196
14642
  "how-to-get-there",
@@ -14204,18 +14650,18 @@ function TripPage({
14204
14650
  ]),
14205
14651
  []
14206
14652
  );
14207
- const [navFloating, setNavFloating] = React31.useState(false);
14208
- const [navHidden, setNavHidden] = React31.useState(false);
14209
- const [isFloating, setIsFloating] = React31.useState(false);
14210
- const [sidebarPos, setSidebarPos] = React31.useState(null);
14211
- const [pricingBarVisible, setPricingBarVisible] = React31.useState(false);
14212
- const navRef = React31.useRef(null);
14213
- const navSentinelRef = React31.useRef(null);
14214
- const sentinelRef = React31.useRef(null);
14215
- const sidebarPlaceholderRef = React31.useRef(null);
14216
- const pricingBarRef = React31.useRef(null);
14217
- const galleryRef = React31.useRef(null);
14218
- const sections = React31.useMemo(
14653
+ const [navFloating, setNavFloating] = React32.useState(false);
14654
+ const [navHidden, setNavHidden] = React32.useState(false);
14655
+ const [isFloating, setIsFloating] = React32.useState(false);
14656
+ const [sidebarPos, setSidebarPos] = React32.useState(null);
14657
+ const [pricingBarVisible, setPricingBarVisible] = React32.useState(false);
14658
+ const navRef = React32.useRef(null);
14659
+ const navSentinelRef = React32.useRef(null);
14660
+ const sentinelRef = React32.useRef(null);
14661
+ const sidebarPlaceholderRef = React32.useRef(null);
14662
+ const pricingBarRef = React32.useRef(null);
14663
+ const galleryRef = React32.useRef(null);
14664
+ const sections = React32.useMemo(
14219
14665
  () => {
14220
14666
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
14221
14667
  return [
@@ -14237,7 +14683,7 @@ function TripPage({
14237
14683
  // eslint-disable-next-line react-hooks/exhaustive-deps
14238
14684
  []
14239
14685
  );
14240
- React31.useEffect(() => {
14686
+ React32.useEffect(() => {
14241
14687
  const sentinel = navSentinelRef.current;
14242
14688
  if (!sentinel) return;
14243
14689
  const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
@@ -14245,7 +14691,7 @@ function TripPage({
14245
14691
  update();
14246
14692
  return () => document.removeEventListener("scroll", update, { capture: true });
14247
14693
  }, []);
14248
- React31.useEffect(() => {
14694
+ React32.useEffect(() => {
14249
14695
  const sentinel = sentinelRef.current;
14250
14696
  if (!sentinel) return;
14251
14697
  const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
@@ -14253,7 +14699,7 @@ function TripPage({
14253
14699
  update();
14254
14700
  return () => document.removeEventListener("scroll", update, { capture: true });
14255
14701
  }, []);
14256
- React31.useEffect(() => {
14702
+ React32.useEffect(() => {
14257
14703
  const measure = () => {
14258
14704
  if (!sidebarPlaceholderRef.current) return;
14259
14705
  const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
@@ -14263,7 +14709,7 @@ function TripPage({
14263
14709
  window.addEventListener("resize", measure);
14264
14710
  return () => window.removeEventListener("resize", measure);
14265
14711
  }, [isFloating]);
14266
- React31.useEffect(() => {
14712
+ React32.useEffect(() => {
14267
14713
  const check = () => {
14268
14714
  var _a2;
14269
14715
  const target = (_a2 = galleryRef.current) != null ? _a2 : pricingBarRef.current;
@@ -14274,7 +14720,7 @@ function TripPage({
14274
14720
  check();
14275
14721
  return () => document.removeEventListener("scroll", check, { capture: true });
14276
14722
  }, []);
14277
- React31.useEffect(() => {
14723
+ React32.useEffect(() => {
14278
14724
  const check = () => {
14279
14725
  if (!pricingBarRef.current) return;
14280
14726
  setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
@@ -14283,7 +14729,7 @@ function TripPage({
14283
14729
  check();
14284
14730
  return () => document.removeEventListener("scroll", check, { capture: true });
14285
14731
  }, []);
14286
- React31.useEffect(() => {
14732
+ React32.useEffect(() => {
14287
14733
  if (sections.length === 0) return;
14288
14734
  setActiveSection(sections[0].id);
14289
14735
  const update = () => {
@@ -14357,6 +14803,15 @@ function TripPage({
14357
14803
  breadcrumb,
14358
14804
  destination,
14359
14805
  duration,
14806
+ groupSize,
14807
+ labels: {
14808
+ night: labels == null ? void 0 : labels.night,
14809
+ nights: labels == null ? void 0 : labels.nights,
14810
+ day: labels == null ? void 0 : labels.day,
14811
+ days: labels == null ? void 0 : labels.days,
14812
+ previousImage: labels == null ? void 0 : labels.previousImage,
14813
+ nextImage: labels == null ? void 0 : labels.nextImage
14814
+ },
14360
14815
  tagline,
14361
14816
  chips,
14362
14817
  siteHeader,
@@ -14417,7 +14872,7 @@ function TripPage({
14417
14872
  )) })
14418
14873
  ] }) : itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
14419
14874
  /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: (_c = labels == null ? void 0 : labels.itinerary) != null ? _c : "Itinerary" }),
14420
- /* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary })
14875
+ /* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary, transferLabel: labels == null ? void 0 : labels.transfer })
14421
14876
  ] }),
14422
14877
  included && included.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
14423
14878
  /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
@@ -14454,7 +14909,7 @@ function TripPage({
14454
14909
  id: "trip-section-when-it-operates",
14455
14910
  className: "scroll-mt-20 border-b border-border",
14456
14911
  children: [
14457
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14912
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14458
14913
  (sectionIcons == null ? void 0 : sectionIcons.whenItOperates) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.whenItOperates }) : /* @__PURE__ */ jsx(CalendarIcon, { className: "h-5 w-5 text-primary" }),
14459
14914
  (_f = labels == null ? void 0 : labels.whenItOperates) != null ? _f : "When this tour operates"
14460
14915
  ] }) }),
@@ -14469,7 +14924,7 @@ function TripPage({
14469
14924
  id: "trip-section-accommodation",
14470
14925
  className: "scroll-mt-20 border-b border-border",
14471
14926
  children: [
14472
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14927
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14473
14928
  (sectionIcons == null ? void 0 : sectionIcons.accommodation) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.accommodation }) : /* @__PURE__ */ jsx(BedDoubleIcon, { className: "h-5 w-5 text-primary" }),
14474
14929
  (_g = labels == null ? void 0 : labels.accommodation) != null ? _g : "Accommodation"
14475
14930
  ] }) }),
@@ -14478,6 +14933,13 @@ function TripPage({
14478
14933
  accommodationGallery && accommodationGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(accommodation && "mt-6"), children: /* @__PURE__ */ jsx(
14479
14934
  PhotoGallery,
14480
14935
  {
14936
+ labels: {
14937
+ seeMore: labels == null ? void 0 : labels.seeMore,
14938
+ showLess: labels == null ? void 0 : labels.showLess,
14939
+ close: labels == null ? void 0 : labels.galleryClose,
14940
+ previous: labels == null ? void 0 : labels.galleryPrevious,
14941
+ next: labels == null ? void 0 : labels.galleryNext
14942
+ },
14481
14943
  photos: accommodationGallery,
14482
14944
  variant: accommodationGalleryVariant,
14483
14945
  initialVisible: 6
@@ -14494,7 +14956,7 @@ function TripPage({
14494
14956
  id: "trip-section-food",
14495
14957
  className: "scroll-mt-20 border-b border-border",
14496
14958
  children: [
14497
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14959
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14498
14960
  (sectionIcons == null ? void 0 : sectionIcons.food) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.food }) : /* @__PURE__ */ jsx(UtensilsIcon, { className: "h-5 w-5 text-primary" }),
14499
14961
  (_h = labels == null ? void 0 : labels.food) != null ? _h : "Food"
14500
14962
  ] }) }),
@@ -14503,8 +14965,15 @@ function TripPage({
14503
14965
  foodGallery && foodGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(food && "mt-6"), children: /* @__PURE__ */ jsx(
14504
14966
  PhotoGallery,
14505
14967
  {
14968
+ labels: {
14969
+ seeMore: labels == null ? void 0 : labels.seeMore,
14970
+ showLess: labels == null ? void 0 : labels.showLess,
14971
+ close: labels == null ? void 0 : labels.galleryClose,
14972
+ previous: labels == null ? void 0 : labels.galleryPrevious,
14973
+ next: labels == null ? void 0 : labels.galleryNext
14974
+ },
14506
14975
  photos: foodGallery,
14507
- variant: "gridCompact",
14976
+ variant: foodGalleryVariant,
14508
14977
  initialVisible: 6
14509
14978
  }
14510
14979
  ) })
@@ -14519,18 +14988,21 @@ function TripPage({
14519
14988
  id: "trip-section-meeting",
14520
14989
  className: "scroll-mt-20 border-b border-border",
14521
14990
  children: [
14522
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14991
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14523
14992
  (sectionIcons == null ? void 0 : sectionIcons.meetingPoint) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.meetingPoint }) : /* @__PURE__ */ jsx(MapPinIcon, { className: "h-5 w-5 text-primary" }),
14524
14993
  (_i = labels == null ? void 0 : labels.meetingPoint) != null ? _i : "Meeting point"
14525
14994
  ] }) }),
14526
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: meetingPoint ? /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: meetingPoint }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
14527
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(MapPinIcon, { className: "h-4 w-4 text-primary" }) }),
14528
- /* @__PURE__ */ jsxs("div", { children: [
14529
- mp.type && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? "Activity location" : mp.type === "alternative" ? "Alternative meeting point" : "Meeting point" }),
14530
- /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
14531
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
14532
- ] })
14533
- ] }, i)) }) })
14995
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: meetingPoint ? /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: meetingPoint }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => {
14996
+ var _a2, _b2, _c2;
14997
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
14998
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(MapPinIcon, { className: "h-4 w-4 text-primary" }) }),
14999
+ /* @__PURE__ */ jsxs("div", { children: [
15000
+ mp.type && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? (_a2 = labels == null ? void 0 : labels.meetingPointActivity) != null ? _a2 : "Activity location" : mp.type === "alternative" ? (_b2 = labels == null ? void 0 : labels.meetingPointAlternative) != null ? _b2 : "Alternative meeting point" : (_c2 = labels == null ? void 0 : labels.meetingPoint) != null ? _c2 : "Meeting point" }),
15001
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
15002
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
15003
+ ] })
15004
+ ] }, i);
15005
+ }) }) })
14534
15006
  ]
14535
15007
  }
14536
15008
  ),
@@ -14541,7 +15013,7 @@ function TripPage({
14541
15013
  id: "trip-section-how-to-get-there",
14542
15014
  className: "scroll-mt-20 border-b border-border",
14543
15015
  children: [
14544
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
15016
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14545
15017
  (sectionIcons == null ? void 0 : sectionIcons.howToGetThere) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.howToGetThere }) : /* @__PURE__ */ jsx(CompassIcon, { className: "h-5 w-5 text-primary" }),
14546
15018
  (_j = labels == null ? void 0 : labels.howToGetThere) != null ? _j : "How to get there"
14547
15019
  ] }) }),
@@ -14556,7 +15028,7 @@ function TripPage({
14556
15028
  id: "trip-section-weather",
14557
15029
  className: "scroll-mt-20 border-b border-border",
14558
15030
  children: [
14559
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
15031
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14560
15032
  (sectionIcons == null ? void 0 : sectionIcons.weather) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.weather }) : /* @__PURE__ */ jsx(SunIcon, { className: "h-5 w-5 text-primary" }),
14561
15033
  (_k = labels == null ? void 0 : labels.weather) != null ? _k : "Weather"
14562
15034
  ] }) }),
@@ -14571,7 +15043,7 @@ function TripPage({
14571
15043
  id: "trip-section-what-to-bring",
14572
15044
  className: "scroll-mt-20 border-b border-border",
14573
15045
  children: [
14574
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
15046
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14575
15047
  (sectionIcons == null ? void 0 : sectionIcons.whatToBring) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.whatToBring }) : /* @__PURE__ */ jsx(BackpackIcon, { className: "h-5 w-5 text-primary" }),
14576
15048
  (_l = labels == null ? void 0 : labels.whatToBring) != null ? _l : "What to bring"
14577
15049
  ] }) }),
@@ -14586,7 +15058,7 @@ function TripPage({
14586
15058
  id: "trip-section-optional-extras",
14587
15059
  className: "scroll-mt-20 border-b border-border",
14588
15060
  children: [
14589
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
15061
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14590
15062
  (sectionIcons == null ? void 0 : sectionIcons.optionalExtras) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.optionalExtras }) : /* @__PURE__ */ jsx(CherryIcon, { className: "h-5 w-5 text-primary" }),
14591
15063
  (_m = labels == null ? void 0 : labels.optionalExtras) != null ? _m : "Optional extras"
14592
15064
  ] }) }),
@@ -14601,7 +15073,7 @@ function TripPage({
14601
15073
  id: "trip-section-terms",
14602
15074
  className: "scroll-mt-20 border-b border-border",
14603
15075
  children: [
14604
- /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
15076
+ /* @__PURE__ */ jsx(AccordionTrigger, { headingLevel: 2, className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
14605
15077
  (sectionIcons == null ? void 0 : sectionIcons.terms) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.terms }) : /* @__PURE__ */ jsx(ReceiptIcon, { className: "h-5 w-5 text-primary" }),
14606
15078
  (_n = labels == null ? void 0 : labels.terms) != null ? _n : "Terms & conditions"
14607
15079
  ] }) }),
@@ -14613,7 +15085,7 @@ function TripPage({
14613
15085
  }
14614
15086
  ),
14615
15087
  faqs && faqs.length > 0 && (() => {
14616
- var _a2;
15088
+ var _a2, _b2, _c2;
14617
15089
  const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
14618
15090
  const hiddenCount = faqs.length - visibleFaqs.length;
14619
15091
  return /* @__PURE__ */ jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
@@ -14635,10 +15107,11 @@ function TripPage({
14635
15107
  ),
14636
15108
  children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
14637
15109
  /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
14638
- "Show less"
15110
+ (_b2 = labels == null ? void 0 : labels.showLess) != null ? _b2 : "Show less"
14639
15111
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
14640
15112
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
14641
- "See more (",
15113
+ (_c2 = labels == null ? void 0 : labels.seeMore) != null ? _c2 : "See more",
15114
+ " (",
14642
15115
  hiddenCount,
14643
15116
  ")"
14644
15117
  ] })
@@ -14679,6 +15152,8 @@ function TripPage({
14679
15152
  departureTimes,
14680
15153
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
14681
15154
  bookLabel: bookLabel != null ? bookLabel : "Check availability",
15155
+ fromLabel,
15156
+ perPersonLabel,
14682
15157
  variant: "card",
14683
15158
  belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
14684
15159
  benefits,
@@ -14721,6 +15196,8 @@ function TripPage({
14721
15196
  departureTimes,
14722
15197
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
14723
15198
  bookLabel: bookLabel != null ? bookLabel : "Check availability",
15199
+ fromLabel,
15200
+ perPersonLabel,
14724
15201
  variant: "card",
14725
15202
  belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
14726
15203
  benefits,
@@ -14733,12 +15210,27 @@ function TripPage({
14733
15210
  gallery && gallery.length > 0 && /* @__PURE__ */ jsx("section", { ref: galleryRef, id: "trip-section-gallery", className: "scroll-mt-20", children: /* @__PURE__ */ jsx(
14734
15211
  PhotoGallery,
14735
15212
  {
15213
+ labels: {
15214
+ seeMore: labels == null ? void 0 : labels.seeMore,
15215
+ showLess: labels == null ? void 0 : labels.showLess,
15216
+ close: labels == null ? void 0 : labels.galleryClose,
15217
+ previous: labels == null ? void 0 : labels.galleryPrevious,
15218
+ next: labels == null ? void 0 : labels.galleryNext
15219
+ },
14736
15220
  photos: gallery,
14737
15221
  variant: "gridCompact",
14738
15222
  initialVisible: 8
14739
15223
  }
14740
15224
  ) }),
14741
- gallery && gallery.length > 0 && /* @__PURE__ */ jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: /* @__PURE__ */ jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsx(BookingForm, { onSubmit: onBook ? (values) => onBook() : void 0 }) }) }),
15225
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: /* @__PURE__ */ jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsx(
15226
+ BookingForm,
15227
+ {
15228
+ labels: bookingLabels,
15229
+ defaultValues: bookingDefaults,
15230
+ onSubmit: onBookingSubmit,
15231
+ loading: bookingLoading
15232
+ }
15233
+ ) }) }),
14742
15234
  /* @__PURE__ */ jsx("div", { className: "fixed bottom-0 inset-x-0 z-30 lg:hidden border-t border-border bg-background/95 backdrop-blur-sm px-4 py-3", children: /* @__PURE__ */ jsx(
14743
15235
  PricingTrip,
14744
15236
  {
@@ -14746,6 +15238,8 @@ function TripPage({
14746
15238
  currency,
14747
15239
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
14748
15240
  bookLabel: bookLabel != null ? bookLabel : "Book now",
15241
+ fromLabel,
15242
+ perPersonLabel,
14749
15243
  variant: "compact",
14750
15244
  sharp: true,
14751
15245
  priceInfo,
@@ -14758,7 +15252,7 @@ function TripPage({
14758
15252
  }
14759
15253
  );
14760
15254
  }
14761
- function SectionHeading({
15255
+ function SectionHeading2({
14762
15256
  eyebrow,
14763
15257
  title,
14764
15258
  rightSlot
@@ -14779,6 +15273,7 @@ function CategoryPage2({
14779
15273
  trustpilotMini,
14780
15274
  breadcrumb,
14781
15275
  siteHeader,
15276
+ heroRightSlot,
14782
15277
  popularTours,
14783
15278
  popularToursTitle = "More adventures calling your name",
14784
15279
  popularToursEyebrow = "Popular tours",
@@ -14789,6 +15284,7 @@ function CategoryPage2({
14789
15284
  sortOptions,
14790
15285
  defaultSort,
14791
15286
  tripsInitialCount = 15,
15287
+ tripListingSlot,
14792
15288
  trustpilot,
14793
15289
  reviewsTitle = "Don't just take our word for it",
14794
15290
  reviewsSubtitle,
@@ -14805,14 +15301,20 @@ function CategoryPage2({
14805
15301
  faqInitialCount = 5,
14806
15302
  gallery,
14807
15303
  galleryTitle,
15304
+ loadMoreLabel,
15305
+ showLessLabel,
15306
+ seeMoreLabel,
15307
+ viewAllPostsLabel,
15308
+ cardLabels,
15309
+ filterLabels,
14808
15310
  className
14809
15311
  }) {
14810
15312
  var _a;
14811
- const [videoReady, setVideoReady] = React31.useState(false);
14812
- const videoRef = React31.useRef(null);
15313
+ const [videoReady, setVideoReady] = React32.useState(false);
15314
+ const videoRef = React32.useRef(null);
14813
15315
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
14814
15316
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
14815
- React31.useEffect(() => {
15317
+ React32.useEffect(() => {
14816
15318
  if (!videoUrl) return;
14817
15319
  const el = videoRef.current;
14818
15320
  if (!el) return;
@@ -14827,13 +15329,13 @@ function CategoryPage2({
14827
15329
  io.observe(el);
14828
15330
  return () => io.disconnect();
14829
15331
  }, [videoUrl]);
14830
- const [faqsExpanded, setFaqsExpanded] = React31.useState(false);
14831
- const [tripsExpanded, setTripsExpanded] = React31.useState(false);
14832
- const [filterValue, setFilterValue] = React31.useState({});
14833
- const [sort, setSort] = React31.useState(
15332
+ const [faqsExpanded, setFaqsExpanded] = React32.useState(false);
15333
+ const [tripsExpanded, setTripsExpanded] = React32.useState(false);
15334
+ const [filterValue, setFilterValue] = React32.useState({});
15335
+ const [sort, setSort] = React32.useState(
14834
15336
  defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
14835
15337
  );
14836
- const sortedTrips = React31.useMemo(() => {
15338
+ const sortedTrips = React32.useMemo(() => {
14837
15339
  const active = Object.entries(filterValue).filter(
14838
15340
  ([, vals]) => vals && vals.length > 0
14839
15341
  );
@@ -14937,7 +15439,7 @@ function CategoryPage2({
14937
15439
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
14938
15440
  breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => {
14939
15441
  const isLast = i === breadcrumb.length - 1;
14940
- return /* @__PURE__ */ jsxs(React31.Fragment, { children: [
15442
+ return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
14941
15443
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
14942
15444
  crumb.href && !isLast ? /* @__PURE__ */ jsx(
14943
15445
  "a",
@@ -14961,13 +15463,14 @@ function CategoryPage2({
14961
15463
  /* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight max-w-3xl", children: title }),
14962
15464
  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 }),
14963
15465
  trustpilotMini && /* @__PURE__ */ jsx("div", { className: "mt-5 max-w-sm", children: /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) })
14964
- ] })
15466
+ ] }),
15467
+ heroRightSlot && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-5 z-20 sm:bottom-6", children: /* @__PURE__ */ jsx("div", { className: "mx-auto flex max-w-6xl justify-end px-6 sm:px-8", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: heroRightSlot }) }) })
14965
15468
  ]
14966
15469
  }
14967
15470
  ),
14968
15471
  popularTours && popularTours.length > 0 && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
14969
15472
  /* @__PURE__ */ jsx(
14970
- SectionHeading,
15473
+ SectionHeading2,
14971
15474
  {
14972
15475
  eyebrow: popularToursEyebrow,
14973
15476
  title: popularToursTitle
@@ -14979,6 +15482,7 @@ function CategoryPage2({
14979
15482
  return /* @__PURE__ */ jsx(
14980
15483
  TripCard,
14981
15484
  __spreadProps(__spreadValues({}, cardProps), {
15485
+ labels: cardLabels,
14982
15486
  variant: "overlay",
14983
15487
  size: (_b = cardProps.size) != null ? _b : "md"
14984
15488
  }),
@@ -14987,64 +15491,69 @@ function CategoryPage2({
14987
15491
  }) }) })
14988
15492
  ] }),
14989
15493
  /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 pt-6 sm:pt-8 pb-12", children: [
14990
- (tripsTitle || tripsEyebrow) && /* @__PURE__ */ jsx(SectionHeading, { eyebrow: tripsEyebrow, title: tripsTitle != null ? tripsTitle : "" }),
14991
- filterGroups && filterGroups.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
14992
- FilterPanel,
14993
- {
14994
- variant: "horizontal",
14995
- groups: filterGroups,
14996
- value: filterValue,
14997
- onChange: setFilterValue,
14998
- onClearAll: () => setFilterValue({}),
14999
- sortOptions,
15000
- sort,
15001
- onSortChange: setSort
15002
- }
15003
- ) }),
15004
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
15005
- sortedTrips.length,
15006
- " ",
15007
- sortedTrips.length === 1 ? "trip" : "trips",
15008
- " found"
15009
- ] }),
15010
- (() => {
15011
- const visibleTrips = tripsExpanded ? sortedTrips : sortedTrips.slice(0, tripsInitialCount);
15012
- const hiddenCount = sortedTrips.length - visibleTrips.length;
15013
- return /* @__PURE__ */ jsxs(Fragment, { children: [
15014
- /* @__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) => {
15015
- const _a2 = trip, { featured: _featured, filterTags: _filterTags, priceValue: _priceValue } = _a2, cardProps = __objRest(_a2, ["featured", "filterTags", "priceValue"]);
15016
- return /* @__PURE__ */ jsx(
15017
- TripCard,
15018
- __spreadProps(__spreadValues({}, cardProps), {
15019
- className: cn("w-full h-auto", cardProps.className)
15020
- }),
15021
- i
15022
- );
15023
- }) }),
15024
- sortedTrips.length > tripsInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsx(
15025
- "button",
15026
- {
15027
- type: "button",
15028
- onClick: () => setTripsExpanded((v) => !v),
15029
- className: cn(
15030
- "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
15031
- "text-sm font-semibold text-foreground shadow-sm",
15032
- "hover:bg-muted transition-colors duration-150",
15033
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
15034
- ),
15035
- children: tripsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
15036
- /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
15037
- "Show less"
15038
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15039
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
15040
- "Load more (",
15041
- hiddenCount,
15042
- ")"
15043
- ] })
15044
- }
15045
- ) })
15046
- ] });
15047
- })()
15494
+ (tripsTitle || tripsEyebrow) && /* @__PURE__ */ jsx(SectionHeading2, { eyebrow: tripsEyebrow, title: tripsTitle != null ? tripsTitle : "" }),
15495
+ tripListingSlot != null ? tripListingSlot : /* @__PURE__ */ jsxs(Fragment, { children: [
15496
+ filterGroups && filterGroups.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
15497
+ FilterPanel,
15498
+ {
15499
+ variant: "horizontal",
15500
+ labels: filterLabels,
15501
+ groups: filterGroups,
15502
+ value: filterValue,
15503
+ onChange: setFilterValue,
15504
+ onClearAll: () => setFilterValue({}),
15505
+ sortOptions,
15506
+ sort,
15507
+ onSortChange: setSort
15508
+ }
15509
+ ) }),
15510
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
15511
+ sortedTrips.length,
15512
+ " ",
15513
+ sortedTrips.length === 1 ? "trip" : "trips",
15514
+ " found"
15515
+ ] }),
15516
+ (() => {
15517
+ const visibleTrips = tripsExpanded ? sortedTrips : sortedTrips.slice(0, tripsInitialCount);
15518
+ const hiddenCount = sortedTrips.length - visibleTrips.length;
15519
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
15520
+ /* @__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) => {
15521
+ const _a2 = trip, { featured: _featured, filterTags: _filterTags, priceValue: _priceValue } = _a2, cardProps = __objRest(_a2, ["featured", "filterTags", "priceValue"]);
15522
+ return /* @__PURE__ */ jsx(
15523
+ TripCard,
15524
+ __spreadProps(__spreadValues({}, cardProps), {
15525
+ labels: cardLabels,
15526
+ className: cn("w-full h-auto", cardProps.className)
15527
+ }),
15528
+ i
15529
+ );
15530
+ }) }),
15531
+ sortedTrips.length > tripsInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsx(
15532
+ "button",
15533
+ {
15534
+ type: "button",
15535
+ onClick: () => setTripsExpanded((v) => !v),
15536
+ className: cn(
15537
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
15538
+ "text-sm font-semibold text-foreground shadow-sm",
15539
+ "hover:bg-muted transition-colors duration-150",
15540
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
15541
+ ),
15542
+ children: tripsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
15543
+ /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
15544
+ showLessLabel != null ? showLessLabel : "Show less"
15545
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15546
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
15547
+ loadMoreLabel != null ? loadMoreLabel : "Load more",
15548
+ " (",
15549
+ hiddenCount,
15550
+ ")"
15551
+ ] })
15552
+ }
15553
+ ) })
15554
+ ] });
15555
+ })()
15556
+ ] })
15048
15557
  ] }),
15049
15558
  trustpilot && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12 border-t border-border", children: [
15050
15559
  /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-2", children: reviewsTitle }),
@@ -15081,7 +15590,7 @@ function CategoryPage2({
15081
15590
  href: travelGuideHref != null ? travelGuideHref : blogPostsViewAllHref,
15082
15591
  className: "inline-flex items-center gap-1.5 text-sm font-semibold text-primary hover:underline",
15083
15592
  children: [
15084
- travelGuideHref ? travelGuideLabel : "View all posts",
15593
+ travelGuideHref ? travelGuideLabel : viewAllPostsLabel != null ? viewAllPostsLabel : "View all posts",
15085
15594
  /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4" })
15086
15595
  ]
15087
15596
  }
@@ -15110,10 +15619,11 @@ function CategoryPage2({
15110
15619
  ),
15111
15620
  children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
15112
15621
  /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
15113
- "Show less"
15622
+ showLessLabel != null ? showLessLabel : "Show less"
15114
15623
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15115
15624
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
15116
- "See more (",
15625
+ seeMoreLabel != null ? seeMoreLabel : "See more",
15626
+ " (",
15117
15627
  hiddenCount,
15118
15628
  ")"
15119
15629
  ] })
@@ -15181,6 +15691,7 @@ function ActivityCard({
15181
15691
  {
15182
15692
  src: image,
15183
15693
  alt: imageAlt,
15694
+ title: imageAlt || void 0,
15184
15695
  className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
15185
15696
  }
15186
15697
  ),
@@ -15225,12 +15736,12 @@ function Toast({
15225
15736
  duration = 6e3,
15226
15737
  className
15227
15738
  }) {
15228
- const [mounted, setMounted] = React31.useState(false);
15229
- const [visible, setVisible] = React31.useState(true);
15230
- React31.useEffect(() => {
15739
+ const [mounted, setMounted] = React32.useState(false);
15740
+ const [visible, setVisible] = React32.useState(true);
15741
+ React32.useEffect(() => {
15231
15742
  setMounted(true);
15232
15743
  }, []);
15233
- React31.useEffect(() => {
15744
+ React32.useEffect(() => {
15234
15745
  if (duration === 0) return;
15235
15746
  const t = setTimeout(() => {
15236
15747
  setVisible(false);
@@ -16732,8 +17243,8 @@ function ShareWidget({
16732
17243
  title = "Invite friends & lower the price",
16733
17244
  className
16734
17245
  }) {
16735
- const [copied, setCopied] = React31.useState(false);
16736
- const [showToast, setShowToast] = React31.useState(false);
17246
+ const [copied, setCopied] = React32.useState(false);
17247
+ const [showToast, setShowToast] = React32.useState(false);
16737
17248
  const encodedUrl = encodeURIComponent(url);
16738
17249
  const encodedMsg = encodeURIComponent(`${message} ${url}`);
16739
17250
  const channels = [
@@ -16882,7 +17393,1402 @@ function StickyBookingCard({
16882
17393
  }
16883
17394
  );
16884
17395
  }
17396
+ var DEFAULT_TRUSTPILOT = {
17397
+ businessUnitId: "6171e6a56fc555750dd81ae7",
17398
+ templateId: "5419b732fbfb950b10de65e5",
17399
+ locale: "en-US",
17400
+ styleHeight: "24px",
17401
+ styleWidth: "100%",
17402
+ token: "d3580e48-fedc-4b14-b705-172180cf241d",
17403
+ theme: "dark",
17404
+ fallbackHref: "https://www.trustpilot.com/review/planetaexo.com",
17405
+ fallbackLabel: "Excellent"
17406
+ };
17407
+ function RatingStars({ stars = 5 }) {
17408
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", "aria-hidden": true, children: Array.from({ length: 5 }).map((_, i) => {
17409
+ const filled = i + 1 <= Math.round(stars);
17410
+ return /* @__PURE__ */ jsx(
17411
+ "span",
17412
+ {
17413
+ className: cn(
17414
+ "flex h-5 w-5 items-center justify-center rounded-[3px]",
17415
+ filled ? "bg-primary" : "bg-white/30"
17416
+ ),
17417
+ children: /* @__PURE__ */ jsx(StarIcon, { className: "h-3 w-3 fill-white text-white" })
17418
+ },
17419
+ i
17420
+ );
17421
+ }) });
17422
+ }
17423
+ function Rating({ label, stars = 5, provider, href }) {
17424
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
17425
+ label && /* @__PURE__ */ jsx("span", { className: "text-sm font-ui font-bold text-white", children: label }),
17426
+ /* @__PURE__ */ jsx(RatingStars, { stars }),
17427
+ provider && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-sm font-ui font-bold text-white", children: [
17428
+ /* @__PURE__ */ jsx(StarIcon, { className: "h-4 w-4 fill-primary text-primary" }),
17429
+ provider
17430
+ ] })
17431
+ ] });
17432
+ if (href) {
17433
+ return /* @__PURE__ */ jsx(
17434
+ "a",
17435
+ {
17436
+ href,
17437
+ target: "_blank",
17438
+ rel: "noreferrer noopener",
17439
+ "aria-label": `${label != null ? label : ""} ${stars} out of 5 \u2014 ${provider != null ? provider : "reviews"}`.trim(),
17440
+ className: "inline-flex items-center gap-2.5 transition-opacity hover:opacity-90",
17441
+ children: content
17442
+ }
17443
+ );
17444
+ }
17445
+ return /* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-2.5", children: content });
17446
+ }
17447
+ function HomeHeader({
17448
+ images,
17449
+ videoUrl,
17450
+ eyebrow,
17451
+ title,
17452
+ subtitle,
17453
+ cta,
17454
+ trustpilot,
17455
+ rating,
17456
+ pressLogos,
17457
+ pressLabel = "In the press",
17458
+ pressLabelHref,
17459
+ siteHeader,
17460
+ align = "center",
17461
+ className
17462
+ }) {
17463
+ var _a;
17464
+ const [heroIndex, setHeroIndex] = React32.useState(0);
17465
+ const [videoReady, setVideoReady] = React32.useState(false);
17466
+ const videoRef = React32.useRef(null);
17467
+ const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
17468
+ const validImages = React32.useMemo(
17469
+ () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
17470
+ [images]
17471
+ );
17472
+ const hasHeroImage = validImages.length > 0;
17473
+ const heroSrc = (i) => {
17474
+ var _a2;
17475
+ return (_a2 = validImages[i]) != null ? _a2 : "";
17476
+ };
17477
+ const safeIndex = Math.min(heroIndex, Math.max(0, validImages.length - 1));
17478
+ const currentSrc = heroSrc(safeIndex);
17479
+ const showCarousel = !videoUrl && validImages.length > 1;
17480
+ const tpConfig = trustpilot ? typeof trustpilot === "object" ? __spreadValues(__spreadValues({}, DEFAULT_TRUSTPILOT), trustpilot) : DEFAULT_TRUSTPILOT : null;
17481
+ useHlsVideo(videoRef, isHls ? videoUrl : void 0);
17482
+ React32.useEffect(() => {
17483
+ if (!videoUrl) return;
17484
+ const el = videoRef.current;
17485
+ if (!el) return;
17486
+ const observer = new IntersectionObserver(
17487
+ ([entry]) => {
17488
+ if (entry.isIntersecting) {
17489
+ el.play().catch(() => {
17490
+ });
17491
+ } else {
17492
+ el.pause();
17493
+ }
17494
+ },
17495
+ { threshold: 0.1 }
17496
+ );
17497
+ observer.observe(el);
17498
+ return () => observer.disconnect();
17499
+ }, [videoUrl]);
17500
+ const isCenter = align === "center";
17501
+ return /* @__PURE__ */ jsxs(
17502
+ "section",
17503
+ {
17504
+ className: cn(
17505
+ "relative w-full overflow-hidden",
17506
+ "h-screen min-h-[640px]",
17507
+ hasHeroImage ? "bg-muted" : "bg-zinc-900",
17508
+ className
17509
+ ),
17510
+ "data-home-header-align": align,
17511
+ children: [
17512
+ !videoUrl && !hasHeroImage && /* @__PURE__ */ jsx(
17513
+ "div",
17514
+ {
17515
+ className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950",
17516
+ "aria-hidden": true
17517
+ }
17518
+ ),
17519
+ videoUrl ? /* @__PURE__ */ jsxs(Fragment, { children: [
17520
+ hasHeroImage ? /* @__PURE__ */ jsx(
17521
+ Picture,
17522
+ {
17523
+ src: validImages[0],
17524
+ alt: "",
17525
+ "aria-hidden": true,
17526
+ fetchPriority: "high",
17527
+ eager: true,
17528
+ className: cn(
17529
+ "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
17530
+ videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
17531
+ )
17532
+ }
17533
+ ) : /* @__PURE__ */ jsx(
17534
+ "div",
17535
+ {
17536
+ className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950 transition-opacity duration-700",
17537
+ "aria-hidden": true
17538
+ }
17539
+ ),
17540
+ /* @__PURE__ */ jsx(
17541
+ "video",
17542
+ {
17543
+ ref: videoRef,
17544
+ src: isHls ? void 0 : videoUrl,
17545
+ autoPlay: true,
17546
+ muted: true,
17547
+ loop: true,
17548
+ playsInline: true,
17549
+ preload: "auto",
17550
+ poster: hasHeroImage ? validImages[0] : void 0,
17551
+ onCanPlay: () => setVideoReady(true),
17552
+ className: cn(
17553
+ "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
17554
+ videoReady ? "opacity-100" : "opacity-0"
17555
+ )
17556
+ }
17557
+ )
17558
+ ] }) : hasHeroImage ? /* @__PURE__ */ jsx(
17559
+ Picture,
17560
+ {
17561
+ src: currentSrc,
17562
+ alt: title,
17563
+ fetchPriority: safeIndex === 0 ? "high" : "auto",
17564
+ eager: safeIndex === 0,
17565
+ className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
17566
+ }
17567
+ ) : null,
17568
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/30", "aria-hidden": true }),
17569
+ /* @__PURE__ */ jsx(
17570
+ "div",
17571
+ {
17572
+ className: "absolute inset-0 bg-gradient-to-t from-black/70 via-black/10 to-black/30",
17573
+ "aria-hidden": true
17574
+ }
17575
+ ),
17576
+ siteHeader && /* @__PURE__ */ jsx(
17577
+ SiteHeader,
17578
+ __spreadProps(__spreadValues({}, Array.isArray(siteHeader) ? { links: siteHeader } : typeof siteHeader === "object" ? siteHeader : {}), {
17579
+ position: "overlay"
17580
+ })
17581
+ ),
17582
+ showCarousel && /* @__PURE__ */ jsxs(Fragment, { children: [
17583
+ /* @__PURE__ */ jsx(
17584
+ "button",
17585
+ {
17586
+ type: "button",
17587
+ onClick: () => setHeroIndex(
17588
+ (i) => (i - 1 + validImages.length) % validImages.length
17589
+ ),
17590
+ className: "absolute left-4 top-1/2 z-20 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
17591
+ "aria-label": "Previous image",
17592
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
17593
+ }
17594
+ ),
17595
+ /* @__PURE__ */ jsx(
17596
+ "button",
17597
+ {
17598
+ type: "button",
17599
+ onClick: () => setHeroIndex((i) => (i + 1) % validImages.length),
17600
+ className: "absolute right-4 top-1/2 z-20 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
17601
+ "aria-label": "Next image",
17602
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
17603
+ }
17604
+ )
17605
+ ] }),
17606
+ /* @__PURE__ */ jsxs(
17607
+ "div",
17608
+ {
17609
+ className: cn(
17610
+ "absolute inset-0 z-10 flex flex-col justify-center",
17611
+ "mx-auto w-full max-w-6xl px-6 sm:px-8",
17612
+ "pt-[72px]",
17613
+ // clear the overlay header
17614
+ pressLogos && pressLogos.length > 0 ? "pb-28" : "pb-16",
17615
+ isCenter ? "items-center text-center" : "items-start text-left"
17616
+ ),
17617
+ children: [
17618
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "mb-3 text-xs sm:text-sm font-ui font-bold uppercase tracking-[0.2em] text-primary-400", children: eyebrow }),
17619
+ /* @__PURE__ */ jsx(
17620
+ "h1",
17621
+ {
17622
+ className: cn(
17623
+ "font-heading font-black uppercase text-white leading-[0.95]",
17624
+ "text-5xl sm:text-6xl lg:text-7xl",
17625
+ isCenter ? "max-w-4xl" : "max-w-3xl"
17626
+ ),
17627
+ children: title
17628
+ }
17629
+ ),
17630
+ subtitle && /* @__PURE__ */ jsx(
17631
+ "p",
17632
+ {
17633
+ className: cn(
17634
+ "mt-5 text-lg sm:text-xl font-sans text-white/90",
17635
+ isCenter ? "max-w-2xl" : "max-w-xl"
17636
+ ),
17637
+ children: subtitle
17638
+ }
17639
+ ),
17640
+ cta && /* @__PURE__ */ jsx("div", { className: "mt-8", children: cta.href ? /* @__PURE__ */ jsx(
17641
+ "a",
17642
+ {
17643
+ href: cta.href,
17644
+ onClick: cta.onClick,
17645
+ className: buttonVariants({ size: "lg" }),
17646
+ children: cta.label
17647
+ }
17648
+ ) : /* @__PURE__ */ jsx(Button, { size: "lg", onClick: cta.onClick, children: cta.label }) }),
17649
+ tpConfig ? /* @__PURE__ */ jsxs(
17650
+ "div",
17651
+ {
17652
+ className: cn(
17653
+ "home-trustpilot relative mt-8",
17654
+ // Wide enough for the Micro Star to show the full "Excellent
17655
+ // ★★★★★ Trustpilot" lockup — at 260px the Trustpilot wordmark
17656
+ // was clipped.
17657
+ isCenter && "w-full max-w-[340px]"
17658
+ ),
17659
+ children: [
17660
+ /* @__PURE__ */ jsx(TrustpilotEmbed, { config: tpConfig }),
17661
+ /* @__PURE__ */ jsx(
17662
+ "a",
17663
+ {
17664
+ href: (_a = tpConfig.fallbackHref) != null ? _a : "https://www.trustpilot.com/review/planetaexo.com",
17665
+ target: "_blank",
17666
+ rel: "noopener noreferrer",
17667
+ "aria-label": "Read our reviews on Trustpilot",
17668
+ className: "absolute inset-0 z-10"
17669
+ }
17670
+ )
17671
+ ]
17672
+ }
17673
+ ) : rating ? /* @__PURE__ */ jsx("div", { className: "mt-8", children: /* @__PURE__ */ jsx(Rating, __spreadValues({}, rating)) }) : null
17674
+ ]
17675
+ }
17676
+ ),
17677
+ pressLogos && pressLogos.length > 0 && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 bottom-0 z-10 pb-7", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-6xl flex-wrap items-center justify-center gap-x-7 gap-y-3 px-6 sm:px-8", children: [
17678
+ pressLabelHref ? /* @__PURE__ */ jsx(
17679
+ "a",
17680
+ {
17681
+ href: pressLabelHref,
17682
+ target: "_blank",
17683
+ rel: "noopener noreferrer",
17684
+ className: "text-[10px] font-ui font-bold uppercase tracking-[0.25em] leading-tight text-white/70 transition-colors hover:text-white",
17685
+ children: pressLabel
17686
+ }
17687
+ ) : /* @__PURE__ */ jsx("span", { className: "text-[10px] font-ui font-bold uppercase tracking-[0.25em] leading-tight text-white/70", children: pressLabel }),
17688
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-nowrap items-center justify-center gap-x-7", children: [
17689
+ /* @__PURE__ */ jsx("span", { className: "hidden h-5 w-px bg-white/25 sm:block", "aria-hidden": true }),
17690
+ pressLogos.map((logo, i) => {
17691
+ var _a2, _b, _c, _d;
17692
+ const content = logo.src ? (
17693
+ // eslint-disable-next-line @next/next/no-img-element
17694
+ /* @__PURE__ */ jsx(
17695
+ "img",
17696
+ {
17697
+ src: logo.src,
17698
+ alt: (_b = (_a2 = logo.alt) != null ? _a2 : logo.label) != null ? _b : "Press logo",
17699
+ className: "h-12 w-12 shrink-0 select-none object-contain",
17700
+ draggable: false
17701
+ }
17702
+ )
17703
+ ) : /* @__PURE__ */ jsx("span", { className: "font-heading text-base font-bold uppercase tracking-wide", children: logo.label });
17704
+ return logo.href ? /* @__PURE__ */ jsx(
17705
+ "a",
17706
+ {
17707
+ href: logo.href,
17708
+ target: "_blank",
17709
+ rel: "noopener noreferrer",
17710
+ "aria-label": (_d = (_c = logo.alt) != null ? _c : logo.label) != null ? _d : "Press article",
17711
+ className: "shrink-0 text-white/80 opacity-100 transition-opacity hover:opacity-100 hover:text-white focus-visible:opacity-100 [&>img]:opacity-80 [&>img]:hover:opacity-100 [&>img]:transition-opacity",
17712
+ children: content
17713
+ },
17714
+ i
17715
+ ) : /* @__PURE__ */ jsx(
17716
+ "span",
17717
+ {
17718
+ className: "shrink-0 text-white/80 [&>img]:opacity-80",
17719
+ children: content
17720
+ },
17721
+ i
17722
+ );
17723
+ })
17724
+ ] })
17725
+ ] }) })
17726
+ ]
17727
+ }
17728
+ );
17729
+ }
17730
+ var ACCENT_PILL = "bg-primary text-primary-foreground";
17731
+ var ACCENT_BUTTON = "bg-primary text-primary-foreground hover:bg-primary/90";
17732
+ var THEME = {
17733
+ dark: {
17734
+ section: "bg-neutral-950",
17735
+ heading: "text-white",
17736
+ body: "text-white/60",
17737
+ tabTrack: "bg-white/5 border-white/10",
17738
+ tabActive: ACCENT_PILL,
17739
+ tabIdle: "text-white/60 hover:text-white",
17740
+ cardRing: "focus-visible:ring-white/70 focus-visible:ring-offset-neutral-950",
17741
+ divider: "border-white/15"
17742
+ },
17743
+ light: {
17744
+ /* Explicit light colours (not mode-aware tokens) so this variant stays a
17745
+ light surface even when the app is in dark mode. */
17746
+ section: "bg-white",
17747
+ heading: "text-neutral-900",
17748
+ body: "text-neutral-500",
17749
+ tabTrack: "bg-neutral-100 border-black/10",
17750
+ tabActive: ACCENT_PILL,
17751
+ tabIdle: "text-neutral-500 hover:text-neutral-900",
17752
+ cardRing: "focus-visible:ring-neutral-900/40 focus-visible:ring-offset-white",
17753
+ divider: "border-black/10"
17754
+ }
17755
+ };
17756
+ var BENTO_SPAN = {
17757
+ featured: "col-span-2 row-span-2",
17758
+ tall: "col-span-2 sm:col-span-1 row-span-2",
17759
+ wide: "col-span-2",
17760
+ normal: "col-span-2 sm:col-span-1"
17761
+ };
17762
+ function BentoTile({
17763
+ card,
17764
+ ring
17765
+ }) {
17766
+ var _a, _b, _c;
17767
+ const isFeatured = card.size === "featured";
17768
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
17769
+ card.image ? /* @__PURE__ */ jsxs(Fragment, { children: [
17770
+ /* @__PURE__ */ jsx(
17771
+ Picture,
17772
+ {
17773
+ src: card.image,
17774
+ alt: (_a = card.imageAlt) != null ? _a : card.label,
17775
+ loading: "lazy",
17776
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-105"
17777
+ }
17778
+ ),
17779
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/85 via-black/15 to-transparent" })
17780
+ ] }) : /* @__PURE__ */ jsx(
17781
+ "div",
17782
+ {
17783
+ className: cn(
17784
+ "absolute inset-0 bg-gradient-to-br",
17785
+ (_b = card.gradient) != null ? _b : "from-primary-800 to-primary-900"
17786
+ )
17787
+ }
17788
+ ),
17789
+ card.tripCount && /* @__PURE__ */ jsx("span", { className: "absolute right-3 top-3 z-10 rounded-full bg-white/90 px-2.5 py-1 text-[11px] font-ui font-bold uppercase tracking-wide text-neutral-900", children: card.tripCount }),
17790
+ /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-0 bottom-0 z-10 p-5", children: [
17791
+ /* @__PURE__ */ jsx(
17792
+ "h3",
17793
+ {
17794
+ className: cn(
17795
+ "font-heading font-bold uppercase leading-tight tracking-wide text-white",
17796
+ isFeatured ? "text-2xl sm:text-3xl" : "text-lg sm:text-xl"
17797
+ ),
17798
+ children: card.label
17799
+ }
17800
+ ),
17801
+ card.description && /* @__PURE__ */ jsx("p", { className: "mt-1 max-h-0 overflow-hidden text-sm leading-snug text-white/85 opacity-0 transition-all duration-300 group-hover:mt-2 group-hover:max-h-32 group-hover:opacity-100", children: card.description }),
17802
+ card.ctaLabel && /* @__PURE__ */ jsxs("span", { className: "mt-2 inline-flex items-center gap-1 text-sm font-ui font-bold text-primary-400", children: [
17803
+ card.ctaLabel,
17804
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "transition-transform group-hover:translate-x-1", children: "\u2192" })
17805
+ ] })
17806
+ ] })
17807
+ ] });
17808
+ const tileClass = cn(
17809
+ "group relative overflow-hidden rounded-2xl bg-muted shadow-sm",
17810
+ BENTO_SPAN[(_c = card.size) != null ? _c : "normal"]
17811
+ );
17812
+ return card.href ? /* @__PURE__ */ jsx(
17813
+ "a",
17814
+ {
17815
+ href: card.href,
17816
+ className: cn(
17817
+ tileClass,
17818
+ "block focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
17819
+ ring
17820
+ ),
17821
+ children: inner
17822
+ }
17823
+ ) : /* @__PURE__ */ jsx("div", { className: tileClass, children: inner });
17824
+ }
17825
+ function AdventureExplorer({
17826
+ tabs,
17827
+ eyebrow,
17828
+ heading,
17829
+ subheading,
17830
+ defaultTabId,
17831
+ viewAllLabel = "View All Adventures",
17832
+ viewAllHref,
17833
+ theme = "dark",
17834
+ layout = "carousel",
17835
+ bentoLimit,
17836
+ moreLabel = "More wild places",
17837
+ className
17838
+ }) {
17839
+ var _a, _b, _c, _d, _e;
17840
+ const [activeId, setActiveId] = React32.useState(
17841
+ defaultTabId != null ? defaultTabId : (_a = tabs[0]) == null ? void 0 : _a.id
17842
+ );
17843
+ const active = (_b = tabs.find((t2) => t2.id === activeId)) != null ? _b : tabs[0];
17844
+ const t = THEME[theme];
17845
+ const ctaHref = (_d = (_c = active == null ? void 0 : active.viewAllHref) != null ? _c : viewAllHref) != null ? _d : "#";
17846
+ const showCta = viewAllLabel.length > 0;
17847
+ const hasHeading = !!(eyebrow || heading || subheading);
17848
+ const cards = (_e = active == null ? void 0 : active.cards) != null ? _e : [];
17849
+ const limited = layout === "bento" && bentoLimit != null && cards.length > bentoLimit;
17850
+ const gridCards = limited ? cards.slice(0, bentoLimit) : cards;
17851
+ const moreCards = limited ? cards.slice(bentoLimit) : [];
17852
+ const showHeadCta = showCta && !limited;
17853
+ return /* @__PURE__ */ jsx("section", { className: cn("w-full py-10 sm:py-16", t.section, className), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
17854
+ hasHeading && /* @__PURE__ */ jsxs("div", { className: "mb-8 flex flex-wrap items-end justify-between gap-6", children: [
17855
+ /* @__PURE__ */ jsxs("div", { className: "max-w-2xl", children: [
17856
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "mb-3 text-xs font-ui font-bold uppercase tracking-[0.22em] text-primary", children: eyebrow }),
17857
+ heading && /* @__PURE__ */ jsx(
17858
+ "h2",
17859
+ {
17860
+ className: cn(
17861
+ "font-heading text-3xl font-black uppercase leading-[1.05] sm:text-4xl lg:text-5xl",
17862
+ t.heading
17863
+ ),
17864
+ children: heading
17865
+ }
17866
+ ),
17867
+ subheading && /* @__PURE__ */ jsx("p", { className: cn("mt-3 text-base", t.body), children: subheading })
17868
+ ] }),
17869
+ showHeadCta && /* @__PURE__ */ jsxs(
17870
+ "a",
17871
+ {
17872
+ href: ctaHref,
17873
+ className: "group inline-flex shrink-0 items-center gap-1.5 font-ui text-sm font-bold text-primary transition-colors hover:text-primary-800",
17874
+ children: [
17875
+ viewAllLabel,
17876
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "transition-transform group-hover:translate-x-1", children: "\u2192" })
17877
+ ]
17878
+ }
17879
+ )
17880
+ ] }),
17881
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
17882
+ /* @__PURE__ */ jsx(
17883
+ "div",
17884
+ {
17885
+ role: "tablist",
17886
+ "aria-label": "Explore categories",
17887
+ className: cn(
17888
+ "inline-flex max-w-full items-center gap-1 overflow-x-auto rounded-full border p-1.5 scrollbar-none",
17889
+ t.tabTrack
17890
+ ),
17891
+ children: tabs.map((tab) => {
17892
+ const isActive = tab.id === (active == null ? void 0 : active.id);
17893
+ return /* @__PURE__ */ jsx(
17894
+ "button",
17895
+ {
17896
+ type: "button",
17897
+ role: "tab",
17898
+ "aria-selected": isActive,
17899
+ onClick: () => setActiveId(tab.id),
17900
+ className: cn(
17901
+ "shrink-0 rounded-full px-5 py-2 text-sm font-ui font-bold transition-colors",
17902
+ isActive ? t.tabActive : t.tabIdle
17903
+ ),
17904
+ children: tab.label
17905
+ },
17906
+ tab.id
17907
+ );
17908
+ })
17909
+ }
17910
+ ),
17911
+ showCta && !hasHeading && /* @__PURE__ */ jsx(
17912
+ "a",
17913
+ {
17914
+ href: ctaHref,
17915
+ className: cn(
17916
+ "hidden shrink-0 items-center rounded-full px-6 py-2.5 text-sm font-heading font-bold transition-colors sm:inline-flex",
17917
+ ACCENT_BUTTON
17918
+ ),
17919
+ children: viewAllLabel
17920
+ }
17921
+ )
17922
+ ] }),
17923
+ layout === "bento" && /* @__PURE__ */ jsx("div", { className: "mt-6 grid auto-rows-[170px] grid-cols-2 gap-4 sm:mt-8 sm:auto-rows-[200px] lg:grid-cols-4", children: gridCards.map((card, i) => /* @__PURE__ */ jsx(BentoTile, { card, ring: t.cardRing }, i)) }),
17924
+ limited && /* @__PURE__ */ jsxs(
17925
+ "div",
17926
+ {
17927
+ className: cn(
17928
+ "mt-7 flex flex-wrap items-center justify-between gap-x-8 gap-y-3 border-t pt-6",
17929
+ t.divider
17930
+ ),
17931
+ children: [
17932
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-2", children: [
17933
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-ui font-bold uppercase tracking-[0.18em] text-primary", children: moreLabel }),
17934
+ moreCards.map((card, i) => {
17935
+ var _a2;
17936
+ return /* @__PURE__ */ jsxs(
17937
+ "a",
17938
+ {
17939
+ href: (_a2 = card.href) != null ? _a2 : "#",
17940
+ className: "group inline-flex items-baseline gap-2",
17941
+ children: [
17942
+ /* @__PURE__ */ jsx(
17943
+ "span",
17944
+ {
17945
+ className: cn(
17946
+ "font-heading text-base font-bold transition-colors group-hover:text-primary",
17947
+ t.heading
17948
+ ),
17949
+ children: card.label
17950
+ }
17951
+ ),
17952
+ card.tripCount && /* @__PURE__ */ jsx("span", { className: cn("text-sm", t.body), children: card.tripCount })
17953
+ ]
17954
+ },
17955
+ i
17956
+ );
17957
+ })
17958
+ ] }),
17959
+ showCta && /* @__PURE__ */ jsxs(
17960
+ "a",
17961
+ {
17962
+ href: ctaHref,
17963
+ className: "group inline-flex shrink-0 items-center gap-1.5 font-ui text-sm font-bold text-primary transition-colors hover:text-primary-800",
17964
+ children: [
17965
+ viewAllLabel,
17966
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "transition-transform group-hover:translate-x-1", children: "\u2192" })
17967
+ ]
17968
+ }
17969
+ )
17970
+ ]
17971
+ }
17972
+ ),
17973
+ layout !== "bento" && /* @__PURE__ */ jsx("div", { className: "-mx-6 mt-6 flex gap-3 overflow-x-auto px-6 pb-2 snap-x snap-mandatory scroll-px-6 scroll-smooth scrollbar-none sm:mx-0 sm:mt-8 sm:gap-4 sm:px-0 sm:scroll-px-0", children: active == null ? void 0 : active.cards.map((card, i) => {
17974
+ var _a2, _b2;
17975
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
17976
+ /* @__PURE__ */ jsx(
17977
+ Picture,
17978
+ {
17979
+ src: (_a2 = card.image) != null ? _a2 : "",
17980
+ alt: (_b2 = card.imageAlt) != null ? _b2 : card.label,
17981
+ loading: "lazy",
17982
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
17983
+ }
17984
+ ),
17985
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/15 to-transparent" }),
17986
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 bottom-0 p-4 font-heading text-sm font-bold uppercase leading-tight tracking-wide text-white", children: card.label })
17987
+ ] });
17988
+ const cardClass = "group relative aspect-[9/16] w-40 shrink-0 snap-start overflow-hidden rounded-2xl bg-muted sm:w-44 lg:w-48";
17989
+ return card.href ? /* @__PURE__ */ jsx(
17990
+ "a",
17991
+ {
17992
+ href: card.href,
17993
+ className: cn(
17994
+ cardClass,
17995
+ "block focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
17996
+ t.cardRing
17997
+ ),
17998
+ children: inner
17999
+ },
18000
+ i
18001
+ ) : /* @__PURE__ */ jsx("div", { className: cardClass, children: inner }, i);
18002
+ }) }),
18003
+ showCta && /* @__PURE__ */ jsx("div", { className: "mt-6 sm:hidden", children: /* @__PURE__ */ jsx(
18004
+ "a",
18005
+ {
18006
+ href: ctaHref,
18007
+ className: cn(
18008
+ "inline-flex w-full items-center justify-center rounded-full px-6 py-3 text-sm font-heading font-bold transition-colors",
18009
+ ACCENT_BUTTON
18010
+ ),
18011
+ children: viewAllLabel
18012
+ }
18013
+ ) })
18014
+ ] }) });
18015
+ }
18016
+ var THEME2 = {
18017
+ light: {
18018
+ section: "bg-neutral-100",
18019
+ heading: "text-neutral-900",
18020
+ title: "text-neutral-800",
18021
+ body: "text-neutral-500",
18022
+ icon: "text-primary",
18023
+ card: "bg-white border-black/10 shadow-sm",
18024
+ chip: "bg-primary/10 text-primary",
18025
+ number: "text-primary"
18026
+ },
18027
+ dark: {
18028
+ section: "bg-neutral-950",
18029
+ heading: "text-white",
18030
+ title: "text-white",
18031
+ body: "text-white/60",
18032
+ icon: "text-primary-400",
18033
+ card: "bg-white/5 border-white/10",
18034
+ chip: "bg-primary-400/15 text-primary-400",
18035
+ number: "text-primary-400"
18036
+ }
18037
+ };
18038
+ var COLS = {
18039
+ 2: "sm:grid-cols-2",
18040
+ 3: "sm:grid-cols-2 lg:grid-cols-3",
18041
+ 4: "sm:grid-cols-2 lg:grid-cols-4"
18042
+ };
18043
+ function USP({
18044
+ items,
18045
+ heading,
18046
+ subheading,
18047
+ columns,
18048
+ variant = "minimal",
18049
+ theme = "light",
18050
+ className
18051
+ }) {
18052
+ const t = THEME2[theme];
18053
+ const cols = columns != null ? columns : Math.min(Math.max(items.length, 2), 4);
18054
+ const isInline = variant === "inline";
18055
+ const isCard = variant === "card";
18056
+ const isNumbered = variant === "numbered";
18057
+ const stacked = !isInline;
18058
+ return /* @__PURE__ */ jsx("section", { className: cn("w-full py-14 sm:py-20", t.section, className), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
18059
+ (heading || subheading) && /* @__PURE__ */ jsxs(
18060
+ "div",
18061
+ {
18062
+ className: cn(
18063
+ "mb-12 max-w-2xl",
18064
+ isNumbered ? "text-left" : "mx-auto text-center"
18065
+ ),
18066
+ children: [
18067
+ heading && /* @__PURE__ */ jsx(
18068
+ "h2",
18069
+ {
18070
+ className: cn(
18071
+ "font-heading font-bold uppercase tracking-wide",
18072
+ isNumbered ? "text-3xl sm:text-4xl lg:text-5xl" : "text-2xl sm:text-3xl",
18073
+ t.heading
18074
+ ),
18075
+ children: heading
18076
+ }
18077
+ ),
18078
+ subheading && /* @__PURE__ */ jsx("p", { className: cn("mt-3 font-sans text-base", t.body), children: subheading })
18079
+ ]
18080
+ }
18081
+ ),
18082
+ /* @__PURE__ */ jsxs(
18083
+ "div",
18084
+ {
18085
+ className: cn(
18086
+ "grid grid-cols-1 gap-x-8 gap-y-10",
18087
+ COLS[cols]
18088
+ ),
18089
+ children: [
18090
+ isNumbered && items.map((item, i) => /* @__PURE__ */ jsxs(
18091
+ "div",
18092
+ {
18093
+ className: cn(
18094
+ "flex flex-col rounded-2xl border p-6 text-left sm:p-7",
18095
+ t.card
18096
+ ),
18097
+ children: [
18098
+ /* @__PURE__ */ jsx(
18099
+ "span",
18100
+ {
18101
+ className: cn(
18102
+ "mb-4 font-sans text-xl font-semibold italic",
18103
+ t.number
18104
+ ),
18105
+ children: String(i + 1).padStart(2, "0")
18106
+ }
18107
+ ),
18108
+ /* @__PURE__ */ jsx(
18109
+ "h3",
18110
+ {
18111
+ className: cn(
18112
+ "font-heading text-lg font-bold leading-snug",
18113
+ t.heading
18114
+ ),
18115
+ children: item.title
18116
+ }
18117
+ ),
18118
+ /* @__PURE__ */ jsx("p", { className: cn("mt-2 font-sans text-base leading-relaxed", t.body), children: item.description })
18119
+ ]
18120
+ },
18121
+ i
18122
+ )),
18123
+ !isNumbered && items.map((item, i) => /* @__PURE__ */ jsxs(
18124
+ "div",
18125
+ {
18126
+ className: cn(
18127
+ isCard && cn("rounded-2xl border p-6 sm:p-7", t.card),
18128
+ stacked ? "flex flex-col items-center text-center" : "flex items-start gap-4 text-left"
18129
+ ),
18130
+ children: [
18131
+ /* @__PURE__ */ jsx(
18132
+ "span",
18133
+ {
18134
+ className: cn(
18135
+ "flex shrink-0 items-center justify-center",
18136
+ isCard ? cn("h-14 w-14 rounded-full [&>svg]:size-7", t.chip) : cn("[&>svg]:size-8", t.icon),
18137
+ stacked && "mb-4"
18138
+ ),
18139
+ children: item.icon
18140
+ }
18141
+ ),
18142
+ /* @__PURE__ */ jsxs("div", { className: isInline ? "flex-1" : "contents", children: [
18143
+ /* @__PURE__ */ jsx(
18144
+ "h3",
18145
+ {
18146
+ className: cn(
18147
+ "font-heading text-sm font-bold uppercase leading-snug tracking-wide",
18148
+ t.title,
18149
+ stacked && "mb-3"
18150
+ ),
18151
+ children: item.title
18152
+ }
18153
+ ),
18154
+ /* @__PURE__ */ jsx(
18155
+ "p",
18156
+ {
18157
+ className: cn(
18158
+ "font-sans text-base leading-relaxed",
18159
+ t.body,
18160
+ isInline && "mt-1.5"
18161
+ ),
18162
+ children: item.description
18163
+ }
18164
+ )
18165
+ ] })
18166
+ ]
18167
+ },
18168
+ i
18169
+ ))
18170
+ ]
18171
+ }
18172
+ )
18173
+ ] }) });
18174
+ }
18175
+ function RotatingSubtitle({
18176
+ phrases,
18177
+ interval,
18178
+ className
18179
+ }) {
18180
+ const [index, setIndex] = React32.useState(0);
18181
+ React32.useEffect(() => {
18182
+ var _a;
18183
+ if (phrases.length < 2) return;
18184
+ const reduce = typeof window !== "undefined" && ((_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)").matches);
18185
+ if (reduce) return;
18186
+ const id = setInterval(
18187
+ () => setIndex((i) => (i + 1) % phrases.length),
18188
+ interval
18189
+ );
18190
+ return () => clearInterval(id);
18191
+ }, [phrases.length, interval]);
18192
+ return (
18193
+ /* Grid-stacks all phrases so the box keeps the height of the tallest line
18194
+ and the crossfade has no layout shift. */
18195
+ /* @__PURE__ */ jsx("span", { className: cn("grid", className), children: phrases.map((phrase, i) => /* @__PURE__ */ jsx(
18196
+ "span",
18197
+ {
18198
+ "aria-hidden": i !== index,
18199
+ className: cn(
18200
+ "col-start-1 row-start-1 transition-opacity duration-700",
18201
+ i === index ? "opacity-100" : "opacity-0"
18202
+ ),
18203
+ children: phrase
18204
+ },
18205
+ phrase + i
18206
+ )) })
18207
+ );
18208
+ }
18209
+ function CtaBanner({
18210
+ image,
18211
+ imageAlt = "",
18212
+ title,
18213
+ subtitle,
18214
+ cta,
18215
+ rotateInterval = 3e3,
18216
+ parallax = true,
18217
+ overlayOpacity = 35,
18218
+ className
18219
+ }) {
18220
+ const phrases = React32.useMemo(
18221
+ () => (Array.isArray(subtitle) ? subtitle : subtitle ? [subtitle] : []).map((s) => s.trim()).filter(Boolean),
18222
+ [subtitle]
18223
+ );
18224
+ return /* @__PURE__ */ jsxs(
18225
+ "section",
18226
+ {
18227
+ className: cn(
18228
+ "relative w-full overflow-hidden",
18229
+ "flex items-center justify-center",
18230
+ "min-h-[360px] py-24 sm:py-28 lg:py-32",
18231
+ "bg-muted",
18232
+ className
18233
+ ),
18234
+ children: [
18235
+ parallax ? (
18236
+ /* Parallax: fixed-attachment CSS background (sm+). Uses a plain div so
18237
+ `bg-fixed` works; on mobile it falls back to a normal cover image. */
18238
+ /* @__PURE__ */ jsx(
18239
+ "div",
18240
+ {
18241
+ "aria-hidden": true,
18242
+ role: imageAlt ? "img" : void 0,
18243
+ "aria-label": imageAlt || void 0,
18244
+ className: "absolute inset-0 bg-cover bg-center sm:bg-fixed",
18245
+ style: { backgroundImage: `url("${image}")` }
18246
+ }
18247
+ )
18248
+ ) : /* @__PURE__ */ jsx(
18249
+ Picture,
18250
+ {
18251
+ src: image,
18252
+ alt: imageAlt,
18253
+ eager: true,
18254
+ className: "absolute inset-0 h-full w-full object-cover"
18255
+ }
18256
+ ),
18257
+ /* @__PURE__ */ jsx(
18258
+ "div",
18259
+ {
18260
+ className: "absolute inset-0 bg-black",
18261
+ style: { opacity: overlayOpacity / 100 },
18262
+ "aria-hidden": true
18263
+ }
18264
+ ),
18265
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10 mx-auto flex w-full max-w-4xl flex-col items-center px-6 text-center", children: [
18266
+ /* @__PURE__ */ jsx("h2", { className: "font-heading text-4xl font-black uppercase leading-none tracking-tight text-white sm:text-5xl lg:text-[3.25rem]", children: title }),
18267
+ phrases.length > 0 && /* @__PURE__ */ jsx("p", { className: "mt-4 font-sans text-xl font-semibold text-white sm:text-2xl lg:text-[1.7rem]", children: phrases.length > 1 ? /* @__PURE__ */ jsx(RotatingSubtitle, { phrases, interval: rotateInterval }) : phrases[0] }),
18268
+ cta && (cta.href ? /* @__PURE__ */ jsx(
18269
+ "a",
18270
+ {
18271
+ href: cta.href,
18272
+ onClick: cta.onClick,
18273
+ className: "mt-8 inline-block border-b border-white/70 pb-1.5 font-ui text-xs font-light uppercase tracking-[0.2em] text-white transition-colors hover:border-white hover:text-white/80",
18274
+ children: cta.label
18275
+ }
18276
+ ) : /* @__PURE__ */ jsx(
18277
+ "button",
18278
+ {
18279
+ type: "button",
18280
+ onClick: cta.onClick,
18281
+ className: "mt-8 inline-block border-b border-white/70 pb-1.5 font-ui text-xs font-light uppercase tracking-[0.2em] text-white transition-colors hover:border-white hover:text-white/80",
18282
+ children: cta.label
18283
+ }
18284
+ ))
18285
+ ] })
18286
+ ]
18287
+ }
18288
+ );
18289
+ }
18290
+ var THEME3 = {
18291
+ light: {
18292
+ section: "bg-background",
18293
+ heading: "text-foreground",
18294
+ sub: "text-muted-foreground",
18295
+ rowTitle: "text-foreground",
18296
+ rowBorder: "border-border",
18297
+ rowArrow: "text-primary"
18298
+ },
18299
+ dark: {
18300
+ section: "bg-neutral-950",
18301
+ heading: "text-white",
18302
+ sub: "text-white/60",
18303
+ rowTitle: "text-white",
18304
+ rowBorder: "border-white/10",
18305
+ rowArrow: "text-primary-400"
18306
+ }
18307
+ };
18308
+ function BlogJournal({
18309
+ eyebrow,
18310
+ title,
18311
+ subtitle,
18312
+ link,
18313
+ feature,
18314
+ posts,
18315
+ theme = "light",
18316
+ className
18317
+ }) {
18318
+ var _a, _b, _c, _d;
18319
+ const t = THEME3[theme];
18320
+ const featRel = feature.external ? "noopener noreferrer" : void 0;
18321
+ const featTarget = feature.external ? "_blank" : void 0;
18322
+ return /* @__PURE__ */ jsx("section", { className: cn("w-full py-20 sm:py-28", t.section, className), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
18323
+ (title || eyebrow || link) && /* @__PURE__ */ jsxs("div", { className: "mb-10 flex flex-wrap items-end justify-between gap-6", children: [
18324
+ /* @__PURE__ */ jsxs("div", { className: "max-w-2xl", children: [
18325
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "mb-3 text-xs font-ui font-bold uppercase tracking-[0.22em] text-primary", children: eyebrow }),
18326
+ title && /* @__PURE__ */ jsx(
18327
+ "h2",
18328
+ {
18329
+ className: cn(
18330
+ "font-heading text-3xl font-black uppercase leading-[1.05] sm:text-4xl lg:text-5xl",
18331
+ t.heading
18332
+ ),
18333
+ children: title
18334
+ }
18335
+ ),
18336
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn("mt-3 text-base", t.sub), children: subtitle })
18337
+ ] }),
18338
+ link && /* @__PURE__ */ jsxs(
18339
+ "a",
18340
+ {
18341
+ href: (_a = link.href) != null ? _a : "#",
18342
+ className: "group inline-flex shrink-0 items-center gap-1.5 font-ui text-sm font-bold text-primary transition-colors hover:text-primary-800",
18343
+ children: [
18344
+ link.label,
18345
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4 transition-transform group-hover:translate-x-1" })
18346
+ ]
18347
+ }
18348
+ )
18349
+ ] }),
18350
+ /* @__PURE__ */ jsxs("div", { className: "grid items-stretch gap-7 lg:grid-cols-[1.12fr_0.88fr]", children: [
18351
+ /* @__PURE__ */ jsxs(
18352
+ "a",
18353
+ {
18354
+ href: (_b = feature.href) != null ? _b : "#",
18355
+ target: featTarget,
18356
+ rel: featRel,
18357
+ className: "group relative flex min-h-[420px] items-end overflow-hidden rounded-2xl text-white shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 lg:min-h-[480px]",
18358
+ children: [
18359
+ /* @__PURE__ */ jsx(
18360
+ Picture,
18361
+ {
18362
+ src: feature.image,
18363
+ alt: (_c = feature.imageAlt) != null ? _c : feature.title,
18364
+ loading: "lazy",
18365
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-105"
18366
+ }
18367
+ ),
18368
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/90 via-black/25 to-transparent" }),
18369
+ /* @__PURE__ */ jsxs("div", { className: "relative p-8 sm:p-9", children: [
18370
+ feature.tag && /* @__PURE__ */ jsx("span", { className: "mb-3.5 inline-block rounded-full bg-primary px-3 py-1 text-[11px] font-ui font-bold uppercase tracking-[0.12em] text-primary-foreground", children: feature.tag }),
18371
+ feature.date && /* @__PURE__ */ jsx("span", { className: "block text-xs font-ui font-bold uppercase tracking-[0.1em] text-primary-400", children: feature.date }),
18372
+ /* @__PURE__ */ jsx("h3", { className: "mt-2.5 max-w-[20ch] font-heading text-2xl font-bold leading-[1.08] sm:text-3xl lg:text-4xl", children: feature.title }),
18373
+ feature.excerpt && /* @__PURE__ */ jsx("p", { className: "mt-3 max-w-[46ch] text-sm leading-relaxed text-white/85", children: feature.excerpt }),
18374
+ /* @__PURE__ */ jsxs("span", { className: "mt-5 inline-flex items-center gap-1.5 font-ui text-sm font-bold", children: [
18375
+ (_d = feature.ctaLabel) != null ? _d : "Read the guide",
18376
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4 transition-transform group-hover:translate-x-1" })
18377
+ ] })
18378
+ ] })
18379
+ ]
18380
+ }
18381
+ ),
18382
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-col justify-center", children: posts.map((post, i) => {
18383
+ var _a2, _b2;
18384
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
18385
+ "a",
18386
+ {
18387
+ href: (_a2 = post.href) != null ? _a2 : "#",
18388
+ target: post.external ? "_blank" : void 0,
18389
+ rel: post.external ? "noopener noreferrer" : void 0,
18390
+ className: cn(
18391
+ "group grid grid-cols-[64px_1fr_auto] items-center gap-4 border-t py-5 transition-[padding] duration-300 hover:pl-3 sm:grid-cols-[78px_1fr_auto]",
18392
+ t.rowBorder,
18393
+ i === 0 && "border-t-0 pt-0"
18394
+ ),
18395
+ children: [
18396
+ /* @__PURE__ */ jsx(
18397
+ Picture,
18398
+ {
18399
+ src: post.image,
18400
+ alt: (_b2 = post.imageAlt) != null ? _b2 : post.title,
18401
+ loading: "lazy",
18402
+ className: "h-16 w-16 rounded-xl object-cover sm:h-[78px] sm:w-[78px]"
18403
+ }
18404
+ ),
18405
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
18406
+ /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-ui font-bold uppercase tracking-[0.1em] text-primary", children: [
18407
+ post.category,
18408
+ post.category && post.date && /* @__PURE__ */ jsx("span", { className: cn("ml-2 font-semibold", t.sub), children: post.date }),
18409
+ !post.category && post.date && /* @__PURE__ */ jsx("span", { className: cn("font-semibold", t.sub), children: post.date })
18410
+ ] }),
18411
+ /* @__PURE__ */ jsx(
18412
+ "h4",
18413
+ {
18414
+ className: cn(
18415
+ "mt-1.5 font-heading text-base font-bold leading-snug sm:text-lg",
18416
+ t.rowTitle
18417
+ ),
18418
+ children: post.title
18419
+ }
18420
+ )
18421
+ ] }),
18422
+ /* @__PURE__ */ jsx(
18423
+ ArrowRightIcon,
18424
+ {
18425
+ className: cn(
18426
+ "h-5 w-5 shrink-0 transition-transform group-hover:translate-x-1",
18427
+ t.rowArrow
18428
+ )
18429
+ }
18430
+ )
18431
+ ]
18432
+ }
18433
+ ) }, i);
18434
+ }) })
18435
+ ] })
18436
+ ] }) });
18437
+ }
18438
+ var SURFACE_WHITE = "bg-white";
18439
+ var SURFACE_SAND = "bg-[oklch(0.94_0.016_86)]";
18440
+ var SURFACE_PRIMARY_700 = "bg-[oklch(0.52_0.082_179)]";
18441
+ var SURFACE_PRIMARY_800 = "bg-[oklch(0.39_0.062_179)]";
18442
+ var SURFACE_PRIMARY_900 = "bg-[oklch(0.27_0.040_179)]";
18443
+ function SectionHead({
18444
+ eyebrow,
18445
+ title,
18446
+ subtitle,
18447
+ link,
18448
+ align = "between",
18449
+ theme = "light"
18450
+ }) {
18451
+ var _a;
18452
+ const isCenter = align === "center";
18453
+ return /* @__PURE__ */ jsxs(
18454
+ "div",
18455
+ {
18456
+ className: cn(
18457
+ "mb-10 flex flex-wrap items-end gap-6",
18458
+ isCenter ? "flex-col items-center text-center" : "justify-between"
18459
+ ),
18460
+ children: [
18461
+ /* @__PURE__ */ jsxs("div", { className: cn("max-w-2xl", isCenter && "mx-auto"), children: [
18462
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "mb-3 text-xs font-ui font-bold uppercase tracking-[0.22em] text-primary", children: eyebrow }),
18463
+ /* @__PURE__ */ jsx(
18464
+ "h2",
18465
+ {
18466
+ className: cn(
18467
+ "font-heading text-3xl font-black uppercase leading-[1.05] sm:text-4xl lg:text-5xl",
18468
+ theme === "dark" ? "text-white" : "text-foreground"
18469
+ ),
18470
+ children: title
18471
+ }
18472
+ ),
18473
+ subtitle && /* @__PURE__ */ jsx(
18474
+ "p",
18475
+ {
18476
+ className: cn(
18477
+ "mt-3 text-base",
18478
+ theme === "dark" ? "text-white/70" : "text-muted-foreground"
18479
+ ),
18480
+ children: subtitle
18481
+ }
18482
+ )
18483
+ ] }),
18484
+ link && !isCenter && /* @__PURE__ */ jsxs(
18485
+ "a",
18486
+ {
18487
+ href: (_a = link.href) != null ? _a : "#",
18488
+ className: "group inline-flex shrink-0 items-center gap-1.5 font-ui text-sm font-bold text-primary transition-colors hover:text-primary-800",
18489
+ children: [
18490
+ link.label,
18491
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4 transition-transform group-hover:translate-x-1" })
18492
+ ]
18493
+ }
18494
+ )
18495
+ ]
18496
+ }
18497
+ );
18498
+ }
18499
+ function ExpeditionsRail({ eyebrow, title, subtitle, link, trips }) {
18500
+ var _a;
18501
+ const railRef = React32.useRef(null);
18502
+ const scrollByCard = (dir) => {
18503
+ const rail = railRef.current;
18504
+ if (!rail) return;
18505
+ const card = rail.querySelector("[data-rail-card]");
18506
+ const amount = card ? card.offsetWidth + 22 : rail.clientWidth * 0.8;
18507
+ rail.scrollBy({ left: dir * amount, behavior: "smooth" });
18508
+ };
18509
+ return /* @__PURE__ */ jsxs("section", { className: cn(SURFACE_SAND, "py-20 sm:py-28"), children: [
18510
+ /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: /* @__PURE__ */ jsxs("div", { className: "mb-10 flex flex-wrap items-end justify-between gap-6", children: [
18511
+ /* @__PURE__ */ jsxs("div", { className: "max-w-2xl", children: [
18512
+ eyebrow && /* @__PURE__ */ jsx("p", { className: "mb-3 text-xs font-ui font-bold uppercase tracking-[0.22em] text-primary", children: eyebrow }),
18513
+ /* @__PURE__ */ jsx("h2", { className: "font-heading text-3xl font-black uppercase leading-[1.05] text-foreground sm:text-4xl lg:text-5xl", children: title }),
18514
+ subtitle && /* @__PURE__ */ jsx("p", { className: "mt-3 text-base text-muted-foreground", children: subtitle })
18515
+ ] }),
18516
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
18517
+ link && /* @__PURE__ */ jsxs(
18518
+ "a",
18519
+ {
18520
+ href: (_a = link.href) != null ? _a : "#",
18521
+ className: "group mr-2 hidden items-center gap-1.5 font-ui text-sm font-bold text-primary transition-colors hover:text-primary-800 sm:inline-flex",
18522
+ children: [
18523
+ link.label,
18524
+ /* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4 transition-transform group-hover:translate-x-1" })
18525
+ ]
18526
+ }
18527
+ ),
18528
+ /* @__PURE__ */ jsx(
18529
+ "button",
18530
+ {
18531
+ type: "button",
18532
+ onClick: () => scrollByCard(-1),
18533
+ "aria-label": "Previous expeditions",
18534
+ className: "flex h-11 w-11 items-center justify-center rounded-full border border-border bg-background text-foreground transition-colors hover:border-primary hover:bg-primary hover:text-primary-foreground",
18535
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
18536
+ }
18537
+ ),
18538
+ /* @__PURE__ */ jsx(
18539
+ "button",
18540
+ {
18541
+ type: "button",
18542
+ onClick: () => scrollByCard(1),
18543
+ "aria-label": "Next expeditions",
18544
+ className: "flex h-11 w-11 items-center justify-center rounded-full border border-border bg-background text-foreground transition-colors hover:border-primary hover:bg-primary hover:text-primary-foreground",
18545
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
18546
+ }
18547
+ )
18548
+ ] })
18549
+ ] }) }),
18550
+ /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl", children: /* @__PURE__ */ jsx(
18551
+ "div",
18552
+ {
18553
+ ref: railRef,
18554
+ className: "flex snap-x snap-mandatory gap-[22px] overflow-x-auto scroll-pl-6 px-6 pb-4 [scrollbar-width:none] sm:scroll-pl-8 sm:px-8 [&::-webkit-scrollbar]:hidden",
18555
+ children: trips.map((trip, i) => /* @__PURE__ */ jsx(
18556
+ "div",
18557
+ {
18558
+ "data-rail-card": true,
18559
+ className: "w-[320px] shrink-0 snap-start sm:w-[340px]",
18560
+ children: /* @__PURE__ */ jsx(TripCard, __spreadValues({ variant: "editorial" }, trip))
18561
+ },
18562
+ i
18563
+ ))
18564
+ }
18565
+ ) })
18566
+ ] });
18567
+ }
18568
+ function PopularCloud({ eyebrow, title, subtitle, chips }) {
18569
+ return /* @__PURE__ */ jsx("section", { className: cn(SURFACE_WHITE, "py-20 sm:py-28"), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
18570
+ /* @__PURE__ */ jsx(
18571
+ SectionHead,
18572
+ {
18573
+ eyebrow,
18574
+ title,
18575
+ subtitle,
18576
+ align: "center"
18577
+ }
18578
+ ),
18579
+ /* @__PURE__ */ jsx("div", { className: "mx-auto flex max-w-3xl flex-wrap items-center justify-center gap-3", children: chips.map((chip, i) => {
18580
+ var _a;
18581
+ return /* @__PURE__ */ jsx(
18582
+ Chip,
18583
+ {
18584
+ href: chip.href,
18585
+ variant: chip.featured ? "solid" : "outline",
18586
+ size: (_a = chip.size) != null ? _a : "md",
18587
+ className: "transition-transform hover:-translate-y-0.5",
18588
+ children: chip.label
18589
+ },
18590
+ i
18591
+ );
18592
+ }) })
18593
+ ] }) });
18594
+ }
18595
+ function StatsBand({ items }) {
18596
+ return /* @__PURE__ */ jsx("section", { className: cn(SURFACE_PRIMARY_700, "py-16 text-white sm:py-20"), children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-x-6 gap-y-10 text-center lg:grid-cols-4", children: items.map((stat, i) => /* @__PURE__ */ jsxs("div", { children: [
18597
+ /* @__PURE__ */ jsx("div", { className: "font-heading text-4xl font-black leading-none text-[oklch(0.94_0.05_179)] sm:text-5xl lg:text-6xl", children: stat.value }),
18598
+ /* @__PURE__ */ jsx("div", { className: "mt-3 text-sm font-medium text-white/90", children: stat.label })
18599
+ ] }, i)) }) }) });
18600
+ }
18601
+ function ReviewStars({ stars = 5 }) {
18602
+ return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center gap-0.5", "aria-label": `${stars} out of 5 stars`, children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx(
18603
+ StarIcon,
18604
+ {
18605
+ className: cn(
18606
+ "h-4 w-4",
18607
+ i + 1 <= Math.round(stars) ? "fill-amber-400 text-amber-400" : "fill-white/15 text-white/15"
18608
+ )
18609
+ },
18610
+ i
18611
+ )) });
18612
+ }
18613
+ function ReviewsBand({ eyebrow, title, subtitle, link, items, note }) {
18614
+ return /* @__PURE__ */ jsx("section", { className: cn(SURFACE_PRIMARY_900, "py-20 text-white sm:py-28"), children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
18615
+ /* @__PURE__ */ jsx(
18616
+ SectionHead,
18617
+ {
18618
+ eyebrow,
18619
+ title,
18620
+ subtitle,
18621
+ link,
18622
+ theme: "dark"
18623
+ }
18624
+ ),
18625
+ /* @__PURE__ */ jsx("div", { className: "grid gap-5 sm:grid-cols-2 lg:grid-cols-3", children: items.map((review, i) => /* @__PURE__ */ jsxs(
18626
+ "figure",
18627
+ {
18628
+ className: "rounded-2xl border border-white/10 bg-white/5 p-7 transition-colors hover:bg-white/10",
18629
+ children: [
18630
+ /* @__PURE__ */ jsx(ReviewStars, { stars: review.stars }),
18631
+ /* @__PURE__ */ jsxs("blockquote", { className: "font-sans text-lg italic leading-relaxed text-white/90", children: [
18632
+ "\u201C",
18633
+ review.quote,
18634
+ "\u201D"
18635
+ ] }),
18636
+ /* @__PURE__ */ jsxs("figcaption", { className: "mt-5 text-sm font-medium text-white/60", children: [
18637
+ "\u2014 ",
18638
+ review.author
18639
+ ] })
18640
+ ]
18641
+ },
18642
+ i
18643
+ )) }),
18644
+ note && /* @__PURE__ */ jsx("p", { className: "mt-8 text-center text-xs text-white/40", children: note })
18645
+ ] }) });
18646
+ }
18647
+ function NewHome({
18648
+ hero,
18649
+ explorer,
18650
+ expeditions,
18651
+ popular,
18652
+ stats,
18653
+ usp,
18654
+ reviews,
18655
+ journal,
18656
+ cta,
18657
+ footer,
18658
+ className
18659
+ }) {
18660
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full bg-background", className), children: [
18661
+ /* @__PURE__ */ jsx(HomeHeader, __spreadValues({}, hero)),
18662
+ explorer && /* @__PURE__ */ jsx(
18663
+ AdventureExplorer,
18664
+ __spreadProps(__spreadValues({}, explorer), {
18665
+ className: cn(SURFACE_WHITE, explorer.className)
18666
+ })
18667
+ ),
18668
+ expeditions && /* @__PURE__ */ jsx(ExpeditionsRail, __spreadValues({}, expeditions)),
18669
+ popular && /* @__PURE__ */ jsx(PopularCloud, __spreadValues({}, popular)),
18670
+ stats && /* @__PURE__ */ jsx(StatsBand, __spreadValues({}, stats)),
18671
+ usp && /* @__PURE__ */ jsx(USP, __spreadProps(__spreadValues({}, usp), { className: cn(SURFACE_PRIMARY_800, usp.className) })),
18672
+ reviews && /* @__PURE__ */ jsx(ReviewsBand, __spreadValues({}, reviews)),
18673
+ journal && /* @__PURE__ */ jsx(BlogJournal, __spreadProps(__spreadValues({}, journal), { className: cn(SURFACE_WHITE, journal.className) })),
18674
+ cta && /* @__PURE__ */ jsx(CtaBanner, __spreadValues({}, cta)),
18675
+ footer && /* @__PURE__ */ jsx(SiteFooter, __spreadValues({}, footer))
18676
+ ] });
18677
+ }
18678
+ var ACTIVE_PILL = "bg-primary text-white shadow-sm";
18679
+ var VARIANT3 = {
18680
+ black: {
18681
+ track: "bg-white/5 border-white/10",
18682
+ idle: "text-white/55 hover:text-white",
18683
+ ring: "focus-visible:ring-white/70"
18684
+ },
18685
+ white: {
18686
+ track: "bg-neutral-100 border-black/10",
18687
+ idle: "text-neutral-500 hover:text-neutral-900",
18688
+ ring: "focus-visible:ring-neutral-900/40"
18689
+ }
18690
+ };
18691
+ var SIZE = {
18692
+ sm: "px-4 py-1.5 text-[13px]",
18693
+ md: "px-5 py-2 text-sm"
18694
+ };
18695
+ function SegmentedControl({
18696
+ items,
18697
+ value,
18698
+ defaultValue,
18699
+ onValueChange,
18700
+ variant = "black",
18701
+ size = "md",
18702
+ fullWidth = false,
18703
+ collapse = false,
18704
+ "aria-label": ariaLabel = "Options",
18705
+ className
18706
+ }) {
18707
+ var _a;
18708
+ const isControlled = value != null;
18709
+ const [internal, setInternal] = React32.useState(
18710
+ defaultValue != null ? defaultValue : (_a = items[0]) == null ? void 0 : _a.id
18711
+ );
18712
+ const active = isControlled ? value : internal;
18713
+ const select = (id) => {
18714
+ if (!isControlled) setInternal(id);
18715
+ onValueChange == null ? void 0 : onValueChange(id);
18716
+ };
18717
+ const onKeyDown = (e) => {
18718
+ if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
18719
+ e.preventDefault();
18720
+ const enabled = items.filter((i) => !i.disabled);
18721
+ const idx = enabled.findIndex((i) => i.id === active);
18722
+ if (idx === -1) return;
18723
+ const next = e.key === "ArrowRight" ? enabled[(idx + 1) % enabled.length] : enabled[(idx - 1 + enabled.length) % enabled.length];
18724
+ select(next.id);
18725
+ };
18726
+ const v = VARIANT3[variant];
18727
+ return /* @__PURE__ */ jsx(
18728
+ "div",
18729
+ {
18730
+ role: "radiogroup",
18731
+ "aria-label": ariaLabel,
18732
+ onKeyDown,
18733
+ className: cn(
18734
+ "inline-flex max-w-full items-center gap-1 overflow-x-auto rounded-full border p-1.5 scrollbar-none",
18735
+ fullWidth && "flex w-full",
18736
+ v.track,
18737
+ className
18738
+ ),
18739
+ children: items.map((item) => {
18740
+ const isActive = item.id === active;
18741
+ const Icon = item.icon;
18742
+ const showLabel = collapse === "all" ? false : collapse ? isActive : true;
18743
+ return /* @__PURE__ */ jsxs(
18744
+ "button",
18745
+ {
18746
+ type: "button",
18747
+ role: "radio",
18748
+ "aria-checked": isActive,
18749
+ "aria-label": collapse && !showLabel ? item.label : void 0,
18750
+ title: collapse && !showLabel ? item.label : void 0,
18751
+ disabled: item.disabled,
18752
+ tabIndex: isActive ? 0 : -1,
18753
+ onClick: () => select(item.id),
18754
+ className: cn(
18755
+ "inline-flex shrink-0 items-center justify-center rounded-full font-ui font-bold transition-all duration-300 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-40",
18756
+ showLabel && Icon ? "gap-2" : "gap-0",
18757
+ variant === "black" ? "focus-visible:ring-offset-neutral-950" : "focus-visible:ring-offset-white",
18758
+ fullWidth && "flex-1",
18759
+ SIZE[size],
18760
+ /* Icon-only segments are square-ish — drop the side padding so
18761
+ the icon centres in a circular pill. */
18762
+ collapse && !showLabel && (size === "sm" ? "!px-1.5" : "!px-2"),
18763
+ isActive ? ACTIVE_PILL : v.idle,
18764
+ v.ring
18765
+ ),
18766
+ children: [
18767
+ Icon && /* @__PURE__ */ jsx(
18768
+ Icon,
18769
+ {
18770
+ className: cn("shrink-0", size === "sm" ? "size-4" : "size-[18px]")
18771
+ }
18772
+ ),
18773
+ /* @__PURE__ */ jsx(
18774
+ "span",
18775
+ {
18776
+ className: cn(
18777
+ "overflow-hidden whitespace-nowrap transition-all duration-300 ease-out",
18778
+ showLabel ? "max-w-[12ch] opacity-100" : "max-w-0 opacity-0"
18779
+ ),
18780
+ children: item.label
18781
+ }
18782
+ )
18783
+ ]
18784
+ },
18785
+ item.id
18786
+ );
18787
+ })
18788
+ }
18789
+ );
18790
+ }
16885
18791
 
16886
- export { ActivityCard, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogPost, 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, NotificationEmail, 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 };
18792
+ export { ActivityCard, AdventureExplorer, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogJournal, BlogPost, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CancellationForm, CategoryPage2, Chip, CounterField, CountrySearchField, CtaBanner, DEFAULT_FOOTER_BADGES, DEFAULT_FOOTER_DESTINATIONS, DEFAULT_FOOTER_LANGUAGES, DEFAULT_FOOTER_LEGAL, DEFAULT_FOOTER_PAGES, DEFAULT_FOOTER_SOCIALS, DEFAULT_FOOTER_THEMES, 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, HomeHeader, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, NewHome, NotificationEmail, OTPCodeInput, Offer, OfferAdventureCard, ParticipantCounter, ParticipantList, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, Picture, PriceProgress, PricingMatrixCard, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, SegmentedControl, ShareWidget, SiteFooter, SiteHeader, StatusBadge2 as StatusBadge, StickyBookingCard, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, USP, buttonVariants, chipVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
16887
18793
  //# sourceMappingURL=index.js.map
16888
18794
  //# sourceMappingURL=index.js.map