@planetaexo/design-system 0.69.1 → 0.71.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 React32 from 'react';
1
+ import * as React20 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, 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';
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 as StarIcon$1, 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 = React32.forwardRef(
84
+ var Button = React20.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 = React32.forwardRef(
313
+ var FloatingInput = React20.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 : React32.useId();
316
+ const inputId = id != null ? id : React20.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 = React32.forwardRef(
353
353
  }
354
354
  );
355
355
  FloatingInput.displayName = "FloatingInput";
356
- var FloatingSelect = React32.forwardRef(
356
+ var FloatingSelect = React20.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 : React32.useId();
359
+ const inputId = id != null ? id : React20.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(
@@ -621,11 +621,11 @@ function PhoneCountrySelect({
621
621
  showDial = true
622
622
  }) {
623
623
  var _a;
624
- const [open, setOpen] = React32.useState(false);
625
- const containerRef = React32.useRef(null);
626
- const listRef = React32.useRef(null);
624
+ const [open, setOpen] = React20.useState(false);
625
+ const containerRef = React20.useRef(null);
626
+ const listRef = React20.useRef(null);
627
627
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
628
- React32.useEffect(() => {
628
+ React20.useEffect(() => {
629
629
  if (!open) return;
630
630
  const handler = (e) => {
631
631
  var _a2;
@@ -636,7 +636,7 @@ function PhoneCountrySelect({
636
636
  document.addEventListener("mousedown", handler);
637
637
  return () => document.removeEventListener("mousedown", handler);
638
638
  }, [open]);
639
- React32.useEffect(() => {
639
+ React20.useEffect(() => {
640
640
  if (!open || !listRef.current) return;
641
641
  const activeEl = listRef.current.querySelector("[data-selected=true]");
642
642
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -906,8 +906,8 @@ function CalendarDayButton(_a) {
906
906
  "locale"
907
907
  ]);
908
908
  const defaultClassNames = getDefaultClassNames();
909
- const ref = React32.useRef(null);
910
- React32.useEffect(() => {
909
+ const ref = React20.useRef(null);
910
+ React20.useEffect(() => {
911
911
  var _a2;
912
912
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
913
913
  }, [modifiers.focused]);
@@ -938,16 +938,16 @@ function BirthDateField({
938
938
  className,
939
939
  disabled
940
940
  }) {
941
- const [open, setOpen] = React32.useState(false);
942
- const [text, setText] = React32.useState(
941
+ const [open, setOpen] = React20.useState(false);
942
+ const [text, setText] = React20.useState(
943
943
  value ? format(value, "dd/MM/yyyy") : ""
944
944
  );
945
- const containerRef = React32.useRef(null);
946
- const inputId = React32.useId();
947
- React32.useEffect(() => {
945
+ const containerRef = React20.useRef(null);
946
+ const inputId = React20.useId();
947
+ React20.useEffect(() => {
948
948
  setText(value ? format(value, "dd/MM/yyyy") : "");
949
949
  }, [value]);
950
- React32.useEffect(() => {
950
+ React20.useEffect(() => {
951
951
  if (!open) return;
952
952
  const handler = (e) => {
953
953
  var _a;
@@ -1156,14 +1156,14 @@ function CountrySearchField({
1156
1156
  }) {
1157
1157
  var _a;
1158
1158
  const list = countries != null ? countries : COUNTRIES;
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);
1159
+ const [query, setQuery] = React20.useState("");
1160
+ const [open, setOpen] = React20.useState(false);
1161
+ const containerRef = React20.useRef(null);
1162
+ const searchRef = React20.useRef(null);
1163
1163
  const selected = list.find((c) => c.code === value);
1164
1164
  const isFloated = open || !!selected;
1165
1165
  const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
1166
- React32.useEffect(() => {
1166
+ React20.useEffect(() => {
1167
1167
  if (!open) return;
1168
1168
  const handler = (e) => {
1169
1169
  var _a2;
@@ -1308,10 +1308,10 @@ function AdventureCard({
1308
1308
  }) {
1309
1309
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1310
1310
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1311
- const [checkedInternal, setCheckedInternal] = React32.useState(
1311
+ const [checkedInternal, setCheckedInternal] = React20.useState(
1312
1312
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
1313
1313
  );
1314
- const [openDescriptionId, setOpenDescriptionId] = React32.useState(null);
1314
+ const [openDescriptionId, setOpenDescriptionId] = React20.useState(null);
1315
1315
  const openDescriptionOptional = openDescriptionId ? (_e = adventure.optionals) == null ? void 0 : _e.find((o) => o.id === openDescriptionId) : void 0;
1316
1316
  const isChecked = (opt) => {
1317
1317
  var _a2;
@@ -1763,7 +1763,7 @@ function BookingShell({
1763
1763
  return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1764
1764
  /* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1765
1765
  /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1766
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
1766
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
1767
1767
  /* @__PURE__ */ jsx(
1768
1768
  "span",
1769
1769
  {
@@ -1962,7 +1962,7 @@ function TermsSection({
1962
1962
  termsContent
1963
1963
  }) {
1964
1964
  var _a;
1965
- const [modalOpen, setModalOpen] = React32.useState(false);
1965
+ const [modalOpen, setModalOpen] = React20.useState(false);
1966
1966
  const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
1967
1967
  return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1968
1968
  /* @__PURE__ */ jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
@@ -2100,9 +2100,9 @@ function BookingWizard({
2100
2100
  }) {
2101
2101
  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;
2102
2102
  const wizardSteps = WIZARD_STEPS_FN(labels);
2103
- const [step, setStep] = React32.useState("responsible");
2104
- const [error, setError] = React32.useState(null);
2105
- const [responsible, setResponsible] = React32.useState({
2103
+ const [step, setStep] = React20.useState("responsible");
2104
+ const [error, setError] = React20.useState(null);
2105
+ const [responsible, setResponsible] = React20.useState({
2106
2106
  firstName: "",
2107
2107
  lastName: "",
2108
2108
  email: "",
@@ -2121,7 +2121,7 @@ function BookingWizard({
2121
2121
  return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
2122
2122
  }, 0);
2123
2123
  const totalPax = totalAdults + totalChildren;
2124
- const [travellers, setTravellers] = React32.useState(
2124
+ const [travellers, setTravellers] = React20.useState(
2125
2125
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
2126
2126
  firstName: "",
2127
2127
  lastName: "",
@@ -2129,9 +2129,9 @@ function BookingWizard({
2129
2129
  email: ""
2130
2130
  }))
2131
2131
  );
2132
- const [payAmount, setPayAmount] = React32.useState("full");
2133
- const [payMethod, setPayMethod] = React32.useState("stripe");
2134
- const [termsAccepted, setTermsAccepted] = React32.useState(false);
2132
+ const [payAmount, setPayAmount] = React20.useState("full");
2133
+ const [payMethod, setPayMethod] = React20.useState("stripe");
2134
+ const [termsAccepted, setTermsAccepted] = React20.useState(false);
2135
2135
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
2136
2136
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
2137
2137
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -2359,7 +2359,7 @@ function Offer({
2359
2359
  className
2360
2360
  }) {
2361
2361
  var _a, _b, _c;
2362
- const [showBooking, setShowBooking] = React32.useState(false);
2362
+ const [showBooking, setShowBooking] = React20.useState(false);
2363
2363
  const isShowingCheckout = !confirmedState && (!!checkoutSlot || internalDemoCheckout && showBooking);
2364
2364
  const handleBook = () => {
2365
2365
  if (!checkoutSlot && !externalBookingFlow && internalDemoCheckout) {
@@ -2726,7 +2726,7 @@ function AdventureSection({
2726
2726
  labels
2727
2727
  }) {
2728
2728
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
2729
- const [detailsOpen, setDetailsOpen] = React32.useState(false);
2729
+ const [detailsOpen, setDetailsOpen] = React20.useState(false);
2730
2730
  const handleCopyUrl = (url) => {
2731
2731
  if (onCopyFormLink) {
2732
2732
  onCopyFormLink(url);
@@ -3265,8 +3265,8 @@ function AddTravellerDialog({
3265
3265
  errorMessage
3266
3266
  }) {
3267
3267
  var _a, _b, _c, _d, _e;
3268
- const [form, setForm] = React32.useState(() => createInitialAddFormData(config));
3269
- React32.useEffect(() => {
3268
+ const [form, setForm] = React20.useState(() => createInitialAddFormData(config));
3269
+ React20.useEffect(() => {
3270
3270
  if (open) {
3271
3271
  setForm(createInitialAddFormData(config));
3272
3272
  }
@@ -3326,7 +3326,7 @@ function EditTravellerDialog({
3326
3326
  errorMessage
3327
3327
  }) {
3328
3328
  var _a, _b, _c, _d, _e;
3329
- const [form, setForm] = React32.useState(() => ({
3329
+ const [form, setForm] = React20.useState(() => ({
3330
3330
  firstName: "",
3331
3331
  lastName: "",
3332
3332
  email: "",
@@ -3335,7 +3335,7 @@ function EditTravellerDialog({
3335
3335
  birthDate: "",
3336
3336
  personType: "ADULT"
3337
3337
  }));
3338
- React32.useEffect(() => {
3338
+ React20.useEffect(() => {
3339
3339
  var _a2, _b2, _c2, _d2, _e2, _f;
3340
3340
  if (open && traveller) {
3341
3341
  setForm({
@@ -3671,48 +3671,48 @@ function BookingDetails({
3671
3671
  const hasSubmitAddTraveller = !!onSubmitAddTraveller;
3672
3672
  const hasSubmitEditTraveller = !!onSubmitEditTraveller;
3673
3673
  const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
3674
- const [addModalState, setAddModalState] = React32.useState({
3674
+ const [addModalState, setAddModalState] = React20.useState({
3675
3675
  open: false,
3676
3676
  adventureId: null
3677
3677
  });
3678
- const [editModalState, setEditModalState] = React32.useState({ open: false, adventureId: null, traveller: null });
3679
- const [deleteModalState, setDeleteModalState] = React32.useState({ open: false, adventureId: null, traveller: null });
3680
- const [resendInviteDialogState, setResendInviteDialogState] = React32.useState({ open: false, traveller: null });
3681
- const handleRequestOpenAddModal = React32.useCallback((adventureId) => {
3678
+ const [editModalState, setEditModalState] = React20.useState({ open: false, adventureId: null, traveller: null });
3679
+ const [deleteModalState, setDeleteModalState] = React20.useState({ open: false, adventureId: null, traveller: null });
3680
+ const [resendInviteDialogState, setResendInviteDialogState] = React20.useState({ open: false, traveller: null });
3681
+ const handleRequestOpenAddModal = React20.useCallback((adventureId) => {
3682
3682
  setAddModalState({ open: true, adventureId });
3683
3683
  }, []);
3684
- const handleRequestOpenEditModal = React32.useCallback(
3684
+ const handleRequestOpenEditModal = React20.useCallback(
3685
3685
  (adventureId, traveller) => {
3686
3686
  setEditModalState({ open: true, adventureId, traveller });
3687
3687
  },
3688
3688
  []
3689
3689
  );
3690
- const handleRequestOpenDeleteModal = React32.useCallback(
3690
+ const handleRequestOpenDeleteModal = React20.useCallback(
3691
3691
  (adventureId, traveller) => {
3692
3692
  setDeleteModalState({ open: true, adventureId, traveller });
3693
3693
  },
3694
3694
  []
3695
3695
  );
3696
- const handleRequestOpenResendInviteDialog = React32.useCallback(
3696
+ const handleRequestOpenResendInviteDialog = React20.useCallback(
3697
3697
  (traveller) => {
3698
3698
  setResendInviteDialogState({ open: true, traveller });
3699
3699
  },
3700
3700
  []
3701
3701
  );
3702
- const closeAddModal = React32.useCallback(() => {
3702
+ const closeAddModal = React20.useCallback(() => {
3703
3703
  setAddModalState({ open: false, adventureId: null });
3704
3704
  }, []);
3705
- const closeEditModal = React32.useCallback(() => {
3705
+ const closeEditModal = React20.useCallback(() => {
3706
3706
  setEditModalState({ open: false, adventureId: null, traveller: null });
3707
3707
  }, []);
3708
- const closeDeleteModal = React32.useCallback(() => {
3708
+ const closeDeleteModal = React20.useCallback(() => {
3709
3709
  setDeleteModalState({ open: false, adventureId: null, traveller: null });
3710
3710
  }, []);
3711
- const closeResendInviteDialog = React32.useCallback(() => {
3711
+ const closeResendInviteDialog = React20.useCallback(() => {
3712
3712
  setResendInviteDialogState({ open: false, traveller: null });
3713
3713
  }, []);
3714
- const submitInFlightRef = React32.useRef(false);
3715
- const handleAddSubmit = React32.useCallback(
3714
+ const submitInFlightRef = React20.useRef(false);
3715
+ const handleAddSubmit = React20.useCallback(
3716
3716
  async (adventureId, data) => {
3717
3717
  if (!onSubmitAddTraveller) return;
3718
3718
  if (submitInFlightRef.current) return;
@@ -3727,7 +3727,7 @@ function BookingDetails({
3727
3727
  },
3728
3728
  [onSubmitAddTraveller, closeAddModal]
3729
3729
  );
3730
- const handleEditSubmit = React32.useCallback(
3730
+ const handleEditSubmit = React20.useCallback(
3731
3731
  async (adventureId, travellerId, data) => {
3732
3732
  if (!onSubmitEditTraveller) return;
3733
3733
  if (submitInFlightRef.current) return;
@@ -3742,7 +3742,7 @@ function BookingDetails({
3742
3742
  },
3743
3743
  [onSubmitEditTraveller, closeEditModal]
3744
3744
  );
3745
- const handleDeleteConfirm = React32.useCallback(
3745
+ const handleDeleteConfirm = React20.useCallback(
3746
3746
  async (adventureId, travellerId) => {
3747
3747
  if (!onConfirmRemoveTraveller) return;
3748
3748
  if (submitInFlightRef.current) return;
@@ -5669,7 +5669,7 @@ function BookingCreatedEmail({
5669
5669
  }, children: i + 1 }) }),
5670
5670
  /* @__PURE__ */ jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
5671
5671
  ] }) }) }, i)) }),
5672
- 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: [
5672
+ 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(React20.Fragment, { children: [
5673
5673
  idx === 0 ? /* @__PURE__ */ jsx("strong", { children: line }) : line,
5674
5674
  idx < arr.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
5675
5675
  ] }, idx)) })
@@ -8452,11 +8452,11 @@ function DatePickerField({
8452
8452
  className,
8453
8453
  error
8454
8454
  }) {
8455
- const [open, setOpen] = React32.useState(false);
8456
- const containerRef = React32.useRef(null);
8457
- const [calendarWidth, setCalendarWidth] = React32.useState();
8455
+ const [open, setOpen] = React20.useState(false);
8456
+ const containerRef = React20.useRef(null);
8457
+ const [calendarWidth, setCalendarWidth] = React20.useState();
8458
8458
  const hasValue = !!value;
8459
- React32.useEffect(() => {
8459
+ React20.useEffect(() => {
8460
8460
  if (!containerRef.current) return;
8461
8461
  const observer = new ResizeObserver(([entry]) => {
8462
8462
  setCalendarWidth(entry.contentRect.width);
@@ -8585,15 +8585,15 @@ function BookingForm({
8585
8585
  const titleText = (_a = title != null ? title : L.title) != null ? _a : "Check availability for your trip";
8586
8586
  const subtitleText = (_b = subtitle != null ? subtitle : L.subtitle) != null ? _b : "Free enquiry \u2013 no commitment";
8587
8587
  const submitText = (_c = submitLabel != null ? submitLabel : L.submit) != null ? _c : "Send my request";
8588
- const [values, setValues] = React32.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
8589
- const [errors, setErrors] = React32.useState({});
8588
+ const [values, setValues] = React20.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
8589
+ const [errors, setErrors] = React20.useState({});
8590
8590
  const set = (key, value) => {
8591
8591
  setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
8592
8592
  setErrors(
8593
8593
  (prev) => prev[key] ? __spreadProps(__spreadValues({}, prev), { [key]: void 0 }) : prev
8594
8594
  );
8595
8595
  };
8596
- React32.useEffect(() => {
8596
+ React20.useEffect(() => {
8597
8597
  if (!defaultValues) return;
8598
8598
  setValues((prev) => {
8599
8599
  let changed = false;
@@ -9232,11 +9232,11 @@ function FloatingTextarea({
9232
9232
  }
9233
9233
  function SelectField({ field, value, onChange, error, disabled }) {
9234
9234
  var _a, _b, _c;
9235
- const [open, setOpen] = React32.useState(false);
9236
- const containerRef = React32.useRef(null);
9235
+ const [open, setOpen] = React20.useState(false);
9236
+ const containerRef = React20.useRef(null);
9237
9237
  const options = (_a = field.options) != null ? _a : [];
9238
9238
  const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
9239
- React32.useEffect(() => {
9239
+ React20.useEffect(() => {
9240
9240
  if (!open) return;
9241
9241
  const handleOutside = (e) => {
9242
9242
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -9704,11 +9704,11 @@ function RegistrationForm({
9704
9704
  readOnly = false
9705
9705
  }) {
9706
9706
  var _a;
9707
- const L = React32.useMemo(
9707
+ const L = React20.useMemo(
9708
9708
  () => __spreadValues(__spreadValues({}, DEFAULT_LABELS14), labels != null ? labels : {}),
9709
9709
  [labels]
9710
9710
  );
9711
- const sortedFields = React32.useMemo(
9711
+ const sortedFields = React20.useMemo(
9712
9712
  () => [...fields].sort((a, b) => {
9713
9713
  var _a2, _b;
9714
9714
  return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
@@ -9716,7 +9716,7 @@ function RegistrationForm({
9716
9716
  [fields]
9717
9717
  );
9718
9718
  const isControlled = values !== void 0;
9719
- const [internal, setInternal] = React32.useState(
9719
+ const [internal, setInternal] = React20.useState(
9720
9720
  () => initializeValues(
9721
9721
  sortedFields,
9722
9722
  defaultValues != null ? defaultValues : {},
@@ -9724,9 +9724,9 @@ function RegistrationForm({
9724
9724
  includeTerms
9725
9725
  )
9726
9726
  );
9727
- const [submitAttempted, setSubmitAttempted] = React32.useState(false);
9728
- const [validationErrors, setValidationErrors] = React32.useState({});
9729
- React32.useEffect(() => {
9727
+ const [submitAttempted, setSubmitAttempted] = React20.useState(false);
9728
+ const [validationErrors, setValidationErrors] = React20.useState({});
9729
+ React20.useEffect(() => {
9730
9730
  if (isControlled) return;
9731
9731
  setInternal((prev) => {
9732
9732
  const next = initializeValues(
@@ -9783,7 +9783,7 @@ function RegistrationForm({
9783
9783
  const termsError = submitAttempted && termsEnabled && !termsAccepted;
9784
9784
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
9785
9785
  const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
9786
- React32.useEffect(() => {
9786
+ React20.useEffect(() => {
9787
9787
  if (!submitAttempted || !scrollTargetId) return;
9788
9788
  const timer = setTimeout(() => {
9789
9789
  const elem = document.getElementById(scrollTargetId);
@@ -10254,18 +10254,18 @@ function CancellationForm({
10254
10254
  className
10255
10255
  }) {
10256
10256
  var _a, _b, _c;
10257
- const [selectedAdventureIds, setSelectedAdventureIds] = React32.useState(/* @__PURE__ */ new Set());
10258
- const [participantsByAdventure, setParticipantsByAdventure] = React32.useState({});
10259
- const [reasonCode, setReasonCode] = React32.useState("");
10260
- const [reasonOther, setReasonOther] = React32.useState("");
10261
- const [refundPreference, setRefundPreference] = React32.useState("");
10262
- const [refundOther, setRefundOther] = React32.useState("");
10263
- const [agreedToPolicy, setAgreedToPolicy] = React32.useState(false);
10264
- const [contactName, setContactName] = React32.useState((_a = identity == null ? void 0 : identity.name) != null ? _a : "");
10265
- const [contactEmail, setContactEmail] = React32.useState((_b = identity == null ? void 0 : identity.email) != null ? _b : "");
10266
- const [contactPhone, setContactPhone] = React32.useState((_c = identity == null ? void 0 : identity.phone) != null ? _c : "");
10267
- const [errors, setErrors] = React32.useState({});
10268
- const allParticipantsOf = React32.useCallback(
10257
+ const [selectedAdventureIds, setSelectedAdventureIds] = React20.useState(/* @__PURE__ */ new Set());
10258
+ const [participantsByAdventure, setParticipantsByAdventure] = React20.useState({});
10259
+ const [reasonCode, setReasonCode] = React20.useState("");
10260
+ const [reasonOther, setReasonOther] = React20.useState("");
10261
+ const [refundPreference, setRefundPreference] = React20.useState("");
10262
+ const [refundOther, setRefundOther] = React20.useState("");
10263
+ const [agreedToPolicy, setAgreedToPolicy] = React20.useState(false);
10264
+ const [contactName, setContactName] = React20.useState((_a = identity == null ? void 0 : identity.name) != null ? _a : "");
10265
+ const [contactEmail, setContactEmail] = React20.useState((_b = identity == null ? void 0 : identity.email) != null ? _b : "");
10266
+ const [contactPhone, setContactPhone] = React20.useState((_c = identity == null ? void 0 : identity.phone) != null ? _c : "");
10267
+ const [errors, setErrors] = React20.useState({});
10268
+ const allParticipantsOf = React20.useCallback(
10269
10269
  (advId) => {
10270
10270
  var _a2, _b2;
10271
10271
  return new Set(((_b2 = (_a2 = adventures.find((a) => a.id === advId)) == null ? void 0 : _a2.participants) != null ? _b2 : []).map((p) => p.id));
@@ -10522,10 +10522,10 @@ var OTPCodeInput = ({
10522
10522
  id,
10523
10523
  required
10524
10524
  }) => {
10525
- const baseId = id != null ? id : React32.useId();
10526
- const inputRef = React32.useRef(null);
10527
- const [focused, setFocused] = React32.useState(false);
10528
- const digits = React32.useMemo(() => {
10525
+ const baseId = id != null ? id : React20.useId();
10526
+ const inputRef = React20.useRef(null);
10527
+ const [focused, setFocused] = React20.useState(false);
10528
+ const digits = React20.useMemo(() => {
10529
10529
  const arr = value.split("").slice(0, length);
10530
10530
  while (arr.length < length) arr.push("");
10531
10531
  return arr;
@@ -10638,7 +10638,7 @@ function Checkbox(_a) {
10638
10638
  })
10639
10639
  );
10640
10640
  }
10641
- var AccordionVariantContext = React32.createContext("default");
10641
+ var AccordionVariantContext = React20.createContext("default");
10642
10642
  function Accordion(_a) {
10643
10643
  var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
10644
10644
  return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
@@ -10656,7 +10656,7 @@ function Accordion(_a) {
10656
10656
  }
10657
10657
  function AccordionItem(_a) {
10658
10658
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
10659
- const variant = React32.useContext(AccordionVariantContext);
10659
+ const variant = React20.useContext(AccordionVariantContext);
10660
10660
  return /* @__PURE__ */ jsx(
10661
10661
  Accordion$1.Item,
10662
10662
  __spreadValues({
@@ -10679,7 +10679,7 @@ function AccordionTrigger(_a) {
10679
10679
  "children",
10680
10680
  "headingLevel"
10681
10681
  ]);
10682
- const variant = React32.useContext(AccordionVariantContext);
10682
+ const variant = React20.useContext(AccordionVariantContext);
10683
10683
  const headingRender = headingLevel === 2 ? /* @__PURE__ */ jsx("h2", {}) : headingLevel === 4 ? /* @__PURE__ */ jsx("h4", {}) : headingLevel === 5 ? /* @__PURE__ */ jsx("h5", {}) : headingLevel === 6 ? /* @__PURE__ */ jsx("h6", {}) : void 0;
10684
10684
  return /* @__PURE__ */ jsx(
10685
10685
  Accordion$1.Header,
@@ -10741,7 +10741,7 @@ function AccordionContent(_a) {
10741
10741
  "className",
10742
10742
  "children"
10743
10743
  ]);
10744
- const variant = React32.useContext(AccordionVariantContext);
10744
+ const variant = React20.useContext(AccordionVariantContext);
10745
10745
  return /* @__PURE__ */ jsx(
10746
10746
  Accordion$1.Panel,
10747
10747
  __spreadProps(__spreadValues({
@@ -10960,15 +10960,15 @@ function FilterPanel({
10960
10960
  labels
10961
10961
  }) {
10962
10962
  var _a, _b, _c, _d, _e, _f, _g, _h;
10963
- const resolvedGroups = React32.useMemo(() => resolveGroups(groups), [groups]);
10964
- const [internalValue, setInternalValue] = React32.useState(
10963
+ const resolvedGroups = React20.useMemo(() => resolveGroups(groups), [groups]);
10964
+ const [internalValue, setInternalValue] = React20.useState(
10965
10965
  () => Object.fromEntries(groups.map((g) => [g.id, []]))
10966
10966
  );
10967
10967
  const selected = value != null ? value : internalValue;
10968
- const [expandedItems, setExpandedItems] = React32.useState(
10968
+ const [expandedItems, setExpandedItems] = React20.useState(
10969
10969
  () => new Set(groups.flatMap((g) => getDefaultExpandedIds(g.items)))
10970
10970
  );
10971
- const toggleExpanded = React32.useCallback((id) => {
10971
+ const toggleExpanded = React20.useCallback((id) => {
10972
10972
  setExpandedItems((prev) => {
10973
10973
  const next = new Set(prev);
10974
10974
  if (next.has(id)) next.delete(id);
@@ -11352,11 +11352,11 @@ function FilterPanel({
11352
11352
  var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
11353
11353
  function TrustpilotEmbed({ config }) {
11354
11354
  var _a, _b, _c, _d, _e, _f;
11355
- const ref = React32.useRef(null);
11356
- const [widgetReady, setWidgetReady] = React32.useState(false);
11357
- const [delayPassed, setDelayPassed] = React32.useState(false);
11355
+ const ref = React20.useRef(null);
11356
+ const [widgetReady, setWidgetReady] = React20.useState(false);
11357
+ const [delayPassed, setDelayPassed] = React20.useState(false);
11358
11358
  const showFallback = delayPassed && !widgetReady;
11359
- React32.useEffect(() => {
11359
+ React20.useEffect(() => {
11360
11360
  var _a2;
11361
11361
  if (typeof document === "undefined" || !ref.current) return;
11362
11362
  const node = ref.current;
@@ -11544,7 +11544,7 @@ function webpVariantUrl(src) {
11544
11544
  return `${withoutQuery}.webp${query}`;
11545
11545
  }
11546
11546
  function PictureLoader() {
11547
- const gradientId = React32.useId();
11547
+ const gradientId = React20.useId();
11548
11548
  return /* @__PURE__ */ jsx(
11549
11549
  "span",
11550
11550
  {
@@ -11614,10 +11614,10 @@ function Picture(_a) {
11614
11614
  "onError"
11615
11615
  ]);
11616
11616
  var _a2, _b2;
11617
- const ref = React32.useRef(null);
11618
- const [visible, setVisible] = React32.useState(eager);
11619
- const [loaded, setLoaded] = React32.useState(false);
11620
- React32.useEffect(() => {
11617
+ const ref = React20.useRef(null);
11618
+ const [visible, setVisible] = React20.useState(eager);
11619
+ const [loaded, setLoaded] = React20.useState(false);
11620
+ React20.useEffect(() => {
11621
11621
  if (eager || visible) return;
11622
11622
  const el = ref.current;
11623
11623
  if (!el || typeof IntersectionObserver === "undefined") {
@@ -11636,7 +11636,7 @@ function Picture(_a) {
11636
11636
  io.observe(el);
11637
11637
  return () => io.disconnect();
11638
11638
  }, [eager, visible, rootMargin]);
11639
- React32.useEffect(() => {
11639
+ React20.useEffect(() => {
11640
11640
  setLoaded(false);
11641
11641
  }, [src]);
11642
11642
  const webp = webpVariantUrl(src);
@@ -11767,11 +11767,11 @@ function ItineraryModal({
11767
11767
  onNext
11768
11768
  }) {
11769
11769
  var _a, _b, _c;
11770
- const [imgIndex, setImgIndex] = React32.useState(0);
11770
+ const [imgIndex, setImgIndex] = React20.useState(0);
11771
11771
  const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
11772
11772
  const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
11773
11773
  const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
11774
- React32.useEffect(() => {
11774
+ React20.useEffect(() => {
11775
11775
  setImgIndex(0);
11776
11776
  }, [stop == null ? void 0 : stop.dayNumber]);
11777
11777
  if (!stop) return null;
@@ -11898,8 +11898,8 @@ function ItineraryModal({
11898
11898
  ) });
11899
11899
  }
11900
11900
  function Itinerary({ title, subtitle, stops, className }) {
11901
- const [activeIndex, setActiveIndex] = React32.useState(null);
11902
- const scrollRef = React32.useRef(null);
11901
+ const [activeIndex, setActiveIndex] = React20.useState(null);
11902
+ const scrollRef = React20.useRef(null);
11903
11903
  const activeStop = activeIndex !== null ? stops[activeIndex] : null;
11904
11904
  const scrollBy = (dir) => {
11905
11905
  if (!scrollRef.current) return;
@@ -11992,18 +11992,18 @@ function Lightbox({
11992
11992
  labels
11993
11993
  }) {
11994
11994
  var _a, _b, _c, _d;
11995
- const [index, setIndex] = React32.useState(initialIndex);
11995
+ const [index, setIndex] = React20.useState(initialIndex);
11996
11996
  const total = photos.length;
11997
11997
  const photo = photos[index];
11998
- const prev = React32.useCallback(
11998
+ const prev = React20.useCallback(
11999
11999
  () => setIndex((i) => (i - 1 + total) % total),
12000
12000
  [total]
12001
12001
  );
12002
- const next = React32.useCallback(
12002
+ const next = React20.useCallback(
12003
12003
  () => setIndex((i) => (i + 1) % total),
12004
12004
  [total]
12005
12005
  );
12006
- React32.useEffect(() => {
12006
+ React20.useEffect(() => {
12007
12007
  const onKey = (e) => {
12008
12008
  if (e.key === "Escape") onClose();
12009
12009
  if (e.key === "ArrowLeft") prev();
@@ -12105,6 +12105,260 @@ function Lightbox({
12105
12105
  }
12106
12106
  );
12107
12107
  }
12108
+ function FeedLightbox({
12109
+ sections,
12110
+ initialIndex,
12111
+ onClose,
12112
+ labels
12113
+ }) {
12114
+ var _a;
12115
+ const { items, total, bounds } = React20.useMemo(() => {
12116
+ const items2 = [];
12117
+ const bounds2 = [];
12118
+ let i = 0;
12119
+ for (const section of sections) {
12120
+ if (!section.photos.length) continue;
12121
+ bounds2.push({
12122
+ label: section.label,
12123
+ start: i,
12124
+ end: i + section.photos.length - 1
12125
+ });
12126
+ section.photos.forEach((photo, p) => {
12127
+ items2.push({
12128
+ photo,
12129
+ index: i,
12130
+ sectionLabel: section.label,
12131
+ isSectionStart: p === 0
12132
+ });
12133
+ i += 1;
12134
+ });
12135
+ }
12136
+ return { items: items2, total: i, bounds: bounds2 };
12137
+ }, [sections]);
12138
+ const scrollRef = React20.useRef(null);
12139
+ const itemRefs = React20.useRef([]);
12140
+ const [active, setActive] = React20.useState(initialIndex);
12141
+ const activeLabel = React20.useMemo(
12142
+ () => {
12143
+ var _a2;
12144
+ return (_a2 = bounds.find((b) => active >= b.start && active <= b.end)) == null ? void 0 : _a2.label;
12145
+ },
12146
+ [bounds, active]
12147
+ );
12148
+ React20.useEffect(() => {
12149
+ const previous = document.body.style.overflow;
12150
+ document.body.style.overflow = "hidden";
12151
+ return () => {
12152
+ document.body.style.overflow = previous;
12153
+ };
12154
+ }, []);
12155
+ React20.useEffect(() => {
12156
+ const onKey = (e) => {
12157
+ if (e.key === "Escape") onClose();
12158
+ };
12159
+ document.addEventListener("keydown", onKey);
12160
+ return () => document.removeEventListener("keydown", onKey);
12161
+ }, [onClose]);
12162
+ React20.useEffect(() => {
12163
+ const root = scrollRef.current;
12164
+ if (!root) return;
12165
+ let frame = 0;
12166
+ let userMoved = false;
12167
+ const recompute = () => {
12168
+ var _a2;
12169
+ frame = 0;
12170
+ if (!userMoved) {
12171
+ (_a2 = itemRefs.current[initialIndex]) == null ? void 0 : _a2.scrollIntoView({ block: "start" });
12172
+ }
12173
+ const anchorY = root.getBoundingClientRect().top + 64;
12174
+ let current = 0;
12175
+ itemRefs.current.forEach((el, i) => {
12176
+ if (el && el.getBoundingClientRect().top <= anchorY) current = i;
12177
+ });
12178
+ if (root.scrollTop + root.clientHeight >= root.scrollHeight - 2) {
12179
+ current = total - 1;
12180
+ }
12181
+ setActive(current);
12182
+ };
12183
+ const schedule = () => {
12184
+ if (!frame) frame = requestAnimationFrame(recompute);
12185
+ };
12186
+ const onScroll = () => schedule();
12187
+ const onUserMove = () => {
12188
+ userMoved = true;
12189
+ };
12190
+ root.addEventListener("scroll", onScroll, { passive: true });
12191
+ root.addEventListener("wheel", onUserMove, { passive: true });
12192
+ root.addEventListener("touchmove", onUserMove, { passive: true });
12193
+ window.addEventListener("keydown", onUserMove);
12194
+ const ro = new ResizeObserver(schedule);
12195
+ itemRefs.current.forEach((el) => el && ro.observe(el));
12196
+ recompute();
12197
+ return () => {
12198
+ root.removeEventListener("scroll", onScroll);
12199
+ root.removeEventListener("wheel", onUserMove);
12200
+ root.removeEventListener("touchmove", onUserMove);
12201
+ window.removeEventListener("keydown", onUserMove);
12202
+ ro.disconnect();
12203
+ if (frame) cancelAnimationFrame(frame);
12204
+ };
12205
+ }, []);
12206
+ return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex flex-col bg-background", children: [
12207
+ /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-10 flex items-center gap-3 border-b border-border/60 bg-background/85 px-3 py-2.5 backdrop-blur-md", children: [
12208
+ /* @__PURE__ */ jsx(
12209
+ "button",
12210
+ {
12211
+ type: "button",
12212
+ onClick: onClose,
12213
+ className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
12214
+ "aria-label": (_a = labels == null ? void 0 : labels.close) != null ? _a : "Close lightbox",
12215
+ children: /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5" })
12216
+ }
12217
+ ),
12218
+ activeLabel && /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-center font-heading text-sm font-bold uppercase tracking-wide text-foreground", children: activeLabel }),
12219
+ total > 1 && /* @__PURE__ */ jsxs(
12220
+ "span",
12221
+ {
12222
+ className: cn(
12223
+ "shrink-0 font-ui text-sm font-medium tabular-nums text-muted-foreground",
12224
+ !activeLabel && "ml-auto"
12225
+ ),
12226
+ children: [
12227
+ active + 1,
12228
+ " / ",
12229
+ total
12230
+ ]
12231
+ }
12232
+ )
12233
+ ] }),
12234
+ /* @__PURE__ */ jsx(
12235
+ "div",
12236
+ {
12237
+ ref: scrollRef,
12238
+ className: "flex-1 overflow-y-auto overscroll-contain",
12239
+ children: /* @__PURE__ */ jsx("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-3 py-4", children: items.map(({ photo, index, sectionLabel, isSectionStart }) => {
12240
+ var _a2;
12241
+ return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
12242
+ sectionLabel && isSectionStart && /* @__PURE__ */ jsx(
12243
+ "h2",
12244
+ {
12245
+ className: cn(
12246
+ "px-3 font-heading text-lg font-bold uppercase tracking-wide text-foreground sm:px-4",
12247
+ index > 0 && "mt-3"
12248
+ ),
12249
+ children: sectionLabel
12250
+ }
12251
+ ),
12252
+ /* @__PURE__ */ jsxs(
12253
+ "figure",
12254
+ {
12255
+ "data-index": index,
12256
+ ref: (el) => {
12257
+ itemRefs.current[index] = el;
12258
+ },
12259
+ children: [
12260
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden bg-muted", children: /* @__PURE__ */ jsx(
12261
+ Picture,
12262
+ {
12263
+ src: photo.src,
12264
+ alt: (_a2 = photo.alt) != null ? _a2 : `Photo ${index + 1}`,
12265
+ title: photo.caption,
12266
+ className: "block h-auto w-full",
12267
+ eager: index < 2,
12268
+ rootMargin: "800px"
12269
+ }
12270
+ ) }),
12271
+ (photo.caption || photo.credit) && /* @__PURE__ */ jsxs("figcaption", { className: "px-3 pt-2 sm:px-4", children: [
12272
+ photo.caption && /* @__PURE__ */ jsx("p", { className: "font-ui text-sm leading-snug text-foreground/80", children: photo.caption }),
12273
+ photo.credit && /* @__PURE__ */ jsxs("p", { className: "font-ui text-xs text-muted-foreground", children: [
12274
+ "\xA9 ",
12275
+ photo.credit
12276
+ ] })
12277
+ ] })
12278
+ ]
12279
+ }
12280
+ )
12281
+ ] }, index);
12282
+ }) })
12283
+ }
12284
+ )
12285
+ ] });
12286
+ }
12287
+ var PhotoTourContext = React20.createContext(null);
12288
+ function PhotoTourProvider({
12289
+ enabled = true,
12290
+ labels,
12291
+ children
12292
+ }) {
12293
+ const entries = React20.useRef(/* @__PURE__ */ new Map());
12294
+ const [open, setOpen] = React20.useState(null);
12295
+ const register = React20.useCallback((entry) => {
12296
+ entries.current.set(entry.id, entry);
12297
+ }, []);
12298
+ const unregister = React20.useCallback((id) => {
12299
+ entries.current.delete(id);
12300
+ }, []);
12301
+ const openTour = React20.useCallback((id, localIndex) => {
12302
+ var _a, _b;
12303
+ const ordered = [...entries.current.values()].filter((e) => e.photos.length).sort((a, b) => {
12304
+ const ea = a.getEl();
12305
+ const eb = b.getEl();
12306
+ if (!ea || !eb) return 0;
12307
+ const pos = ea.compareDocumentPosition(eb);
12308
+ if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
12309
+ if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;
12310
+ return 0;
12311
+ });
12312
+ const targetSrc = (_b = (_a = entries.current.get(id)) == null ? void 0 : _a.photos[localIndex]) == null ? void 0 : _b.src;
12313
+ const seen = /* @__PURE__ */ new Set();
12314
+ const sections = [];
12315
+ for (const entry of ordered) {
12316
+ const photos = entry.photos.filter((p) => {
12317
+ if (seen.has(p.src)) return false;
12318
+ seen.add(p.src);
12319
+ return true;
12320
+ });
12321
+ if (!photos.length) continue;
12322
+ const prev = sections[sections.length - 1];
12323
+ if (prev && prev.label === entry.label) {
12324
+ prev.photos.push(...photos);
12325
+ } else {
12326
+ sections.push({ label: entry.label, photos: [...photos] });
12327
+ }
12328
+ }
12329
+ let index = 0;
12330
+ let running = 0;
12331
+ let done = false;
12332
+ for (const section of sections) {
12333
+ for (const photo of section.photos) {
12334
+ if (photo.src === targetSrc) {
12335
+ index = running;
12336
+ done = true;
12337
+ break;
12338
+ }
12339
+ running += 1;
12340
+ }
12341
+ if (done) break;
12342
+ }
12343
+ setOpen({ sections, index });
12344
+ }, []);
12345
+ const value = React20.useMemo(
12346
+ () => ({ enabled, register, unregister, open: openTour }),
12347
+ [enabled, register, unregister, openTour]
12348
+ );
12349
+ return /* @__PURE__ */ jsxs(PhotoTourContext.Provider, { value, children: [
12350
+ children,
12351
+ open && /* @__PURE__ */ jsx(
12352
+ FeedLightbox,
12353
+ {
12354
+ sections: open.sections,
12355
+ initialIndex: open.index,
12356
+ labels,
12357
+ onClose: () => setOpen(null)
12358
+ }
12359
+ )
12360
+ ] });
12361
+ }
12108
12362
  function PhotoTile({
12109
12363
  photo,
12110
12364
  index,
@@ -12177,7 +12431,7 @@ function GridGallery({
12177
12431
  onOpen,
12178
12432
  labels
12179
12433
  }) {
12180
- const [expanded, setExpanded] = React32.useState(false);
12434
+ const [expanded, setExpanded] = React20.useState(false);
12181
12435
  const cols = gridCols(photos.length);
12182
12436
  const hasMore = photos.length > initialVisible;
12183
12437
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
@@ -12209,7 +12463,7 @@ function CompactGridGallery({
12209
12463
  onOpen,
12210
12464
  labels
12211
12465
  }) {
12212
- const [expanded, setExpanded] = React32.useState(false);
12466
+ const [expanded, setExpanded] = React20.useState(false);
12213
12467
  const hasMore = photos.length > initialVisible;
12214
12468
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
12215
12469
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -12240,7 +12494,7 @@ function MasonryGallery({
12240
12494
  onOpen,
12241
12495
  labels
12242
12496
  }) {
12243
- const [expanded, setExpanded] = React32.useState(false);
12497
+ const [expanded, setExpanded] = React20.useState(false);
12244
12498
  const hasMore = photos.length > initialVisible;
12245
12499
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
12246
12500
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -12317,7 +12571,7 @@ function FeaturedGallery({
12317
12571
  onOpen,
12318
12572
  labels
12319
12573
  }) {
12320
- const [expanded, setExpanded] = React32.useState(false);
12574
+ const [expanded, setExpanded] = React20.useState(false);
12321
12575
  const featured = photos.slice(0, 3);
12322
12576
  const extra = photos.slice(3);
12323
12577
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -12432,11 +12686,33 @@ function CarouselGallery({
12432
12686
  const photo = photos[index];
12433
12687
  const prev = () => onIndexChange((index - 1 + total) % total);
12434
12688
  const next = () => onIndexChange((index + 1) % total);
12689
+ const touchStart = React20.useRef(null);
12690
+ const swiped = React20.useRef(false);
12691
+ const onTouchStart = (e) => {
12692
+ const t = e.touches[0];
12693
+ touchStart.current = { x: t.clientX, y: t.clientY };
12694
+ swiped.current = false;
12695
+ };
12696
+ const onTouchEnd = (e) => {
12697
+ const start = touchStart.current;
12698
+ touchStart.current = null;
12699
+ if (!start || total <= 1) return;
12700
+ const t = e.changedTouches[0];
12701
+ const dx = t.clientX - start.x;
12702
+ const dy = t.clientY - start.y;
12703
+ if (Math.abs(dx) > 40 && Math.abs(dx) > Math.abs(dy)) {
12704
+ swiped.current = true;
12705
+ if (dx < 0) next();
12706
+ else prev();
12707
+ }
12708
+ };
12435
12709
  return /* @__PURE__ */ jsxs(
12436
12710
  "div",
12437
12711
  {
12712
+ onTouchStart,
12713
+ onTouchEnd,
12438
12714
  className: cn(
12439
- "relative w-full aspect-[4/3] sm:aspect-[16/10] overflow-hidden bg-muted group/photo",
12715
+ "relative w-full aspect-[4/3] sm:aspect-[16/10] overflow-hidden bg-muted group/photo touch-pan-y select-none",
12440
12716
  className
12441
12717
  ),
12442
12718
  children: [
@@ -12444,7 +12720,13 @@ function CarouselGallery({
12444
12720
  "button",
12445
12721
  {
12446
12722
  type: "button",
12447
- onClick: () => onOpen(index),
12723
+ onClick: () => {
12724
+ if (swiped.current) {
12725
+ swiped.current = false;
12726
+ return;
12727
+ }
12728
+ onOpen(index);
12729
+ },
12448
12730
  "aria-label": `Open photo ${index + 1} fullscreen`,
12449
12731
  className: "absolute inset-0 w-full h-full cursor-zoom-in focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
12450
12732
  children: /* @__PURE__ */ jsx(
@@ -12517,17 +12799,46 @@ function PhotoGallery({
12517
12799
  initialVisible = 6,
12518
12800
  onPhotoClick,
12519
12801
  labels,
12802
+ lightbox: lightboxMode = "classic",
12803
+ tourSection,
12520
12804
  className
12521
12805
  }) {
12522
- const [lightboxIndex, setLightboxIndex] = React32.useState(null);
12523
- const [carouselIndex, setCarouselIndex] = React32.useState(0);
12524
- const normalised = React32.useMemo(() => photos.map(normalise), [photos]);
12806
+ const [lightboxIndex, setLightboxIndex] = React20.useState(null);
12807
+ const [carouselIndex, setCarouselIndex] = React20.useState(0);
12808
+ const normalised = React20.useMemo(() => photos.map(normalise), [photos]);
12809
+ const tour = React20.useContext(PhotoTourContext);
12810
+ const tourId = React20.useId();
12811
+ const markerRef = React20.useRef(null);
12812
+ const inTour = !!((tour == null ? void 0 : tour.enabled) && tourSection);
12813
+ React20.useEffect(() => {
12814
+ if (!inTour || !tour) return;
12815
+ tour.register({
12816
+ id: tourId,
12817
+ label: tourSection,
12818
+ getEl: () => markerRef.current,
12819
+ photos: normalised
12820
+ });
12821
+ return () => tour.unregister(tourId);
12822
+ }, [inTour, tour, tourId, tourSection, normalised]);
12525
12823
  const handleOpen = (index) => {
12526
- setLightboxIndex(index);
12527
12824
  onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
12825
+ if (inTour && tour) {
12826
+ tour.open(tourId, index);
12827
+ return;
12828
+ }
12829
+ setLightboxIndex(index);
12528
12830
  };
12529
12831
  if (normalised.length === 0) return null;
12530
- const lightbox = lightboxIndex !== null && /* @__PURE__ */ jsx(
12832
+ const tourMarker = inTour && /* @__PURE__ */ jsx("span", { ref: markerRef, "aria-hidden": true, className: "hidden" });
12833
+ const lightbox = lightboxIndex !== null && (lightboxMode === "feed" ? /* @__PURE__ */ jsx(
12834
+ FeedLightbox,
12835
+ {
12836
+ sections: [{ photos: normalised }],
12837
+ initialIndex: lightboxIndex,
12838
+ onClose: () => setLightboxIndex(null),
12839
+ labels
12840
+ }
12841
+ ) : /* @__PURE__ */ jsx(
12531
12842
  Lightbox,
12532
12843
  {
12533
12844
  photos: normalised,
@@ -12535,9 +12846,10 @@ function PhotoGallery({
12535
12846
  onClose: () => setLightboxIndex(null),
12536
12847
  labels
12537
12848
  }
12538
- );
12849
+ ));
12539
12850
  if (variant === "carousel" || variant === "fullBleed") {
12540
12851
  return /* @__PURE__ */ jsxs(Fragment, { children: [
12852
+ tourMarker,
12541
12853
  /* @__PURE__ */ jsx(
12542
12854
  CarouselGallery,
12543
12855
  {
@@ -12556,6 +12868,7 @@ function PhotoGallery({
12556
12868
  ] });
12557
12869
  }
12558
12870
  return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
12871
+ tourMarker,
12559
12872
  variant === "grid" && /* @__PURE__ */ jsx(
12560
12873
  GridGallery,
12561
12874
  {
@@ -12611,14 +12924,15 @@ function ItineraryDay({
12611
12924
  photoLayout = "rounded",
12612
12925
  className
12613
12926
  }) {
12614
- const photoList = React32.useMemo(() => normalisePhotos(photos), [photos]);
12927
+ const photoList = React20.useMemo(() => normalisePhotos(photos), [photos]);
12615
12928
  const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
12616
12929
  const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
12617
12930
  const gallery = photoList.length > 0 && /* @__PURE__ */ jsx(
12618
12931
  PhotoGallery,
12619
12932
  {
12620
12933
  photos: photoList,
12621
- variant: isFullBleed ? "fullBleed" : "carousel"
12934
+ variant: isFullBleed ? "fullBleed" : "carousel",
12935
+ tourSection: dayLabel != null ? dayLabel : `Day ${dayNumber}`
12622
12936
  }
12623
12937
  );
12624
12938
  return /* @__PURE__ */ jsxs("article", { className: cn("w-full flex flex-col gap-5", className), children: [
@@ -12666,8 +12980,8 @@ function MenuTrip({
12666
12980
  bold = true,
12667
12981
  className
12668
12982
  }) {
12669
- const scrollRef = React32.useRef(null);
12670
- React32.useEffect(() => {
12983
+ const scrollRef = React20.useRef(null);
12984
+ React20.useEffect(() => {
12671
12985
  if (!scrollRef.current || !activeSection) return;
12672
12986
  const container = scrollRef.current;
12673
12987
  const btn = container.querySelector(
@@ -12865,8 +13179,8 @@ function PricingTrip({
12865
13179
  className
12866
13180
  }) {
12867
13181
  const rOuter = sharp ? "rounded-none" : "rounded-2xl";
12868
- const [showEstimates, setShowEstimates] = React32.useState(false);
12869
- const [showPriceInfo, setShowPriceInfo] = React32.useState(false);
13182
+ const [showEstimates, setShowEstimates] = React20.useState(false);
13183
+ const [showPriceInfo, setShowPriceInfo] = React20.useState(false);
12870
13184
  if (variant === "compact") {
12871
13185
  const showOverlay = showPriceInfo && (!!priceInfo || !!currencyEstimates && currencyEstimates.length > 0);
12872
13186
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -13302,6 +13616,7 @@ function SiteHeader({
13302
13616
  logoSrcDark = "/logo-planetaexo-green.png",
13303
13617
  logoSrc,
13304
13618
  logoAlt = "Planeta Exo",
13619
+ logoHref = "#",
13305
13620
  languages = DEFAULT_LANGUAGES,
13306
13621
  currentLanguage = "EN",
13307
13622
  onLanguageChange,
@@ -13314,14 +13629,14 @@ function SiteHeader({
13314
13629
  var _a, _b, _c, _d, _e, _f, _g;
13315
13630
  const t = VARIANT[variant];
13316
13631
  const resolvedLogo = logoSrc != null ? logoSrc : variant === "white" ? logoSrcDark : logoSrcLight;
13317
- const [openMenu, setOpenMenu] = React32.useState(null);
13318
- const [langOpen, setLangOpen] = React32.useState(false);
13319
- const [mobileOpen, setMobileOpen] = React32.useState(false);
13320
- const [openMobileSection, setOpenMobileSection] = React32.useState(null);
13321
- const [activeLang, setActiveLang] = React32.useState(currentLanguage);
13632
+ const [openMenu, setOpenMenu] = React20.useState(null);
13633
+ const [langOpen, setLangOpen] = React20.useState(false);
13634
+ const [mobileOpen, setMobileOpen] = React20.useState(false);
13635
+ const [openMobileSection, setOpenMobileSection] = React20.useState(null);
13636
+ const [activeLang, setActiveLang] = React20.useState(currentLanguage);
13322
13637
  const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
13323
- const menuCloseTimer = React32.useRef(void 0);
13324
- const langCloseTimer = React32.useRef(void 0);
13638
+ const menuCloseTimer = React20.useRef(void 0);
13639
+ const langCloseTimer = React20.useRef(void 0);
13325
13640
  const handleMenuEnter = (label) => {
13326
13641
  clearTimeout(menuCloseTimer.current);
13327
13642
  setOpenMenu(label);
@@ -13342,7 +13657,7 @@ function SiteHeader({
13342
13657
  setOpenMenu(null);
13343
13658
  setLangOpen(false);
13344
13659
  };
13345
- React32.useEffect(() => () => {
13660
+ React20.useEffect(() => () => {
13346
13661
  clearTimeout(menuCloseTimer.current);
13347
13662
  clearTimeout(langCloseTimer.current);
13348
13663
  }, []);
@@ -13380,7 +13695,7 @@ function SiteHeader({
13380
13695
  /* @__PURE__ */ jsx(
13381
13696
  "a",
13382
13697
  {
13383
- href: "#",
13698
+ href: logoHref,
13384
13699
  className: cn(
13385
13700
  "shrink-0 flex items-center",
13386
13701
  "absolute left-1/2 -translate-x-1/2",
@@ -13532,7 +13847,7 @@ function SiteHeader({
13532
13847
  ),
13533
13848
  children: [
13534
13849
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 h-[72px] shrink-0 border-b border-white/8", children: [
13535
- /* @__PURE__ */ jsx("a", { href: "#", className: "shrink-0 flex items-center", onClick: () => setMobileOpen(false), children: /* @__PURE__ */ jsx(
13850
+ /* @__PURE__ */ jsx("a", { href: logoHref, className: "shrink-0 flex items-center", onClick: () => setMobileOpen(false), children: /* @__PURE__ */ jsx(
13536
13851
  "img",
13537
13852
  {
13538
13853
  src: resolvedLogo,
@@ -13618,7 +13933,7 @@ function SiteHeader({
13618
13933
  ), children: [
13619
13934
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
13620
13935
  const isActive = lang.code === activeLang;
13621
- return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
13936
+ return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
13622
13937
  i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
13623
13938
  "text-xs select-none",
13624
13939
  variant === "white" ? "text-border" : "text-white/15"
@@ -13680,8 +13995,8 @@ function SiteHeader({
13680
13995
  );
13681
13996
  }
13682
13997
  function ThemeToggle({ className }) {
13683
- const [dark, setDark] = React32.useState(false);
13684
- React32.useEffect(() => {
13998
+ const [dark, setDark] = React20.useState(false);
13999
+ React20.useEffect(() => {
13685
14000
  const saved = localStorage.getItem("theme");
13686
14001
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
13687
14002
  const isDark = saved === "dark" || !saved && prefersDark;
@@ -13731,7 +14046,7 @@ var chipVariants = cva(
13731
14046
  }
13732
14047
  }
13733
14048
  );
13734
- var Chip = React32.forwardRef(function Chip2(_a, ref) {
14049
+ var Chip = React20.forwardRef(function Chip2(_a, ref) {
13735
14050
  var _b = _a, { className, variant, size, href, children } = _b, props = __objRest(_b, ["className", "variant", "size", "href", "children"]);
13736
14051
  const classes = cn(chipVariants({ variant, size }), className);
13737
14052
  if (href) {
@@ -13798,6 +14113,19 @@ var statusConfig = {
13798
14113
  icon: /* @__PURE__ */ jsx(TrendingIcon, {})
13799
14114
  }
13800
14115
  };
14116
+ function StarIcon() {
14117
+ return /* @__PURE__ */ jsx(
14118
+ "svg",
14119
+ {
14120
+ width: "15",
14121
+ height: "15",
14122
+ viewBox: "0 0 24 24",
14123
+ fill: "currentColor",
14124
+ "aria-hidden": "true",
14125
+ children: /* @__PURE__ */ jsx("path", { d: "M12 17.27l-5.4 3.27 1.43-6.16-4.78-4.14 6.3-.54L12 4l2.45 5.7 6.3.54-4.78 4.14 1.43 6.16z" })
14126
+ }
14127
+ );
14128
+ }
13801
14129
  function HeartIcon({ filled = false }) {
13802
14130
  return /* @__PURE__ */ jsx(
13803
14131
  "svg",
@@ -13815,7 +14143,7 @@ function HeartIcon({ filled = false }) {
13815
14143
  );
13816
14144
  }
13817
14145
  function TripCardEditorial(props) {
13818
- var _a, _b, _c, _d;
14146
+ var _a, _b, _c, _d, _e, _f;
13819
14147
  const {
13820
14148
  image,
13821
14149
  imageAlt = "",
@@ -13832,10 +14160,14 @@ function TripCardEditorial(props) {
13832
14160
  location,
13833
14161
  locationHref,
13834
14162
  difficulty,
14163
+ rating,
14164
+ reviewCount,
13835
14165
  tag,
13836
14166
  tagHref
13837
14167
  } = props;
13838
- const [internalFav, setInternalFav] = React32.useState(false);
14168
+ const hasRating = typeof rating === "number" && rating > 0;
14169
+ const reviewsWord = reviewCount === 1 ? (_a = labels == null ? void 0 : labels.review) != null ? _a : "review" : (_b = labels == null ? void 0 : labels.reviews) != null ? _b : "reviews";
14170
+ const [internalFav, setInternalFav] = React20.useState(false);
13839
14171
  const favorited = favoritedProp != null ? favoritedProp : internalFav;
13840
14172
  const handleFav = (e) => {
13841
14173
  e.preventDefault();
@@ -13877,7 +14209,7 @@ function TripCardEditorial(props) {
13877
14209
  "button",
13878
14210
  {
13879
14211
  type: "button",
13880
- "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",
14212
+ "aria-label": favorited ? (_c = labels == null ? void 0 : labels.removeFromFavorites) != null ? _c : "Remove from favorites" : (_d = labels == null ? void 0 : labels.addToFavorites) != null ? _d : "Add to favorites",
13881
14213
  "aria-pressed": favorited,
13882
14214
  onClick: handleFav,
13883
14215
  className: cn(
@@ -13891,7 +14223,24 @@ function TripCardEditorial(props) {
13891
14223
  ),
13892
14224
  /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 bottom-0 p-5 text-white", children: /* @__PURE__ */ jsx("h3", { className: "text-lg sm:text-xl font-bold font-heading leading-tight", children: title }) })
13893
14225
  ] }),
13894
- (description || price || nights || location || difficulty) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 bg-card p-6", children: [
14226
+ (description || price || nights || location || difficulty || hasRating) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 bg-card p-6", children: [
14227
+ hasRating && /* @__PURE__ */ jsxs(
14228
+ "div",
14229
+ {
14230
+ className: "flex items-center gap-1.5 text-foreground/85",
14231
+ "aria-label": reviewCount ? `${rating.toFixed(1)} (${reviewCount} ${reviewsWord})` : `${rating.toFixed(1)}`,
14232
+ children: [
14233
+ /* @__PURE__ */ jsx("span", { className: "text-amber-500", children: /* @__PURE__ */ jsx(StarIcon, {}) }),
14234
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-ui font-semibold", children: rating.toFixed(1) }),
14235
+ reviewCount ? /* @__PURE__ */ jsxs("span", { className: "text-xs font-ui text-muted-foreground", children: [
14236
+ "\xB7 ",
14237
+ reviewCount,
14238
+ " ",
14239
+ reviewsWord
14240
+ ] }) : null
14241
+ ]
14242
+ }
14243
+ ),
13895
14244
  (location || difficulty) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
13896
14245
  location ? locationHref ? (
13897
14246
  // Above the card's stretched link (z-20) so the location is
@@ -13921,7 +14270,7 @@ function TripCardEditorial(props) {
13921
14270
  /* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
13922
14271
  nights,
13923
14272
  " ",
13924
- nights === 1 ? (_c = labels == null ? void 0 : labels.night) != null ? _c : "night" : (_d = labels == null ? void 0 : labels.nights) != null ? _d : "nights"
14273
+ nights === 1 ? (_e = labels == null ? void 0 : labels.night) != null ? _e : "night" : (_f = labels == null ? void 0 : labels.nights) != null ? _f : "nights"
13925
14274
  ] })
13926
14275
  ] }) : /* @__PURE__ */ jsx("span", {}),
13927
14276
  price && /* @__PURE__ */ jsx("p", { className: "text-base font-bold text-foreground font-ui", children: price })
@@ -14350,7 +14699,7 @@ function BlogPost({
14350
14699
  ) }),
14351
14700
  /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/90 via-black/45 to-transparent" }),
14352
14701
  /* @__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: [
14353
- 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: [
14702
+ 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(React20.Fragment, { children: [
14354
14703
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
14355
14704
  crumb.href ? /* @__PURE__ */ jsx(
14356
14705
  "a",
@@ -14404,7 +14753,7 @@ function BlogPost({
14404
14753
  ] });
14405
14754
  }
14406
14755
  function useHlsVideo(videoRef, src) {
14407
- React32.useEffect(() => {
14756
+ React20.useEffect(() => {
14408
14757
  if (!src || !videoRef.current) return;
14409
14758
  const video = videoRef.current;
14410
14759
  if (!src.includes(".m3u8")) return;
@@ -14450,11 +14799,11 @@ function TripHeader({
14450
14799
  className
14451
14800
  }) {
14452
14801
  var _a, _b, _c, _d, _e, _f, _g;
14453
- const [heroIndex, setHeroIndex] = React32.useState(0);
14454
- const [videoReady, setVideoReady] = React32.useState(false);
14455
- const videoRef = React32.useRef(null);
14802
+ const [heroIndex, setHeroIndex] = React20.useState(0);
14803
+ const [videoReady, setVideoReady] = React20.useState(false);
14804
+ const videoRef = React20.useRef(null);
14456
14805
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
14457
- const validImages = React32.useMemo(
14806
+ const validImages = React20.useMemo(
14458
14807
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
14459
14808
  [images]
14460
14809
  );
@@ -14469,7 +14818,7 @@ function TripHeader({
14469
14818
  const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
14470
14819
  const hasMeta = !!(destination || duration || groupSize);
14471
14820
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
14472
- React32.useEffect(() => {
14821
+ React20.useEffect(() => {
14473
14822
  if (!videoUrl) return;
14474
14823
  const el = videoRef.current;
14475
14824
  if (!el) return;
@@ -14612,7 +14961,7 @@ function TripHeader({
14612
14961
  chips && chips.length > 0 ? siteHeader ? "-mt-[200px] sm:-mt-[214px]" : "-mt-[168px] sm:-mt-[182px]" : siteHeader ? "-mt-44" : "-mt-36"
14613
14962
  ),
14614
14963
  children: [
14615
- 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: [
14964
+ 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(React20.Fragment, { children: [
14616
14965
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
14617
14966
  /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
14618
14967
  ] }, i)) }),
@@ -14782,10 +15131,10 @@ function LanguagePicker({
14782
15131
  }) {
14783
15132
  var _a;
14784
15133
  const t = VARIANT2[variant];
14785
- const [open, setOpen] = React32.useState(false);
14786
- const ref = React32.useRef(null);
15134
+ const [open, setOpen] = React20.useState(false);
15135
+ const ref = React20.useRef(null);
14787
15136
  const active = (_a = languages.find((l) => l.code === currentLanguage)) != null ? _a : languages[0];
14788
- React32.useEffect(() => {
15137
+ React20.useEffect(() => {
14789
15138
  if (!open) return;
14790
15139
  const onDocClick = (e) => {
14791
15140
  if (ref.current && !ref.current.contains(e.target)) {
@@ -14993,7 +15342,7 @@ function SiteFooter({
14993
15342
  children: wrapper
14994
15343
  },
14995
15344
  b.alt + i
14996
- ) : /* @__PURE__ */ jsx(React32.Fragment, { children: wrapper }, b.alt + i);
15345
+ ) : /* @__PURE__ */ jsx(React20.Fragment, { children: wrapper }, b.alt + i);
14997
15346
  }) })
14998
15347
  ] }),
14999
15348
  themes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "lg:col-span-3", children: [
@@ -15081,7 +15430,7 @@ function SiteFooter({
15081
15430
  }
15082
15431
  function Stars({ count = 5 }) {
15083
15432
  return /* @__PURE__ */ jsx("span", { className: "flex gap-0.5", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx(
15084
- StarIcon,
15433
+ StarIcon$1,
15085
15434
  {
15086
15435
  className: cn(
15087
15436
  "h-3.5 w-3.5",
@@ -15135,6 +15484,7 @@ function TripPage({
15135
15484
  itinerary,
15136
15485
  itineraryDays,
15137
15486
  gallery,
15487
+ galleryLightbox = "classic",
15138
15488
  included,
15139
15489
  notIncluded,
15140
15490
  whatToBring,
@@ -15174,15 +15524,16 @@ function TripPage({
15174
15524
  fromLabel,
15175
15525
  perPersonLabel,
15176
15526
  siteHeader,
15527
+ footerBadges,
15177
15528
  uiVariant = "v1",
15178
15529
  features,
15179
15530
  className
15180
15531
  }) {
15181
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
15182
- const [activeSection, setActiveSection] = React32.useState("");
15183
- const [accordionValue, setAccordionValue] = React32.useState([]);
15184
- const [faqsExpanded, setFaqsExpanded] = React32.useState(false);
15185
- const accordionSectionIds = React32.useMemo(
15532
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
15533
+ const [activeSection, setActiveSection] = React20.useState("");
15534
+ const [accordionValue, setAccordionValue] = React20.useState([]);
15535
+ const [faqsExpanded, setFaqsExpanded] = React20.useState(false);
15536
+ const accordionSectionIds = React20.useMemo(
15186
15537
  () => /* @__PURE__ */ new Set([
15187
15538
  "when-it-operates",
15188
15539
  "how-to-get-there",
@@ -15196,18 +15547,18 @@ function TripPage({
15196
15547
  ]),
15197
15548
  []
15198
15549
  );
15199
- const [navFloating, setNavFloating] = React32.useState(false);
15200
- const [navHidden, setNavHidden] = React32.useState(false);
15201
- const [isFloating, setIsFloating] = React32.useState(false);
15202
- const [sidebarPos, setSidebarPos] = React32.useState(null);
15203
- const [pricingBarVisible, setPricingBarVisible] = React32.useState(false);
15204
- const navRef = React32.useRef(null);
15205
- const navSentinelRef = React32.useRef(null);
15206
- const sentinelRef = React32.useRef(null);
15207
- const sidebarPlaceholderRef = React32.useRef(null);
15208
- const pricingBarRef = React32.useRef(null);
15209
- const galleryRef = React32.useRef(null);
15210
- const sections = React32.useMemo(
15550
+ const [navFloating, setNavFloating] = React20.useState(false);
15551
+ const [navHidden, setNavHidden] = React20.useState(false);
15552
+ const [isFloating, setIsFloating] = React20.useState(false);
15553
+ const [sidebarPos, setSidebarPos] = React20.useState(null);
15554
+ const [pricingBarVisible, setPricingBarVisible] = React20.useState(false);
15555
+ const navRef = React20.useRef(null);
15556
+ const navSentinelRef = React20.useRef(null);
15557
+ const sentinelRef = React20.useRef(null);
15558
+ const sidebarPlaceholderRef = React20.useRef(null);
15559
+ const pricingBarRef = React20.useRef(null);
15560
+ const galleryRef = React20.useRef(null);
15561
+ const sections = React20.useMemo(
15211
15562
  () => {
15212
15563
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
15213
15564
  return [
@@ -15229,7 +15580,7 @@ function TripPage({
15229
15580
  // eslint-disable-next-line react-hooks/exhaustive-deps
15230
15581
  []
15231
15582
  );
15232
- React32.useEffect(() => {
15583
+ React20.useEffect(() => {
15233
15584
  const sentinel = navSentinelRef.current;
15234
15585
  if (!sentinel) return;
15235
15586
  const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
@@ -15237,7 +15588,7 @@ function TripPage({
15237
15588
  update();
15238
15589
  return () => document.removeEventListener("scroll", update, { capture: true });
15239
15590
  }, []);
15240
- React32.useEffect(() => {
15591
+ React20.useEffect(() => {
15241
15592
  const sentinel = sentinelRef.current;
15242
15593
  if (!sentinel) return;
15243
15594
  const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
@@ -15245,7 +15596,7 @@ function TripPage({
15245
15596
  update();
15246
15597
  return () => document.removeEventListener("scroll", update, { capture: true });
15247
15598
  }, []);
15248
- React32.useEffect(() => {
15599
+ React20.useEffect(() => {
15249
15600
  const measure = () => {
15250
15601
  if (!sidebarPlaceholderRef.current) return;
15251
15602
  const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
@@ -15255,7 +15606,7 @@ function TripPage({
15255
15606
  window.addEventListener("resize", measure);
15256
15607
  return () => window.removeEventListener("resize", measure);
15257
15608
  }, [isFloating]);
15258
- React32.useEffect(() => {
15609
+ React20.useEffect(() => {
15259
15610
  const check = () => {
15260
15611
  var _a2;
15261
15612
  const target = (_a2 = galleryRef.current) != null ? _a2 : pricingBarRef.current;
@@ -15266,7 +15617,7 @@ function TripPage({
15266
15617
  check();
15267
15618
  return () => document.removeEventListener("scroll", check, { capture: true });
15268
15619
  }, []);
15269
- React32.useEffect(() => {
15620
+ React20.useEffect(() => {
15270
15621
  const check = () => {
15271
15622
  if (!pricingBarRef.current) return;
15272
15623
  setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
@@ -15275,7 +15626,7 @@ function TripPage({
15275
15626
  check();
15276
15627
  return () => document.removeEventListener("scroll", check, { capture: true });
15277
15628
  }, []);
15278
- React32.useEffect(() => {
15629
+ React20.useEffect(() => {
15279
15630
  if (sections.length === 0) return;
15280
15631
  setActiveSection(sections[0].id);
15281
15632
  const update = () => {
@@ -15333,468 +15684,483 @@ function TripPage({
15333
15684
  }
15334
15685
  performScroll();
15335
15686
  };
15336
- return /* @__PURE__ */ jsxs(
15337
- "div",
15687
+ return /* @__PURE__ */ jsx(
15688
+ PhotoTourProvider,
15338
15689
  {
15339
- className: cn("w-full overflow-x-hidden", className),
15340
- "data-ui-variant": uiVariant,
15341
- "data-features": features ? JSON.stringify(features) : void 0,
15342
- children: [
15343
- /* @__PURE__ */ jsx(
15344
- TripHeader,
15345
- {
15346
- images,
15347
- videoUrl,
15348
- title,
15349
- breadcrumb,
15350
- destination,
15351
- duration,
15352
- groupSize,
15353
- labels: {
15354
- night: labels == null ? void 0 : labels.night,
15355
- nights: labels == null ? void 0 : labels.nights,
15356
- day: labels == null ? void 0 : labels.day,
15357
- days: labels == null ? void 0 : labels.days,
15358
- previousImage: labels == null ? void 0 : labels.previousImage,
15359
- nextImage: labels == null ? void 0 : labels.nextImage
15360
- },
15361
- tagline,
15362
- chips,
15363
- siteHeader,
15364
- uiVariant,
15365
- belowMeta: trustpilotHero ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotHero }) : void 0
15366
- }
15367
- ),
15368
- /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
15369
- highlights && highlights.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6 flex flex-wrap justify-center gap-6 py-2", children: highlights.map((h, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
15370
- h.icon && /* @__PURE__ */ jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full border-2 border-border text-foreground", children: h.icon }),
15371
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground font-ui", children: h.label })
15372
- ] }, i)) }),
15373
- /* @__PURE__ */ jsx("div", { ref: navSentinelRef, className: "h-px", "aria-hidden": true }),
15374
- sections.length > 0 ? /* @__PURE__ */ jsx(
15375
- "div",
15376
- {
15377
- className: cn(
15378
- "pt-8 pb-2 flex justify-center transition-opacity duration-150",
15379
- navFloating ? "opacity-0 pointer-events-none" : "opacity-100"
15380
- ),
15381
- children: /* @__PURE__ */ jsx(
15382
- MenuTrip,
15690
+ enabled: galleryLightbox === "feed",
15691
+ labels: {
15692
+ close: labels == null ? void 0 : labels.galleryClose,
15693
+ previous: labels == null ? void 0 : labels.galleryPrevious,
15694
+ next: labels == null ? void 0 : labels.galleryNext
15695
+ },
15696
+ children: /* @__PURE__ */ jsxs(
15697
+ "div",
15698
+ {
15699
+ className: cn("w-full overflow-x-hidden", className),
15700
+ "data-ui-variant": uiVariant,
15701
+ "data-features": features ? JSON.stringify(features) : void 0,
15702
+ children: [
15703
+ /* @__PURE__ */ jsx(
15704
+ TripHeader,
15705
+ {
15706
+ images,
15707
+ videoUrl,
15708
+ title,
15709
+ breadcrumb,
15710
+ destination,
15711
+ duration,
15712
+ groupSize,
15713
+ labels: {
15714
+ night: labels == null ? void 0 : labels.night,
15715
+ nights: labels == null ? void 0 : labels.nights,
15716
+ day: labels == null ? void 0 : labels.day,
15717
+ days: labels == null ? void 0 : labels.days,
15718
+ previousImage: labels == null ? void 0 : labels.previousImage,
15719
+ nextImage: labels == null ? void 0 : labels.nextImage
15720
+ },
15721
+ tagline,
15722
+ chips,
15723
+ siteHeader,
15724
+ uiVariant,
15725
+ belowMeta: trustpilotHero ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotHero }) : void 0
15726
+ }
15727
+ ),
15728
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
15729
+ highlights && highlights.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6 flex flex-wrap justify-center gap-6 py-2", children: highlights.map((h, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
15730
+ h.icon && /* @__PURE__ */ jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full border-2 border-border text-foreground", children: h.icon }),
15731
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground font-ui", children: h.label })
15732
+ ] }, i)) }),
15733
+ /* @__PURE__ */ jsx("div", { ref: navSentinelRef, className: "h-px", "aria-hidden": true }),
15734
+ sections.length > 0 ? /* @__PURE__ */ jsx(
15735
+ "div",
15383
15736
  {
15384
- sections,
15385
- activeSection,
15386
- onSelect: scrollToSection,
15387
- variant: "floating"
15737
+ className: cn(
15738
+ "pt-8 pb-2 flex justify-center transition-opacity duration-150",
15739
+ navFloating ? "opacity-0 pointer-events-none" : "opacity-100"
15740
+ ),
15741
+ children: /* @__PURE__ */ jsx(
15742
+ MenuTrip,
15743
+ {
15744
+ sections,
15745
+ activeSection,
15746
+ onSelect: scrollToSection,
15747
+ variant: "floating"
15748
+ }
15749
+ )
15388
15750
  }
15389
- )
15390
- }
15391
- ) : /* @__PURE__ */ jsx(Separator, { className: "my-6" }),
15392
- /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: "h-px -mt-px", "aria-hidden": true }),
15393
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row gap-8 mt-4", children: [
15394
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 space-y-12 pb-12", children: [
15395
- (overview || (overviewHighlights == null ? void 0 : overviewHighlights.length)) && /* @__PURE__ */ jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
15396
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-4", children: (_a = labels == null ? void 0 : labels.overview) != null ? _a : "Overview" }),
15397
- overview && /* @__PURE__ */ jsx("div", { className: "text-lg text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview }),
15398
- overviewHighlights && overviewHighlights.length > 0 && /* @__PURE__ */ jsx("ul", { className: cn("flex flex-col gap-5", overview && "mt-8"), children: overviewHighlights.map((h, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-4", children: [
15399
- h.icon && /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center text-foreground [&_svg]:h-8 [&_svg]:w-8", children: h.icon }),
15400
- /* @__PURE__ */ jsx("div", { className: "flex-1 pt-1 text-base text-foreground leading-relaxed [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: h.description })
15401
- ] }, i)) }),
15402
- recommendedFor && /* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-start gap-2.5 rounded-xl bg-primary/8 border border-primary/20 p-4", children: [
15403
- /* @__PURE__ */ jsx(UsersIcon, { className: "h-4 w-4 text-primary mt-0.5 shrink-0" }),
15404
- /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground font-ui", children: [
15405
- /* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Recommended for: " }),
15406
- recommendedFor
15407
- ] })
15408
- ] })
15409
- ] }),
15410
- itineraryDays && itineraryDays.length > 0 ? /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
15411
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: (_b = labels == null ? void 0 : labels.itinerary) != null ? _b : "Itinerary" }),
15412
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12", children: itineraryDays.map((day) => /* @__PURE__ */ jsx(
15413
- ItineraryDay,
15414
- __spreadProps(__spreadValues({}, day), {
15415
- photoLayout: "fullBleedBottom"
15416
- }),
15417
- day.dayNumber
15418
- )) })
15419
- ] }) : itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
15420
- /* @__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" }),
15421
- /* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary, transferLabel: labels == null ? void 0 : labels.transfer })
15422
- ] }),
15423
- included && included.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
15424
- /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
15425
- (sectionIcons == null ? void 0 : sectionIcons.whatIsIncluded) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.whatIsIncluded }) : /* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
15426
- (_d = labels == null ? void 0 : labels.whatIsIncluded) != null ? _d : "Included"
15427
- ] }),
15428
- /* @__PURE__ */ jsx(Checklist, { items: included })
15429
- ] }),
15430
- notIncluded && notIncluded.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-not-included", className: "scroll-mt-20", children: [
15431
- /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
15432
- /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5 text-muted-foreground" }),
15433
- (_e = labels == null ? void 0 : labels.notIncluded) != null ? _e : "Not included"
15434
- ] }),
15435
- /* @__PURE__ */ jsx(
15436
- Checklist,
15437
- {
15438
- items: notIncluded,
15439
- icon: /* @__PURE__ */ jsx(XIcon, { className: "h-4 w-4 text-muted-foreground" })
15440
- }
15441
- )
15442
- ] }),
15443
- (howToGetThere || (whatToBring == null ? void 0 : whatToBring.length) || weather || optionalExtras || accommodation || (accommodationGallery == null ? void 0 : accommodationGallery.length) || food || (foodGallery == null ? void 0 : foodGallery.length) || (meetingPoints == null ? void 0 : meetingPoints.length) || meetingPoint || termsAndConditions || whenItOperates) && /* @__PURE__ */ jsxs(
15444
- Accordion,
15445
- {
15446
- multiple: false,
15447
- value: accordionValue,
15448
- onValueChange: setAccordionValue,
15449
- className: "border-t border-border",
15450
- children: [
15451
- whenItOperates && /* @__PURE__ */ jsxs(
15452
- AccordionItem,
15453
- {
15454
- value: "when-it-operates",
15455
- id: "trip-section-when-it-operates",
15456
- className: "scroll-mt-20 border-b border-border",
15457
- children: [
15458
- /* @__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: [
15459
- (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" }),
15460
- (_f = labels == null ? void 0 : labels.whenItOperates) != null ? _f : "When this tour operates"
15461
- ] }) }),
15462
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-bold [&_a]:text-primary [&_a]:underline", children: whenItOperates }) })
15463
- ]
15464
- }
15465
- ),
15466
- (accommodation || accommodationGallery && accommodationGallery.length > 0) && /* @__PURE__ */ jsxs(
15467
- AccordionItem,
15468
- {
15469
- value: "accommodation",
15470
- id: "trip-section-accommodation",
15471
- className: "scroll-mt-20 border-b border-border",
15472
- children: [
15473
- /* @__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: [
15474
- (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" }),
15475
- (_g = labels == null ? void 0 : labels.accommodation) != null ? _g : "Accommodation"
15476
- ] }) }),
15477
- /* @__PURE__ */ jsxs(AccordionContent, { className: "pb-6", children: [
15478
- accommodation && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: accommodation }),
15479
- accommodationGallery && accommodationGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(accommodation && "mt-6"), children: /* @__PURE__ */ jsx(
15480
- PhotoGallery,
15481
- {
15482
- labels: {
15483
- seeMore: labels == null ? void 0 : labels.seeMore,
15484
- showLess: labels == null ? void 0 : labels.showLess,
15485
- close: labels == null ? void 0 : labels.galleryClose,
15486
- previous: labels == null ? void 0 : labels.galleryPrevious,
15487
- next: labels == null ? void 0 : labels.galleryNext
15488
- },
15489
- photos: accommodationGallery,
15490
- variant: accommodationGalleryVariant,
15491
- initialVisible: 6
15492
- }
15493
- ) })
15494
- ] })
15495
- ]
15496
- }
15497
- ),
15498
- (food || foodGallery && foodGallery.length > 0) && /* @__PURE__ */ jsxs(
15499
- AccordionItem,
15500
- {
15501
- value: "food",
15502
- id: "trip-section-food",
15503
- className: "scroll-mt-20 border-b border-border",
15504
- children: [
15505
- /* @__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: [
15506
- (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" }),
15507
- (_h = labels == null ? void 0 : labels.food) != null ? _h : "Food"
15508
- ] }) }),
15509
- /* @__PURE__ */ jsxs(AccordionContent, { className: "pb-6", children: [
15510
- food && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: food }),
15511
- foodGallery && foodGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(food && "mt-6"), children: /* @__PURE__ */ jsx(
15512
- PhotoGallery,
15513
- {
15514
- labels: {
15515
- seeMore: labels == null ? void 0 : labels.seeMore,
15516
- showLess: labels == null ? void 0 : labels.showLess,
15517
- close: labels == null ? void 0 : labels.galleryClose,
15518
- previous: labels == null ? void 0 : labels.galleryPrevious,
15519
- next: labels == null ? void 0 : labels.galleryNext
15520
- },
15521
- photos: foodGallery,
15522
- variant: foodGalleryVariant,
15523
- initialVisible: 6
15524
- }
15525
- ) })
15526
- ] })
15527
- ]
15528
- }
15529
- ),
15530
- (meetingPoint || meetingPoints && meetingPoints.length > 0) && /* @__PURE__ */ jsxs(
15531
- AccordionItem,
15532
- {
15533
- value: "meeting",
15534
- id: "trip-section-meeting",
15535
- className: "scroll-mt-20 border-b border-border",
15536
- children: [
15537
- /* @__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: [
15538
- (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" }),
15539
- (_i = labels == null ? void 0 : labels.meetingPoint) != null ? _i : "Meeting point"
15540
- ] }) }),
15541
- /* @__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) => {
15542
- var _a2, _b2, _c2;
15543
- return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
15544
- /* @__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" }) }),
15545
- /* @__PURE__ */ jsxs("div", { children: [
15546
- 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" }),
15547
- /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
15548
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
15549
- ] })
15550
- ] }, i);
15551
- }) }) })
15552
- ]
15553
- }
15554
- ),
15555
- howToGetThere && /* @__PURE__ */ jsxs(
15556
- AccordionItem,
15557
- {
15558
- value: "how-to-get-there",
15559
- id: "trip-section-how-to-get-there",
15560
- className: "scroll-mt-20 border-b border-border",
15561
- children: [
15562
- /* @__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: [
15563
- (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" }),
15564
- (_j = labels == null ? void 0 : labels.howToGetThere) != null ? _j : "How to get there"
15565
- ] }) }),
15566
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: howToGetThere }) })
15567
- ]
15568
- }
15569
- ),
15570
- weather && /* @__PURE__ */ jsxs(
15571
- AccordionItem,
15572
- {
15573
- value: "weather",
15574
- id: "trip-section-weather",
15575
- className: "scroll-mt-20 border-b border-border",
15576
- children: [
15577
- /* @__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: [
15578
- (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" }),
15579
- (_k = labels == null ? void 0 : labels.weather) != null ? _k : "Weather"
15580
- ] }) }),
15581
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: weather }) })
15582
- ]
15583
- }
15584
- ),
15585
- whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxs(
15586
- AccordionItem,
15587
- {
15588
- value: "what-to-bring",
15589
- id: "trip-section-what-to-bring",
15590
- className: "scroll-mt-20 border-b border-border",
15591
- children: [
15592
- /* @__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: [
15593
- (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" }),
15594
- (_l = labels == null ? void 0 : labels.whatToBring) != null ? _l : "What to bring"
15595
- ] }) }),
15596
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4" }) }) })
15597
- ]
15598
- }
15599
- ),
15600
- optionalExtras && /* @__PURE__ */ jsxs(
15601
- AccordionItem,
15602
- {
15603
- value: "optional-extras",
15604
- id: "trip-section-optional-extras",
15605
- className: "scroll-mt-20 border-b border-border",
15606
- children: [
15607
- /* @__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: [
15608
- (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" }),
15609
- (_m = labels == null ? void 0 : labels.optionalExtras) != null ? _m : "Optional extras"
15610
- ] }) }),
15611
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: optionalExtras }) })
15612
- ]
15613
- }
15614
- ),
15615
- termsAndConditions && /* @__PURE__ */ jsxs(
15616
- AccordionItem,
15751
+ ) : /* @__PURE__ */ jsx(Separator, { className: "my-6" }),
15752
+ /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: "h-px -mt-px", "aria-hidden": true }),
15753
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row gap-8 mt-4", children: [
15754
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 space-y-12 pb-12", children: [
15755
+ (overview || (overviewHighlights == null ? void 0 : overviewHighlights.length)) && /* @__PURE__ */ jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
15756
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-4", children: (_a = labels == null ? void 0 : labels.overview) != null ? _a : "Overview" }),
15757
+ overview && /* @__PURE__ */ jsx("div", { className: "text-lg text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview }),
15758
+ overviewHighlights && overviewHighlights.length > 0 && /* @__PURE__ */ jsx("ul", { className: cn("flex flex-col gap-5", overview && "mt-8"), children: overviewHighlights.map((h, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-4", children: [
15759
+ h.icon && /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center text-foreground [&_svg]:h-8 [&_svg]:w-8", children: h.icon }),
15760
+ /* @__PURE__ */ jsx("div", { className: "flex-1 pt-1 text-base text-foreground leading-relaxed [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: h.description })
15761
+ ] }, i)) }),
15762
+ recommendedFor && /* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-start gap-2.5 rounded-xl bg-primary/8 border border-primary/20 p-4", children: [
15763
+ /* @__PURE__ */ jsx(UsersIcon, { className: "h-4 w-4 text-primary mt-0.5 shrink-0" }),
15764
+ /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground font-ui", children: [
15765
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Recommended for: " }),
15766
+ recommendedFor
15767
+ ] })
15768
+ ] })
15769
+ ] }),
15770
+ itineraryDays && itineraryDays.length > 0 ? /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
15771
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: (_b = labels == null ? void 0 : labels.itinerary) != null ? _b : "Itinerary" }),
15772
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12", children: itineraryDays.map((day) => /* @__PURE__ */ jsx(
15773
+ ItineraryDay,
15774
+ __spreadProps(__spreadValues({}, day), {
15775
+ photoLayout: "fullBleedBottom"
15776
+ }),
15777
+ day.dayNumber
15778
+ )) })
15779
+ ] }) : itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
15780
+ /* @__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" }),
15781
+ /* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary, transferLabel: labels == null ? void 0 : labels.transfer })
15782
+ ] }),
15783
+ included && included.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
15784
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
15785
+ (sectionIcons == null ? void 0 : sectionIcons.whatIsIncluded) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.whatIsIncluded }) : /* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
15786
+ (_d = labels == null ? void 0 : labels.whatIsIncluded) != null ? _d : "Included"
15787
+ ] }),
15788
+ /* @__PURE__ */ jsx(Checklist, { items: included })
15789
+ ] }),
15790
+ notIncluded && notIncluded.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-not-included", className: "scroll-mt-20", children: [
15791
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
15792
+ /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5 text-muted-foreground" }),
15793
+ (_e = labels == null ? void 0 : labels.notIncluded) != null ? _e : "Not included"
15794
+ ] }),
15795
+ /* @__PURE__ */ jsx(
15796
+ Checklist,
15617
15797
  {
15618
- value: "terms",
15619
- id: "trip-section-terms",
15620
- className: "scroll-mt-20 border-b border-border",
15621
- children: [
15622
- /* @__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: [
15623
- (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" }),
15624
- (_n = labels == null ? void 0 : labels.terms) != null ? _n : "Terms & conditions"
15625
- ] }) }),
15626
- /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: termsAndConditions }) })
15627
- ]
15798
+ items: notIncluded,
15799
+ icon: /* @__PURE__ */ jsx(XIcon, { className: "h-4 w-4 text-muted-foreground" })
15628
15800
  }
15629
15801
  )
15630
- ]
15631
- }
15632
- ),
15633
- faqs && faqs.length > 0 && (() => {
15634
- var _a2, _b2, _c2;
15635
- const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
15636
- const hiddenCount = faqs.length - visibleFaqs.length;
15637
- return /* @__PURE__ */ jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
15638
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: (_a2 = labels == null ? void 0 : labels.faq) != null ? _a2 : "FAQ" }),
15639
- /* @__PURE__ */ jsx(Accordion, { variant: "faq", children: visibleFaqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
15640
- /* @__PURE__ */ jsx(AccordionTrigger, { children: faq.question }),
15641
- /* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
15642
- ] }, i)) }),
15643
- faqs.length > faqInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-center", children: /* @__PURE__ */ jsx(
15644
- "button",
15802
+ ] }),
15803
+ (howToGetThere || (whatToBring == null ? void 0 : whatToBring.length) || weather || optionalExtras || accommodation || (accommodationGallery == null ? void 0 : accommodationGallery.length) || food || (foodGallery == null ? void 0 : foodGallery.length) || (meetingPoints == null ? void 0 : meetingPoints.length) || meetingPoint || termsAndConditions || whenItOperates) && /* @__PURE__ */ jsxs(
15804
+ Accordion,
15645
15805
  {
15646
- type: "button",
15647
- onClick: () => setFaqsExpanded((v) => !v),
15648
- className: cn(
15649
- "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
15650
- "text-sm font-semibold text-foreground shadow-sm",
15651
- "hover:bg-muted transition-colors duration-150",
15652
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
15653
- ),
15654
- children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
15655
- /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
15656
- (_b2 = labels == null ? void 0 : labels.showLess) != null ? _b2 : "Show less"
15657
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15658
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
15659
- (_c2 = labels == null ? void 0 : labels.seeMore) != null ? _c2 : "See more",
15660
- " (",
15661
- hiddenCount,
15662
- ")"
15663
- ] })
15806
+ multiple: false,
15807
+ value: accordionValue,
15808
+ onValueChange: setAccordionValue,
15809
+ className: "border-t border-border",
15810
+ children: [
15811
+ whenItOperates && /* @__PURE__ */ jsxs(
15812
+ AccordionItem,
15813
+ {
15814
+ value: "when-it-operates",
15815
+ id: "trip-section-when-it-operates",
15816
+ className: "scroll-mt-20 border-b border-border",
15817
+ children: [
15818
+ /* @__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: [
15819
+ (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" }),
15820
+ (_f = labels == null ? void 0 : labels.whenItOperates) != null ? _f : "When this tour operates"
15821
+ ] }) }),
15822
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-bold [&_a]:text-primary [&_a]:underline", children: whenItOperates }) })
15823
+ ]
15824
+ }
15825
+ ),
15826
+ (accommodation || accommodationGallery && accommodationGallery.length > 0) && /* @__PURE__ */ jsxs(
15827
+ AccordionItem,
15828
+ {
15829
+ value: "accommodation",
15830
+ id: "trip-section-accommodation",
15831
+ className: "scroll-mt-20 border-b border-border",
15832
+ children: [
15833
+ /* @__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: [
15834
+ (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" }),
15835
+ (_g = labels == null ? void 0 : labels.accommodation) != null ? _g : "Accommodation"
15836
+ ] }) }),
15837
+ /* @__PURE__ */ jsxs(AccordionContent, { className: "pb-6", keepMounted: true, children: [
15838
+ accommodation && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: accommodation }),
15839
+ accommodationGallery && accommodationGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(accommodation && "mt-6"), children: /* @__PURE__ */ jsx(
15840
+ PhotoGallery,
15841
+ {
15842
+ labels: {
15843
+ seeMore: labels == null ? void 0 : labels.seeMore,
15844
+ showLess: labels == null ? void 0 : labels.showLess,
15845
+ close: labels == null ? void 0 : labels.galleryClose,
15846
+ previous: labels == null ? void 0 : labels.galleryPrevious,
15847
+ next: labels == null ? void 0 : labels.galleryNext
15848
+ },
15849
+ photos: accommodationGallery,
15850
+ variant: accommodationGalleryVariant,
15851
+ initialVisible: 6,
15852
+ tourSection: (_h = labels == null ? void 0 : labels.accommodation) != null ? _h : "Accommodation"
15853
+ }
15854
+ ) })
15855
+ ] })
15856
+ ]
15857
+ }
15858
+ ),
15859
+ (food || foodGallery && foodGallery.length > 0) && /* @__PURE__ */ jsxs(
15860
+ AccordionItem,
15861
+ {
15862
+ value: "food",
15863
+ id: "trip-section-food",
15864
+ className: "scroll-mt-20 border-b border-border",
15865
+ children: [
15866
+ /* @__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: [
15867
+ (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" }),
15868
+ (_i = labels == null ? void 0 : labels.food) != null ? _i : "Food"
15869
+ ] }) }),
15870
+ /* @__PURE__ */ jsxs(AccordionContent, { className: "pb-6", keepMounted: true, children: [
15871
+ food && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: food }),
15872
+ foodGallery && foodGallery.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(food && "mt-6"), children: /* @__PURE__ */ jsx(
15873
+ PhotoGallery,
15874
+ {
15875
+ labels: {
15876
+ seeMore: labels == null ? void 0 : labels.seeMore,
15877
+ showLess: labels == null ? void 0 : labels.showLess,
15878
+ close: labels == null ? void 0 : labels.galleryClose,
15879
+ previous: labels == null ? void 0 : labels.galleryPrevious,
15880
+ next: labels == null ? void 0 : labels.galleryNext
15881
+ },
15882
+ photos: foodGallery,
15883
+ variant: foodGalleryVariant,
15884
+ initialVisible: 6,
15885
+ tourSection: (_j = labels == null ? void 0 : labels.food) != null ? _j : "Food"
15886
+ }
15887
+ ) })
15888
+ ] })
15889
+ ]
15890
+ }
15891
+ ),
15892
+ (meetingPoint || meetingPoints && meetingPoints.length > 0) && /* @__PURE__ */ jsxs(
15893
+ AccordionItem,
15894
+ {
15895
+ value: "meeting",
15896
+ id: "trip-section-meeting",
15897
+ className: "scroll-mt-20 border-b border-border",
15898
+ children: [
15899
+ /* @__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: [
15900
+ (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" }),
15901
+ (_k = labels == null ? void 0 : labels.meetingPoint) != null ? _k : "Meeting point"
15902
+ ] }) }),
15903
+ /* @__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) => {
15904
+ var _a2, _b2, _c2;
15905
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
15906
+ /* @__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" }) }),
15907
+ /* @__PURE__ */ jsxs("div", { children: [
15908
+ 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" }),
15909
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
15910
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
15911
+ ] })
15912
+ ] }, i);
15913
+ }) }) })
15914
+ ]
15915
+ }
15916
+ ),
15917
+ howToGetThere && /* @__PURE__ */ jsxs(
15918
+ AccordionItem,
15919
+ {
15920
+ value: "how-to-get-there",
15921
+ id: "trip-section-how-to-get-there",
15922
+ className: "scroll-mt-20 border-b border-border",
15923
+ children: [
15924
+ /* @__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: [
15925
+ (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" }),
15926
+ (_l = labels == null ? void 0 : labels.howToGetThere) != null ? _l : "How to get there"
15927
+ ] }) }),
15928
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: howToGetThere }) })
15929
+ ]
15930
+ }
15931
+ ),
15932
+ weather && /* @__PURE__ */ jsxs(
15933
+ AccordionItem,
15934
+ {
15935
+ value: "weather",
15936
+ id: "trip-section-weather",
15937
+ className: "scroll-mt-20 border-b border-border",
15938
+ children: [
15939
+ /* @__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: [
15940
+ (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" }),
15941
+ (_m = labels == null ? void 0 : labels.weather) != null ? _m : "Weather"
15942
+ ] }) }),
15943
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: weather }) })
15944
+ ]
15945
+ }
15946
+ ),
15947
+ whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxs(
15948
+ AccordionItem,
15949
+ {
15950
+ value: "what-to-bring",
15951
+ id: "trip-section-what-to-bring",
15952
+ className: "scroll-mt-20 border-b border-border",
15953
+ children: [
15954
+ /* @__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: [
15955
+ (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" }),
15956
+ (_n = labels == null ? void 0 : labels.whatToBring) != null ? _n : "What to bring"
15957
+ ] }) }),
15958
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4" }) }) })
15959
+ ]
15960
+ }
15961
+ ),
15962
+ optionalExtras && /* @__PURE__ */ jsxs(
15963
+ AccordionItem,
15964
+ {
15965
+ value: "optional-extras",
15966
+ id: "trip-section-optional-extras",
15967
+ className: "scroll-mt-20 border-b border-border",
15968
+ children: [
15969
+ /* @__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: [
15970
+ (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" }),
15971
+ (_o = labels == null ? void 0 : labels.optionalExtras) != null ? _o : "Optional extras"
15972
+ ] }) }),
15973
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: optionalExtras }) })
15974
+ ]
15975
+ }
15976
+ ),
15977
+ termsAndConditions && /* @__PURE__ */ jsxs(
15978
+ AccordionItem,
15979
+ {
15980
+ value: "terms",
15981
+ id: "trip-section-terms",
15982
+ className: "scroll-mt-20 border-b border-border",
15983
+ children: [
15984
+ /* @__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: [
15985
+ (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" }),
15986
+ (_p = labels == null ? void 0 : labels.terms) != null ? _p : "Terms & conditions"
15987
+ ] }) }),
15988
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: termsAndConditions }) })
15989
+ ]
15990
+ }
15991
+ )
15992
+ ]
15664
15993
  }
15665
- ) })
15666
- ] });
15667
- })(),
15668
- trustpilot ? /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
15669
- /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
15670
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: (_o = labels == null ? void 0 : labels.reviews) != null ? _o : "What our guests think" }),
15671
- /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilot })
15672
- ] }) : reviews && reviews.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
15673
- /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
15674
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: (_p = labels == null ? void 0 : labels.reviews) != null ? _p : "What our guests think" }),
15675
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: reviews.map((r, i) => {
15676
- var _a2;
15677
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border p-5", children: [
15678
- /* @__PURE__ */ jsx(Stars, { count: (_a2 = r.rating) != null ? _a2 : 5 }),
15679
- /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground leading-relaxed line-clamp-4", children: [
15680
- "\u201C",
15681
- r.text,
15682
- "\u201D"
15683
- ] }),
15684
- /* @__PURE__ */ jsxs("p", { className: "text-xs font-semibold text-muted-foreground font-ui mt-auto", children: [
15685
- "\u2014 ",
15686
- r.author
15687
- ] })
15688
- ] }, i);
15689
- }) })
15994
+ ),
15995
+ faqs && faqs.length > 0 && (() => {
15996
+ var _a2, _b2, _c2;
15997
+ const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
15998
+ const hiddenCount = faqs.length - visibleFaqs.length;
15999
+ return /* @__PURE__ */ jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
16000
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: (_a2 = labels == null ? void 0 : labels.faq) != null ? _a2 : "FAQ" }),
16001
+ /* @__PURE__ */ jsx(Accordion, { variant: "faq", children: visibleFaqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
16002
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: faq.question }),
16003
+ /* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
16004
+ ] }, i)) }),
16005
+ faqs.length > faqInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-center", children: /* @__PURE__ */ jsx(
16006
+ "button",
16007
+ {
16008
+ type: "button",
16009
+ onClick: () => setFaqsExpanded((v) => !v),
16010
+ className: cn(
16011
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
16012
+ "text-sm font-semibold text-foreground shadow-sm",
16013
+ "hover:bg-muted transition-colors duration-150",
16014
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
16015
+ ),
16016
+ children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
16017
+ /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
16018
+ (_b2 = labels == null ? void 0 : labels.showLess) != null ? _b2 : "Show less"
16019
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
16020
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
16021
+ (_c2 = labels == null ? void 0 : labels.seeMore) != null ? _c2 : "See more",
16022
+ " (",
16023
+ hiddenCount,
16024
+ ")"
16025
+ ] })
16026
+ }
16027
+ ) })
16028
+ ] });
16029
+ })(),
16030
+ trustpilot ? /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
16031
+ /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
16032
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: (_q = labels == null ? void 0 : labels.reviews) != null ? _q : "What our guests think" }),
16033
+ /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilot })
16034
+ ] }) : reviews && reviews.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
16035
+ /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
16036
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: (_r = labels == null ? void 0 : labels.reviews) != null ? _r : "What our guests think" }),
16037
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: reviews.map((r, i) => {
16038
+ var _a2;
16039
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border p-5", children: [
16040
+ /* @__PURE__ */ jsx(Stars, { count: (_a2 = r.rating) != null ? _a2 : 5 }),
16041
+ /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground leading-relaxed line-clamp-4", children: [
16042
+ "\u201C",
16043
+ r.text,
16044
+ "\u201D"
16045
+ ] }),
16046
+ /* @__PURE__ */ jsxs("p", { className: "text-xs font-semibold text-muted-foreground font-ui mt-auto", children: [
16047
+ "\u2014 ",
16048
+ r.author
16049
+ ] })
16050
+ ] }, i);
16051
+ }) })
16052
+ ] })
16053
+ ] }),
16054
+ /* @__PURE__ */ jsx("div", { ref: sidebarPlaceholderRef, className: "hidden lg:block lg:w-72 xl:w-80 shrink-0", children: !isFloating && /* @__PURE__ */ jsx("div", { className: "sticky top-20 rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
16055
+ PricingTrip,
16056
+ {
16057
+ priceFrom,
16058
+ currency,
16059
+ season,
16060
+ departureTimes,
16061
+ onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
16062
+ bookLabel: bookLabel != null ? bookLabel : "Check availability",
16063
+ fromLabel,
16064
+ perPersonLabel,
16065
+ variant: "card",
16066
+ belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
16067
+ benefits,
16068
+ currencyEstimates,
16069
+ priceInfo
16070
+ }
16071
+ ) }) })
15690
16072
  ] })
15691
16073
  ] }),
15692
- /* @__PURE__ */ jsx("div", { ref: sidebarPlaceholderRef, className: "hidden lg:block lg:w-72 xl:w-80 shrink-0", children: !isFloating && /* @__PURE__ */ jsx("div", { className: "sticky top-20 rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
15693
- PricingTrip,
16074
+ sections.length > 0 && /* @__PURE__ */ jsx(
16075
+ "div",
15694
16076
  {
15695
- priceFrom,
15696
- currency,
15697
- season,
15698
- departureTimes,
15699
- onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
15700
- bookLabel: bookLabel != null ? bookLabel : "Check availability",
15701
- fromLabel,
15702
- perPersonLabel,
15703
- variant: "card",
15704
- belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
15705
- benefits,
15706
- currencyEstimates,
15707
- priceInfo
16077
+ ref: navRef,
16078
+ className: cn(
16079
+ "fixed top-0 left-0 right-0 z-20 py-3 transition-all duration-200",
16080
+ navFloating && !navHidden ? "translate-y-0 opacity-100" : "-translate-y-full opacity-0 pointer-events-none"
16081
+ ),
16082
+ children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 flex justify-center", children: /* @__PURE__ */ jsx(
16083
+ MenuTrip,
16084
+ {
16085
+ sections,
16086
+ activeSection,
16087
+ onSelect: scrollToSection,
16088
+ variant: "floating"
16089
+ }
16090
+ ) })
15708
16091
  }
15709
- ) }) })
15710
- ] })
15711
- ] }),
15712
- sections.length > 0 && /* @__PURE__ */ jsx(
15713
- "div",
15714
- {
15715
- ref: navRef,
15716
- className: cn(
15717
- "fixed top-0 left-0 right-0 z-20 py-3 transition-all duration-200",
15718
- navFloating && !navHidden ? "translate-y-0 opacity-100" : "-translate-y-full opacity-0 pointer-events-none"
15719
16092
  ),
15720
- children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 flex justify-center", children: /* @__PURE__ */ jsx(
15721
- MenuTrip,
16093
+ isFloating && !pricingBarVisible && sidebarPos && /* @__PURE__ */ jsx(
16094
+ "div",
15722
16095
  {
15723
- sections,
15724
- activeSection,
15725
- onSelect: scrollToSection,
15726
- variant: "floating"
16096
+ className: "hidden lg:block fixed z-20",
16097
+ style: { top: "5rem", left: sidebarPos.left, width: sidebarPos.width },
16098
+ children: /* @__PURE__ */ jsx("div", { className: "rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
16099
+ PricingTrip,
16100
+ {
16101
+ priceFrom,
16102
+ currency,
16103
+ season,
16104
+ departureTimes,
16105
+ onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
16106
+ bookLabel: bookLabel != null ? bookLabel : "Check availability",
16107
+ fromLabel,
16108
+ perPersonLabel,
16109
+ variant: "card",
16110
+ belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
16111
+ benefits,
16112
+ currencyEstimates,
16113
+ priceInfo
16114
+ }
16115
+ ) })
15727
16116
  }
15728
- ) })
15729
- }
15730
- ),
15731
- isFloating && !pricingBarVisible && sidebarPos && /* @__PURE__ */ jsx(
15732
- "div",
15733
- {
15734
- className: "hidden lg:block fixed z-20",
15735
- style: { top: "5rem", left: sidebarPos.left, width: sidebarPos.width },
15736
- children: /* @__PURE__ */ jsx("div", { className: "rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
16117
+ ),
16118
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsx("section", { ref: galleryRef, id: "trip-section-gallery", className: "scroll-mt-20", children: /* @__PURE__ */ jsx(
16119
+ PhotoGallery,
16120
+ {
16121
+ labels: {
16122
+ seeMore: labels == null ? void 0 : labels.seeMore,
16123
+ showLess: labels == null ? void 0 : labels.showLess,
16124
+ close: labels == null ? void 0 : labels.galleryClose,
16125
+ previous: labels == null ? void 0 : labels.galleryPrevious,
16126
+ next: labels == null ? void 0 : labels.galleryNext
16127
+ },
16128
+ photos: gallery,
16129
+ variant: "gridCompact",
16130
+ initialVisible: 8,
16131
+ lightbox: galleryLightbox,
16132
+ tourSection: (_s = labels == null ? void 0 : labels.gallery) != null ? _s : "Gallery"
16133
+ }
16134
+ ) }),
16135
+ 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(
16136
+ BookingForm,
16137
+ {
16138
+ labels: bookingLabels,
16139
+ defaultValues: bookingDefaults,
16140
+ onSubmit: onBookingSubmit,
16141
+ loading: bookingLoading
16142
+ }
16143
+ ) }) }),
16144
+ /* @__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(
15737
16145
  PricingTrip,
15738
16146
  {
15739
16147
  priceFrom,
15740
16148
  currency,
15741
- season,
15742
- departureTimes,
15743
16149
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
15744
- bookLabel: bookLabel != null ? bookLabel : "Check availability",
16150
+ bookLabel: bookLabel != null ? bookLabel : "Book now",
15745
16151
  fromLabel,
15746
16152
  perPersonLabel,
15747
- variant: "card",
15748
- belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
15749
- benefits,
15750
- currencyEstimates,
15751
- priceInfo
16153
+ variant: "compact",
16154
+ sharp: true,
16155
+ priceInfo,
16156
+ currencyEstimates
15752
16157
  }
15753
- ) })
15754
- }
15755
- ),
15756
- gallery && gallery.length > 0 && /* @__PURE__ */ jsx("section", { ref: galleryRef, id: "trip-section-gallery", className: "scroll-mt-20", children: /* @__PURE__ */ jsx(
15757
- PhotoGallery,
15758
- {
15759
- labels: {
15760
- seeMore: labels == null ? void 0 : labels.seeMore,
15761
- showLess: labels == null ? void 0 : labels.showLess,
15762
- close: labels == null ? void 0 : labels.galleryClose,
15763
- previous: labels == null ? void 0 : labels.galleryPrevious,
15764
- next: labels == null ? void 0 : labels.galleryNext
15765
- },
15766
- photos: gallery,
15767
- variant: "gridCompact",
15768
- initialVisible: 8
15769
- }
15770
- ) }),
15771
- 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(
15772
- BookingForm,
15773
- {
15774
- labels: bookingLabels,
15775
- defaultValues: bookingDefaults,
15776
- onSubmit: onBookingSubmit,
15777
- loading: bookingLoading
15778
- }
15779
- ) }) }),
15780
- /* @__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(
15781
- PricingTrip,
15782
- {
15783
- priceFrom,
15784
- currency,
15785
- onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
15786
- bookLabel: bookLabel != null ? bookLabel : "Book now",
15787
- fromLabel,
15788
- perPersonLabel,
15789
- variant: "compact",
15790
- sharp: true,
15791
- priceInfo,
15792
- currencyEstimates
15793
- }
15794
- ) }),
15795
- /* @__PURE__ */ jsx("div", { className: "h-20 lg:hidden" }),
15796
- /* @__PURE__ */ jsx(SiteFooter, {})
15797
- ]
16158
+ ) }),
16159
+ /* @__PURE__ */ jsx("div", { className: "h-20 lg:hidden" }),
16160
+ /* @__PURE__ */ jsx(SiteFooter, { badges: footerBadges })
16161
+ ]
16162
+ }
16163
+ )
15798
16164
  }
15799
16165
  );
15800
16166
  }
@@ -15853,14 +16219,15 @@ function CategoryPage2({
15853
16219
  viewAllPostsLabel,
15854
16220
  cardLabels,
15855
16221
  filterLabels,
16222
+ footerBadges,
15856
16223
  className
15857
16224
  }) {
15858
16225
  var _a;
15859
- const [videoReady, setVideoReady] = React32.useState(false);
15860
- const videoRef = React32.useRef(null);
16226
+ const [videoReady, setVideoReady] = React20.useState(false);
16227
+ const videoRef = React20.useRef(null);
15861
16228
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
15862
16229
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
15863
- React32.useEffect(() => {
16230
+ React20.useEffect(() => {
15864
16231
  if (!videoUrl) return;
15865
16232
  const el = videoRef.current;
15866
16233
  if (!el) return;
@@ -15875,13 +16242,13 @@ function CategoryPage2({
15875
16242
  io.observe(el);
15876
16243
  return () => io.disconnect();
15877
16244
  }, [videoUrl]);
15878
- const [faqsExpanded, setFaqsExpanded] = React32.useState(false);
15879
- const [tripsExpanded, setTripsExpanded] = React32.useState(false);
15880
- const [filterValue, setFilterValue] = React32.useState({});
15881
- const [sort, setSort] = React32.useState(
16245
+ const [faqsExpanded, setFaqsExpanded] = React20.useState(false);
16246
+ const [tripsExpanded, setTripsExpanded] = React20.useState(false);
16247
+ const [filterValue, setFilterValue] = React20.useState({});
16248
+ const [sort, setSort] = React20.useState(
15882
16249
  defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
15883
16250
  );
15884
- const sortedTrips = React32.useMemo(() => {
16251
+ const sortedTrips = React20.useMemo(() => {
15885
16252
  const active = Object.entries(filterValue).filter(
15886
16253
  ([, vals]) => vals && vals.length > 0
15887
16254
  );
@@ -15985,7 +16352,7 @@ function CategoryPage2({
15985
16352
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
15986
16353
  breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => {
15987
16354
  const isLast = i === breadcrumb.length - 1;
15988
- return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
16355
+ return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
15989
16356
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
15990
16357
  crumb.href && !isLast ? /* @__PURE__ */ jsx(
15991
16358
  "a",
@@ -16177,7 +16544,7 @@ function CategoryPage2({
16177
16544
  ) })
16178
16545
  ] });
16179
16546
  })(),
16180
- /* @__PURE__ */ jsx(SiteFooter, {})
16547
+ /* @__PURE__ */ jsx(SiteFooter, { badges: footerBadges })
16181
16548
  ] });
16182
16549
  }
16183
16550
  var sizeConfig3 = {
@@ -16282,12 +16649,12 @@ function Toast({
16282
16649
  duration = 6e3,
16283
16650
  className
16284
16651
  }) {
16285
- const [mounted, setMounted] = React32.useState(false);
16286
- const [visible, setVisible] = React32.useState(true);
16287
- React32.useEffect(() => {
16652
+ const [mounted, setMounted] = React20.useState(false);
16653
+ const [visible, setVisible] = React20.useState(true);
16654
+ React20.useEffect(() => {
16288
16655
  setMounted(true);
16289
16656
  }, []);
16290
- React32.useEffect(() => {
16657
+ React20.useEffect(() => {
16291
16658
  if (duration === 0) return;
16292
16659
  const t = setTimeout(() => {
16293
16660
  setVisible(false);
@@ -17789,8 +18156,8 @@ function ShareWidget({
17789
18156
  title = "Invite friends & lower the price",
17790
18157
  className
17791
18158
  }) {
17792
- const [copied, setCopied] = React32.useState(false);
17793
- const [showToast, setShowToast] = React32.useState(false);
18159
+ const [copied, setCopied] = React20.useState(false);
18160
+ const [showToast, setShowToast] = React20.useState(false);
17794
18161
  const encodedUrl = encodeURIComponent(url);
17795
18162
  const encodedMsg = encodeURIComponent(`${message} ${url}`);
17796
18163
  const channels = [
@@ -17960,7 +18327,7 @@ function RatingStars({ stars = 5 }) {
17960
18327
  "flex h-5 w-5 items-center justify-center rounded-[3px]",
17961
18328
  filled ? "bg-primary" : "bg-white/30"
17962
18329
  ),
17963
- children: /* @__PURE__ */ jsx(StarIcon, { className: "h-3 w-3 fill-white text-white" })
18330
+ children: /* @__PURE__ */ jsx(StarIcon$1, { className: "h-3 w-3 fill-white text-white" })
17964
18331
  },
17965
18332
  i
17966
18333
  );
@@ -17971,7 +18338,7 @@ function Rating({ label, stars = 5, provider, href }) {
17971
18338
  label && /* @__PURE__ */ jsx("span", { className: "text-sm font-ui font-bold text-white", children: label }),
17972
18339
  /* @__PURE__ */ jsx(RatingStars, { stars }),
17973
18340
  provider && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-sm font-ui font-bold text-white", children: [
17974
- /* @__PURE__ */ jsx(StarIcon, { className: "h-4 w-4 fill-primary text-primary" }),
18341
+ /* @__PURE__ */ jsx(StarIcon$1, { className: "h-4 w-4 fill-primary text-primary" }),
17975
18342
  provider
17976
18343
  ] })
17977
18344
  ] });
@@ -18007,11 +18374,11 @@ function HomeHeader({
18007
18374
  className
18008
18375
  }) {
18009
18376
  var _a;
18010
- const [heroIndex, setHeroIndex] = React32.useState(0);
18011
- const [videoReady, setVideoReady] = React32.useState(false);
18012
- const videoRef = React32.useRef(null);
18377
+ const [heroIndex, setHeroIndex] = React20.useState(0);
18378
+ const [videoReady, setVideoReady] = React20.useState(false);
18379
+ const videoRef = React20.useRef(null);
18013
18380
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
18014
- const validImages = React32.useMemo(
18381
+ const validImages = React20.useMemo(
18015
18382
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
18016
18383
  [images]
18017
18384
  );
@@ -18025,7 +18392,7 @@ function HomeHeader({
18025
18392
  const showCarousel = !videoUrl && validImages.length > 1;
18026
18393
  const tpConfig = trustpilot ? typeof trustpilot === "object" ? __spreadValues(__spreadValues({}, DEFAULT_TRUSTPILOT), trustpilot) : DEFAULT_TRUSTPILOT : null;
18027
18394
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
18028
- React32.useEffect(() => {
18395
+ React20.useEffect(() => {
18029
18396
  if (!videoUrl) return;
18030
18397
  const el = videoRef.current;
18031
18398
  if (!el) return;
@@ -18383,7 +18750,7 @@ function AdventureExplorer({
18383
18750
  className
18384
18751
  }) {
18385
18752
  var _a, _b, _c, _d, _e;
18386
- const [activeId, setActiveId] = React32.useState(
18753
+ const [activeId, setActiveId] = React20.useState(
18387
18754
  defaultTabId != null ? defaultTabId : (_a = tabs[0]) == null ? void 0 : _a.id
18388
18755
  );
18389
18756
  const active = (_b = tabs.find((t2) => t2.id === activeId)) != null ? _b : tabs[0];
@@ -18723,8 +19090,8 @@ function RotatingSubtitle({
18723
19090
  interval,
18724
19091
  className
18725
19092
  }) {
18726
- const [index, setIndex] = React32.useState(0);
18727
- React32.useEffect(() => {
19093
+ const [index, setIndex] = React20.useState(0);
19094
+ React20.useEffect(() => {
18728
19095
  var _a;
18729
19096
  if (phrases.length < 2) return;
18730
19097
  const reduce = typeof window !== "undefined" && ((_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)").matches);
@@ -18763,7 +19130,7 @@ function CtaBanner({
18763
19130
  overlayOpacity = 35,
18764
19131
  className
18765
19132
  }) {
18766
- const phrases = React32.useMemo(
19133
+ const phrases = React20.useMemo(
18767
19134
  () => (Array.isArray(subtitle) ? subtitle : subtitle ? [subtitle] : []).map((s) => s.trim()).filter(Boolean),
18768
19135
  [subtitle]
18769
19136
  );
@@ -19044,7 +19411,7 @@ function SectionHead({
19044
19411
  }
19045
19412
  function ExpeditionsRail({ eyebrow, title, subtitle, link, trips }) {
19046
19413
  var _a;
19047
- const railRef = React32.useRef(null);
19414
+ const railRef = React20.useRef(null);
19048
19415
  const scrollByCard = (dir) => {
19049
19416
  const rail = railRef.current;
19050
19417
  if (!rail) return;
@@ -19146,7 +19513,7 @@ function StatsBand({ items }) {
19146
19513
  }
19147
19514
  function ReviewStars({ stars = 5 }) {
19148
19515
  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(
19149
- StarIcon,
19516
+ StarIcon$1,
19150
19517
  {
19151
19518
  className: cn(
19152
19519
  "h-4 w-4",
@@ -19252,7 +19619,7 @@ function SegmentedControl({
19252
19619
  }) {
19253
19620
  var _a;
19254
19621
  const isControlled = value != null;
19255
- const [internal, setInternal] = React32.useState(
19622
+ const [internal, setInternal] = React20.useState(
19256
19623
  defaultValue != null ? defaultValue : (_a = items[0]) == null ? void 0 : _a.id
19257
19624
  );
19258
19625
  const active = isControlled ? value : internal;
@@ -19335,6 +19702,6 @@ function SegmentedControl({
19335
19702
  );
19336
19703
  }
19337
19704
 
19338
- export { ActivityCard, AdventureExplorer, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogJournal, BlogPost, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPartialCancellationEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CancellationForm, CancellationRequestReceivedEmail, 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 };
19705
+ export { ActivityCard, AdventureExplorer, AgentContactCard, Alert, AskExo, BirthDateField, BlogCard, BlogJournal, BlogPost, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPartialCancellationEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CancellationForm, CancellationRequestReceivedEmail, 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, PhotoTourProvider, 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 };
19339
19706
  //# sourceMappingURL=index.js.map
19340
19707
  //# sourceMappingURL=index.js.map