@planetaexo/design-system 0.23.0 → 0.23.1

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 React23 from 'react';
1
+ import * as React25 from 'react';
2
2
  import { useState, useRef, useCallback, useEffect } 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, ChevronLeftIcon, ClockIcon, ChevronUpIcon, UserIcon, MenuIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, InfoIcon, Loader2Icon, SendIcon, CheckCircleIcon, CheckIcon, MailIcon, PhoneIcon, MessageCircleIcon, CompassIcon, UserPlusIcon, ExternalLinkIcon, CopyIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, CarIcon, ZoomInIcon, StarIcon, LayoutGridIcon } from 'lucide-react';
7
+ import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, ClockIcon, CheckIcon, ChevronUpIcon, UserIcon, MenuIcon, SunIcon, MoonIcon, MapPinIcon, InfoIcon, PackageIcon, SparklesIcon, BackpackIcon, BedDoubleIcon, UtensilsIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, MailIcon, PhoneIcon, MessageCircleIcon, CompassIcon, UserPlusIcon, ExternalLinkIcon, CopyIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon, LayoutGridIcon } from 'lucide-react';
8
8
  import { Separator as Separator$1 } from '@base-ui/react/separator';
9
9
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
10
10
  import { Button as Button$1 } from '@base-ui/react/button';
@@ -81,7 +81,7 @@ var buttonVariants = cva(
81
81
  }
82
82
  }
83
83
  );
84
- var Button = React23.forwardRef(
84
+ var Button = React25.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(
@@ -302,10 +302,10 @@ function DialogDescription(_a) {
302
302
  }, props)
303
303
  );
304
304
  }
305
- var FloatingInput = React23.forwardRef(
305
+ var FloatingInput = React25.forwardRef(
306
306
  (_a, ref) => {
307
307
  var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
308
- const inputId = id != null ? id : React23.useId();
308
+ const inputId = id != null ? id : React25.useId();
309
309
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
310
310
  /* @__PURE__ */ jsx(
311
311
  "input",
@@ -345,10 +345,10 @@ var FloatingInput = React23.forwardRef(
345
345
  }
346
346
  );
347
347
  FloatingInput.displayName = "FloatingInput";
348
- var FloatingSelect = React23.forwardRef(
348
+ var FloatingSelect = React25.forwardRef(
349
349
  (_a, ref) => {
350
350
  var _b = _a, { label, error, id, className, required, children, value } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children", "value"]);
351
- const inputId = id != null ? id : React23.useId();
351
+ const inputId = id != null ? id : React25.useId();
352
352
  const hasValue = typeof value === "string" ? value !== "" : value !== void 0 && value !== null;
353
353
  return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
354
354
  /* @__PURE__ */ jsx(
@@ -612,11 +612,11 @@ function PhoneCountrySelect({
612
612
  disabled
613
613
  }) {
614
614
  var _a;
615
- const [open, setOpen] = React23.useState(false);
616
- const containerRef = React23.useRef(null);
617
- const listRef = React23.useRef(null);
615
+ const [open, setOpen] = React25.useState(false);
616
+ const containerRef = React25.useRef(null);
617
+ const listRef = React25.useRef(null);
618
618
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
619
- React23.useEffect(() => {
619
+ React25.useEffect(() => {
620
620
  if (!open) return;
621
621
  const handler = (e) => {
622
622
  var _a2;
@@ -627,7 +627,7 @@ function PhoneCountrySelect({
627
627
  document.addEventListener("mousedown", handler);
628
628
  return () => document.removeEventListener("mousedown", handler);
629
629
  }, [open]);
630
- React23.useEffect(() => {
630
+ React25.useEffect(() => {
631
631
  if (!open || !listRef.current) return;
632
632
  const activeEl = listRef.current.querySelector("[data-selected=true]");
633
633
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -897,8 +897,8 @@ function CalendarDayButton(_a) {
897
897
  "locale"
898
898
  ]);
899
899
  const defaultClassNames = getDefaultClassNames();
900
- const ref = React23.useRef(null);
901
- React23.useEffect(() => {
900
+ const ref = React25.useRef(null);
901
+ React25.useEffect(() => {
902
902
  var _a2;
903
903
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
904
904
  }, [modifiers.focused]);
@@ -929,16 +929,16 @@ function BirthDateField({
929
929
  className,
930
930
  disabled
931
931
  }) {
932
- const [open, setOpen] = React23.useState(false);
933
- const [text, setText] = React23.useState(
932
+ const [open, setOpen] = React25.useState(false);
933
+ const [text, setText] = React25.useState(
934
934
  value ? format(value, "dd/MM/yyyy") : ""
935
935
  );
936
- const containerRef = React23.useRef(null);
937
- const inputId = React23.useId();
938
- React23.useEffect(() => {
936
+ const containerRef = React25.useRef(null);
937
+ const inputId = React25.useId();
938
+ React25.useEffect(() => {
939
939
  setText(value ? format(value, "dd/MM/yyyy") : "");
940
940
  }, [value]);
941
- React23.useEffect(() => {
941
+ React25.useEffect(() => {
942
942
  if (!open) return;
943
943
  const handler = (e) => {
944
944
  var _a;
@@ -1147,14 +1147,14 @@ function CountrySearchField({
1147
1147
  }) {
1148
1148
  var _a;
1149
1149
  const list = countries != null ? countries : COUNTRIES;
1150
- const [query, setQuery] = React23.useState("");
1151
- const [open, setOpen] = React23.useState(false);
1152
- const containerRef = React23.useRef(null);
1153
- const searchRef = React23.useRef(null);
1150
+ const [query, setQuery] = React25.useState("");
1151
+ const [open, setOpen] = React25.useState(false);
1152
+ const containerRef = React25.useRef(null);
1153
+ const searchRef = React25.useRef(null);
1154
1154
  const selected = list.find((c) => c.code === value);
1155
1155
  const isFloated = open || !!selected;
1156
1156
  const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
1157
- React23.useEffect(() => {
1157
+ React25.useEffect(() => {
1158
1158
  if (!open) return;
1159
1159
  const handler = (e) => {
1160
1160
  var _a2;
@@ -1268,7 +1268,7 @@ function AdventureCard({
1268
1268
  }) {
1269
1269
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1270
1270
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1271
- const [checkedInternal, setCheckedInternal] = React23.useState(
1271
+ const [checkedInternal, setCheckedInternal] = React25.useState(
1272
1272
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
1273
1273
  );
1274
1274
  const isChecked = (opt) => {
@@ -1666,7 +1666,7 @@ function BookingShell({
1666
1666
  return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1667
1667
  /* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1668
1668
  /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1669
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React23.Fragment, { children: [
1669
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React25.Fragment, { children: [
1670
1670
  /* @__PURE__ */ jsx(
1671
1671
  "span",
1672
1672
  {
@@ -1865,7 +1865,7 @@ function TermsSection({
1865
1865
  termsContent
1866
1866
  }) {
1867
1867
  var _a;
1868
- const [modalOpen, setModalOpen] = React23.useState(false);
1868
+ const [modalOpen, setModalOpen] = React25.useState(false);
1869
1869
  const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
1870
1870
  return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1871
1871
  /* @__PURE__ */ jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
@@ -1934,7 +1934,7 @@ function BookingConfirmedCard({
1934
1934
  " ",
1935
1935
  /* @__PURE__ */ jsx("span", { className: "font-bold text-foreground font-heading", children: bookingNumber })
1936
1936
  ] }),
1937
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground font-sans max-w-sm mx-auto leading-relaxed", children: message != null ? message : /* @__PURE__ */ jsxs(Fragment, { children: [
1937
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground font-sans max-w-sm mx-auto leading-relaxed", children: message != null ? message : /* @__PURE__ */ jsxs("p", { children: [
1938
1938
  "A confirmation email has been sent to",
1939
1939
  " ",
1940
1940
  /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: email || "your email" }),
@@ -1960,6 +1960,32 @@ function BookingConfirmedCard({
1960
1960
  )
1961
1961
  ] });
1962
1962
  }
1963
+ function TransferDetailsBlock({
1964
+ label,
1965
+ items,
1966
+ className
1967
+ }) {
1968
+ if (!items.length) return null;
1969
+ return /* @__PURE__ */ jsxs(
1970
+ "div",
1971
+ {
1972
+ className: [
1973
+ "w-full max-w-md mx-auto rounded-xl border border-border bg-muted/40 px-5 py-4 text-left",
1974
+ className != null ? className : ""
1975
+ ].filter(Boolean).join(" "),
1976
+ children: [
1977
+ /* @__PURE__ */ jsx("div", { className: "mb-3 text-xs uppercase tracking-wide text-muted-foreground font-heading", children: label }),
1978
+ /* @__PURE__ */ jsx("dl", { className: "space-y-1.5 text-sm font-mono", children: items.map(([term, value], i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [
1979
+ /* @__PURE__ */ jsxs("dt", { className: "text-muted-foreground shrink-0", children: [
1980
+ term,
1981
+ ":"
1982
+ ] }),
1983
+ /* @__PURE__ */ jsx("dd", { className: "text-foreground font-semibold break-all", children: value })
1984
+ ] }, i)) })
1985
+ ]
1986
+ }
1987
+ );
1988
+ }
1963
1989
  var WIZARD_STEPS_FN = (l) => {
1964
1990
  var _a, _b, _c, _d, _e, _f;
1965
1991
  return [
@@ -1977,9 +2003,9 @@ function BookingWizard({
1977
2003
  }) {
1978
2004
  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;
1979
2005
  const wizardSteps = WIZARD_STEPS_FN(labels);
1980
- const [step, setStep] = React23.useState("responsible");
1981
- const [error, setError] = React23.useState(null);
1982
- const [responsible, setResponsible] = React23.useState({
2006
+ const [step, setStep] = React25.useState("responsible");
2007
+ const [error, setError] = React25.useState(null);
2008
+ const [responsible, setResponsible] = React25.useState({
1983
2009
  firstName: "",
1984
2010
  lastName: "",
1985
2011
  email: "",
@@ -1998,7 +2024,7 @@ function BookingWizard({
1998
2024
  return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
1999
2025
  }, 0);
2000
2026
  const totalPax = totalAdults + totalChildren;
2001
- const [travellers, setTravellers] = React23.useState(
2027
+ const [travellers, setTravellers] = React25.useState(
2002
2028
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
2003
2029
  firstName: "",
2004
2030
  lastName: "",
@@ -2006,9 +2032,9 @@ function BookingWizard({
2006
2032
  email: ""
2007
2033
  }))
2008
2034
  );
2009
- const [payAmount, setPayAmount] = React23.useState("full");
2010
- const [payMethod, setPayMethod] = React23.useState("stripe");
2011
- const [termsAccepted, setTermsAccepted] = React23.useState(false);
2035
+ const [payAmount, setPayAmount] = React25.useState("full");
2036
+ const [payMethod, setPayMethod] = React25.useState("stripe");
2037
+ const [termsAccepted, setTermsAccepted] = React25.useState(false);
2012
2038
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
2013
2039
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
2014
2040
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -2235,7 +2261,7 @@ function Offer({
2235
2261
  className
2236
2262
  }) {
2237
2263
  var _a, _b, _c;
2238
- const [showBooking, setShowBooking] = React23.useState(false);
2264
+ const [showBooking, setShowBooking] = React25.useState(false);
2239
2265
  const isShowingCheckout = !confirmedState && (!!checkoutSlot || showBooking);
2240
2266
  const handleBook = () => {
2241
2267
  if (!checkoutSlot && !externalBookingFlow) setShowBooking(true);
@@ -2596,7 +2622,7 @@ function AdventureSection({
2596
2622
  labels
2597
2623
  }) {
2598
2624
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
2599
- const [detailsOpen, setDetailsOpen] = React23.useState(false);
2625
+ const [detailsOpen, setDetailsOpen] = React25.useState(false);
2600
2626
  const handleCopyUrl = (url) => {
2601
2627
  if (onCopyFormLink) {
2602
2628
  onCopyFormLink(url);
@@ -3090,8 +3116,8 @@ function AddTravellerDialog({
3090
3116
  errorMessage
3091
3117
  }) {
3092
3118
  var _a, _b, _c, _d, _e;
3093
- const [form, setForm] = React23.useState(() => createInitialAddFormData(config));
3094
- React23.useEffect(() => {
3119
+ const [form, setForm] = React25.useState(() => createInitialAddFormData(config));
3120
+ React25.useEffect(() => {
3095
3121
  if (open) {
3096
3122
  setForm(createInitialAddFormData(config));
3097
3123
  }
@@ -3151,7 +3177,7 @@ function EditTravellerDialog({
3151
3177
  errorMessage
3152
3178
  }) {
3153
3179
  var _a, _b, _c, _d, _e;
3154
- const [form, setForm] = React23.useState(() => ({
3180
+ const [form, setForm] = React25.useState(() => ({
3155
3181
  firstName: "",
3156
3182
  lastName: "",
3157
3183
  email: "",
@@ -3160,7 +3186,7 @@ function EditTravellerDialog({
3160
3186
  birthDate: "",
3161
3187
  personType: "ADULT"
3162
3188
  }));
3163
- React23.useEffect(() => {
3189
+ React25.useEffect(() => {
3164
3190
  var _a2, _b2, _c2, _d2, _e2, _f;
3165
3191
  if (open && traveller) {
3166
3192
  setForm({
@@ -3440,38 +3466,38 @@ function BookingDetails({
3440
3466
  const hasSubmitAddTraveller = !!onSubmitAddTraveller;
3441
3467
  const hasSubmitEditTraveller = !!onSubmitEditTraveller;
3442
3468
  const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
3443
- const [addModalState, setAddModalState] = React23.useState({
3469
+ const [addModalState, setAddModalState] = React25.useState({
3444
3470
  open: false,
3445
3471
  adventureId: null
3446
3472
  });
3447
- const [editModalState, setEditModalState] = React23.useState({ open: false, adventureId: null, traveller: null });
3448
- const [deleteModalState, setDeleteModalState] = React23.useState({ open: false, adventureId: null, traveller: null });
3449
- const handleRequestOpenAddModal = React23.useCallback((adventureId) => {
3473
+ const [editModalState, setEditModalState] = React25.useState({ open: false, adventureId: null, traveller: null });
3474
+ const [deleteModalState, setDeleteModalState] = React25.useState({ open: false, adventureId: null, traveller: null });
3475
+ const handleRequestOpenAddModal = React25.useCallback((adventureId) => {
3450
3476
  setAddModalState({ open: true, adventureId });
3451
3477
  }, []);
3452
- const handleRequestOpenEditModal = React23.useCallback(
3478
+ const handleRequestOpenEditModal = React25.useCallback(
3453
3479
  (adventureId, traveller) => {
3454
3480
  setEditModalState({ open: true, adventureId, traveller });
3455
3481
  },
3456
3482
  []
3457
3483
  );
3458
- const handleRequestOpenDeleteModal = React23.useCallback(
3484
+ const handleRequestOpenDeleteModal = React25.useCallback(
3459
3485
  (adventureId, traveller) => {
3460
3486
  setDeleteModalState({ open: true, adventureId, traveller });
3461
3487
  },
3462
3488
  []
3463
3489
  );
3464
- const closeAddModal = React23.useCallback(() => {
3490
+ const closeAddModal = React25.useCallback(() => {
3465
3491
  setAddModalState({ open: false, adventureId: null });
3466
3492
  }, []);
3467
- const closeEditModal = React23.useCallback(() => {
3493
+ const closeEditModal = React25.useCallback(() => {
3468
3494
  setEditModalState({ open: false, adventureId: null, traveller: null });
3469
3495
  }, []);
3470
- const closeDeleteModal = React23.useCallback(() => {
3496
+ const closeDeleteModal = React25.useCallback(() => {
3471
3497
  setDeleteModalState({ open: false, adventureId: null, traveller: null });
3472
3498
  }, []);
3473
- const submitInFlightRef = React23.useRef(false);
3474
- const handleAddSubmit = React23.useCallback(
3499
+ const submitInFlightRef = React25.useRef(false);
3500
+ const handleAddSubmit = React25.useCallback(
3475
3501
  async (adventureId, data) => {
3476
3502
  if (!onSubmitAddTraveller) return;
3477
3503
  if (submitInFlightRef.current) return;
@@ -3486,7 +3512,7 @@ function BookingDetails({
3486
3512
  },
3487
3513
  [onSubmitAddTraveller, closeAddModal]
3488
3514
  );
3489
- const handleEditSubmit = React23.useCallback(
3515
+ const handleEditSubmit = React25.useCallback(
3490
3516
  async (adventureId, travellerId, data) => {
3491
3517
  if (!onSubmitEditTraveller) return;
3492
3518
  if (submitInFlightRef.current) return;
@@ -3501,7 +3527,7 @@ function BookingDetails({
3501
3527
  },
3502
3528
  [onSubmitEditTraveller, closeEditModal]
3503
3529
  );
3504
- const handleDeleteConfirm = React23.useCallback(
3530
+ const handleDeleteConfirm = React25.useCallback(
3505
3531
  async (adventureId, travellerId) => {
3506
3532
  if (!onConfirmRemoveTraveller) return;
3507
3533
  if (submitInFlightRef.current) return;
@@ -4231,7 +4257,7 @@ function BookingConfirmationEmail({
4231
4257
  }, children: i + 1 }) }),
4232
4258
  /* @__PURE__ */ jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
4233
4259
  ] }) }) }, i)) }),
4234
- 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(React23.Fragment, { children: [
4260
+ 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(React25.Fragment, { children: [
4235
4261
  idx === 0 ? /* @__PURE__ */ jsx("strong", { children: line }) : line,
4236
4262
  idx < arr.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
4237
4263
  ] }, idx)) })
@@ -4684,11 +4710,11 @@ function DatePickerField({
4684
4710
  fromDate,
4685
4711
  className
4686
4712
  }) {
4687
- const [open, setOpen] = React23.useState(false);
4688
- const containerRef = React23.useRef(null);
4689
- const [calendarWidth, setCalendarWidth] = React23.useState();
4713
+ const [open, setOpen] = React25.useState(false);
4714
+ const containerRef = React25.useRef(null);
4715
+ const [calendarWidth, setCalendarWidth] = React25.useState();
4690
4716
  const hasValue = !!value;
4691
- React23.useEffect(() => {
4717
+ React25.useEffect(() => {
4692
4718
  if (!containerRef.current) return;
4693
4719
  const observer = new ResizeObserver(([entry]) => {
4694
4720
  setCalendarWidth(entry.contentRect.width);
@@ -4797,7 +4823,7 @@ function BookingForm({
4797
4823
  subtitle = "Free enquiry \u2013 no commitment",
4798
4824
  className
4799
4825
  }) {
4800
- const [values, setValues] = React23.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
4826
+ const [values, setValues] = React25.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
4801
4827
  const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
4802
4828
  const handleSubmit = (e) => {
4803
4829
  e.preventDefault();
@@ -5334,11 +5360,11 @@ function FloatingTextarea({
5334
5360
  }
5335
5361
  function SelectField({ field, value, onChange, error, disabled }) {
5336
5362
  var _a, _b, _c;
5337
- const [open, setOpen] = React23.useState(false);
5338
- const containerRef = React23.useRef(null);
5363
+ const [open, setOpen] = React25.useState(false);
5364
+ const containerRef = React25.useRef(null);
5339
5365
  const options = (_a = field.options) != null ? _a : [];
5340
5366
  const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
5341
- React23.useEffect(() => {
5367
+ React25.useEffect(() => {
5342
5368
  if (!open) return;
5343
5369
  const handleOutside = (e) => {
5344
5370
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -5727,11 +5753,11 @@ function RegistrationForm({
5727
5753
  readOnly = false
5728
5754
  }) {
5729
5755
  var _a;
5730
- const L = React23.useMemo(
5756
+ const L = React25.useMemo(
5731
5757
  () => __spreadValues(__spreadValues({}, DEFAULT_LABELS4), labels != null ? labels : {}),
5732
5758
  [labels]
5733
5759
  );
5734
- const sortedFields = React23.useMemo(
5760
+ const sortedFields = React25.useMemo(
5735
5761
  () => [...fields].sort((a, b) => {
5736
5762
  var _a2, _b;
5737
5763
  return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
@@ -5739,7 +5765,7 @@ function RegistrationForm({
5739
5765
  [fields]
5740
5766
  );
5741
5767
  const isControlled = values !== void 0;
5742
- const [internal, setInternal] = React23.useState(
5768
+ const [internal, setInternal] = React25.useState(
5743
5769
  () => initializeValues(
5744
5770
  sortedFields,
5745
5771
  defaultValues != null ? defaultValues : {},
@@ -5747,9 +5773,9 @@ function RegistrationForm({
5747
5773
  includeTerms
5748
5774
  )
5749
5775
  );
5750
- const [submitAttempted, setSubmitAttempted] = React23.useState(false);
5751
- const [validationErrors, setValidationErrors] = React23.useState({});
5752
- React23.useEffect(() => {
5776
+ const [submitAttempted, setSubmitAttempted] = React25.useState(false);
5777
+ const [validationErrors, setValidationErrors] = React25.useState({});
5778
+ React25.useEffect(() => {
5753
5779
  if (isControlled) return;
5754
5780
  setInternal((prev) => {
5755
5781
  const next = initializeValues(
@@ -5806,7 +5832,7 @@ function RegistrationForm({
5806
5832
  const termsError = submitAttempted && termsEnabled && !termsAccepted;
5807
5833
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
5808
5834
  const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
5809
- React23.useEffect(() => {
5835
+ React25.useEffect(() => {
5810
5836
  if (!submitAttempted || !scrollTargetId) return;
5811
5837
  const timer = setTimeout(() => {
5812
5838
  const elem = document.getElementById(scrollTargetId);
@@ -6268,10 +6294,10 @@ var OTPCodeInput = ({
6268
6294
  id,
6269
6295
  required
6270
6296
  }) => {
6271
- const baseId = id != null ? id : React23.useId();
6272
- const inputRef = React23.useRef(null);
6273
- const [focused, setFocused] = React23.useState(false);
6274
- const digits = React23.useMemo(() => {
6297
+ const baseId = id != null ? id : React25.useId();
6298
+ const inputRef = React25.useRef(null);
6299
+ const [focused, setFocused] = React25.useState(false);
6300
+ const digits = React25.useMemo(() => {
6275
6301
  const arr = value.split("").slice(0, length);
6276
6302
  while (arr.length < length) arr.push("");
6277
6303
  return arr;
@@ -6387,7 +6413,7 @@ function Checkbox(_a) {
6387
6413
  })
6388
6414
  );
6389
6415
  }
6390
- var AccordionVariantContext = React23.createContext("default");
6416
+ var AccordionVariantContext = React25.createContext("default");
6391
6417
  function Accordion(_a) {
6392
6418
  var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
6393
6419
  return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
@@ -6405,7 +6431,7 @@ function Accordion(_a) {
6405
6431
  }
6406
6432
  function AccordionItem(_a) {
6407
6433
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6408
- const variant = React23.useContext(AccordionVariantContext);
6434
+ const variant = React25.useContext(AccordionVariantContext);
6409
6435
  return /* @__PURE__ */ jsx(
6410
6436
  Accordion$1.Item,
6411
6437
  __spreadValues({
@@ -6426,7 +6452,7 @@ function AccordionTrigger(_a) {
6426
6452
  "className",
6427
6453
  "children"
6428
6454
  ]);
6429
- const variant = React23.useContext(AccordionVariantContext);
6455
+ const variant = React25.useContext(AccordionVariantContext);
6430
6456
  return /* @__PURE__ */ jsx(Accordion$1.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
6431
6457
  Accordion$1.Trigger,
6432
6458
  __spreadProps(__spreadValues({
@@ -6480,7 +6506,7 @@ function AccordionContent(_a) {
6480
6506
  "className",
6481
6507
  "children"
6482
6508
  ]);
6483
- const variant = React23.useContext(AccordionVariantContext);
6509
+ const variant = React25.useContext(AccordionVariantContext);
6484
6510
  return /* @__PURE__ */ jsx(
6485
6511
  Accordion$1.Panel,
6486
6512
  __spreadProps(__spreadValues({
@@ -6512,7 +6538,7 @@ function FilterPanel({
6512
6538
  title = "Filters",
6513
6539
  className
6514
6540
  }) {
6515
- const [internalValue, setInternalValue] = React23.useState(
6541
+ const [internalValue, setInternalValue] = React25.useState(
6516
6542
  () => Object.fromEntries(groups.map((g) => [g.id, []]))
6517
6543
  );
6518
6544
  const selected = value != null ? value : internalValue;
@@ -6608,6 +6634,76 @@ function FilterPanel({
6608
6634
  )
6609
6635
  ] });
6610
6636
  }
6637
+ var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
6638
+ function TrustpilotEmbed({ config }) {
6639
+ var _a, _b, _c, _d, _e, _f;
6640
+ const ref = React25.useRef(null);
6641
+ React25.useEffect(() => {
6642
+ if (typeof document === "undefined" || !ref.current) return;
6643
+ let cancelled = false;
6644
+ const initWidget = () => {
6645
+ if (cancelled || !ref.current) return;
6646
+ const tp = window.Trustpilot;
6647
+ if (tp == null ? void 0 : tp.loadFromElement) {
6648
+ tp.loadFromElement(ref.current, true);
6649
+ }
6650
+ };
6651
+ const existing = document.querySelector(
6652
+ `script[src="${TRUSTPILOT_SCRIPT_SRC}"]`
6653
+ );
6654
+ if (existing) {
6655
+ const tp = window.Trustpilot;
6656
+ if (tp == null ? void 0 : tp.loadFromElement) {
6657
+ initWidget();
6658
+ } else {
6659
+ existing.addEventListener("load", initWidget, { once: true });
6660
+ }
6661
+ return () => {
6662
+ cancelled = true;
6663
+ existing.removeEventListener("load", initWidget);
6664
+ };
6665
+ }
6666
+ const s = document.createElement("script");
6667
+ s.src = TRUSTPILOT_SCRIPT_SRC;
6668
+ s.async = true;
6669
+ s.addEventListener("load", initWidget, { once: true });
6670
+ document.body.appendChild(s);
6671
+ return () => {
6672
+ cancelled = true;
6673
+ s.removeEventListener("load", initWidget);
6674
+ };
6675
+ }, [config]);
6676
+ const sku = Array.isArray(config.sku) ? config.sku.join(",") : config.sku;
6677
+ return /* @__PURE__ */ jsx(
6678
+ "div",
6679
+ {
6680
+ ref,
6681
+ className: "trustpilot-widget",
6682
+ "data-locale": (_a = config.locale) != null ? _a : "en-US",
6683
+ "data-template-id": (_b = config.templateId) != null ? _b : "5763bccae0a06d08e809ecbb",
6684
+ "data-businessunit-id": config.businessUnitId,
6685
+ "data-style-height": (_c = config.styleHeight) != null ? _c : "700px",
6686
+ "data-style-width": (_d = config.styleWidth) != null ? _d : "100%",
6687
+ "data-sku": sku,
6688
+ "data-no-reviews": (_e = config.noReviews) != null ? _e : "hide",
6689
+ "data-fullwidth": "true",
6690
+ "data-theme": config.theme,
6691
+ "data-token": config.token,
6692
+ "data-scroll-to-list": config.scrollToList ? "true" : void 0,
6693
+ "data-style-alignment": config.styleAlignment,
6694
+ "data-star-color": config.starColor,
6695
+ children: /* @__PURE__ */ jsx(
6696
+ "a",
6697
+ {
6698
+ href: (_f = config.fallbackHref) != null ? _f : "https://www.trustpilot.com/",
6699
+ target: "_blank",
6700
+ rel: "noopener noreferrer",
6701
+ children: "Trustpilot"
6702
+ }
6703
+ )
6704
+ }
6705
+ );
6706
+ }
6611
6707
  function ItineraryDayCard({
6612
6708
  stop,
6613
6709
  onOpen
@@ -6674,11 +6770,11 @@ function ItineraryModal({
6674
6770
  onNext
6675
6771
  }) {
6676
6772
  var _a, _b, _c;
6677
- const [imgIndex, setImgIndex] = React23.useState(0);
6773
+ const [imgIndex, setImgIndex] = React25.useState(0);
6678
6774
  const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
6679
6775
  const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
6680
6776
  const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
6681
- React23.useEffect(() => {
6777
+ React25.useEffect(() => {
6682
6778
  setImgIndex(0);
6683
6779
  }, [stop == null ? void 0 : stop.dayNumber]);
6684
6780
  if (!stop) return null;
@@ -6805,8 +6901,8 @@ function ItineraryModal({
6805
6901
  ) });
6806
6902
  }
6807
6903
  function Itinerary({ title, subtitle, stops, className }) {
6808
- const [activeIndex, setActiveIndex] = React23.useState(null);
6809
- const scrollRef = React23.useRef(null);
6904
+ const [activeIndex, setActiveIndex] = React25.useState(null);
6905
+ const scrollRef = React25.useRef(null);
6810
6906
  const activeStop = activeIndex !== null ? stops[activeIndex] : null;
6811
6907
  const scrollBy = (dir) => {
6812
6908
  if (!scrollRef.current) return;
@@ -6884,147 +6980,6 @@ function Itinerary({ title, subtitle, stops, className }) {
6884
6980
  )
6885
6981
  ] });
6886
6982
  }
6887
- function MenuTrip({
6888
- sections,
6889
- activeSection,
6890
- onSelect,
6891
- variant = "pill",
6892
- bold = true,
6893
- className
6894
- }) {
6895
- const scrollRef = React23.useRef(null);
6896
- React23.useEffect(() => {
6897
- if (!scrollRef.current || !activeSection) return;
6898
- const container = scrollRef.current;
6899
- const btn = container.querySelector(
6900
- `[data-section="${activeSection}"]`
6901
- );
6902
- if (!btn) return;
6903
- const btnLeft = btn.offsetLeft;
6904
- const btnRight = btnLeft + btn.offsetWidth;
6905
- const cLeft = container.scrollLeft;
6906
- const cRight = cLeft + container.offsetWidth;
6907
- if (btnLeft < cLeft) {
6908
- container.scrollTo({ left: btnLeft - 16, behavior: "smooth" });
6909
- } else if (btnRight > cRight) {
6910
- container.scrollTo({ left: btnRight - container.offsetWidth + 16, behavior: "smooth" });
6911
- }
6912
- }, [activeSection]);
6913
- if (variant === "underline") {
6914
- return /* @__PURE__ */ jsx(
6915
- "div",
6916
- {
6917
- ref: scrollRef,
6918
- className: cn(
6919
- "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
6920
- "border-b border-border",
6921
- className
6922
- ),
6923
- children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-end gap-0", children: sections.map((s) => /* @__PURE__ */ jsx(
6924
- "button",
6925
- {
6926
- "data-section": s.id,
6927
- type: "button",
6928
- onClick: () => onSelect == null ? void 0 : onSelect(s.id),
6929
- className: cn(
6930
- "relative px-4 py-2.5 text-sm font-ui whitespace-nowrap transition-colors duration-150",
6931
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
6932
- "after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full after:transition-all",
6933
- bold ? "font-semibold" : "font-normal",
6934
- activeSection === s.id ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent"
6935
- ),
6936
- children: s.label
6937
- },
6938
- s.id
6939
- )) })
6940
- }
6941
- );
6942
- }
6943
- if (variant === "outlined") {
6944
- return /* @__PURE__ */ jsx(
6945
- "div",
6946
- {
6947
- ref: scrollRef,
6948
- className: cn(
6949
- "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
6950
- className
6951
- ),
6952
- children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-2", children: sections.map((s) => /* @__PURE__ */ jsx(
6953
- "button",
6954
- {
6955
- "data-section": s.id,
6956
- type: "button",
6957
- onClick: () => onSelect == null ? void 0 : onSelect(s.id),
6958
- className: cn(
6959
- "rounded-full border px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
6960
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6961
- bold ? "font-semibold" : "font-normal",
6962
- activeSection === s.id ? "border-foreground bg-foreground text-background" : "border-border bg-background text-muted-foreground hover:border-foreground/50 hover:text-foreground"
6963
- ),
6964
- children: s.label
6965
- },
6966
- s.id
6967
- )) })
6968
- }
6969
- );
6970
- }
6971
- if (variant === "floating") {
6972
- return /* @__PURE__ */ jsx(
6973
- "div",
6974
- {
6975
- ref: scrollRef,
6976
- className: cn(
6977
- "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
6978
- "py-1 px-0.5",
6979
- /* padding so shadow isn't clipped by overflow */
6980
- className
6981
- ),
6982
- children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-0.5 rounded-full border border-border/40 bg-background/90 backdrop-blur-md shadow-sm px-1.5 py-1.5", children: sections.map((s) => /* @__PURE__ */ jsx(
6983
- "button",
6984
- {
6985
- "data-section": s.id,
6986
- type: "button",
6987
- onClick: () => onSelect == null ? void 0 : onSelect(s.id),
6988
- className: cn(
6989
- "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
6990
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6991
- bold ? "font-semibold" : "font-normal",
6992
- activeSection === s.id ? "bg-foreground text-background shadow-sm" : "text-foreground/60 hover:text-foreground hover:bg-muted/60"
6993
- ),
6994
- children: s.label
6995
- },
6996
- s.id
6997
- )) })
6998
- }
6999
- );
7000
- }
7001
- return /* @__PURE__ */ jsx(
7002
- "div",
7003
- {
7004
- ref: scrollRef,
7005
- className: cn(
7006
- "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
7007
- className
7008
- ),
7009
- children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-1 p-1", children: sections.map((s) => /* @__PURE__ */ jsx(
7010
- "button",
7011
- {
7012
- "data-section": s.id,
7013
- type: "button",
7014
- onClick: () => onSelect == null ? void 0 : onSelect(s.id),
7015
- className: cn(
7016
- "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
7017
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7018
- bold ? "font-semibold" : "font-normal",
7019
- activeSection === s.id ? "bg-foreground text-background shadow-sm" : "bg-white text-foreground/70 hover:text-foreground shadow-sm"
7020
- ),
7021
- children: s.label
7022
- },
7023
- s.id
7024
- )) })
7025
- }
7026
- );
7027
- }
7028
6983
  function normalise(p) {
7029
6984
  return typeof p === "string" ? { src: p } : p;
7030
6985
  }
@@ -7039,18 +6994,18 @@ function Lightbox({
7039
6994
  onClose
7040
6995
  }) {
7041
6996
  var _a;
7042
- const [index, setIndex] = React23.useState(initialIndex);
6997
+ const [index, setIndex] = React25.useState(initialIndex);
7043
6998
  const total = photos.length;
7044
6999
  const photo = photos[index];
7045
- const prev = React23.useCallback(
7000
+ const prev = React25.useCallback(
7046
7001
  () => setIndex((i) => (i - 1 + total) % total),
7047
7002
  [total]
7048
7003
  );
7049
- const next = React23.useCallback(
7004
+ const next = React25.useCallback(
7050
7005
  () => setIndex((i) => (i + 1) % total),
7051
7006
  [total]
7052
7007
  );
7053
- React23.useEffect(() => {
7008
+ React25.useEffect(() => {
7054
7009
  const onKey = (e) => {
7055
7010
  if (e.key === "Escape") onClose();
7056
7011
  if (e.key === "ArrowLeft") prev();
@@ -7124,55 +7079,27 @@ function Lightbox({
7124
7079
  ]
7125
7080
  }
7126
7081
  ),
7127
- total > 1 && /* @__PURE__ */ jsxs(
7082
+ total > 1 && /* @__PURE__ */ jsx(
7128
7083
  "div",
7129
7084
  {
7130
- className: "absolute bottom-5 inset-x-0 flex items-center justify-center gap-3 px-5",
7085
+ className: "absolute bottom-5 inset-x-0 flex items-center justify-center px-5",
7131
7086
  onClick: (e) => e.stopPropagation(),
7132
- children: [
7133
- /* @__PURE__ */ jsx(
7134
- "button",
7135
- {
7136
- type: "button",
7137
- onClick: (e) => {
7138
- e.stopPropagation();
7139
- prev();
7140
- },
7141
- className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
7142
- "aria-label": "Previous photo",
7143
- children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-4 w-4" })
7144
- }
7145
- ),
7146
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: photos.map((_, i) => /* @__PURE__ */ jsx(
7147
- "button",
7148
- {
7149
- type: "button",
7150
- onClick: (e) => {
7151
- e.stopPropagation();
7152
- setIndex(i);
7153
- },
7154
- "aria-label": `Go to photo ${i + 1}`,
7155
- className: cn(
7156
- "h-1.5 rounded-full transition-all duration-300 focus-visible:outline-none",
7157
- i === index ? "w-6 bg-primary" : "w-1.5 bg-white/40 hover:bg-white/70"
7158
- )
7087
+ children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: photos.map((_, i) => /* @__PURE__ */ jsx(
7088
+ "button",
7089
+ {
7090
+ type: "button",
7091
+ onClick: (e) => {
7092
+ e.stopPropagation();
7093
+ setIndex(i);
7159
7094
  },
7160
- i
7161
- )) }),
7162
- /* @__PURE__ */ jsx(
7163
- "button",
7164
- {
7165
- type: "button",
7166
- onClick: (e) => {
7167
- e.stopPropagation();
7168
- next();
7169
- },
7170
- className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
7171
- "aria-label": "Next photo",
7172
- children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-4 w-4" })
7173
- }
7174
- )
7175
- ]
7095
+ "aria-label": `Go to photo ${i + 1}`,
7096
+ className: cn(
7097
+ "h-1.5 rounded-full transition-all duration-300 focus-visible:outline-none",
7098
+ i === index ? "w-6 bg-primary" : "w-1.5 bg-white/40 hover:bg-white/70"
7099
+ )
7100
+ },
7101
+ i
7102
+ )) })
7176
7103
  }
7177
7104
  )
7178
7105
  ]
@@ -7244,7 +7171,7 @@ function GridGallery({
7244
7171
  initialVisible,
7245
7172
  onOpen
7246
7173
  }) {
7247
- const [expanded, setExpanded] = React23.useState(false);
7174
+ const [expanded, setExpanded] = React25.useState(false);
7248
7175
  const cols = gridCols(photos.length);
7249
7176
  const hasMore = photos.length > initialVisible;
7250
7177
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
@@ -7274,7 +7201,7 @@ function MasonryGallery({
7274
7201
  initialVisible,
7275
7202
  onOpen
7276
7203
  }) {
7277
- const [expanded, setExpanded] = React23.useState(false);
7204
+ const [expanded, setExpanded] = React25.useState(false);
7278
7205
  const hasMore = photos.length > initialVisible;
7279
7206
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
7280
7207
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -7347,7 +7274,7 @@ function FeaturedGallery({
7347
7274
  photos,
7348
7275
  onOpen
7349
7276
  }) {
7350
- const [expanded, setExpanded] = React23.useState(false);
7277
+ const [expanded, setExpanded] = React25.useState(false);
7351
7278
  const featured = photos.slice(0, 3);
7352
7279
  const extra = photos.slice(3);
7353
7280
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -7417,66 +7344,386 @@ function FeaturedGallery({
7417
7344
  )
7418
7345
  ] });
7419
7346
  }
7420
- function PhotoGallery({
7347
+ function CarouselGallery({
7421
7348
  photos,
7422
- variant = "grid",
7423
- initialVisible = 6,
7424
- onPhotoClick,
7349
+ index,
7350
+ onIndexChange,
7351
+ onOpen,
7425
7352
  className
7426
7353
  }) {
7427
- const [lightboxIndex, setLightboxIndex] = React23.useState(null);
7428
- const normalised = React23.useMemo(() => photos.map(normalise), [photos]);
7429
- const handleOpen = (index) => {
7430
- setLightboxIndex(index);
7431
- onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
7432
- };
7433
- if (normalised.length === 0) return null;
7434
- return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
7435
- variant === "grid" && /* @__PURE__ */ jsx(
7436
- GridGallery,
7437
- {
7438
- photos: normalised,
7439
- initialVisible,
7440
- onOpen: handleOpen
7441
- }
7442
- ),
7443
- variant === "masonry" && /* @__PURE__ */ jsx(
7444
- MasonryGallery,
7445
- {
7446
- photos: normalised,
7447
- initialVisible,
7448
- onOpen: handleOpen
7449
- }
7450
- ),
7451
- variant === "filmstrip" && /* @__PURE__ */ jsx(FilmstripGallery, { photos: normalised, onOpen: handleOpen }),
7452
- variant === "featured" && /* @__PURE__ */ jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen }),
7453
- lightboxIndex !== null && /* @__PURE__ */ jsx(
7454
- Lightbox,
7455
- {
7456
- photos: normalised,
7457
- initialIndex: lightboxIndex,
7458
- onClose: () => setLightboxIndex(null)
7459
- }
7460
- )
7461
- ] });
7462
- }
7463
- var badgeVariants = cva(
7464
- "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
7465
- {
7466
- variants: {
7467
- variant: {
7468
- default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
7469
- secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
7470
- destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
7471
- outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
7472
- ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
7473
- link: "text-primary underline-offset-4 hover:underline"
7474
- }
7475
- },
7476
- defaultVariants: {
7477
- variant: "default"
7478
- }
7479
- }
7354
+ var _a;
7355
+ const total = photos.length;
7356
+ const photo = photos[index];
7357
+ const prev = () => onIndexChange((index - 1 + total) % total);
7358
+ const next = () => onIndexChange((index + 1) % total);
7359
+ return /* @__PURE__ */ jsxs(
7360
+ "div",
7361
+ {
7362
+ className: cn(
7363
+ "relative w-full aspect-[4/3] sm:aspect-[16/10] overflow-hidden bg-muted group/photo",
7364
+ className
7365
+ ),
7366
+ children: [
7367
+ /* @__PURE__ */ jsx(
7368
+ "button",
7369
+ {
7370
+ type: "button",
7371
+ onClick: () => onOpen(index),
7372
+ "aria-label": `Open photo ${index + 1} fullscreen`,
7373
+ 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",
7374
+ children: /* @__PURE__ */ jsx(
7375
+ "img",
7376
+ {
7377
+ src: photo.src,
7378
+ alt: (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
7379
+ className: "h-full w-full object-cover transition-transform duration-500 group-hover/photo:scale-[1.02]",
7380
+ loading: "lazy"
7381
+ },
7382
+ photo.src
7383
+ )
7384
+ }
7385
+ ),
7386
+ total > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
7387
+ /* @__PURE__ */ jsx(
7388
+ "button",
7389
+ {
7390
+ type: "button",
7391
+ onClick: prev,
7392
+ "aria-label": "Previous photo",
7393
+ className: cn(
7394
+ "absolute left-3 sm:left-4 top-1/2 -translate-y-1/2 z-10",
7395
+ "flex h-8 w-8 items-center justify-center rounded-full",
7396
+ "bg-black/25 text-white backdrop-blur-sm",
7397
+ "hover:bg-black/45 transition-colors",
7398
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/60"
7399
+ ),
7400
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-4 w-4" })
7401
+ }
7402
+ ),
7403
+ /* @__PURE__ */ jsx(
7404
+ "button",
7405
+ {
7406
+ type: "button",
7407
+ onClick: next,
7408
+ "aria-label": "Next photo",
7409
+ className: cn(
7410
+ "absolute right-3 sm:right-4 top-1/2 -translate-y-1/2 z-10",
7411
+ "flex h-8 w-8 items-center justify-center rounded-full",
7412
+ "bg-black/25 text-white backdrop-blur-sm",
7413
+ "hover:bg-black/45 transition-colors",
7414
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/60"
7415
+ ),
7416
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-4 w-4" })
7417
+ }
7418
+ )
7419
+ ] }),
7420
+ total > 1 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-3 sm:bottom-4 inset-x-0 z-10 flex justify-center pointer-events-none", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto flex items-center gap-1.5 rounded-full bg-black/25 backdrop-blur-sm px-2 py-1.5", children: photos.map((_, i) => /* @__PURE__ */ jsx(
7421
+ "button",
7422
+ {
7423
+ type: "button",
7424
+ onClick: () => onIndexChange(i),
7425
+ "aria-label": `Go to photo ${i + 1}`,
7426
+ className: cn(
7427
+ "h-1.5 rounded-full transition-all duration-300",
7428
+ i === index ? "w-5 bg-white" : "w-1.5 bg-white/45 hover:bg-white/75"
7429
+ )
7430
+ },
7431
+ i
7432
+ )) }) })
7433
+ ]
7434
+ }
7435
+ );
7436
+ }
7437
+ function PhotoGallery({
7438
+ photos,
7439
+ variant = "grid",
7440
+ initialVisible = 6,
7441
+ onPhotoClick,
7442
+ className
7443
+ }) {
7444
+ const [lightboxIndex, setLightboxIndex] = React25.useState(null);
7445
+ const [carouselIndex, setCarouselIndex] = React25.useState(0);
7446
+ const normalised = React25.useMemo(() => photos.map(normalise), [photos]);
7447
+ const handleOpen = (index) => {
7448
+ setLightboxIndex(index);
7449
+ onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
7450
+ };
7451
+ if (normalised.length === 0) return null;
7452
+ const lightbox = lightboxIndex !== null && /* @__PURE__ */ jsx(
7453
+ Lightbox,
7454
+ {
7455
+ photos: normalised,
7456
+ initialIndex: lightboxIndex,
7457
+ onClose: () => setLightboxIndex(null)
7458
+ }
7459
+ );
7460
+ if (variant === "carousel" || variant === "fullBleed") {
7461
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7462
+ /* @__PURE__ */ jsx(
7463
+ CarouselGallery,
7464
+ {
7465
+ photos: normalised,
7466
+ index: carouselIndex,
7467
+ onIndexChange: setCarouselIndex,
7468
+ onOpen: handleOpen,
7469
+ className: cn(
7470
+ variant === "carousel" && "rounded-2xl",
7471
+ variant === "fullBleed" && "w-screen mx-[calc(50%-50vw)] lg:w-full lg:mx-0",
7472
+ className
7473
+ )
7474
+ }
7475
+ ),
7476
+ lightbox
7477
+ ] });
7478
+ }
7479
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
7480
+ variant === "grid" && /* @__PURE__ */ jsx(
7481
+ GridGallery,
7482
+ {
7483
+ photos: normalised,
7484
+ initialVisible,
7485
+ onOpen: handleOpen
7486
+ }
7487
+ ),
7488
+ variant === "masonry" && /* @__PURE__ */ jsx(
7489
+ MasonryGallery,
7490
+ {
7491
+ photos: normalised,
7492
+ initialVisible,
7493
+ onOpen: handleOpen
7494
+ }
7495
+ ),
7496
+ variant === "filmstrip" && /* @__PURE__ */ jsx(FilmstripGallery, { photos: normalised, onOpen: handleOpen }),
7497
+ variant === "featured" && /* @__PURE__ */ jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen }),
7498
+ lightbox
7499
+ ] });
7500
+ }
7501
+ var itineraryDaySpecIcons = {
7502
+ hiking: /* @__PURE__ */ jsx(FootprintsIcon, { className: "h-5 w-5", strokeWidth: 1.75 }),
7503
+ swimming: /* @__PURE__ */ jsx(WavesIcon, { className: "h-5 w-5", strokeWidth: 1.75 }),
7504
+ driving: /* @__PURE__ */ jsx(CarIcon, { className: "h-5 w-5", strokeWidth: 1.75 }),
7505
+ boat: /* @__PURE__ */ jsx(SailboatIcon, { className: "h-5 w-5", strokeWidth: 1.75 }),
7506
+ lodging: /* @__PURE__ */ jsx(HomeIcon, { className: "h-5 w-5", strokeWidth: 1.75 })
7507
+ };
7508
+ function normalisePhotos(input) {
7509
+ const list = Array.isArray(input) ? input : [input];
7510
+ return list.filter(Boolean).map((p) => typeof p === "string" ? { src: p } : p);
7511
+ }
7512
+ function ItineraryDay({
7513
+ dayNumber,
7514
+ dayLabel,
7515
+ title,
7516
+ photos,
7517
+ specs,
7518
+ description,
7519
+ photoLayout = "rounded",
7520
+ className
7521
+ }) {
7522
+ const photoList = React25.useMemo(() => normalisePhotos(photos), [photos]);
7523
+ const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
7524
+ const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
7525
+ const gallery = photoList.length > 0 && /* @__PURE__ */ jsx(
7526
+ PhotoGallery,
7527
+ {
7528
+ photos: photoList,
7529
+ variant: isFullBleed ? "fullBleed" : "carousel"
7530
+ }
7531
+ );
7532
+ return /* @__PURE__ */ jsxs("article", { className: cn("w-full flex flex-col gap-5", className), children: [
7533
+ photoPosition === "top" && gallery,
7534
+ /* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-2", children: [
7535
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-widest text-muted-foreground font-ui", children: dayLabel != null ? dayLabel : `Day ${dayNumber}` }),
7536
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground leading-tight font-heading", children: title })
7537
+ ] }),
7538
+ specs && specs.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-3 sm:gap-2.5", children: specs.map((spec, i) => /* @__PURE__ */ jsxs(
7539
+ "li",
7540
+ {
7541
+ className: "flex items-start gap-3 text-base text-foreground font-ui",
7542
+ children: [
7543
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true, children: spec.icon }),
7544
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
7545
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [
7546
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: spec.label }),
7547
+ spec.detail && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: spec.detail })
7548
+ ] }),
7549
+ spec.subdetail && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: spec.subdetail })
7550
+ ] })
7551
+ ]
7552
+ },
7553
+ i
7554
+ )) }),
7555
+ description && /* @__PURE__ */ jsx(
7556
+ "div",
7557
+ {
7558
+ className: cn(
7559
+ "text-base text-foreground/85 leading-relaxed space-y-3",
7560
+ "[&_strong]:font-semibold [&_strong]:text-foreground",
7561
+ "[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2 hover:[&_a]:no-underline"
7562
+ ),
7563
+ children: description
7564
+ }
7565
+ ),
7566
+ photoPosition === "bottom" && gallery
7567
+ ] });
7568
+ }
7569
+ function MenuTrip({
7570
+ sections,
7571
+ activeSection,
7572
+ onSelect,
7573
+ variant = "pill",
7574
+ bold = true,
7575
+ className
7576
+ }) {
7577
+ const scrollRef = React25.useRef(null);
7578
+ React25.useEffect(() => {
7579
+ if (!scrollRef.current || !activeSection) return;
7580
+ const container = scrollRef.current;
7581
+ const btn = container.querySelector(
7582
+ `[data-section="${activeSection}"]`
7583
+ );
7584
+ if (!btn) return;
7585
+ const btnLeft = btn.offsetLeft;
7586
+ const btnRight = btnLeft + btn.offsetWidth;
7587
+ const cLeft = container.scrollLeft;
7588
+ const cRight = cLeft + container.offsetWidth;
7589
+ if (btnLeft < cLeft) {
7590
+ container.scrollTo({ left: btnLeft - 16, behavior: "smooth" });
7591
+ } else if (btnRight > cRight) {
7592
+ container.scrollTo({ left: btnRight - container.offsetWidth + 16, behavior: "smooth" });
7593
+ }
7594
+ }, [activeSection]);
7595
+ if (variant === "underline") {
7596
+ return /* @__PURE__ */ jsx(
7597
+ "div",
7598
+ {
7599
+ ref: scrollRef,
7600
+ className: cn(
7601
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
7602
+ "border-b border-border",
7603
+ className
7604
+ ),
7605
+ children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-end gap-0", children: sections.map((s) => /* @__PURE__ */ jsx(
7606
+ "button",
7607
+ {
7608
+ "data-section": s.id,
7609
+ type: "button",
7610
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
7611
+ className: cn(
7612
+ "relative px-4 py-2.5 text-sm font-ui whitespace-nowrap transition-colors duration-150",
7613
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
7614
+ "after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full after:transition-all",
7615
+ bold ? "font-semibold" : "font-normal",
7616
+ activeSection === s.id ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent"
7617
+ ),
7618
+ children: s.label
7619
+ },
7620
+ s.id
7621
+ )) })
7622
+ }
7623
+ );
7624
+ }
7625
+ if (variant === "outlined") {
7626
+ return /* @__PURE__ */ jsx(
7627
+ "div",
7628
+ {
7629
+ ref: scrollRef,
7630
+ className: cn(
7631
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
7632
+ className
7633
+ ),
7634
+ children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-2", children: sections.map((s) => /* @__PURE__ */ jsx(
7635
+ "button",
7636
+ {
7637
+ "data-section": s.id,
7638
+ type: "button",
7639
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
7640
+ className: cn(
7641
+ "rounded-full border px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
7642
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7643
+ bold ? "font-semibold" : "font-normal",
7644
+ activeSection === s.id ? "border-foreground bg-foreground text-background" : "border-border bg-background text-muted-foreground hover:border-foreground/50 hover:text-foreground"
7645
+ ),
7646
+ children: s.label
7647
+ },
7648
+ s.id
7649
+ )) })
7650
+ }
7651
+ );
7652
+ }
7653
+ if (variant === "floating") {
7654
+ return /* @__PURE__ */ jsx(
7655
+ "div",
7656
+ {
7657
+ ref: scrollRef,
7658
+ className: cn(
7659
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
7660
+ "py-1 px-0.5",
7661
+ /* padding so shadow isn't clipped by overflow */
7662
+ className
7663
+ ),
7664
+ children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-0.5 rounded-full border border-border/40 bg-background/90 backdrop-blur-md shadow-sm px-1.5 py-1.5", children: sections.map((s) => /* @__PURE__ */ jsx(
7665
+ "button",
7666
+ {
7667
+ "data-section": s.id,
7668
+ type: "button",
7669
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
7670
+ className: cn(
7671
+ "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
7672
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7673
+ bold ? "font-semibold" : "font-normal",
7674
+ activeSection === s.id ? "bg-foreground text-background shadow-sm" : "text-foreground/60 hover:text-foreground hover:bg-muted/60"
7675
+ ),
7676
+ children: s.label
7677
+ },
7678
+ s.id
7679
+ )) })
7680
+ }
7681
+ );
7682
+ }
7683
+ return /* @__PURE__ */ jsx(
7684
+ "div",
7685
+ {
7686
+ ref: scrollRef,
7687
+ className: cn(
7688
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
7689
+ className
7690
+ ),
7691
+ children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-1 p-1", children: sections.map((s) => /* @__PURE__ */ jsx(
7692
+ "button",
7693
+ {
7694
+ "data-section": s.id,
7695
+ type: "button",
7696
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
7697
+ className: cn(
7698
+ "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
7699
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7700
+ bold ? "font-semibold" : "font-normal",
7701
+ activeSection === s.id ? "bg-foreground text-background shadow-sm" : "bg-white text-foreground/70 hover:text-foreground shadow-sm"
7702
+ ),
7703
+ children: s.label
7704
+ },
7705
+ s.id
7706
+ )) })
7707
+ }
7708
+ );
7709
+ }
7710
+ var badgeVariants = cva(
7711
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
7712
+ {
7713
+ variants: {
7714
+ variant: {
7715
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
7716
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
7717
+ destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
7718
+ outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
7719
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
7720
+ link: "text-primary underline-offset-4 hover:underline"
7721
+ }
7722
+ },
7723
+ defaultVariants: {
7724
+ variant: "default"
7725
+ }
7726
+ }
7480
7727
  );
7481
7728
  function Badge(_a) {
7482
7729
  var _b = _a, {
@@ -7508,34 +7755,124 @@ function PricingTrip({
7508
7755
  currency = "CHF",
7509
7756
  season,
7510
7757
  departureTimes,
7511
- pricingOptions,
7512
7758
  onBook,
7513
7759
  bookLabel = "Check availability",
7514
7760
  variant = "card",
7761
+ sharp = false,
7762
+ belowPrice,
7763
+ benefits,
7764
+ currencyEstimates,
7765
+ priceInfo,
7515
7766
  className
7516
7767
  }) {
7517
- const [showPricing, setShowPricing] = React23.useState(false);
7768
+ const rOuter = sharp ? "rounded-none" : "rounded-2xl";
7769
+ const [showEstimates, setShowEstimates] = React25.useState(false);
7770
+ const [showPriceInfo, setShowPriceInfo] = React25.useState(false);
7518
7771
  if (variant === "compact") {
7519
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", className), children: [
7520
- /* @__PURE__ */ jsxs("div", { children: [
7521
- /* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
7522
- /* @__PURE__ */ jsxs("p", { className: "text-lg font-bold text-foreground font-heading leading-none", children: [
7523
- currency,
7524
- " ",
7525
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: priceFrom })
7526
- ] })
7772
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
7773
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
7774
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
7775
+ /* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
7776
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-1.5 flex-wrap", children: [
7777
+ /* @__PURE__ */ jsxs("p", { className: "text-lg font-bold text-foreground font-heading leading-none", children: [
7778
+ currency,
7779
+ " ",
7780
+ priceFrom,
7781
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] font-normal text-muted-foreground font-ui ml-1", children: "/ per person" })
7782
+ ] }),
7783
+ (priceInfo || currencyEstimates && currencyEstimates.length > 0) && /* @__PURE__ */ jsx(
7784
+ "button",
7785
+ {
7786
+ type: "button",
7787
+ onClick: () => setShowPriceInfo((v) => !v),
7788
+ "aria-label": "Price details and currency estimates",
7789
+ "aria-expanded": showPriceInfo,
7790
+ className: cn(
7791
+ "inline-flex h-4 w-4 items-center justify-center rounded-full translate-y-px",
7792
+ "text-muted-foreground hover:text-foreground transition-colors",
7793
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
7794
+ ),
7795
+ children: /* @__PURE__ */ jsx(
7796
+ ChevronDownIcon,
7797
+ {
7798
+ className: cn(
7799
+ "h-4 w-4 transition-transform",
7800
+ showPriceInfo && "rotate-180"
7801
+ )
7802
+ }
7803
+ )
7804
+ }
7805
+ )
7806
+ ] })
7807
+ ] }),
7808
+ /* @__PURE__ */ jsx(
7809
+ "button",
7810
+ {
7811
+ type: "button",
7812
+ onClick: onBook,
7813
+ className: cn(
7814
+ "shrink-0 rounded-full bg-primary px-5 py-2 text-sm font-semibold",
7815
+ "text-primary-foreground font-ui transition-colors hover:bg-primary/90",
7816
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
7817
+ ),
7818
+ children: bookLabel
7819
+ }
7820
+ )
7527
7821
  ] }),
7528
- /* @__PURE__ */ jsx(
7529
- "button",
7822
+ showPriceInfo && (priceInfo || currencyEstimates && currencyEstimates.length > 0) && /* @__PURE__ */ jsxs(
7823
+ "div",
7530
7824
  {
7531
- type: "button",
7532
- onClick: onBook,
7533
7825
  className: cn(
7534
- "flex-1 rounded-full bg-primary px-4 py-2 text-sm font-semibold",
7535
- "text-primary-foreground font-ui transition-colors hover:bg-primary/90",
7536
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
7826
+ "rounded-xl border border-border bg-muted/40 overflow-hidden",
7827
+ "font-ui text-sm leading-relaxed text-foreground"
7537
7828
  ),
7538
- children: bookLabel
7829
+ children: [
7830
+ priceInfo && /* @__PURE__ */ jsx(
7831
+ "div",
7832
+ {
7833
+ className: cn(
7834
+ "p-3",
7835
+ "[&_a]:font-semibold [&_a]:text-primary [&_a]:underline-offset-4",
7836
+ "[&_a]:underline [&_a]:decoration-primary/30 hover:[&_a]:decoration-primary"
7837
+ ),
7838
+ children: priceInfo
7839
+ }
7840
+ ),
7841
+ currencyEstimates && currencyEstimates.length > 0 && /* @__PURE__ */ jsxs(
7842
+ "div",
7843
+ {
7844
+ className: cn(
7845
+ "bg-background",
7846
+ priceInfo && "border-t border-border"
7847
+ ),
7848
+ children: [
7849
+ /* @__PURE__ */ jsx("p", { className: "px-3 pt-3 pb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "See estimates in other currencies" }),
7850
+ currencyEstimates.map((est, i) => /* @__PURE__ */ jsxs(
7851
+ "div",
7852
+ {
7853
+ className: cn(
7854
+ "flex items-center justify-between px-3 py-2 text-sm",
7855
+ "border-t border-border"
7856
+ ),
7857
+ children: [
7858
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: est.currency }),
7859
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-foreground", children: [
7860
+ est.symbol ? `${est.symbol} ` : "",
7861
+ est.price
7862
+ ] })
7863
+ ]
7864
+ },
7865
+ i
7866
+ )),
7867
+ /* @__PURE__ */ jsxs("p", { className: "px-3 py-2 text-[11px] leading-snug text-muted-foreground bg-muted/40 italic border-t border-border", children: [
7868
+ "Estimates based on the current exchange rate. The final price charged is in ",
7869
+ currency,
7870
+ "."
7871
+ ] })
7872
+ ]
7873
+ }
7874
+ )
7875
+ ]
7539
7876
  }
7540
7877
  )
7541
7878
  ] });
@@ -7545,7 +7882,8 @@ function PricingTrip({
7545
7882
  "div",
7546
7883
  {
7547
7884
  className: cn(
7548
- "flex items-center gap-4 rounded-2xl border border-border bg-card px-5 py-3 shadow-sm",
7885
+ "flex items-center gap-4 border border-border bg-card px-5 py-3 shadow-sm",
7886
+ rOuter,
7549
7887
  className
7550
7888
  ),
7551
7889
  children: [
@@ -7589,67 +7927,103 @@ function PricingTrip({
7589
7927
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
7590
7928
  /* @__PURE__ */ jsxs("div", { children: [
7591
7929
  /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide", children: "From" }),
7592
- /* @__PURE__ */ jsxs("p", { className: "text-3xl font-bold text-foreground font-heading", children: [
7593
- currency,
7594
- " ",
7595
- /* @__PURE__ */ jsx("span", { className: "text-primary", children: priceFrom }),
7596
- /* @__PURE__ */ jsx("span", { className: "text-base font-normal text-muted-foreground font-ui", children: " / guest" })
7930
+ /* @__PURE__ */ jsxs("p", { className: "text-2xl font-bold text-foreground font-heading flex items-center gap-2 flex-wrap", children: [
7931
+ /* @__PURE__ */ jsxs("span", { children: [
7932
+ currency,
7933
+ " ",
7934
+ priceFrom,
7935
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground font-ui", children: " / per person" })
7936
+ ] }),
7937
+ priceInfo && /* @__PURE__ */ jsx(
7938
+ "button",
7939
+ {
7940
+ type: "button",
7941
+ onClick: () => setShowPriceInfo((v) => !v),
7942
+ "aria-label": "Why does the price vary?",
7943
+ "aria-expanded": showPriceInfo,
7944
+ className: cn(
7945
+ "inline-flex h-5 w-5 items-center justify-center rounded-full",
7946
+ "translate-y-[3px] -translate-x-[3px]",
7947
+ "text-muted-foreground hover:text-foreground transition-colors",
7948
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
7949
+ ),
7950
+ children: /* @__PURE__ */ jsx(
7951
+ ChevronDownIcon,
7952
+ {
7953
+ className: cn(
7954
+ "h-4 w-4 transition-transform",
7955
+ showPriceInfo && "rotate-180"
7956
+ )
7957
+ }
7958
+ )
7959
+ }
7960
+ )
7597
7961
  ] })
7598
7962
  ] }),
7599
- season && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-sm text-muted-foreground font-ui", children: [
7600
- /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4 shrink-0 text-primary mt-0.5" }),
7601
- /* @__PURE__ */ jsx("span", { children: season })
7602
- ] }),
7603
- departureTimes && departureTimes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
7604
- /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-foreground font-ui uppercase tracking-wide", children: "Departure times" }),
7605
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: departureTimes.map((t) => /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "font-ui text-xs", children: t }, t)) })
7606
- ] }),
7607
- pricingOptions && pricingOptions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
7963
+ priceInfo && showPriceInfo && /* @__PURE__ */ jsx(
7964
+ "div",
7965
+ {
7966
+ className: cn(
7967
+ "rounded-xl border border-border bg-muted/40 p-4",
7968
+ "font-ui text-sm leading-relaxed text-foreground",
7969
+ "[&_a]:font-semibold [&_a]:text-primary [&_a]:underline-offset-4",
7970
+ "[&_a]:underline [&_a]:decoration-primary/30 hover:[&_a]:decoration-primary"
7971
+ ),
7972
+ children: priceInfo
7973
+ }
7974
+ ),
7975
+ belowPrice && /* @__PURE__ */ jsx("div", { children: belowPrice }),
7976
+ benefits && benefits.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: benefits.map((b, i) => /* @__PURE__ */ jsxs(
7977
+ "li",
7978
+ {
7979
+ className: "flex items-start gap-2.5 text-sm text-foreground font-ui",
7980
+ children: [
7981
+ /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4 shrink-0 text-primary mt-0.5" }),
7982
+ b
7983
+ ]
7984
+ },
7985
+ i
7986
+ )) }),
7987
+ currencyEstimates && currencyEstimates.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
7608
7988
  /* @__PURE__ */ jsx(
7609
7989
  "button",
7610
7990
  {
7611
7991
  type: "button",
7612
- onClick: () => setShowPricing((v) => !v),
7992
+ onClick: () => setShowEstimates((v) => !v),
7613
7993
  className: "flex items-center gap-1 text-xs text-primary font-ui text-left hover:underline underline-offset-2",
7614
- children: showPricing ? /* @__PURE__ */ jsxs(Fragment, { children: [
7615
- "Show pricing options ",
7994
+ children: showEstimates ? /* @__PURE__ */ jsxs(Fragment, { children: [
7995
+ "Hide estimates in other currencies ",
7616
7996
  /* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-3 w-3" })
7617
7997
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7618
- "Show pricing options ",
7998
+ "Show estimates in other currencies ",
7619
7999
  /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-3 w-3" })
7620
8000
  ] })
7621
8001
  }
7622
8002
  ),
7623
- showPricing && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border overflow-hidden", children: pricingOptions.map((opt, i) => /* @__PURE__ */ jsxs(
7624
- "div",
7625
- {
7626
- className: cn(
7627
- "flex items-center justify-between px-3 py-2.5 text-sm",
7628
- i < pricingOptions.length - 1 && "border-b border-border"
7629
- ),
7630
- children: [
7631
- /* @__PURE__ */ jsx("span", { className: "text-foreground font-ui", children: opt.label }),
7632
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-right", children: [
7633
- opt.originalPrice && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground line-through font-ui", children: [
7634
- currency,
7635
- " ",
7636
- opt.originalPrice
7637
- ] }),
7638
- /* @__PURE__ */ jsxs("span", { className: "font-bold text-foreground font-ui", children: [
7639
- currency,
7640
- " ",
7641
- opt.price,
7642
- opt.unit && /* @__PURE__ */ jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: [
7643
- " ",
7644
- "/ ",
7645
- opt.unit
7646
- ] })
8003
+ showEstimates && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border overflow-hidden", children: [
8004
+ currencyEstimates.map((est, i) => /* @__PURE__ */ jsxs(
8005
+ "div",
8006
+ {
8007
+ className: cn(
8008
+ "flex items-center justify-between px-3 py-2 text-sm font-ui",
8009
+ i < currencyEstimates.length - 1 && "border-b border-border"
8010
+ ),
8011
+ children: [
8012
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: est.currency }),
8013
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold text-foreground", children: [
8014
+ est.symbol ? `${est.symbol} ` : "",
8015
+ est.price
7647
8016
  ] })
7648
- ] })
7649
- ]
7650
- },
7651
- i
7652
- )) })
8017
+ ]
8018
+ },
8019
+ i
8020
+ )),
8021
+ /* @__PURE__ */ jsxs("p", { className: "px-3 py-2 text-[11px] leading-snug text-muted-foreground bg-muted/40 italic font-ui border-t border-border", children: [
8022
+ "Estimates based on the current exchange rate. The final price charged is in ",
8023
+ currency,
8024
+ "."
8025
+ ] })
8026
+ ] })
7653
8027
  ] }),
7654
8028
  /* @__PURE__ */ jsx(
7655
8029
  "button",
@@ -7837,14 +8211,14 @@ function SiteHeader({
7837
8211
  className
7838
8212
  }) {
7839
8213
  const t = VARIANT[variant];
7840
- const [openMenu, setOpenMenu] = React23.useState(null);
7841
- const [langOpen, setLangOpen] = React23.useState(false);
7842
- const [mobileOpen, setMobileOpen] = React23.useState(false);
7843
- const [openMobileSection, setOpenMobileSection] = React23.useState(null);
7844
- const [activeLang, setActiveLang] = React23.useState(currentLanguage);
8214
+ const [openMenu, setOpenMenu] = React25.useState(null);
8215
+ const [langOpen, setLangOpen] = React25.useState(false);
8216
+ const [mobileOpen, setMobileOpen] = React25.useState(false);
8217
+ const [openMobileSection, setOpenMobileSection] = React25.useState(null);
8218
+ const [activeLang, setActiveLang] = React25.useState(currentLanguage);
7845
8219
  const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
7846
- const menuCloseTimer = React23.useRef(void 0);
7847
- const langCloseTimer = React23.useRef(void 0);
8220
+ const menuCloseTimer = React25.useRef(void 0);
8221
+ const langCloseTimer = React25.useRef(void 0);
7848
8222
  const handleMenuEnter = (label) => {
7849
8223
  clearTimeout(menuCloseTimer.current);
7850
8224
  setOpenMenu(label);
@@ -7865,7 +8239,7 @@ function SiteHeader({
7865
8239
  setOpenMenu(null);
7866
8240
  setLangOpen(false);
7867
8241
  };
7868
- React23.useEffect(() => () => {
8242
+ React25.useEffect(() => () => {
7869
8243
  clearTimeout(menuCloseTimer.current);
7870
8244
  clearTimeout(langCloseTimer.current);
7871
8245
  }, []);
@@ -8130,7 +8504,7 @@ function SiteHeader({
8130
8504
  ), children: [
8131
8505
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
8132
8506
  const isActive = lang.code === activeLang;
8133
- return /* @__PURE__ */ jsxs(React23.Fragment, { children: [
8507
+ return /* @__PURE__ */ jsxs(React25.Fragment, { children: [
8134
8508
  i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
8135
8509
  "text-xs select-none",
8136
8510
  variant === "white" ? "text-border" : "text-white/15"
@@ -8192,8 +8566,8 @@ function SiteHeader({
8192
8566
  );
8193
8567
  }
8194
8568
  function ThemeToggle({ className }) {
8195
- const [dark, setDark] = React23.useState(false);
8196
- React23.useEffect(() => {
8569
+ const [dark, setDark] = React25.useState(false);
8570
+ React25.useEffect(() => {
8197
8571
  const saved = localStorage.getItem("theme");
8198
8572
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
8199
8573
  const isDark = saved === "dark" || !saved && prefersDark;
@@ -8344,7 +8718,7 @@ function TripCard({
8344
8718
  );
8345
8719
  }
8346
8720
  function useHlsVideo(videoRef, src) {
8347
- React23.useEffect(() => {
8721
+ React25.useEffect(() => {
8348
8722
  if (!src || !videoRef.current) return;
8349
8723
  const video = videoRef.current;
8350
8724
  if (!src.includes(".m3u8")) return;
@@ -8381,16 +8755,17 @@ function TripHeader({
8381
8755
  destination,
8382
8756
  duration,
8383
8757
  tagline,
8758
+ belowMeta,
8384
8759
  siteHeader,
8385
8760
  uiVariant = "v1",
8386
8761
  className
8387
8762
  }) {
8388
8763
  var _a;
8389
- const [heroIndex, setHeroIndex] = React23.useState(0);
8390
- const [videoReady, setVideoReady] = React23.useState(false);
8391
- const videoRef = React23.useRef(null);
8764
+ const [heroIndex, setHeroIndex] = React25.useState(0);
8765
+ const [videoReady, setVideoReady] = React25.useState(false);
8766
+ const videoRef = React25.useRef(null);
8392
8767
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
8393
- const validImages = React23.useMemo(
8768
+ const validImages = React25.useMemo(
8394
8769
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
8395
8770
  [images]
8396
8771
  );
@@ -8405,7 +8780,7 @@ function TripHeader({
8405
8780
  const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
8406
8781
  const hasMeta = !!(destination || duration);
8407
8782
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
8408
- React23.useEffect(() => {
8783
+ React25.useEffect(() => {
8409
8784
  if (!videoUrl) return;
8410
8785
  const el = videoRef.current;
8411
8786
  if (!el) return;
@@ -8547,7 +8922,7 @@ function TripHeader({
8547
8922
  siteHeader ? "-mt-44" : "-mt-36"
8548
8923
  ),
8549
8924
  children: [
8550
- 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(React23.Fragment, { children: [
8925
+ 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(React25.Fragment, { children: [
8551
8926
  i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
8552
8927
  /* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
8553
8928
  ] }, i)) }),
@@ -8572,7 +8947,8 @@ function TripHeader({
8572
8947
  duration.days === 1 ? "dia" : "dias"
8573
8948
  ] })
8574
8949
  ] })
8575
- ] }) : tagline ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm sm:text-base text-white/80 font-ui", children: tagline }) : null
8950
+ ] }) : tagline ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm sm:text-base text-white/80 font-ui", children: tagline }) : null,
8951
+ belowMeta && /* @__PURE__ */ jsx("div", { className: "mt-3", children: belowMeta })
8576
8952
  ]
8577
8953
  }
8578
8954
  ) })
@@ -8605,12 +8981,12 @@ function ItineraryTimeline({ steps }) {
8605
8981
  ] }),
8606
8982
  step.isTransfer && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs font-ui h-5 px-2", children: "Transfer" })
8607
8983
  ] }),
8608
- /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground leading-relaxed [&_p:not(:last-child)]:mb-2 [&_strong]:text-foreground [&_strong]:font-semibold", children: step.description })
8984
+ /* @__PURE__ */ jsx("div", { className: "text-base text-muted-foreground leading-relaxed [&_p:not(:last-child)]:mb-2 [&_strong]:text-foreground [&_strong]:font-semibold", children: step.description })
8609
8985
  ] })
8610
8986
  ] }, i)) });
8611
8987
  }
8612
8988
  function Checklist({ items, icon }) {
8613
- return /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
8989
+ return /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5 text-base text-foreground", children: [
8614
8990
  /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 text-primary", children: icon != null ? icon : /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }) }),
8615
8991
  item
8616
8992
  ] }, i)) });
@@ -8625,21 +9001,36 @@ function TripPage({
8625
9001
  breadcrumb,
8626
9002
  highlights,
8627
9003
  infoGroups,
9004
+ keyInfo,
8628
9005
  recommendedFor,
8629
9006
  overview,
9007
+ overviewHighlights,
8630
9008
  itinerary,
9009
+ itineraryDays,
8631
9010
  gallery,
8632
9011
  included,
9012
+ notIncluded,
8633
9013
  whatToBring,
8634
9014
  weather,
9015
+ optionalExtras,
9016
+ accommodation,
9017
+ food,
9018
+ termsAndConditions,
8635
9019
  meetingPoints,
9020
+ meetingPoint,
8636
9021
  faqs,
9022
+ sectionIcons,
8637
9023
  reviews,
9024
+ trustpilot,
9025
+ trustpilotMini,
9026
+ trustpilotHero,
8638
9027
  priceFrom,
8639
9028
  currency = "CHF",
8640
9029
  season,
8641
9030
  departureTimes,
8642
- pricingOptions,
9031
+ benefits,
9032
+ currencyEstimates,
9033
+ priceInfo,
8643
9034
  onBook,
8644
9035
  bookLabel,
8645
9036
  siteHeader,
@@ -8647,34 +9038,51 @@ function TripPage({
8647
9038
  features,
8648
9039
  className
8649
9040
  }) {
8650
- const [activeSection, setActiveSection] = React23.useState("");
8651
- const [navFloating, setNavFloating] = React23.useState(false);
8652
- const [navHidden, setNavHidden] = React23.useState(false);
8653
- const [isFloating, setIsFloating] = React23.useState(false);
8654
- const [sidebarPos, setSidebarPos] = React23.useState(null);
8655
- const [pricingBarVisible, setPricingBarVisible] = React23.useState(false);
8656
- const navRef = React23.useRef(null);
8657
- const navSentinelRef = React23.useRef(null);
8658
- const sentinelRef = React23.useRef(null);
8659
- const sidebarPlaceholderRef = React23.useRef(null);
8660
- const pricingBarRef = React23.useRef(null);
8661
- const galleryRef = React23.useRef(null);
8662
- const sections = React23.useMemo(
9041
+ const [activeSection, setActiveSection] = React25.useState("");
9042
+ const [accordionValue, setAccordionValue] = React25.useState([]);
9043
+ const accordionSectionIds = React25.useMemo(
9044
+ () => /* @__PURE__ */ new Set([
9045
+ "key-info",
9046
+ "what-to-bring",
9047
+ "weather",
9048
+ "optional-extras",
9049
+ "accommodation",
9050
+ "food",
9051
+ "meeting",
9052
+ "terms"
9053
+ ]),
9054
+ []
9055
+ );
9056
+ const [navFloating, setNavFloating] = React25.useState(false);
9057
+ const [navHidden, setNavHidden] = React25.useState(false);
9058
+ const [isFloating, setIsFloating] = React25.useState(false);
9059
+ const [sidebarPos, setSidebarPos] = React25.useState(null);
9060
+ const [pricingBarVisible, setPricingBarVisible] = React25.useState(false);
9061
+ const navRef = React25.useRef(null);
9062
+ const navSentinelRef = React25.useRef(null);
9063
+ const sentinelRef = React25.useRef(null);
9064
+ const sidebarPlaceholderRef = React25.useRef(null);
9065
+ const pricingBarRef = React25.useRef(null);
9066
+ const galleryRef = React25.useRef(null);
9067
+ const sections = React25.useMemo(
8663
9068
  () => [
8664
- { id: "key-info", label: "Key info", show: !!(infoGroups == null ? void 0 : infoGroups.length) },
8665
- { id: "overview", label: "Overview", show: !!overview },
8666
- { id: "itinerary", label: "Itinerary", show: !!(itinerary == null ? void 0 : itinerary.length) },
8667
- { id: "included", label: "Included", show: !!((included == null ? void 0 : included.length) || (whatToBring == null ? void 0 : whatToBring.length)) },
8668
- { id: "what-to-bring", label: "What to bring", show: !!(whatToBring == null ? void 0 : whatToBring.length) },
8669
- { id: "weather", label: "Weather", show: !!weather },
8670
- { id: "meeting", label: "Meeting point", show: !!(meetingPoints == null ? void 0 : meetingPoints.length) },
9069
+ { id: "overview", label: "Overview", show: !!(overview || (overviewHighlights == null ? void 0 : overviewHighlights.length)) },
9070
+ {
9071
+ id: "itinerary",
9072
+ label: "Itinerary",
9073
+ show: !!((itineraryDays == null ? void 0 : itineraryDays.length) || (itinerary == null ? void 0 : itinerary.length))
9074
+ },
9075
+ { id: "included", label: "What is Included", show: !!(included == null ? void 0 : included.length) },
9076
+ { id: "what-to-bring", label: "What to Bring", show: !!(whatToBring == null ? void 0 : whatToBring.length) },
9077
+ { id: "accommodation", label: "Accommodation", show: !!accommodation },
9078
+ { id: "terms", label: "Terms", show: !!termsAndConditions },
8671
9079
  { id: "faq", label: "FAQ", show: !!(faqs == null ? void 0 : faqs.length) },
8672
- { id: "gallery", label: "Photos", show: !!(gallery == null ? void 0 : gallery.length) }
9080
+ { id: "reviews", label: "Reviews", show: !!(trustpilot || (reviews == null ? void 0 : reviews.length)) }
8673
9081
  ].filter((s) => s.show),
8674
9082
  // eslint-disable-next-line react-hooks/exhaustive-deps
8675
9083
  []
8676
9084
  );
8677
- React23.useEffect(() => {
9085
+ React25.useEffect(() => {
8678
9086
  const sentinel = navSentinelRef.current;
8679
9087
  if (!sentinel) return;
8680
9088
  const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
@@ -8682,7 +9090,7 @@ function TripPage({
8682
9090
  update();
8683
9091
  return () => document.removeEventListener("scroll", update, { capture: true });
8684
9092
  }, []);
8685
- React23.useEffect(() => {
9093
+ React25.useEffect(() => {
8686
9094
  const sentinel = sentinelRef.current;
8687
9095
  if (!sentinel) return;
8688
9096
  const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
@@ -8690,7 +9098,7 @@ function TripPage({
8690
9098
  update();
8691
9099
  return () => document.removeEventListener("scroll", update, { capture: true });
8692
9100
  }, []);
8693
- React23.useEffect(() => {
9101
+ React25.useEffect(() => {
8694
9102
  const measure = () => {
8695
9103
  if (!sidebarPlaceholderRef.current) return;
8696
9104
  const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
@@ -8700,7 +9108,7 @@ function TripPage({
8700
9108
  window.addEventListener("resize", measure);
8701
9109
  return () => window.removeEventListener("resize", measure);
8702
9110
  }, [isFloating]);
8703
- React23.useEffect(() => {
9111
+ React25.useEffect(() => {
8704
9112
  const check = () => {
8705
9113
  var _a;
8706
9114
  const target = (_a = galleryRef.current) != null ? _a : pricingBarRef.current;
@@ -8711,7 +9119,7 @@ function TripPage({
8711
9119
  check();
8712
9120
  return () => document.removeEventListener("scroll", check, { capture: true });
8713
9121
  }, []);
8714
- React23.useEffect(() => {
9122
+ React25.useEffect(() => {
8715
9123
  const check = () => {
8716
9124
  if (!pricingBarRef.current) return;
8717
9125
  setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
@@ -8720,7 +9128,7 @@ function TripPage({
8720
9128
  check();
8721
9129
  return () => document.removeEventListener("scroll", check, { capture: true });
8722
9130
  }, []);
8723
- React23.useEffect(() => {
9131
+ React25.useEffect(() => {
8724
9132
  if (sections.length === 0) return;
8725
9133
  setActiveSection(sections[0].id);
8726
9134
  const update = () => {
@@ -8755,20 +9163,28 @@ function TripPage({
8755
9163
  }
8756
9164
  };
8757
9165
  const scrollToSection = (id) => {
8758
- var _a, _b, _c;
8759
- const el = document.getElementById(`trip-section-${id}`);
8760
- if (!el) return;
8761
- const navHeight = (_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56;
8762
- const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
8763
- const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
8764
- const elTop = el.getBoundingClientRect().top;
8765
- const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
8766
- const target = currentScroll + (elTop - containerTop) - navHeight - 12;
8767
- if (scrollEl) {
8768
- scrollEl.scrollTo({ top: target, behavior: "smooth" });
8769
- } else {
8770
- window.scrollTo({ top: target, behavior: "smooth" });
9166
+ const performScroll = () => {
9167
+ var _a, _b, _c;
9168
+ const el = document.getElementById(`trip-section-${id}`);
9169
+ if (!el) return;
9170
+ const navHeight = (_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56;
9171
+ const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
9172
+ const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
9173
+ const elTop = el.getBoundingClientRect().top;
9174
+ const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
9175
+ const target = currentScroll + (elTop - containerTop) - navHeight - 12;
9176
+ if (scrollEl) {
9177
+ scrollEl.scrollTo({ top: target, behavior: "smooth" });
9178
+ } else {
9179
+ window.scrollTo({ top: target, behavior: "smooth" });
9180
+ }
9181
+ };
9182
+ if (accordionSectionIds.has(id)) {
9183
+ setAccordionValue([id]);
9184
+ window.setTimeout(performScroll, 320);
9185
+ return;
8771
9186
  }
9187
+ performScroll();
8772
9188
  };
8773
9189
  return /* @__PURE__ */ jsxs(
8774
9190
  "div",
@@ -8788,10 +9204,11 @@ function TripPage({
8788
9204
  duration,
8789
9205
  tagline,
8790
9206
  siteHeader,
8791
- uiVariant
9207
+ uiVariant,
9208
+ belowMeta: trustpilotHero ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotHero }) : void 0
8792
9209
  }
8793
9210
  ),
8794
- /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6", children: [
9211
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
8795
9212
  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: [
8796
9213
  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 }),
8797
9214
  /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground font-ui", children: h.label })
@@ -8801,7 +9218,7 @@ function TripPage({
8801
9218
  "div",
8802
9219
  {
8803
9220
  className: cn(
8804
- "py-2 flex justify-center transition-opacity duration-150",
9221
+ "pt-8 pb-2 flex justify-center transition-opacity duration-150",
8805
9222
  navFloating ? "opacity-0 pointer-events-none" : "opacity-100"
8806
9223
  ),
8807
9224
  children: /* @__PURE__ */ jsx(
@@ -8818,67 +9235,208 @@ function TripPage({
8818
9235
  /* @__PURE__ */ jsx("div", { ref: sentinelRef, className: "h-px -mt-px", "aria-hidden": true }),
8819
9236
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row gap-8 mt-4", children: [
8820
9237
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 space-y-12 pb-12", children: [
8821
- infoGroups && infoGroups.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-key-info", className: "scroll-mt-20", children: [
8822
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Key info" }),
8823
- /* @__PURE__ */ jsx("div", { className: "space-y-6", children: infoGroups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
8824
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
8825
- group.icon && /* @__PURE__ */ jsx("span", { className: "text-primary", children: group.icon }),
8826
- /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading", children: group.title })
8827
- ] }),
8828
- /* @__PURE__ */ jsx(Checklist, { items: group.items }),
8829
- i < infoGroups.length - 1 && /* @__PURE__ */ jsx(Separator, { className: "mt-6" })
8830
- ] }, i)) })
8831
- ] }),
8832
- overview && /* @__PURE__ */ jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
8833
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-4", children: "Overview" }),
8834
- recommendedFor && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2.5 rounded-xl bg-primary/8 border border-primary/20 p-4 mb-4", children: [
9238
+ (overview || (overviewHighlights == null ? void 0 : overviewHighlights.length)) && /* @__PURE__ */ jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
9239
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
9240
+ (sectionIcons == null ? void 0 : sectionIcons.overview) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.overview }) : /* @__PURE__ */ jsx(InfoIcon, { className: "h-5 w-5 text-primary" }),
9241
+ "Overview"
9242
+ ] }),
9243
+ overview && /* @__PURE__ */ jsx("div", { className: "text-lg text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview }),
9244
+ 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: [
9245
+ 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 }),
9246
+ /* @__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 })
9247
+ ] }, i)) }),
9248
+ 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: [
8835
9249
  /* @__PURE__ */ jsx(UsersIcon, { className: "h-4 w-4 text-primary mt-0.5 shrink-0" }),
8836
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-foreground font-ui", children: [
9250
+ /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground font-ui", children: [
8837
9251
  /* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Recommended for: " }),
8838
9252
  recommendedFor
8839
9253
  ] })
8840
- ] }),
8841
- /* @__PURE__ */ jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview })
9254
+ ] })
8842
9255
  ] }),
8843
- itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
8844
- /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Itinerary" }),
9256
+ itineraryDays && itineraryDays.length > 0 ? /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
9257
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-6 flex items-center gap-2", children: [
9258
+ (sectionIcons == null ? void 0 : sectionIcons.itinerary) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.itinerary }) : /* @__PURE__ */ jsx(ClockIcon, { className: "h-5 w-5 text-primary" }),
9259
+ "Itinerary"
9260
+ ] }),
9261
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12", children: itineraryDays.map((day) => /* @__PURE__ */ jsx(
9262
+ ItineraryDay,
9263
+ __spreadProps(__spreadValues({}, day), {
9264
+ photoLayout: "fullBleedBottom"
9265
+ }),
9266
+ day.dayNumber
9267
+ )) })
9268
+ ] }) : itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
9269
+ /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-6 flex items-center gap-2", children: [
9270
+ (sectionIcons == null ? void 0 : sectionIcons.itinerary) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.itinerary }) : /* @__PURE__ */ jsx(ClockIcon, { className: "h-5 w-5 text-primary" }),
9271
+ "Itinerary"
9272
+ ] }),
8845
9273
  /* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary })
8846
9274
  ] }),
8847
9275
  included && included.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
8848
9276
  /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
8849
- /* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
9277
+ (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" }),
8850
9278
  "Included"
8851
9279
  ] }),
8852
9280
  /* @__PURE__ */ jsx(Checklist, { items: included })
8853
9281
  ] }),
8854
- whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-what-to-bring", className: "scroll-mt-20", children: [
8855
- /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
8856
- /* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
8857
- "What to bring"
8858
- ] }),
8859
- /* @__PURE__ */ jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4" }) })
8860
- ] }),
8861
- weather && /* @__PURE__ */ jsxs("section", { id: "trip-section-weather", className: "scroll-mt-20", children: [
9282
+ notIncluded && notIncluded.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-not-included", className: "scroll-mt-20", children: [
8862
9283
  /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
8863
- /* @__PURE__ */ jsx(SunIcon, { className: "h-5 w-5 text-primary" }),
8864
- "Weather"
9284
+ /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5 text-muted-foreground" }),
9285
+ "Not included"
8865
9286
  ] }),
8866
- /* @__PURE__ */ jsx("div", { className: "flex items-start gap-3 rounded-xl bg-muted/60 border border-border p-5", children: /* @__PURE__ */ jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-2 [&_strong]:font-semibold", children: weather }) })
8867
- ] }),
8868
- meetingPoints && meetingPoints.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-meeting", className: "scroll-mt-20", children: [
8869
- /* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
8870
- /* @__PURE__ */ jsx(MapPinIcon, { className: "h-5 w-5 text-primary" }),
8871
- "Meeting point"
8872
- ] }),
8873
- /* @__PURE__ */ jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
8874
- /* @__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" }) }),
8875
- /* @__PURE__ */ jsxs("div", { children: [
8876
- mp.type && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? "Activity location" : mp.type === "alternative" ? "Alternative meeting point" : "Meeting point" }),
8877
- /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
8878
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
8879
- ] })
8880
- ] }, i)) })
9287
+ /* @__PURE__ */ jsx(
9288
+ Checklist,
9289
+ {
9290
+ items: notIncluded,
9291
+ icon: /* @__PURE__ */ jsx(XIcon, { className: "h-4 w-4 text-muted-foreground" })
9292
+ }
9293
+ )
8881
9294
  ] }),
9295
+ ((infoGroups == null ? void 0 : infoGroups.length) || keyInfo || (whatToBring == null ? void 0 : whatToBring.length) || weather || optionalExtras || accommodation || food || (meetingPoints == null ? void 0 : meetingPoints.length) || meetingPoint || termsAndConditions) && /* @__PURE__ */ jsxs(
9296
+ Accordion,
9297
+ {
9298
+ multiple: false,
9299
+ value: accordionValue,
9300
+ onValueChange: setAccordionValue,
9301
+ className: "border-t border-border",
9302
+ children: [
9303
+ (keyInfo || infoGroups && infoGroups.length > 0) && /* @__PURE__ */ jsxs(
9304
+ AccordionItem,
9305
+ {
9306
+ value: "key-info",
9307
+ id: "trip-section-key-info",
9308
+ className: "scroll-mt-20 border-b border-border",
9309
+ children: [
9310
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9311
+ (sectionIcons == null ? void 0 : sectionIcons.keyInfo) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.keyInfo }) : /* @__PURE__ */ jsx(InfoIcon, { className: "h-5 w-5 text-primary" }),
9312
+ "Key info"
9313
+ ] }) }),
9314
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: keyInfo ? /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: keyInfo }) : /* @__PURE__ */ jsx("div", { className: "space-y-6", children: infoGroups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
9315
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
9316
+ group.icon && /* @__PURE__ */ jsx("span", { className: "text-primary", children: group.icon }),
9317
+ /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading", children: group.title })
9318
+ ] }),
9319
+ /* @__PURE__ */ jsx(Checklist, { items: group.items }),
9320
+ i < infoGroups.length - 1 && /* @__PURE__ */ jsx(Separator, { className: "mt-6" })
9321
+ ] }, i)) }) })
9322
+ ]
9323
+ }
9324
+ ),
9325
+ (meetingPoint || meetingPoints && meetingPoints.length > 0) && /* @__PURE__ */ jsxs(
9326
+ AccordionItem,
9327
+ {
9328
+ value: "meeting",
9329
+ id: "trip-section-meeting",
9330
+ className: "scroll-mt-20 border-b border-border",
9331
+ children: [
9332
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9333
+ (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" }),
9334
+ "Meeting point"
9335
+ ] }) }),
9336
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: meetingPoint ? /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: meetingPoint }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
9337
+ /* @__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" }) }),
9338
+ /* @__PURE__ */ jsxs("div", { children: [
9339
+ mp.type && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? "Activity location" : mp.type === "alternative" ? "Alternative meeting point" : "Meeting point" }),
9340
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
9341
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
9342
+ ] })
9343
+ ] }, i)) }) })
9344
+ ]
9345
+ }
9346
+ ),
9347
+ optionalExtras && /* @__PURE__ */ jsxs(
9348
+ AccordionItem,
9349
+ {
9350
+ value: "optional-extras",
9351
+ id: "trip-section-optional-extras",
9352
+ className: "scroll-mt-20 border-b border-border",
9353
+ children: [
9354
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9355
+ (sectionIcons == null ? void 0 : sectionIcons.optionalExtras) ? /* @__PURE__ */ jsx("span", { className: "text-primary [&>svg]:h-5 [&>svg]:w-5", children: sectionIcons.optionalExtras }) : /* @__PURE__ */ jsx(SparklesIcon, { className: "h-5 w-5 text-primary" }),
9356
+ "Optional extras"
9357
+ ] }) }),
9358
+ /* @__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 }) })
9359
+ ]
9360
+ }
9361
+ ),
9362
+ whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxs(
9363
+ AccordionItem,
9364
+ {
9365
+ value: "what-to-bring",
9366
+ id: "trip-section-what-to-bring",
9367
+ className: "scroll-mt-20 border-b border-border",
9368
+ children: [
9369
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9370
+ (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" }),
9371
+ "What to bring"
9372
+ ] }) }),
9373
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4" }) }) })
9374
+ ]
9375
+ }
9376
+ ),
9377
+ accommodation && /* @__PURE__ */ jsxs(
9378
+ AccordionItem,
9379
+ {
9380
+ value: "accommodation",
9381
+ id: "trip-section-accommodation",
9382
+ className: "scroll-mt-20 border-b border-border",
9383
+ children: [
9384
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9385
+ (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" }),
9386
+ "Accommodation"
9387
+ ] }) }),
9388
+ /* @__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: accommodation }) })
9389
+ ]
9390
+ }
9391
+ ),
9392
+ food && /* @__PURE__ */ jsxs(
9393
+ AccordionItem,
9394
+ {
9395
+ value: "food",
9396
+ id: "trip-section-food",
9397
+ className: "scroll-mt-20 border-b border-border",
9398
+ children: [
9399
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9400
+ (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" }),
9401
+ "Food"
9402
+ ] }) }),
9403
+ /* @__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: food }) })
9404
+ ]
9405
+ }
9406
+ ),
9407
+ weather && /* @__PURE__ */ jsxs(
9408
+ AccordionItem,
9409
+ {
9410
+ value: "weather",
9411
+ id: "trip-section-weather",
9412
+ className: "scroll-mt-20 border-b border-border",
9413
+ children: [
9414
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9415
+ (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" }),
9416
+ "Weather"
9417
+ ] }) }),
9418
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-6", children: /* @__PURE__ */ jsx("div", { className: "flex items-start gap-3 rounded-xl bg-muted/60 border border-border p-5", children: /* @__PURE__ */ jsx("div", { className: "text-base text-foreground leading-relaxed space-y-2 [&_strong]:font-semibold", children: weather }) }) })
9419
+ ]
9420
+ }
9421
+ ),
9422
+ termsAndConditions && /* @__PURE__ */ jsxs(
9423
+ AccordionItem,
9424
+ {
9425
+ value: "terms",
9426
+ id: "trip-section-terms",
9427
+ className: "scroll-mt-20 border-b border-border",
9428
+ children: [
9429
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: "py-5 text-xl font-bold text-foreground font-heading hover:no-underline", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
9430
+ (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" }),
9431
+ "Terms & conditions"
9432
+ ] }) }),
9433
+ /* @__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 }) })
9434
+ ]
9435
+ }
9436
+ )
9437
+ ]
9438
+ }
9439
+ ),
8882
9440
  faqs && faqs.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
8883
9441
  /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "FAQ" }),
8884
9442
  /* @__PURE__ */ jsx(Accordion, { variant: "faq", children: faqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
@@ -8886,14 +9444,18 @@ function TripPage({
8886
9444
  /* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
8887
9445
  ] }, i)) })
8888
9446
  ] }),
8889
- reviews && reviews.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
9447
+ trustpilot ? /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
9448
+ /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
9449
+ /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: "What our guests think" }),
9450
+ /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilot })
9451
+ ] }) : reviews && reviews.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-reviews", className: "scroll-mt-20", children: [
8890
9452
  /* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
8891
9453
  /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: "What our guests think" }),
8892
9454
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: reviews.map((r, i) => {
8893
9455
  var _a;
8894
9456
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border p-5", children: [
8895
9457
  /* @__PURE__ */ jsx(Stars, { count: (_a = r.rating) != null ? _a : 5 }),
8896
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-foreground leading-relaxed line-clamp-4", children: [
9458
+ /* @__PURE__ */ jsxs("p", { className: "text-base text-foreground leading-relaxed line-clamp-4", children: [
8897
9459
  "\u201C",
8898
9460
  r.text,
8899
9461
  "\u201D"
@@ -8913,10 +9475,13 @@ function TripPage({
8913
9475
  currency,
8914
9476
  season,
8915
9477
  departureTimes,
8916
- pricingOptions,
8917
9478
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
8918
9479
  bookLabel: bookLabel != null ? bookLabel : "Check availability",
8919
- variant: "card"
9480
+ variant: "card",
9481
+ belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
9482
+ benefits,
9483
+ currencyEstimates,
9484
+ priceInfo
8920
9485
  }
8921
9486
  ) }) })
8922
9487
  ] })
@@ -8929,7 +9494,7 @@ function TripPage({
8929
9494
  "fixed top-0 left-0 right-0 z-20 py-3 transition-all duration-200",
8930
9495
  navFloating && !navHidden ? "translate-y-0 opacity-100" : "-translate-y-full opacity-0 pointer-events-none"
8931
9496
  ),
8932
- children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6 flex justify-center", children: /* @__PURE__ */ jsx(
9497
+ children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 flex justify-center", children: /* @__PURE__ */ jsx(
8933
9498
  MenuTrip,
8934
9499
  {
8935
9500
  sections,
@@ -8952,10 +9517,13 @@ function TripPage({
8952
9517
  currency,
8953
9518
  season,
8954
9519
  departureTimes,
8955
- pricingOptions,
8956
9520
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
8957
9521
  bookLabel: bookLabel != null ? bookLabel : "Check availability",
8958
- variant: "card"
9522
+ variant: "card",
9523
+ belowPrice: trustpilotMini ? /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) : void 0,
9524
+ benefits,
9525
+ currencyEstimates,
9526
+ priceInfo
8959
9527
  }
8960
9528
  ) })
8961
9529
  }
@@ -8968,7 +9536,7 @@ function TripPage({
8968
9536
  initialVisible: 6
8969
9537
  }
8970
9538
  ) }),
8971
- gallery && gallery.length > 0 && /* @__PURE__ */ jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-5xl px-4 sm:px-6 py-12", children: /* @__PURE__ */ jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsx(BookingForm, { onSubmit: onBook ? (values) => onBook() : void 0 }) }) }),
9539
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: /* @__PURE__ */ jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsx(BookingForm, { onSubmit: onBook ? (values) => onBook() : void 0 }) }) }),
8972
9540
  /* @__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(
8973
9541
  PricingTrip,
8974
9542
  {
@@ -8976,7 +9544,10 @@ function TripPage({
8976
9544
  currency,
8977
9545
  onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
8978
9546
  bookLabel: bookLabel != null ? bookLabel : "Book now",
8979
- variant: "compact"
9547
+ variant: "compact",
9548
+ sharp: true,
9549
+ priceInfo,
9550
+ currencyEstimates
8980
9551
  }
8981
9552
  ) }),
8982
9553
  /* @__PURE__ */ jsx("div", { className: "h-20 lg:hidden" })
@@ -9085,12 +9656,12 @@ function Toast({
9085
9656
  duration = 6e3,
9086
9657
  className
9087
9658
  }) {
9088
- const [mounted, setMounted] = React23.useState(false);
9089
- const [visible, setVisible] = React23.useState(true);
9090
- React23.useEffect(() => {
9659
+ const [mounted, setMounted] = React25.useState(false);
9660
+ const [visible, setVisible] = React25.useState(true);
9661
+ React25.useEffect(() => {
9091
9662
  setMounted(true);
9092
9663
  }, []);
9093
- React23.useEffect(() => {
9664
+ React25.useEffect(() => {
9094
9665
  if (duration === 0) return;
9095
9666
  const t = setTimeout(() => {
9096
9667
  setVisible(false);
@@ -9794,6 +10365,6 @@ function LeadCapturePopup({
9794
10365
  );
9795
10366
  }
9796
10367
 
9797
- export { ActivityCard, AgentContactCard, Alert, BirthDateField, BookingConfirmation, BookingConfirmationEmail, BookingConfirmedCard, BookingDetails, BookingForm, BookingOtpEmail, BookingShell, Button, COUNTRIES, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, FilterPanel, FloatingInput, FloatingSelect, Itinerary, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, PaymentAmountSelector, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PhoneCountrySelect, PhotoGallery, PricingTrip, RegistrationForm, RegistrationSuccessCard, SiteHeader, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, buttonVariants, cn, emailTokens, getStripeAppearance, stripeAppearance, wrapEmailHtml };
10368
+ export { ActivityCard, AgentContactCard, Alert, BirthDateField, BookingConfirmation, BookingConfirmationEmail, BookingConfirmedCard, BookingDetails, BookingForm, BookingOtpEmail, BookingShell, Button, COUNTRIES, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, FilterPanel, FloatingInput, FloatingSelect, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, PaymentAmountSelector, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PhoneCountrySelect, PhotoGallery, PricingTrip, RegistrationForm, RegistrationSuccessCard, SiteHeader, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, buttonVariants, cn, emailTokens, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, wrapEmailHtml };
9798
10369
  //# sourceMappingURL=index.js.map
9799
10370
  //# sourceMappingURL=index.js.map