@planetaexo/design-system 0.52.3 → 0.54.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.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React28 = require('react');
3
+ var React29 = require('react');
4
4
  var classVarianceAuthority = require('class-variance-authority');
5
5
  var clsx = require('clsx');
6
6
  var tailwindMerge = require('tailwind-merge');
@@ -37,7 +37,7 @@ function _interopNamespace(e) {
37
37
  return Object.freeze(n);
38
38
  }
39
39
 
40
- var React28__namespace = /*#__PURE__*/_interopNamespace(React28);
40
+ var React29__namespace = /*#__PURE__*/_interopNamespace(React29);
41
41
 
42
42
  var __defProp = Object.defineProperty;
43
43
  var __defProps = Object.defineProperties;
@@ -102,7 +102,7 @@ var buttonVariants = classVarianceAuthority.cva(
102
102
  }
103
103
  }
104
104
  );
105
- var Button = React28__namespace.forwardRef(
105
+ var Button = React29__namespace.forwardRef(
106
106
  (_a, ref) => {
107
107
  var _b = _a, { className, variant, size } = _b, props = __objRest(_b, ["className", "variant", "size"]);
108
108
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -331,10 +331,10 @@ function DialogDescription(_a) {
331
331
  }, props)
332
332
  );
333
333
  }
334
- var FloatingInput = React28__namespace.forwardRef(
334
+ var FloatingInput = React29__namespace.forwardRef(
335
335
  (_a, ref) => {
336
336
  var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
337
- const inputId = id != null ? id : React28__namespace.useId();
337
+ const inputId = id != null ? id : React29__namespace.useId();
338
338
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
339
339
  /* @__PURE__ */ jsxRuntime.jsx(
340
340
  "input",
@@ -374,10 +374,10 @@ var FloatingInput = React28__namespace.forwardRef(
374
374
  }
375
375
  );
376
376
  FloatingInput.displayName = "FloatingInput";
377
- var FloatingSelect = React28__namespace.forwardRef(
377
+ var FloatingSelect = React29__namespace.forwardRef(
378
378
  (_a, ref) => {
379
379
  var _b = _a, { label, error, id, className, required, children, value } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children", "value"]);
380
- const inputId = id != null ? id : React28__namespace.useId();
380
+ const inputId = id != null ? id : React29__namespace.useId();
381
381
  const hasValue = typeof value === "string" ? value !== "" : value !== void 0 && value !== null;
382
382
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
383
383
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -641,11 +641,11 @@ function PhoneCountrySelect({
641
641
  disabled
642
642
  }) {
643
643
  var _a;
644
- const [open, setOpen] = React28__namespace.useState(false);
645
- const containerRef = React28__namespace.useRef(null);
646
- const listRef = React28__namespace.useRef(null);
644
+ const [open, setOpen] = React29__namespace.useState(false);
645
+ const containerRef = React29__namespace.useRef(null);
646
+ const listRef = React29__namespace.useRef(null);
647
647
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
648
- React28__namespace.useEffect(() => {
648
+ React29__namespace.useEffect(() => {
649
649
  if (!open) return;
650
650
  const handler = (e) => {
651
651
  var _a2;
@@ -656,7 +656,7 @@ function PhoneCountrySelect({
656
656
  document.addEventListener("mousedown", handler);
657
657
  return () => document.removeEventListener("mousedown", handler);
658
658
  }, [open]);
659
- React28__namespace.useEffect(() => {
659
+ React29__namespace.useEffect(() => {
660
660
  if (!open || !listRef.current) return;
661
661
  const activeEl = listRef.current.querySelector("[data-selected=true]");
662
662
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -926,8 +926,8 @@ function CalendarDayButton(_a) {
926
926
  "locale"
927
927
  ]);
928
928
  const defaultClassNames = reactDayPicker.getDefaultClassNames();
929
- const ref = React28__namespace.useRef(null);
930
- React28__namespace.useEffect(() => {
929
+ const ref = React29__namespace.useRef(null);
930
+ React29__namespace.useEffect(() => {
931
931
  var _a2;
932
932
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
933
933
  }, [modifiers.focused]);
@@ -958,16 +958,16 @@ function BirthDateField({
958
958
  className,
959
959
  disabled
960
960
  }) {
961
- const [open, setOpen] = React28__namespace.useState(false);
962
- const [text, setText] = React28__namespace.useState(
961
+ const [open, setOpen] = React29__namespace.useState(false);
962
+ const [text, setText] = React29__namespace.useState(
963
963
  value ? dateFns.format(value, "dd/MM/yyyy") : ""
964
964
  );
965
- const containerRef = React28__namespace.useRef(null);
966
- const inputId = React28__namespace.useId();
967
- React28__namespace.useEffect(() => {
965
+ const containerRef = React29__namespace.useRef(null);
966
+ const inputId = React29__namespace.useId();
967
+ React29__namespace.useEffect(() => {
968
968
  setText(value ? dateFns.format(value, "dd/MM/yyyy") : "");
969
969
  }, [value]);
970
- React28__namespace.useEffect(() => {
970
+ React29__namespace.useEffect(() => {
971
971
  if (!open) return;
972
972
  const handler = (e) => {
973
973
  var _a;
@@ -1176,14 +1176,14 @@ function CountrySearchField({
1176
1176
  }) {
1177
1177
  var _a;
1178
1178
  const list = countries != null ? countries : COUNTRIES;
1179
- const [query, setQuery] = React28__namespace.useState("");
1180
- const [open, setOpen] = React28__namespace.useState(false);
1181
- const containerRef = React28__namespace.useRef(null);
1182
- const searchRef = React28__namespace.useRef(null);
1179
+ const [query, setQuery] = React29__namespace.useState("");
1180
+ const [open, setOpen] = React29__namespace.useState(false);
1181
+ const containerRef = React29__namespace.useRef(null);
1182
+ const searchRef = React29__namespace.useRef(null);
1183
1183
  const selected = list.find((c) => c.code === value);
1184
1184
  const isFloated = open || !!selected;
1185
1185
  const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
1186
- React28__namespace.useEffect(() => {
1186
+ React29__namespace.useEffect(() => {
1187
1187
  if (!open) return;
1188
1188
  const handler = (e) => {
1189
1189
  var _a2;
@@ -1277,16 +1277,47 @@ var VARIANT_STYLES = {
1277
1277
  success: "text-primary border-primary/30 bg-primary/10",
1278
1278
  info: "text-muted-foreground border-primary/25 bg-primary/5"
1279
1279
  };
1280
- function Alert({ variant = "info", children, className }) {
1281
- return /* @__PURE__ */ jsxRuntime.jsx(
1280
+ function Alert({
1281
+ variant = "info",
1282
+ title,
1283
+ icon,
1284
+ action,
1285
+ role = "status",
1286
+ children,
1287
+ className
1288
+ }) {
1289
+ const isBanner = Boolean(title || icon || action);
1290
+ if (!isBanner) {
1291
+ return /* @__PURE__ */ jsxRuntime.jsx(
1292
+ "div",
1293
+ {
1294
+ role,
1295
+ className: cn(
1296
+ "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
1297
+ VARIANT_STYLES[variant],
1298
+ className
1299
+ ),
1300
+ children
1301
+ }
1302
+ );
1303
+ }
1304
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1282
1305
  "div",
1283
1306
  {
1307
+ role,
1284
1308
  className: cn(
1285
- "rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
1309
+ "flex items-start gap-3 rounded-lg border px-4 py-3 text-sm font-sans leading-snug",
1286
1310
  VARIANT_STYLES[variant],
1287
1311
  className
1288
1312
  ),
1289
- children
1313
+ children: [
1314
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 shrink-0 [&>svg]:size-4", "aria-hidden": "true", children: icon }),
1315
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1316
+ title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-ui font-bold text-current leading-snug", children: title }),
1317
+ children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(title && "mt-0.5", "text-current/90"), children })
1318
+ ] }),
1319
+ action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 self-center", children: action })
1320
+ ]
1290
1321
  }
1291
1322
  );
1292
1323
  }
@@ -1297,10 +1328,10 @@ function AdventureCard({
1297
1328
  }) {
1298
1329
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1299
1330
  const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
1300
- const [checkedInternal, setCheckedInternal] = React28__namespace.useState(
1331
+ const [checkedInternal, setCheckedInternal] = React29__namespace.useState(
1301
1332
  new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
1302
1333
  );
1303
- const [openDescriptionId, setOpenDescriptionId] = React28__namespace.useState(null);
1334
+ const [openDescriptionId, setOpenDescriptionId] = React29__namespace.useState(null);
1304
1335
  const openDescriptionOptional = openDescriptionId ? (_e = adventure.optionals) == null ? void 0 : _e.find((o) => o.id === openDescriptionId) : void 0;
1305
1336
  const isChecked = (opt) => {
1306
1337
  var _a2;
@@ -1730,7 +1761,7 @@ function BookingShell({
1730
1761
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1731
1762
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1732
1763
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1733
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxRuntime.jsxs(React28__namespace.Fragment, { children: [
1764
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
1734
1765
  /* @__PURE__ */ jsxRuntime.jsx(
1735
1766
  "span",
1736
1767
  {
@@ -1929,7 +1960,7 @@ function TermsSection({
1929
1960
  termsContent
1930
1961
  }) {
1931
1962
  var _a;
1932
- const [modalOpen, setModalOpen] = React28__namespace.useState(false);
1963
+ const [modalOpen, setModalOpen] = React29__namespace.useState(false);
1933
1964
  const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
1934
1965
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1935
1966
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
@@ -2067,9 +2098,9 @@ function BookingWizard({
2067
2098
  }) {
2068
2099
  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;
2069
2100
  const wizardSteps = WIZARD_STEPS_FN(labels);
2070
- const [step, setStep] = React28__namespace.useState("responsible");
2071
- const [error, setError] = React28__namespace.useState(null);
2072
- const [responsible, setResponsible] = React28__namespace.useState({
2101
+ const [step, setStep] = React29__namespace.useState("responsible");
2102
+ const [error, setError] = React29__namespace.useState(null);
2103
+ const [responsible, setResponsible] = React29__namespace.useState({
2073
2104
  firstName: "",
2074
2105
  lastName: "",
2075
2106
  email: "",
@@ -2088,7 +2119,7 @@ function BookingWizard({
2088
2119
  return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
2089
2120
  }, 0);
2090
2121
  const totalPax = totalAdults + totalChildren;
2091
- const [travellers, setTravellers] = React28__namespace.useState(
2122
+ const [travellers, setTravellers] = React29__namespace.useState(
2092
2123
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
2093
2124
  firstName: "",
2094
2125
  lastName: "",
@@ -2096,9 +2127,9 @@ function BookingWizard({
2096
2127
  email: ""
2097
2128
  }))
2098
2129
  );
2099
- const [payAmount, setPayAmount] = React28__namespace.useState("full");
2100
- const [payMethod, setPayMethod] = React28__namespace.useState("stripe");
2101
- const [termsAccepted, setTermsAccepted] = React28__namespace.useState(false);
2130
+ const [payAmount, setPayAmount] = React29__namespace.useState("full");
2131
+ const [payMethod, setPayMethod] = React29__namespace.useState("stripe");
2132
+ const [termsAccepted, setTermsAccepted] = React29__namespace.useState(false);
2102
2133
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
2103
2134
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
2104
2135
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -2326,7 +2357,7 @@ function Offer({
2326
2357
  className
2327
2358
  }) {
2328
2359
  var _a, _b, _c;
2329
- const [showBooking, setShowBooking] = React28__namespace.useState(false);
2360
+ const [showBooking, setShowBooking] = React29__namespace.useState(false);
2330
2361
  const isShowingCheckout = !confirmedState && (!!checkoutSlot || internalDemoCheckout && showBooking);
2331
2362
  const handleBook = () => {
2332
2363
  if (!checkoutSlot && !externalBookingFlow && internalDemoCheckout) {
@@ -2693,7 +2724,7 @@ function AdventureSection({
2693
2724
  labels
2694
2725
  }) {
2695
2726
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
2696
- const [detailsOpen, setDetailsOpen] = React28__namespace.useState(false);
2727
+ const [detailsOpen, setDetailsOpen] = React29__namespace.useState(false);
2697
2728
  const handleCopyUrl = (url) => {
2698
2729
  if (onCopyFormLink) {
2699
2730
  onCopyFormLink(url);
@@ -3206,8 +3237,8 @@ function AddTravellerDialog({
3206
3237
  errorMessage
3207
3238
  }) {
3208
3239
  var _a, _b, _c, _d, _e;
3209
- const [form, setForm] = React28__namespace.useState(() => createInitialAddFormData(config));
3210
- React28__namespace.useEffect(() => {
3240
+ const [form, setForm] = React29__namespace.useState(() => createInitialAddFormData(config));
3241
+ React29__namespace.useEffect(() => {
3211
3242
  if (open) {
3212
3243
  setForm(createInitialAddFormData(config));
3213
3244
  }
@@ -3267,7 +3298,7 @@ function EditTravellerDialog({
3267
3298
  errorMessage
3268
3299
  }) {
3269
3300
  var _a, _b, _c, _d, _e;
3270
- const [form, setForm] = React28__namespace.useState(() => ({
3301
+ const [form, setForm] = React29__namespace.useState(() => ({
3271
3302
  firstName: "",
3272
3303
  lastName: "",
3273
3304
  email: "",
@@ -3276,7 +3307,7 @@ function EditTravellerDialog({
3276
3307
  birthDate: "",
3277
3308
  personType: "ADULT"
3278
3309
  }));
3279
- React28__namespace.useEffect(() => {
3310
+ React29__namespace.useEffect(() => {
3280
3311
  var _a2, _b2, _c2, _d2, _e2, _f;
3281
3312
  if (open && traveller) {
3282
3313
  setForm({
@@ -3612,48 +3643,48 @@ function BookingDetails({
3612
3643
  const hasSubmitAddTraveller = !!onSubmitAddTraveller;
3613
3644
  const hasSubmitEditTraveller = !!onSubmitEditTraveller;
3614
3645
  const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
3615
- const [addModalState, setAddModalState] = React28__namespace.useState({
3646
+ const [addModalState, setAddModalState] = React29__namespace.useState({
3616
3647
  open: false,
3617
3648
  adventureId: null
3618
3649
  });
3619
- const [editModalState, setEditModalState] = React28__namespace.useState({ open: false, adventureId: null, traveller: null });
3620
- const [deleteModalState, setDeleteModalState] = React28__namespace.useState({ open: false, adventureId: null, traveller: null });
3621
- const [resendInviteDialogState, setResendInviteDialogState] = React28__namespace.useState({ open: false, traveller: null });
3622
- const handleRequestOpenAddModal = React28__namespace.useCallback((adventureId) => {
3650
+ const [editModalState, setEditModalState] = React29__namespace.useState({ open: false, adventureId: null, traveller: null });
3651
+ const [deleteModalState, setDeleteModalState] = React29__namespace.useState({ open: false, adventureId: null, traveller: null });
3652
+ const [resendInviteDialogState, setResendInviteDialogState] = React29__namespace.useState({ open: false, traveller: null });
3653
+ const handleRequestOpenAddModal = React29__namespace.useCallback((adventureId) => {
3623
3654
  setAddModalState({ open: true, adventureId });
3624
3655
  }, []);
3625
- const handleRequestOpenEditModal = React28__namespace.useCallback(
3656
+ const handleRequestOpenEditModal = React29__namespace.useCallback(
3626
3657
  (adventureId, traveller) => {
3627
3658
  setEditModalState({ open: true, adventureId, traveller });
3628
3659
  },
3629
3660
  []
3630
3661
  );
3631
- const handleRequestOpenDeleteModal = React28__namespace.useCallback(
3662
+ const handleRequestOpenDeleteModal = React29__namespace.useCallback(
3632
3663
  (adventureId, traveller) => {
3633
3664
  setDeleteModalState({ open: true, adventureId, traveller });
3634
3665
  },
3635
3666
  []
3636
3667
  );
3637
- const handleRequestOpenResendInviteDialog = React28__namespace.useCallback(
3668
+ const handleRequestOpenResendInviteDialog = React29__namespace.useCallback(
3638
3669
  (traveller) => {
3639
3670
  setResendInviteDialogState({ open: true, traveller });
3640
3671
  },
3641
3672
  []
3642
3673
  );
3643
- const closeAddModal = React28__namespace.useCallback(() => {
3674
+ const closeAddModal = React29__namespace.useCallback(() => {
3644
3675
  setAddModalState({ open: false, adventureId: null });
3645
3676
  }, []);
3646
- const closeEditModal = React28__namespace.useCallback(() => {
3677
+ const closeEditModal = React29__namespace.useCallback(() => {
3647
3678
  setEditModalState({ open: false, adventureId: null, traveller: null });
3648
3679
  }, []);
3649
- const closeDeleteModal = React28__namespace.useCallback(() => {
3680
+ const closeDeleteModal = React29__namespace.useCallback(() => {
3650
3681
  setDeleteModalState({ open: false, adventureId: null, traveller: null });
3651
3682
  }, []);
3652
- const closeResendInviteDialog = React28__namespace.useCallback(() => {
3683
+ const closeResendInviteDialog = React29__namespace.useCallback(() => {
3653
3684
  setResendInviteDialogState({ open: false, traveller: null });
3654
3685
  }, []);
3655
- const submitInFlightRef = React28__namespace.useRef(false);
3656
- const handleAddSubmit = React28__namespace.useCallback(
3686
+ const submitInFlightRef = React29__namespace.useRef(false);
3687
+ const handleAddSubmit = React29__namespace.useCallback(
3657
3688
  async (adventureId, data) => {
3658
3689
  if (!onSubmitAddTraveller) return;
3659
3690
  if (submitInFlightRef.current) return;
@@ -3668,7 +3699,7 @@ function BookingDetails({
3668
3699
  },
3669
3700
  [onSubmitAddTraveller, closeAddModal]
3670
3701
  );
3671
- const handleEditSubmit = React28__namespace.useCallback(
3702
+ const handleEditSubmit = React29__namespace.useCallback(
3672
3703
  async (adventureId, travellerId, data) => {
3673
3704
  if (!onSubmitEditTraveller) return;
3674
3705
  if (submitInFlightRef.current) return;
@@ -3683,7 +3714,7 @@ function BookingDetails({
3683
3714
  },
3684
3715
  [onSubmitEditTraveller, closeEditModal]
3685
3716
  );
3686
- const handleDeleteConfirm = React28__namespace.useCallback(
3717
+ const handleDeleteConfirm = React29__namespace.useCallback(
3687
3718
  async (adventureId, travellerId) => {
3688
3719
  if (!onConfirmRemoveTraveller) return;
3689
3720
  if (submitInFlightRef.current) return;
@@ -5259,7 +5290,7 @@ function BookingCreatedEmail({
5259
5290
  }, children: i + 1 }) }),
5260
5291
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
5261
5292
  ] }) }) }, i)) }),
5262
- nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxRuntime.jsxs(React28__namespace.Fragment, { children: [
5293
+ nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
5263
5294
  idx === 0 ? /* @__PURE__ */ jsxRuntime.jsx("strong", { children: line }) : line,
5264
5295
  idx < arr.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : null
5265
5296
  ] }, idx)) })
@@ -7279,11 +7310,11 @@ function DatePickerField({
7279
7310
  fromDate,
7280
7311
  className
7281
7312
  }) {
7282
- const [open, setOpen] = React28__namespace.useState(false);
7283
- const containerRef = React28__namespace.useRef(null);
7284
- const [calendarWidth, setCalendarWidth] = React28__namespace.useState();
7313
+ const [open, setOpen] = React29__namespace.useState(false);
7314
+ const containerRef = React29__namespace.useRef(null);
7315
+ const [calendarWidth, setCalendarWidth] = React29__namespace.useState();
7285
7316
  const hasValue = !!value;
7286
- React28__namespace.useEffect(() => {
7317
+ React29__namespace.useEffect(() => {
7287
7318
  if (!containerRef.current) return;
7288
7319
  const observer = new ResizeObserver(([entry]) => {
7289
7320
  setCalendarWidth(entry.contentRect.width);
@@ -7392,7 +7423,7 @@ function BookingForm({
7392
7423
  subtitle = "Free enquiry \u2013 no commitment",
7393
7424
  className
7394
7425
  }) {
7395
- const [values, setValues] = React28__namespace.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
7426
+ const [values, setValues] = React29__namespace.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
7396
7427
  const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
7397
7428
  const handleSubmit = (e) => {
7398
7429
  e.preventDefault();
@@ -7960,11 +7991,11 @@ function FloatingTextarea({
7960
7991
  }
7961
7992
  function SelectField({ field, value, onChange, error, disabled }) {
7962
7993
  var _a, _b, _c;
7963
- const [open, setOpen] = React28__namespace.useState(false);
7964
- const containerRef = React28__namespace.useRef(null);
7994
+ const [open, setOpen] = React29__namespace.useState(false);
7995
+ const containerRef = React29__namespace.useRef(null);
7965
7996
  const options = (_a = field.options) != null ? _a : [];
7966
7997
  const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
7967
- React28__namespace.useEffect(() => {
7998
+ React29__namespace.useEffect(() => {
7968
7999
  if (!open) return;
7969
8000
  const handleOutside = (e) => {
7970
8001
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -8429,11 +8460,11 @@ function RegistrationForm({
8429
8460
  readOnly = false
8430
8461
  }) {
8431
8462
  var _a;
8432
- const L = React28__namespace.useMemo(
8463
+ const L = React29__namespace.useMemo(
8433
8464
  () => __spreadValues(__spreadValues({}, DEFAULT_LABELS12), labels != null ? labels : {}),
8434
8465
  [labels]
8435
8466
  );
8436
- const sortedFields = React28__namespace.useMemo(
8467
+ const sortedFields = React29__namespace.useMemo(
8437
8468
  () => [...fields].sort((a, b) => {
8438
8469
  var _a2, _b;
8439
8470
  return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
@@ -8441,7 +8472,7 @@ function RegistrationForm({
8441
8472
  [fields]
8442
8473
  );
8443
8474
  const isControlled = values !== void 0;
8444
- const [internal, setInternal] = React28__namespace.useState(
8475
+ const [internal, setInternal] = React29__namespace.useState(
8445
8476
  () => initializeValues(
8446
8477
  sortedFields,
8447
8478
  defaultValues != null ? defaultValues : {},
@@ -8449,9 +8480,9 @@ function RegistrationForm({
8449
8480
  includeTerms
8450
8481
  )
8451
8482
  );
8452
- const [submitAttempted, setSubmitAttempted] = React28__namespace.useState(false);
8453
- const [validationErrors, setValidationErrors] = React28__namespace.useState({});
8454
- React28__namespace.useEffect(() => {
8483
+ const [submitAttempted, setSubmitAttempted] = React29__namespace.useState(false);
8484
+ const [validationErrors, setValidationErrors] = React29__namespace.useState({});
8485
+ React29__namespace.useEffect(() => {
8455
8486
  if (isControlled) return;
8456
8487
  setInternal((prev) => {
8457
8488
  const next = initializeValues(
@@ -8508,7 +8539,7 @@ function RegistrationForm({
8508
8539
  const termsError = submitAttempted && termsEnabled && !termsAccepted;
8509
8540
  const firstErrorFieldId = Object.keys(fieldErrors)[0];
8510
8541
  const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
8511
- React28__namespace.useEffect(() => {
8542
+ React29__namespace.useEffect(() => {
8512
8543
  if (!submitAttempted || !scrollTargetId) return;
8513
8544
  const timer = setTimeout(() => {
8514
8545
  const elem = document.getElementById(scrollTargetId);
@@ -8970,10 +9001,10 @@ var OTPCodeInput = ({
8970
9001
  id,
8971
9002
  required
8972
9003
  }) => {
8973
- const baseId = id != null ? id : React28__namespace.useId();
8974
- const inputRef = React28__namespace.useRef(null);
8975
- const [focused, setFocused] = React28__namespace.useState(false);
8976
- const digits = React28__namespace.useMemo(() => {
9004
+ const baseId = id != null ? id : React29__namespace.useId();
9005
+ const inputRef = React29__namespace.useRef(null);
9006
+ const [focused, setFocused] = React29__namespace.useState(false);
9007
+ const digits = React29__namespace.useMemo(() => {
8977
9008
  const arr = value.split("").slice(0, length);
8978
9009
  while (arr.length < length) arr.push("");
8979
9010
  return arr;
@@ -9086,7 +9117,7 @@ function Checkbox(_a) {
9086
9117
  })
9087
9118
  );
9088
9119
  }
9089
- var AccordionVariantContext = React28__namespace.createContext("default");
9120
+ var AccordionVariantContext = React29__namespace.createContext("default");
9090
9121
  function Accordion(_a) {
9091
9122
  var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
9092
9123
  return /* @__PURE__ */ jsxRuntime.jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -9104,7 +9135,7 @@ function Accordion(_a) {
9104
9135
  }
9105
9136
  function AccordionItem(_a) {
9106
9137
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
9107
- const variant = React28__namespace.useContext(AccordionVariantContext);
9138
+ const variant = React29__namespace.useContext(AccordionVariantContext);
9108
9139
  return /* @__PURE__ */ jsxRuntime.jsx(
9109
9140
  accordion.Accordion.Item,
9110
9141
  __spreadValues({
@@ -9125,7 +9156,7 @@ function AccordionTrigger(_a) {
9125
9156
  "className",
9126
9157
  "children"
9127
9158
  ]);
9128
- const variant = React28__namespace.useContext(AccordionVariantContext);
9159
+ const variant = React29__namespace.useContext(AccordionVariantContext);
9129
9160
  return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion.Header, { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
9130
9161
  accordion.Accordion.Trigger,
9131
9162
  __spreadProps(__spreadValues({
@@ -9179,7 +9210,7 @@ function AccordionContent(_a) {
9179
9210
  "className",
9180
9211
  "children"
9181
9212
  ]);
9182
- const variant = React28__namespace.useContext(AccordionVariantContext);
9213
+ const variant = React29__namespace.useContext(AccordionVariantContext);
9183
9214
  return /* @__PURE__ */ jsxRuntime.jsx(
9184
9215
  accordion.Accordion.Panel,
9185
9216
  __spreadProps(__spreadValues({
@@ -9397,15 +9428,15 @@ function FilterPanel({
9397
9428
  onSortChange
9398
9429
  }) {
9399
9430
  var _a, _b;
9400
- const resolvedGroups = React28__namespace.useMemo(() => resolveGroups(groups), [groups]);
9401
- const [internalValue, setInternalValue] = React28__namespace.useState(
9431
+ const resolvedGroups = React29__namespace.useMemo(() => resolveGroups(groups), [groups]);
9432
+ const [internalValue, setInternalValue] = React29__namespace.useState(
9402
9433
  () => Object.fromEntries(groups.map((g) => [g.id, []]))
9403
9434
  );
9404
9435
  const selected = value != null ? value : internalValue;
9405
- const [expandedItems, setExpandedItems] = React28__namespace.useState(
9436
+ const [expandedItems, setExpandedItems] = React29__namespace.useState(
9406
9437
  () => new Set(groups.flatMap((g) => getDefaultExpandedIds(g.items)))
9407
9438
  );
9408
- const toggleExpanded = React28__namespace.useCallback((id) => {
9439
+ const toggleExpanded = React29__namespace.useCallback((id) => {
9409
9440
  setExpandedItems((prev) => {
9410
9441
  const next = new Set(prev);
9411
9442
  if (next.has(id)) next.delete(id);
@@ -9789,11 +9820,11 @@ function FilterPanel({
9789
9820
  var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
9790
9821
  function TrustpilotEmbed({ config }) {
9791
9822
  var _a, _b, _c, _d, _e, _f;
9792
- const ref = React28__namespace.useRef(null);
9793
- const [widgetReady, setWidgetReady] = React28__namespace.useState(false);
9794
- const [delayPassed, setDelayPassed] = React28__namespace.useState(false);
9823
+ const ref = React29__namespace.useRef(null);
9824
+ const [widgetReady, setWidgetReady] = React29__namespace.useState(false);
9825
+ const [delayPassed, setDelayPassed] = React29__namespace.useState(false);
9795
9826
  const showFallback = delayPassed && !widgetReady;
9796
- React28__namespace.useEffect(() => {
9827
+ React29__namespace.useEffect(() => {
9797
9828
  var _a2;
9798
9829
  if (typeof document === "undefined" || !ref.current) return;
9799
9830
  const node = ref.current;
@@ -9980,16 +10011,73 @@ function webpVariantUrl(src) {
9980
10011
  const withoutQuery = query ? src.slice(0, -query.length) : src;
9981
10012
  return `${withoutQuery}.webp${query}`;
9982
10013
  }
10014
+ var PLACEHOLDER_SRC = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
9983
10015
  function Picture(_a) {
9984
- var _b = _a, { src, extraSources } = _b, imgProps = __objRest(_b, ["src", "extraSources"]);
10016
+ var _b = _a, {
10017
+ src,
10018
+ extraSources,
10019
+ eager = false,
10020
+ rootMargin = "200px",
10021
+ decoding,
10022
+ loading
10023
+ } = _b, imgProps = __objRest(_b, [
10024
+ "src",
10025
+ "extraSources",
10026
+ "eager",
10027
+ "rootMargin",
10028
+ "decoding",
10029
+ "loading"
10030
+ ]);
10031
+ const ref = React29__namespace.useRef(null);
10032
+ const [visible, setVisible] = React29__namespace.useState(eager);
10033
+ React29__namespace.useEffect(() => {
10034
+ if (eager || visible) return;
10035
+ const el = ref.current;
10036
+ if (!el || typeof IntersectionObserver === "undefined") {
10037
+ setVisible(true);
10038
+ return;
10039
+ }
10040
+ const io = new IntersectionObserver(
10041
+ (entries) => {
10042
+ if (entries.some((e) => e.isIntersecting)) {
10043
+ setVisible(true);
10044
+ io.disconnect();
10045
+ }
10046
+ },
10047
+ { rootMargin }
10048
+ );
10049
+ io.observe(el);
10050
+ return () => io.disconnect();
10051
+ }, [eager, visible, rootMargin]);
9985
10052
  const webp = webpVariantUrl(src);
10053
+ const realSrc = visible ? src : PLACEHOLDER_SRC;
10054
+ const decodingResolved = decoding != null ? decoding : eager ? void 0 : "async";
9986
10055
  if (!webp) {
9987
- return /* @__PURE__ */ jsxRuntime.jsx("img", __spreadValues({ src }, imgProps));
10056
+ return /* @__PURE__ */ jsxRuntime.jsx(
10057
+ "img",
10058
+ __spreadValues({
10059
+ ref,
10060
+ src: realSrc,
10061
+ "data-src": visible ? void 0 : src,
10062
+ decoding: decodingResolved,
10063
+ loading: loading != null ? loading : eager ? void 0 : "lazy"
10064
+ }, imgProps)
10065
+ );
9988
10066
  }
9989
10067
  return /* @__PURE__ */ jsxRuntime.jsxs("picture", { style: { display: "contents" }, children: [
9990
- /* @__PURE__ */ jsxRuntime.jsx("source", { srcSet: webp, type: "image/webp" }),
10068
+ visible && /* @__PURE__ */ jsxRuntime.jsx("source", { srcSet: webp, type: "image/webp" }),
9991
10069
  extraSources,
9992
- /* @__PURE__ */ jsxRuntime.jsx("img", __spreadValues({ src }, imgProps))
10070
+ /* @__PURE__ */ jsxRuntime.jsx(
10071
+ "img",
10072
+ __spreadValues({
10073
+ ref,
10074
+ src: realSrc,
10075
+ "data-src": visible ? void 0 : src,
10076
+ "data-srcset-webp": visible ? void 0 : webp,
10077
+ decoding: decodingResolved,
10078
+ loading: loading != null ? loading : eager ? void 0 : "lazy"
10079
+ }, imgProps)
10080
+ )
9993
10081
  ] });
9994
10082
  }
9995
10083
  function ItineraryDayCard({
@@ -10058,11 +10146,11 @@ function ItineraryModal({
10058
10146
  onNext
10059
10147
  }) {
10060
10148
  var _a, _b, _c;
10061
- const [imgIndex, setImgIndex] = React28__namespace.useState(0);
10149
+ const [imgIndex, setImgIndex] = React29__namespace.useState(0);
10062
10150
  const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
10063
10151
  const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
10064
10152
  const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
10065
- React28__namespace.useEffect(() => {
10153
+ React29__namespace.useEffect(() => {
10066
10154
  setImgIndex(0);
10067
10155
  }, [stop == null ? void 0 : stop.dayNumber]);
10068
10156
  if (!stop) return null;
@@ -10189,8 +10277,8 @@ function ItineraryModal({
10189
10277
  ) });
10190
10278
  }
10191
10279
  function Itinerary({ title, subtitle, stops, className }) {
10192
- const [activeIndex, setActiveIndex] = React28__namespace.useState(null);
10193
- const scrollRef = React28__namespace.useRef(null);
10280
+ const [activeIndex, setActiveIndex] = React29__namespace.useState(null);
10281
+ const scrollRef = React29__namespace.useRef(null);
10194
10282
  const activeStop = activeIndex !== null ? stops[activeIndex] : null;
10195
10283
  const scrollBy = (dir) => {
10196
10284
  if (!scrollRef.current) return;
@@ -10282,18 +10370,18 @@ function Lightbox({
10282
10370
  onClose
10283
10371
  }) {
10284
10372
  var _a;
10285
- const [index, setIndex] = React28__namespace.useState(initialIndex);
10373
+ const [index, setIndex] = React29__namespace.useState(initialIndex);
10286
10374
  const total = photos.length;
10287
10375
  const photo = photos[index];
10288
- const prev = React28__namespace.useCallback(
10376
+ const prev = React29__namespace.useCallback(
10289
10377
  () => setIndex((i) => (i - 1 + total) % total),
10290
10378
  [total]
10291
10379
  );
10292
- const next = React28__namespace.useCallback(
10380
+ const next = React29__namespace.useCallback(
10293
10381
  () => setIndex((i) => (i + 1) % total),
10294
10382
  [total]
10295
10383
  );
10296
- React28__namespace.useEffect(() => {
10384
+ React29__namespace.useEffect(() => {
10297
10385
  const onKey = (e) => {
10298
10386
  if (e.key === "Escape") onClose();
10299
10387
  if (e.key === "ArrowLeft") prev();
@@ -10459,7 +10547,7 @@ function GridGallery({
10459
10547
  initialVisible,
10460
10548
  onOpen
10461
10549
  }) {
10462
- const [expanded, setExpanded] = React28__namespace.useState(false);
10550
+ const [expanded, setExpanded] = React29__namespace.useState(false);
10463
10551
  const cols = gridCols(photos.length);
10464
10552
  const hasMore = photos.length > initialVisible;
10465
10553
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
@@ -10489,7 +10577,7 @@ function CompactGridGallery({
10489
10577
  initialVisible,
10490
10578
  onOpen
10491
10579
  }) {
10492
- const [expanded, setExpanded] = React28__namespace.useState(false);
10580
+ const [expanded, setExpanded] = React29__namespace.useState(false);
10493
10581
  const hasMore = photos.length > initialVisible;
10494
10582
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
10495
10583
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -10518,7 +10606,7 @@ function MasonryGallery({
10518
10606
  initialVisible,
10519
10607
  onOpen
10520
10608
  }) {
10521
- const [expanded, setExpanded] = React28__namespace.useState(false);
10609
+ const [expanded, setExpanded] = React29__namespace.useState(false);
10522
10610
  const hasMore = photos.length > initialVisible;
10523
10611
  const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
10524
10612
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -10591,7 +10679,7 @@ function FeaturedGallery({
10591
10679
  photos,
10592
10680
  onOpen
10593
10681
  }) {
10594
- const [expanded, setExpanded] = React28__namespace.useState(false);
10682
+ const [expanded, setExpanded] = React29__namespace.useState(false);
10595
10683
  const featured = photos.slice(0, 3);
10596
10684
  const extra = photos.slice(3);
10597
10685
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -10758,9 +10846,9 @@ function PhotoGallery({
10758
10846
  onPhotoClick,
10759
10847
  className
10760
10848
  }) {
10761
- const [lightboxIndex, setLightboxIndex] = React28__namespace.useState(null);
10762
- const [carouselIndex, setCarouselIndex] = React28__namespace.useState(0);
10763
- const normalised = React28__namespace.useMemo(() => photos.map(normalise), [photos]);
10849
+ const [lightboxIndex, setLightboxIndex] = React29__namespace.useState(null);
10850
+ const [carouselIndex, setCarouselIndex] = React29__namespace.useState(0);
10851
+ const normalised = React29__namespace.useMemo(() => photos.map(normalise), [photos]);
10764
10852
  const handleOpen = (index) => {
10765
10853
  setLightboxIndex(index);
10766
10854
  onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
@@ -10844,7 +10932,7 @@ function ItineraryDay({
10844
10932
  photoLayout = "rounded",
10845
10933
  className
10846
10934
  }) {
10847
- const photoList = React28__namespace.useMemo(() => normalisePhotos(photos), [photos]);
10935
+ const photoList = React29__namespace.useMemo(() => normalisePhotos(photos), [photos]);
10848
10936
  const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
10849
10937
  const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
10850
10938
  const gallery = photoList.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
@@ -10899,8 +10987,8 @@ function MenuTrip({
10899
10987
  bold = true,
10900
10988
  className
10901
10989
  }) {
10902
- const scrollRef = React28__namespace.useRef(null);
10903
- React28__namespace.useEffect(() => {
10990
+ const scrollRef = React29__namespace.useRef(null);
10991
+ React29__namespace.useEffect(() => {
10904
10992
  if (!scrollRef.current || !activeSection) return;
10905
10993
  const container = scrollRef.current;
10906
10994
  const btn = container.querySelector(
@@ -11042,7 +11130,12 @@ var badgeVariants = classVarianceAuthority.cva(
11042
11130
  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",
11043
11131
  outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
11044
11132
  ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
11045
- link: "text-primary underline-offset-4 hover:underline"
11133
+ link: "text-primary underline-offset-4 hover:underline",
11134
+ // ── Semantic soft tones (added for status surfaces) ────────────────
11135
+ success: "bg-success/10 text-success border-success/20 [a]:hover:bg-success/20",
11136
+ warning: "bg-warning/15 text-warning-foreground border-warning/30 dark:bg-warning/20 dark:text-warning [a]:hover:bg-warning/25",
11137
+ info: "bg-info/10 text-info border-info/20 [a]:hover:bg-info/20",
11138
+ neutral: "bg-muted text-muted-foreground border-border [a]:hover:bg-muted/70"
11046
11139
  }
11047
11140
  },
11048
11141
  defaultVariants: {
@@ -11091,8 +11184,8 @@ function PricingTrip({
11091
11184
  className
11092
11185
  }) {
11093
11186
  const rOuter = sharp ? "rounded-none" : "rounded-2xl";
11094
- const [showEstimates, setShowEstimates] = React28__namespace.useState(false);
11095
- const [showPriceInfo, setShowPriceInfo] = React28__namespace.useState(false);
11187
+ const [showEstimates, setShowEstimates] = React29__namespace.useState(false);
11188
+ const [showPriceInfo, setShowPriceInfo] = React29__namespace.useState(false);
11096
11189
  if (variant === "compact") {
11097
11190
  const showOverlay = showPriceInfo && (!!priceInfo || !!currencyEstimates && currencyEstimates.length > 0);
11098
11191
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -11532,14 +11625,14 @@ function SiteHeader({
11532
11625
  }) {
11533
11626
  const t = VARIANT[variant];
11534
11627
  const resolvedLogo = logoSrc != null ? logoSrc : variant === "white" ? logoSrcDark : logoSrcLight;
11535
- const [openMenu, setOpenMenu] = React28__namespace.useState(null);
11536
- const [langOpen, setLangOpen] = React28__namespace.useState(false);
11537
- const [mobileOpen, setMobileOpen] = React28__namespace.useState(false);
11538
- const [openMobileSection, setOpenMobileSection] = React28__namespace.useState(null);
11539
- const [activeLang, setActiveLang] = React28__namespace.useState(currentLanguage);
11628
+ const [openMenu, setOpenMenu] = React29__namespace.useState(null);
11629
+ const [langOpen, setLangOpen] = React29__namespace.useState(false);
11630
+ const [mobileOpen, setMobileOpen] = React29__namespace.useState(false);
11631
+ const [openMobileSection, setOpenMobileSection] = React29__namespace.useState(null);
11632
+ const [activeLang, setActiveLang] = React29__namespace.useState(currentLanguage);
11540
11633
  const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
11541
- const menuCloseTimer = React28__namespace.useRef(void 0);
11542
- const langCloseTimer = React28__namespace.useRef(void 0);
11634
+ const menuCloseTimer = React29__namespace.useRef(void 0);
11635
+ const langCloseTimer = React29__namespace.useRef(void 0);
11543
11636
  const handleMenuEnter = (label) => {
11544
11637
  clearTimeout(menuCloseTimer.current);
11545
11638
  setOpenMenu(label);
@@ -11560,7 +11653,7 @@ function SiteHeader({
11560
11653
  setOpenMenu(null);
11561
11654
  setLangOpen(false);
11562
11655
  };
11563
- React28__namespace.useEffect(() => () => {
11656
+ React29__namespace.useEffect(() => () => {
11564
11657
  clearTimeout(menuCloseTimer.current);
11565
11658
  clearTimeout(langCloseTimer.current);
11566
11659
  }, []);
@@ -11836,7 +11929,7 @@ function SiteHeader({
11836
11929
  ), children: [
11837
11930
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
11838
11931
  const isActive = lang.code === activeLang;
11839
- return /* @__PURE__ */ jsxRuntime.jsxs(React28__namespace.Fragment, { children: [
11932
+ return /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
11840
11933
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
11841
11934
  "text-xs select-none",
11842
11935
  variant === "white" ? "text-border" : "text-white/15"
@@ -11898,8 +11991,8 @@ function SiteHeader({
11898
11991
  );
11899
11992
  }
11900
11993
  function ThemeToggle({ className }) {
11901
- const [dark, setDark] = React28__namespace.useState(false);
11902
- React28__namespace.useEffect(() => {
11994
+ const [dark, setDark] = React29__namespace.useState(false);
11995
+ React29__namespace.useEffect(() => {
11903
11996
  const saved = localStorage.getItem("theme");
11904
11997
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
11905
11998
  const isDark = saved === "dark" || !saved && prefersDark;
@@ -11949,7 +12042,7 @@ var chipVariants = classVarianceAuthority.cva(
11949
12042
  }
11950
12043
  }
11951
12044
  );
11952
- var Chip = React28__namespace.forwardRef(function Chip2(_a, ref) {
12045
+ var Chip = React29__namespace.forwardRef(function Chip2(_a, ref) {
11953
12046
  var _b = _a, { className, variant, size, href, children } = _b, props = __objRest(_b, ["className", "variant", "size", "href", "children"]);
11954
12047
  const classes = cn(chipVariants({ variant, size }), className);
11955
12048
  if (href) {
@@ -12049,7 +12142,7 @@ function TripCardEditorial(props) {
12049
12142
  difficulty,
12050
12143
  tag
12051
12144
  } = props;
12052
- const [internalFav, setInternalFav] = React28__namespace.useState(false);
12145
+ const [internalFav, setInternalFav] = React29__namespace.useState(false);
12053
12146
  const favorited = favoritedProp != null ? favoritedProp : internalFav;
12054
12147
  const handleFav = (e) => {
12055
12148
  e.preventDefault();
@@ -12194,7 +12287,7 @@ function TripCard(props) {
12194
12287
  );
12195
12288
  }
12196
12289
  function useHlsVideo(videoRef, src) {
12197
- React28__namespace.useEffect(() => {
12290
+ React29__namespace.useEffect(() => {
12198
12291
  if (!src || !videoRef.current) return;
12199
12292
  const video = videoRef.current;
12200
12293
  if (!src.includes(".m3u8")) return;
@@ -12238,11 +12331,11 @@ function TripHeader({
12238
12331
  className
12239
12332
  }) {
12240
12333
  var _a;
12241
- const [heroIndex, setHeroIndex] = React28__namespace.useState(0);
12242
- const [videoReady, setVideoReady] = React28__namespace.useState(false);
12243
- const videoRef = React28__namespace.useRef(null);
12334
+ const [heroIndex, setHeroIndex] = React29__namespace.useState(0);
12335
+ const [videoReady, setVideoReady] = React29__namespace.useState(false);
12336
+ const videoRef = React29__namespace.useRef(null);
12244
12337
  const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
12245
- const validImages = React28__namespace.useMemo(
12338
+ const validImages = React29__namespace.useMemo(
12246
12339
  () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
12247
12340
  [images]
12248
12341
  );
@@ -12257,7 +12350,7 @@ function TripHeader({
12257
12350
  const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
12258
12351
  const hasMeta = !!(destination || duration);
12259
12352
  useHlsVideo(videoRef, isHls ? videoUrl : void 0);
12260
- React28__namespace.useEffect(() => {
12353
+ React29__namespace.useEffect(() => {
12261
12354
  if (!videoUrl) return;
12262
12355
  const el = videoRef.current;
12263
12356
  if (!el) return;
@@ -12305,6 +12398,7 @@ function TripHeader({
12305
12398
  alt: "",
12306
12399
  "aria-hidden": true,
12307
12400
  fetchPriority: "high",
12401
+ eager: true,
12308
12402
  className: cn(
12309
12403
  "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
12310
12404
  videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
@@ -12341,6 +12435,7 @@ function TripHeader({
12341
12435
  src: currentSrc,
12342
12436
  alt: title,
12343
12437
  fetchPriority: safeIndex === 0 ? "high" : "auto",
12438
+ eager: safeIndex === 0,
12344
12439
  className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
12345
12440
  }
12346
12441
  ) : null,
@@ -12398,7 +12493,7 @@ function TripHeader({
12398
12493
  chips && chips.length > 0 ? siteHeader ? "-mt-[200px] sm:-mt-[214px]" : "-mt-[168px] sm:-mt-[182px]" : siteHeader ? "-mt-44" : "-mt-36"
12399
12494
  ),
12400
12495
  children: [
12401
- breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React28__namespace.Fragment, { children: [
12496
+ breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
12402
12497
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
12403
12498
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
12404
12499
  ] }, i)) }),
@@ -12564,10 +12659,10 @@ function LanguagePicker({
12564
12659
  }) {
12565
12660
  var _a;
12566
12661
  const t = VARIANT2[variant];
12567
- const [open, setOpen] = React28__namespace.useState(false);
12568
- const ref = React28__namespace.useRef(null);
12662
+ const [open, setOpen] = React29__namespace.useState(false);
12663
+ const ref = React29__namespace.useRef(null);
12569
12664
  const active = (_a = languages.find((l) => l.code === currentLanguage)) != null ? _a : languages[0];
12570
- React28__namespace.useEffect(() => {
12665
+ React29__namespace.useEffect(() => {
12571
12666
  if (!open) return;
12572
12667
  const onDocClick = (e) => {
12573
12668
  if (ref.current && !ref.current.contains(e.target)) {
@@ -12768,7 +12863,7 @@ function SiteFooter({
12768
12863
  children: wrapper
12769
12864
  },
12770
12865
  b.alt + i
12771
- ) : /* @__PURE__ */ jsxRuntime.jsx(React28__namespace.Fragment, { children: wrapper }, b.alt + i);
12866
+ ) : /* @__PURE__ */ jsxRuntime.jsx(React29__namespace.Fragment, { children: wrapper }, b.alt + i);
12772
12867
  }) })
12773
12868
  ] }),
12774
12869
  themes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "lg:col-span-3", children: [
@@ -12943,10 +13038,10 @@ function TripPage({
12943
13038
  className
12944
13039
  }) {
12945
13040
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
12946
- const [activeSection, setActiveSection] = React28__namespace.useState("");
12947
- const [accordionValue, setAccordionValue] = React28__namespace.useState([]);
12948
- const [faqsExpanded, setFaqsExpanded] = React28__namespace.useState(false);
12949
- const accordionSectionIds = React28__namespace.useMemo(
13041
+ const [activeSection, setActiveSection] = React29__namespace.useState("");
13042
+ const [accordionValue, setAccordionValue] = React29__namespace.useState([]);
13043
+ const [faqsExpanded, setFaqsExpanded] = React29__namespace.useState(false);
13044
+ const accordionSectionIds = React29__namespace.useMemo(
12950
13045
  () => /* @__PURE__ */ new Set([
12951
13046
  "when-it-operates",
12952
13047
  "how-to-get-there",
@@ -12960,18 +13055,18 @@ function TripPage({
12960
13055
  ]),
12961
13056
  []
12962
13057
  );
12963
- const [navFloating, setNavFloating] = React28__namespace.useState(false);
12964
- const [navHidden, setNavHidden] = React28__namespace.useState(false);
12965
- const [isFloating, setIsFloating] = React28__namespace.useState(false);
12966
- const [sidebarPos, setSidebarPos] = React28__namespace.useState(null);
12967
- const [pricingBarVisible, setPricingBarVisible] = React28__namespace.useState(false);
12968
- const navRef = React28__namespace.useRef(null);
12969
- const navSentinelRef = React28__namespace.useRef(null);
12970
- const sentinelRef = React28__namespace.useRef(null);
12971
- const sidebarPlaceholderRef = React28__namespace.useRef(null);
12972
- const pricingBarRef = React28__namespace.useRef(null);
12973
- const galleryRef = React28__namespace.useRef(null);
12974
- const sections = React28__namespace.useMemo(
13058
+ const [navFloating, setNavFloating] = React29__namespace.useState(false);
13059
+ const [navHidden, setNavHidden] = React29__namespace.useState(false);
13060
+ const [isFloating, setIsFloating] = React29__namespace.useState(false);
13061
+ const [sidebarPos, setSidebarPos] = React29__namespace.useState(null);
13062
+ const [pricingBarVisible, setPricingBarVisible] = React29__namespace.useState(false);
13063
+ const navRef = React29__namespace.useRef(null);
13064
+ const navSentinelRef = React29__namespace.useRef(null);
13065
+ const sentinelRef = React29__namespace.useRef(null);
13066
+ const sidebarPlaceholderRef = React29__namespace.useRef(null);
13067
+ const pricingBarRef = React29__namespace.useRef(null);
13068
+ const galleryRef = React29__namespace.useRef(null);
13069
+ const sections = React29__namespace.useMemo(
12975
13070
  () => {
12976
13071
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
12977
13072
  return [
@@ -12993,7 +13088,7 @@ function TripPage({
12993
13088
  // eslint-disable-next-line react-hooks/exhaustive-deps
12994
13089
  []
12995
13090
  );
12996
- React28__namespace.useEffect(() => {
13091
+ React29__namespace.useEffect(() => {
12997
13092
  const sentinel = navSentinelRef.current;
12998
13093
  if (!sentinel) return;
12999
13094
  const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
@@ -13001,7 +13096,7 @@ function TripPage({
13001
13096
  update();
13002
13097
  return () => document.removeEventListener("scroll", update, { capture: true });
13003
13098
  }, []);
13004
- React28__namespace.useEffect(() => {
13099
+ React29__namespace.useEffect(() => {
13005
13100
  const sentinel = sentinelRef.current;
13006
13101
  if (!sentinel) return;
13007
13102
  const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
@@ -13009,7 +13104,7 @@ function TripPage({
13009
13104
  update();
13010
13105
  return () => document.removeEventListener("scroll", update, { capture: true });
13011
13106
  }, []);
13012
- React28__namespace.useEffect(() => {
13107
+ React29__namespace.useEffect(() => {
13013
13108
  const measure = () => {
13014
13109
  if (!sidebarPlaceholderRef.current) return;
13015
13110
  const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
@@ -13019,7 +13114,7 @@ function TripPage({
13019
13114
  window.addEventListener("resize", measure);
13020
13115
  return () => window.removeEventListener("resize", measure);
13021
13116
  }, [isFloating]);
13022
- React28__namespace.useEffect(() => {
13117
+ React29__namespace.useEffect(() => {
13023
13118
  const check = () => {
13024
13119
  var _a2;
13025
13120
  const target = (_a2 = galleryRef.current) != null ? _a2 : pricingBarRef.current;
@@ -13030,7 +13125,7 @@ function TripPage({
13030
13125
  check();
13031
13126
  return () => document.removeEventListener("scroll", check, { capture: true });
13032
13127
  }, []);
13033
- React28__namespace.useEffect(() => {
13128
+ React29__namespace.useEffect(() => {
13034
13129
  const check = () => {
13035
13130
  if (!pricingBarRef.current) return;
13036
13131
  setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
@@ -13039,7 +13134,7 @@ function TripPage({
13039
13134
  check();
13040
13135
  return () => document.removeEventListener("scroll", check, { capture: true });
13041
13136
  }, []);
13042
- React28__namespace.useEffect(() => {
13137
+ React29__namespace.useEffect(() => {
13043
13138
  if (sections.length === 0) return;
13044
13139
  setActiveSection(sections[0].id);
13045
13140
  const update = () => {
@@ -13514,7 +13609,385 @@ function TripPage({
13514
13609
  }
13515
13610
  );
13516
13611
  }
13612
+ function ArrowIcon2() {
13613
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13614
+ "svg",
13615
+ {
13616
+ width: "13",
13617
+ height: "13",
13618
+ viewBox: "0 0 24 24",
13619
+ fill: "none",
13620
+ stroke: "currentColor",
13621
+ strokeWidth: "2.2",
13622
+ strokeLinecap: "round",
13623
+ strokeLinejoin: "round",
13624
+ children: [
13625
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
13626
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 5 19 12 12 19" })
13627
+ ]
13628
+ }
13629
+ );
13630
+ }
13517
13631
  var sizeConfig2 = {
13632
+ sm: {
13633
+ card: "h-72 w-56",
13634
+ title: "text-lg font-bold",
13635
+ meta: "text-xs",
13636
+ excerpt: "text-xs"
13637
+ },
13638
+ md: {
13639
+ card: "h-96 w-72",
13640
+ title: "text-xl font-bold",
13641
+ meta: "text-xs",
13642
+ excerpt: "text-sm"
13643
+ },
13644
+ lg: {
13645
+ card: "h-[28rem] w-96",
13646
+ title: "text-2xl font-bold",
13647
+ meta: "text-sm",
13648
+ excerpt: "text-sm"
13649
+ }
13650
+ };
13651
+ function BlogCard({
13652
+ image,
13653
+ imageAlt = "",
13654
+ category,
13655
+ readingTime,
13656
+ date,
13657
+ title,
13658
+ excerpt,
13659
+ href,
13660
+ cta,
13661
+ size = "md",
13662
+ className
13663
+ }) {
13664
+ var _a;
13665
+ const s = sizeConfig2[size];
13666
+ const meta = [date != null ? date : null, readingTime != null ? readingTime : null].filter(Boolean).join(" | ");
13667
+ const ctaLabel = (_a = cta == null ? void 0 : cta.label) != null ? _a : "Read more";
13668
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13669
+ /* @__PURE__ */ jsxRuntime.jsx(
13670
+ "img",
13671
+ {
13672
+ src: image,
13673
+ alt: imageAlt,
13674
+ loading: "lazy",
13675
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
13676
+ }
13677
+ ),
13678
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 to-black/10" }),
13679
+ category ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsxRuntime.jsx(Chip, { variant: "glass", children: category }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10" }),
13680
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
13681
+ meta && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-white/70 font-medium font-ui", s.meta), children: meta }),
13682
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-white leading-snug", s.title), children: title }),
13683
+ excerpt && /* @__PURE__ */ jsxRuntime.jsx(
13684
+ "p",
13685
+ {
13686
+ className: cn(
13687
+ "text-white/80 leading-relaxed -mt-1 line-clamp-2",
13688
+ s.excerpt
13689
+ ),
13690
+ children: excerpt
13691
+ }
13692
+ ),
13693
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex items-center justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
13694
+ "span",
13695
+ {
13696
+ className: cn(
13697
+ "group/cta inline-flex items-center gap-1.5 border-b border-white/70 pb-0.5",
13698
+ "text-sm font-semibold text-white transition-colors hover:border-white hover:text-white",
13699
+ "font-ui"
13700
+ ),
13701
+ children: [
13702
+ ctaLabel,
13703
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "transition-transform duration-150 group-hover/cta:translate-x-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon2, {}) })
13704
+ ]
13705
+ }
13706
+ ) })
13707
+ ] })
13708
+ ] });
13709
+ const baseClasses = cn(
13710
+ "group relative flex flex-col justify-between overflow-hidden rounded-2xl",
13711
+ "shadow-md transition-shadow duration-300 hover:shadow-xl",
13712
+ s.card,
13713
+ className
13714
+ );
13715
+ return href ? /* @__PURE__ */ jsxRuntime.jsx(
13716
+ "a",
13717
+ {
13718
+ href,
13719
+ onClick: cta == null ? void 0 : cta.onClick,
13720
+ className: baseClasses,
13721
+ "aria-label": title,
13722
+ children: inner
13723
+ }
13724
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: baseClasses, children: inner });
13725
+ }
13726
+ function SectionHeading({
13727
+ eyebrow,
13728
+ title,
13729
+ rightSlot
13730
+ }) {
13731
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end justify-between gap-4 flex-wrap mb-6", children: [
13732
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13733
+ eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-mono font-semibold text-primary uppercase tracking-widest mb-1", children: eyebrow }),
13734
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading leading-tight", children: title })
13735
+ ] }),
13736
+ rightSlot
13737
+ ] });
13738
+ }
13739
+ function CategoryPage2({
13740
+ title,
13741
+ intro,
13742
+ heroImage,
13743
+ trustpilotMini,
13744
+ breadcrumb,
13745
+ siteHeader,
13746
+ popularTours,
13747
+ popularToursTitle = "More adventures calling your name",
13748
+ popularToursEyebrow = "Popular tours",
13749
+ trips,
13750
+ tripsTitle,
13751
+ tripsEyebrow,
13752
+ filterGroups,
13753
+ sortOptions,
13754
+ defaultSort,
13755
+ tripsInitialCount = 15,
13756
+ trustpilot,
13757
+ reviewsTitle = "Don't just take our word for it",
13758
+ reviewsSubtitle,
13759
+ blogPosts,
13760
+ aboutTitle,
13761
+ aboutContent,
13762
+ blogIntro,
13763
+ travelGuideHref,
13764
+ travelGuideLabel = "Read our Travel Guide",
13765
+ blogPostsTitle,
13766
+ blogPostsViewAllHref,
13767
+ faqs,
13768
+ faqsTitle = "Frequently asked questions",
13769
+ faqInitialCount = 5,
13770
+ gallery,
13771
+ galleryTitle,
13772
+ className
13773
+ }) {
13774
+ var _a;
13775
+ const [faqsExpanded, setFaqsExpanded] = React29__namespace.useState(false);
13776
+ const [tripsExpanded, setTripsExpanded] = React29__namespace.useState(false);
13777
+ const [filterValue, setFilterValue] = React29__namespace.useState({});
13778
+ const [sort, setSort] = React29__namespace.useState(
13779
+ defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
13780
+ );
13781
+ const sortedTrips = React29__namespace.useMemo(
13782
+ () => [...trips].sort((a, b) => {
13783
+ const af = a.featured ? 1 : 0;
13784
+ const bf = b.featured ? 1 : 0;
13785
+ return bf - af;
13786
+ }),
13787
+ [trips]
13788
+ );
13789
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
13790
+ /* @__PURE__ */ jsxRuntime.jsxs(
13791
+ "section",
13792
+ {
13793
+ className: cn(
13794
+ "relative w-full",
13795
+ siteHeader ? "min-h-[420px] pt-[140px]" : "min-h-[300px] pt-16",
13796
+ "pb-12 text-white",
13797
+ !heroImage && "bg-gradient-to-br from-primary-900 via-primary-800 to-primary-950"
13798
+ ),
13799
+ children: [
13800
+ heroImage && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 overflow-hidden", children: [
13801
+ /* @__PURE__ */ jsxRuntime.jsx(
13802
+ "img",
13803
+ {
13804
+ src: heroImage,
13805
+ alt: "",
13806
+ "aria-hidden": true,
13807
+ fetchPriority: "high",
13808
+ className: "absolute inset-0 h-full w-full object-cover"
13809
+ }
13810
+ ),
13811
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-b from-black/55 via-black/40 to-black/65" })
13812
+ ] }),
13813
+ siteHeader && /* @__PURE__ */ jsxRuntime.jsx(
13814
+ SiteHeader,
13815
+ {
13816
+ links: Array.isArray(siteHeader) ? siteHeader : void 0,
13817
+ position: "overlay"
13818
+ }
13819
+ ),
13820
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
13821
+ breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
13822
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
13823
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white/70 font-ui", children: crumb.label })
13824
+ ] }, i)) }),
13825
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight max-w-3xl", children: title }),
13826
+ intro && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 text-base sm:text-lg text-white/90 leading-relaxed max-w-2xl [&_strong]:font-semibold [&_a]:underline", children: intro }),
13827
+ trustpilotMini && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-5 max-w-sm", children: /* @__PURE__ */ jsxRuntime.jsx(TrustpilotEmbed, { config: trustpilotMini }) })
13828
+ ] })
13829
+ ]
13830
+ }
13831
+ ),
13832
+ popularTours && popularTours.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
13833
+ /* @__PURE__ */ jsxRuntime.jsx(
13834
+ SectionHeading,
13835
+ {
13836
+ eyebrow: popularToursEyebrow,
13837
+ title: popularToursTitle
13838
+ }
13839
+ ),
13840
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-6 sm:-mx-8 px-6 sm:px-8 overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex gap-5 min-w-max pb-2", children: popularTours.map((trip, i) => {
13841
+ var _b;
13842
+ const _a2 = trip, { featured: _featured, variant: _variant } = _a2, cardProps = __objRest(_a2, ["featured", "variant"]);
13843
+ return /* @__PURE__ */ jsxRuntime.jsx(
13844
+ TripCard,
13845
+ __spreadProps(__spreadValues({}, cardProps), {
13846
+ variant: "overlay",
13847
+ size: (_b = cardProps.size) != null ? _b : "md"
13848
+ }),
13849
+ i
13850
+ );
13851
+ }) }) })
13852
+ ] }),
13853
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 pt-6 sm:pt-8 pb-12", children: [
13854
+ (tripsTitle || tripsEyebrow) && /* @__PURE__ */ jsxRuntime.jsx(SectionHeading, { eyebrow: tripsEyebrow, title: tripsTitle != null ? tripsTitle : "" }),
13855
+ filterGroups && filterGroups.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
13856
+ FilterPanel,
13857
+ {
13858
+ variant: "horizontal",
13859
+ groups: filterGroups,
13860
+ value: filterValue,
13861
+ onChange: setFilterValue,
13862
+ onClearAll: () => setFilterValue({}),
13863
+ sortOptions,
13864
+ sort,
13865
+ onSortChange: setSort
13866
+ }
13867
+ ) }),
13868
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
13869
+ trips.length,
13870
+ " ",
13871
+ trips.length === 1 ? "trip" : "trips",
13872
+ " found"
13873
+ ] }),
13874
+ (() => {
13875
+ const visibleTrips = tripsExpanded ? sortedTrips : sortedTrips.slice(0, tripsInitialCount);
13876
+ const hiddenCount = sortedTrips.length - visibleTrips.length;
13877
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13878
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-8 lg:gap-x-[35px] lg:gap-y-[38px]", children: visibleTrips.map((trip, i) => {
13879
+ const _a2 = trip, { featured: _featured } = _a2, cardProps = __objRest(_a2, ["featured"]);
13880
+ return /* @__PURE__ */ jsxRuntime.jsx(
13881
+ TripCard,
13882
+ __spreadProps(__spreadValues({}, cardProps), {
13883
+ className: cn("w-full h-auto", cardProps.className)
13884
+ }),
13885
+ i
13886
+ );
13887
+ }) }),
13888
+ sortedTrips.length > tripsInitialCount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
13889
+ "button",
13890
+ {
13891
+ type: "button",
13892
+ onClick: () => setTripsExpanded((v) => !v),
13893
+ className: cn(
13894
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
13895
+ "text-sm font-semibold text-foreground shadow-sm",
13896
+ "hover:bg-muted transition-colors duration-150",
13897
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
13898
+ ),
13899
+ children: tripsExpanded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13900
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
13901
+ "Show less"
13902
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13903
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
13904
+ "Load more (",
13905
+ hiddenCount,
13906
+ ")"
13907
+ ] })
13908
+ }
13909
+ ) })
13910
+ ] });
13911
+ })()
13912
+ ] }),
13913
+ trustpilot && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12 border-t border-border", children: [
13914
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-2", children: reviewsTitle }),
13915
+ reviewsSubtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base text-muted-foreground leading-relaxed max-w-3xl mb-6 [&_a]:text-primary [&_a]:underline", children: reviewsSubtitle }),
13916
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx(TrustpilotEmbed, { config: trustpilot }) })
13917
+ ] }),
13918
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pt-4", children: [
13919
+ galleryTitle && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 mb-6 text-2xl sm:text-3xl font-bold text-foreground font-heading", children: galleryTitle }),
13920
+ /* @__PURE__ */ jsxRuntime.jsx(PhotoGallery, { photos: gallery, variant: "gridCompact", initialVisible: 8 })
13921
+ ] }),
13922
+ (aboutTitle || aboutContent || blogPostsTitle || blogPosts && blogPosts.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("section", { className: "w-full bg-gray-100", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-14", children: [
13923
+ (aboutTitle || blogPostsTitle) && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-5", children: aboutTitle != null ? aboutTitle : blogPostsTitle }),
13924
+ aboutContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-base text-foreground/85 leading-relaxed space-y-3 max-w-3xl mb-10 [&_strong]:font-semibold [&_a]:text-primary [&_a]:font-bold [&_a]:underline", children: aboutContent }),
13925
+ blogPosts && blogPosts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13926
+ blogIntro && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-6 text-base sm:text-lg font-semibold text-foreground font-heading", children: blogIntro }),
13927
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5", children: blogPosts.map((post, i) => /* @__PURE__ */ jsxRuntime.jsx(
13928
+ BlogCard,
13929
+ {
13930
+ href: post.href,
13931
+ image: post.image,
13932
+ imageAlt: post.imageAlt,
13933
+ title: post.title,
13934
+ excerpt: post.excerpt,
13935
+ category: post.category,
13936
+ readingTime: post.readingTime,
13937
+ className: "w-full"
13938
+ },
13939
+ i
13940
+ )) }),
13941
+ (travelGuideHref || blogPostsViewAllHref) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
13942
+ "a",
13943
+ {
13944
+ href: travelGuideHref != null ? travelGuideHref : blogPostsViewAllHref,
13945
+ className: "inline-flex items-center gap-1.5 text-sm font-semibold text-primary hover:underline",
13946
+ children: [
13947
+ travelGuideHref ? travelGuideLabel : "View all posts",
13948
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRightIcon, { className: "h-4 w-4" })
13949
+ ]
13950
+ }
13951
+ ) })
13952
+ ] })
13953
+ ] }) }),
13954
+ faqs && faqs.length > 0 && (() => {
13955
+ const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
13956
+ const hiddenCount = faqs.length - visibleFaqs.length;
13957
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
13958
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-6", children: faqsTitle }),
13959
+ /* @__PURE__ */ jsxRuntime.jsx(Accordion, { variant: "faq", children: visibleFaqs.map((faq, i) => /* @__PURE__ */ jsxRuntime.jsxs(AccordionItem, { value: `faq-${i}`, children: [
13960
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionTrigger, { children: faq.question }),
13961
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionContent, { children: faq.answer })
13962
+ ] }, i)) }),
13963
+ faqs.length > faqInitialCount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-5 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
13964
+ "button",
13965
+ {
13966
+ type: "button",
13967
+ onClick: () => setFaqsExpanded((v) => !v),
13968
+ className: cn(
13969
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
13970
+ "text-sm font-semibold text-foreground shadow-sm",
13971
+ "hover:bg-muted transition-colors duration-150",
13972
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
13973
+ ),
13974
+ children: faqsExpanded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13975
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
13976
+ "Show less"
13977
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13978
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
13979
+ "See more (",
13980
+ hiddenCount,
13981
+ ")"
13982
+ ] })
13983
+ }
13984
+ ) })
13985
+ ] });
13986
+ })(),
13987
+ /* @__PURE__ */ jsxRuntime.jsx(SiteFooter, {})
13988
+ ] });
13989
+ }
13990
+ var sizeConfig3 = {
13518
13991
  sm: {
13519
13992
  card: "w-56",
13520
13993
  image: "h-36",
@@ -13549,7 +14022,7 @@ function ActivityCard({
13549
14022
  size = "md",
13550
14023
  className
13551
14024
  }) {
13552
- const s = sizeConfig2[size];
14025
+ const s = sizeConfig3[size];
13553
14026
  return /* @__PURE__ */ jsxRuntime.jsxs(
13554
14027
  "div",
13555
14028
  {
@@ -13615,12 +14088,12 @@ function Toast({
13615
14088
  duration = 6e3,
13616
14089
  className
13617
14090
  }) {
13618
- const [mounted, setMounted] = React28__namespace.useState(false);
13619
- const [visible, setVisible] = React28__namespace.useState(true);
13620
- React28__namespace.useEffect(() => {
14091
+ const [mounted, setMounted] = React29__namespace.useState(false);
14092
+ const [visible, setVisible] = React29__namespace.useState(true);
14093
+ React29__namespace.useEffect(() => {
13621
14094
  setMounted(true);
13622
14095
  }, []);
13623
- React28__namespace.useEffect(() => {
14096
+ React29__namespace.useEffect(() => {
13624
14097
  if (duration === 0) return;
13625
14098
  const t = setTimeout(() => {
13626
14099
  setVisible(false);
@@ -14027,21 +14500,21 @@ function LeadCapturePopup({
14027
14500
  }) {
14028
14501
  var _a;
14029
14502
  const config = __spreadValues(__spreadValues({}, DEFAULTS), _config);
14030
- const [open, setOpen] = React28.useState(false);
14031
- const [closing, setClosing] = React28.useState(false);
14032
- const [submitted, setSubmitted] = React28.useState(false);
14033
- const [submitting, setSubmitting] = React28.useState(false);
14034
- const [error, setError] = React28.useState(null);
14035
- const [name, setName] = React28.useState("");
14036
- const [email, setEmail] = React28.useState("");
14037
- const [travelDate, setTravelDate] = React28.useState("");
14038
- const panelRef = React28.useRef(null);
14039
- const nameRef = React28.useRef(null);
14040
- const show = React28.useCallback(() => {
14503
+ const [open, setOpen] = React29.useState(false);
14504
+ const [closing, setClosing] = React29.useState(false);
14505
+ const [submitted, setSubmitted] = React29.useState(false);
14506
+ const [submitting, setSubmitting] = React29.useState(false);
14507
+ const [error, setError] = React29.useState(null);
14508
+ const [name, setName] = React29.useState("");
14509
+ const [email, setEmail] = React29.useState("");
14510
+ const [travelDate, setTravelDate] = React29.useState("");
14511
+ const panelRef = React29.useRef(null);
14512
+ const nameRef = React29.useRef(null);
14513
+ const show = React29.useCallback(() => {
14041
14514
  if (isDismissed()) return;
14042
14515
  setOpen(true);
14043
14516
  }, []);
14044
- React28.useEffect(() => {
14517
+ React29.useEffect(() => {
14045
14518
  var _a2;
14046
14519
  if (isDismissed()) return;
14047
14520
  if (config.trigger === "delay") {
@@ -14068,7 +14541,7 @@ function LeadCapturePopup({
14068
14541
  return () => window.removeEventListener("scroll", handler);
14069
14542
  }
14070
14543
  }, [config.trigger, config.delaySeconds, config.scrollPercent, show]);
14071
- React28.useEffect(() => {
14544
+ React29.useEffect(() => {
14072
14545
  if (open && !submitted) {
14073
14546
  requestAnimationFrame(() => {
14074
14547
  var _a2;
@@ -14076,7 +14549,7 @@ function LeadCapturePopup({
14076
14549
  });
14077
14550
  }
14078
14551
  }, [open, submitted]);
14079
- const close = React28.useCallback(() => {
14552
+ const close = React29.useCallback(() => {
14080
14553
  setClosing(true);
14081
14554
  setDismissed(config.dismissDays);
14082
14555
  setTimeout(() => {
@@ -14084,7 +14557,7 @@ function LeadCapturePopup({
14084
14557
  setClosing(false);
14085
14558
  }, 250);
14086
14559
  }, [config.dismissDays]);
14087
- React28.useEffect(() => {
14560
+ React29.useEffect(() => {
14088
14561
  if (!open) return;
14089
14562
  const handler = (e) => {
14090
14563
  if (e.key === "Escape") close();
@@ -14092,7 +14565,7 @@ function LeadCapturePopup({
14092
14565
  document.addEventListener("keydown", handler);
14093
14566
  return () => document.removeEventListener("keydown", handler);
14094
14567
  }, [open, close]);
14095
- const onOverlayClick = React28.useCallback(
14568
+ const onOverlayClick = React29.useCallback(
14096
14569
  (e) => {
14097
14570
  if (panelRef.current && !panelRef.current.contains(e.target)) {
14098
14571
  close();
@@ -14330,11 +14803,11 @@ function ExoOrb({
14330
14803
  trackCursor = true,
14331
14804
  className
14332
14805
  }) {
14333
- const uid = React28.useId().replace(/:/g, "");
14806
+ const uid = React29.useId().replace(/:/g, "");
14334
14807
  const id = (name) => `exo-orb-${uid}-${name}`;
14335
- const rootRef = React28.useRef(null);
14336
- const pupilRef = React28.useRef(null);
14337
- React28.useEffect(() => {
14808
+ const rootRef = React29.useRef(null);
14809
+ const pupilRef = React29.useRef(null);
14810
+ React29.useEffect(() => {
14338
14811
  if (!trackCursor) return;
14339
14812
  if (typeof window === "undefined") return;
14340
14813
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
@@ -14530,13 +15003,13 @@ function AskExo({
14530
15003
  teaserDelayMs = 2500,
14531
15004
  teaserDurationMs = 6e3
14532
15005
  }) {
14533
- const [open, setOpen] = React28.useState(false);
14534
- const [question, setQuestion] = React28.useState("");
14535
- const [teaserVisible, setTeaserVisible] = React28.useState(false);
15006
+ const [open, setOpen] = React29.useState(false);
15007
+ const [question, setQuestion] = React29.useState("");
15008
+ const [teaserVisible, setTeaserVisible] = React29.useState(false);
14536
15009
  const teaserEnabled = !!teaser && teaser !== "";
14537
- const inputRef = React28.useRef(null);
14538
- const textareaRef = React28.useRef(null);
14539
- React28.useEffect(() => {
15010
+ const inputRef = React29.useRef(null);
15011
+ const textareaRef = React29.useRef(null);
15012
+ React29.useEffect(() => {
14540
15013
  if (!open) {
14541
15014
  setQuestion("");
14542
15015
  return;
@@ -14548,7 +15021,7 @@ function AskExo({
14548
15021
  }, 200);
14549
15022
  return () => clearTimeout(t);
14550
15023
  }, [open, variant]);
14551
- React28.useEffect(() => {
15024
+ React29.useEffect(() => {
14552
15025
  if (!open) return;
14553
15026
  const onKey = (e) => {
14554
15027
  if (e.key === "Escape") setOpen(false);
@@ -14556,7 +15029,7 @@ function AskExo({
14556
15029
  document.addEventListener("keydown", onKey);
14557
15030
  return () => document.removeEventListener("keydown", onKey);
14558
15031
  }, [open]);
14559
- React28.useEffect(() => {
15032
+ React29.useEffect(() => {
14560
15033
  if (!teaserEnabled || open) return;
14561
15034
  if (typeof window === "undefined") return;
14562
15035
  const showTimer = setTimeout(() => setTeaserVisible(true), teaserDelayMs);
@@ -14569,7 +15042,7 @@ function AskExo({
14569
15042
  clearTimeout(hideTimer);
14570
15043
  };
14571
15044
  }, [teaserEnabled, teaserDelayMs, teaserDurationMs, open]);
14572
- React28.useEffect(() => {
15045
+ React29.useEffect(() => {
14573
15046
  if (open) setTeaserVisible(false);
14574
15047
  }, [open]);
14575
15048
  const askExo = (q) => {
@@ -14762,6 +15235,516 @@ function AskExo({
14762
15235
  )
14763
15236
  ] });
14764
15237
  }
15238
+ var STATUS_MAP = {
15239
+ "draft": { label: "Draft", variant: "neutral", dot: "bg-muted-foreground" },
15240
+ "pending-approval": { label: "Pending approval", variant: "warning", dot: "bg-warning" },
15241
+ "pending-group": { label: "Pending group", variant: "info", dot: "bg-info" },
15242
+ "confirmed": { label: "Confirmed", variant: "success", dot: "bg-success" },
15243
+ "payment-pending": { label: "Payment pending", variant: "warning", dot: "bg-warning" },
15244
+ "payment-reconciliation": { label: "Reconciliation", variant: "info", dot: "bg-info" },
15245
+ "fully-paid": { label: "Fully paid", variant: "default", dot: "bg-primary-foreground" },
15246
+ "full": { label: "Full", variant: "secondary", dot: "bg-secondary-foreground" },
15247
+ "waiting-list": { label: "Waiting list", variant: "info", dot: "bg-info" },
15248
+ "operating": { label: "Operating", variant: "default", dot: "bg-primary-foreground" },
15249
+ "cancelled": { label: "Cancelled", variant: "destructive", dot: "bg-destructive" }
15250
+ };
15251
+ function StatusBadge2({ status, dot = true, label, className }) {
15252
+ const config = STATUS_MAP[status];
15253
+ return /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: config.variant, className: cn("gap-1.5", className), children: [
15254
+ dot && /* @__PURE__ */ jsxRuntime.jsx(
15255
+ "span",
15256
+ {
15257
+ "aria-hidden": "true",
15258
+ className: cn("size-1.5 shrink-0 rounded-full", config.dot)
15259
+ }
15260
+ ),
15261
+ label != null ? label : config.label
15262
+ ] });
15263
+ }
15264
+ function GroupStatusBanner({
15265
+ variant = "info",
15266
+ title,
15267
+ icon,
15268
+ action,
15269
+ urgent = false,
15270
+ children,
15271
+ className
15272
+ }) {
15273
+ return /* @__PURE__ */ jsxRuntime.jsx(
15274
+ Alert,
15275
+ {
15276
+ variant,
15277
+ title,
15278
+ icon,
15279
+ action,
15280
+ role: urgent ? "alert" : "status",
15281
+ className,
15282
+ children
15283
+ }
15284
+ );
15285
+ }
15286
+ function ParticipantCounter({
15287
+ current,
15288
+ max,
15289
+ label = "Travelers",
15290
+ hideIcon = false,
15291
+ className
15292
+ }) {
15293
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15294
+ "span",
15295
+ {
15296
+ className: cn(
15297
+ "inline-flex items-center gap-1.5 font-ui text-sm text-foreground",
15298
+ className
15299
+ ),
15300
+ children: [
15301
+ !hideIcon && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "size-4 text-primary", "aria-hidden": "true" }),
15302
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold tabular-nums", children: [
15303
+ current,
15304
+ " / ",
15305
+ max
15306
+ ] }),
15307
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: label })
15308
+ ]
15309
+ }
15310
+ );
15311
+ }
15312
+ function GroupProgressBar({
15313
+ current,
15314
+ min,
15315
+ max,
15316
+ hideLabels = false,
15317
+ className
15318
+ }) {
15319
+ const pct = Math.max(0, Math.min(100, current / max * 100));
15320
+ const minPct = Math.max(0, Math.min(100, min / max * 100));
15321
+ const quorumMet = current >= min;
15322
+ const isFull = current >= max;
15323
+ const fillTone = isFull ? "bg-success" : quorumMet ? "bg-primary" : "bg-warning";
15324
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
15325
+ /* @__PURE__ */ jsxRuntime.jsxs(
15326
+ "div",
15327
+ {
15328
+ className: "relative h-3 w-full overflow-visible rounded-full bg-muted",
15329
+ role: "progressbar",
15330
+ "aria-valuenow": current,
15331
+ "aria-valuemin": 0,
15332
+ "aria-valuemax": max,
15333
+ "aria-label": `${current} of ${max} travelers, minimum ${min}${quorumMet ? " met" : " not yet met"}`,
15334
+ children: [
15335
+ /* @__PURE__ */ jsxRuntime.jsx(
15336
+ "div",
15337
+ {
15338
+ className: cn(
15339
+ "h-full rounded-full transition-[width,background-color] duration-500",
15340
+ fillTone
15341
+ ),
15342
+ style: { width: `${pct}%` }
15343
+ }
15344
+ ),
15345
+ /* @__PURE__ */ jsxRuntime.jsx(
15346
+ "span",
15347
+ {
15348
+ "aria-hidden": "true",
15349
+ className: "absolute top-1/2 z-10 h-5 w-0.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-foreground/60",
15350
+ style: { left: `${minPct}%` }
15351
+ }
15352
+ )
15353
+ ]
15354
+ }
15355
+ ),
15356
+ !hideLabels && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between font-ui text-[11px] text-muted-foreground", children: [
15357
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(quorumMet && "text-success font-semibold"), children: quorumMet ? "Quorum reached" : `Min ${min} to confirm` }),
15358
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums", children: [
15359
+ max,
15360
+ " max"
15361
+ ] })
15362
+ ] })
15363
+ ] });
15364
+ }
15365
+ function Card(_a) {
15366
+ var _b = _a, {
15367
+ className,
15368
+ size = "default"
15369
+ } = _b, props = __objRest(_b, [
15370
+ "className",
15371
+ "size"
15372
+ ]);
15373
+ return /* @__PURE__ */ jsxRuntime.jsx(
15374
+ "div",
15375
+ __spreadValues({
15376
+ "data-slot": "card",
15377
+ "data-size": size,
15378
+ className: cn(
15379
+ "group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
15380
+ className
15381
+ )
15382
+ }, props)
15383
+ );
15384
+ }
15385
+ function CardHeader(_a) {
15386
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15387
+ return /* @__PURE__ */ jsxRuntime.jsx(
15388
+ "div",
15389
+ __spreadValues({
15390
+ "data-slot": "card-header",
15391
+ className: cn(
15392
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
15393
+ className
15394
+ )
15395
+ }, props)
15396
+ );
15397
+ }
15398
+ function CardTitle(_a) {
15399
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15400
+ return /* @__PURE__ */ jsxRuntime.jsx(
15401
+ "div",
15402
+ __spreadValues({
15403
+ "data-slot": "card-title",
15404
+ className: cn(
15405
+ "text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
15406
+ className
15407
+ )
15408
+ }, props)
15409
+ );
15410
+ }
15411
+ function CardContent(_a) {
15412
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
15413
+ return /* @__PURE__ */ jsxRuntime.jsx(
15414
+ "div",
15415
+ __spreadValues({
15416
+ "data-slot": "card-content",
15417
+ className: cn("px-4 group-data-[size=sm]/card:px-3", className)
15418
+ }, props)
15419
+ );
15420
+ }
15421
+ function PricingMatrixCard({
15422
+ tiers,
15423
+ currentTravelers,
15424
+ title = "Group pricing",
15425
+ locked = false,
15426
+ className
15427
+ }) {
15428
+ const activeIndex = tiers.reduce(
15429
+ (acc, t, i) => currentTravelers >= t.threshold ? i : acc,
15430
+ -1
15431
+ );
15432
+ const bestIndex = tiers.length - 1;
15433
+ return /* @__PURE__ */ jsxRuntime.jsxs(Card, { className, children: [
15434
+ /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle, { className: "font-heading", children: title }) }),
15435
+ /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "px-0", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full text-sm", children: [
15436
+ /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "sr-only", children: "Price per person by number of travelers" }),
15437
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-y border-border text-left font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: [
15438
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2 font-semibold", children: "Travelers" }),
15439
+ /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", className: "px-4 py-2 text-right font-semibold", children: "Price / person" })
15440
+ ] }) }),
15441
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: tiers.map((tier, i) => {
15442
+ const isActive = !locked && i === activeIndex;
15443
+ const isBest = i === bestIndex;
15444
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15445
+ "tr",
15446
+ {
15447
+ className: cn(
15448
+ "border-b border-border last:border-0 transition-colors",
15449
+ isActive && "bg-accent",
15450
+ locked && "opacity-60"
15451
+ ),
15452
+ "aria-current": isActive ? "true" : void 0,
15453
+ children: [
15454
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
15455
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui font-semibold text-foreground", children: tier.travelers }),
15456
+ isActive && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "success", className: "h-4 px-1.5 text-[10px]", children: "You are here" }),
15457
+ isBest && !isActive && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: "Best price" })
15458
+ ] }) }),
15459
+ /* @__PURE__ */ jsxRuntime.jsx(
15460
+ "td",
15461
+ {
15462
+ className: cn(
15463
+ "px-4 py-2.5 text-right font-ui tabular-nums",
15464
+ isActive ? "font-bold text-foreground" : "text-muted-foreground",
15465
+ isBest && "text-primary"
15466
+ ),
15467
+ children: tier.price
15468
+ }
15469
+ )
15470
+ ]
15471
+ },
15472
+ tier.travelers
15473
+ );
15474
+ }) })
15475
+ ] }) })
15476
+ ] });
15477
+ }
15478
+ function PriceProgress({
15479
+ currentPrice,
15480
+ lowestPrice,
15481
+ travelersToLowest,
15482
+ pct,
15483
+ className
15484
+ }) {
15485
+ const reached = travelersToLowest <= 0;
15486
+ const safePct = reached ? 100 : Math.max(0, Math.min(100, pct));
15487
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15488
+ "div",
15489
+ {
15490
+ className: cn(
15491
+ "flex flex-col gap-3 rounded-xl border border-border bg-card p-4",
15492
+ className
15493
+ ),
15494
+ "aria-live": "polite",
15495
+ children: [
15496
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end justify-between gap-4", children: [
15497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
15498
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current" }),
15499
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-heading text-xl font-bold text-foreground tabular-nums", children: currentPrice })
15500
+ ] }),
15501
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDownIcon, { className: "mb-1 size-4 shrink-0 text-success", "aria-hidden": "true" }),
15502
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col text-right", children: [
15503
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Potential" }),
15504
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-heading text-xl font-bold text-primary tabular-nums", children: lowestPrice })
15505
+ ] })
15506
+ ] }),
15507
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(
15508
+ "div",
15509
+ {
15510
+ className: cn(
15511
+ "h-full rounded-full transition-[width] duration-500",
15512
+ reached ? "bg-success" : "bg-primary"
15513
+ ),
15514
+ style: { width: `${safePct}%` }
15515
+ }
15516
+ ) }),
15517
+ /* @__PURE__ */ jsxRuntime.jsx(
15518
+ "p",
15519
+ {
15520
+ className: cn(
15521
+ "flex items-center gap-1.5 font-ui text-sm font-semibold",
15522
+ reached ? "text-success" : "text-foreground"
15523
+ ),
15524
+ children: reached ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15525
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparkleIcon, { className: "size-4", "aria-hidden": "true" }),
15526
+ "Best possible price unlocked"
15527
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15528
+ travelersToLowest,
15529
+ " more ",
15530
+ travelersToLowest === 1 ? "traveler" : "travelers",
15531
+ " for the lowest price"
15532
+ ] })
15533
+ }
15534
+ )
15535
+ ]
15536
+ }
15537
+ );
15538
+ }
15539
+ function ParticipantList({
15540
+ participants,
15541
+ emptySlots = 0,
15542
+ title = "Travelers",
15543
+ leaderLabel = "Leader",
15544
+ emptyMessage = "Be the first to join this adventure.",
15545
+ className
15546
+ }) {
15547
+ if (participants.length === 0 && emptySlots === 0) {
15548
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("font-sans text-sm text-muted-foreground", className), children: emptyMessage });
15549
+ }
15550
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
15551
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-heading text-sm font-bold text-foreground", children: title }),
15552
+ /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "flex flex-col gap-2", children: [
15553
+ participants.map((p, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-3", children: [
15554
+ /* @__PURE__ */ jsxRuntime.jsx(
15555
+ "span",
15556
+ {
15557
+ className: "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-full bg-primary/10 text-primary",
15558
+ "aria-hidden": "true",
15559
+ children: p.avatarUrl ? (
15560
+ // eslint-disable-next-line @next/next/no-img-element
15561
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: p.avatarUrl, alt: "", className: "size-full object-cover" })
15562
+ ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "size-4.5" })
15563
+ }
15564
+ ),
15565
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
15566
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-ui text-sm font-medium text-foreground", children: p.firstName }),
15567
+ p.flag && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-label": p.country, role: "img", className: "text-base leading-none", children: p.flag }),
15568
+ p.isLeader && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: leaderLabel })
15569
+ ] })
15570
+ ] }, `${p.firstName}-${i}`)),
15571
+ Array.from({ length: emptySlots }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-3 opacity-60", children: [
15572
+ /* @__PURE__ */ jsxRuntime.jsx(
15573
+ "span",
15574
+ {
15575
+ "aria-hidden": "true",
15576
+ className: "flex size-9 shrink-0 items-center justify-center rounded-full border border-dashed border-border text-muted-foreground",
15577
+ children: "+"
15578
+ }
15579
+ ),
15580
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Open spot" })
15581
+ ] }, `empty-${i}`))
15582
+ ] })
15583
+ ] });
15584
+ }
15585
+ function BrandIcon({ path }) {
15586
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "size-4", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: path }) });
15587
+ }
15588
+ var WHATSAPP = "M.057 24l1.687-6.163a11.867 11.867 0 01-1.587-5.945C.16 5.335 5.495 0 12.05 0a11.82 11.82 0 018.413 3.488 11.82 11.82 0 013.48 8.414c-.003 6.557-5.338 11.892-11.893 11.892a11.9 11.9 0 01-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.82 9.82 0 001.51 5.26l-.999 3.648 3.978-1.945zm5.473-6.231c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.768.967-.941 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.096 3.2 5.077 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414z";
15589
+ var FACEBOOK = "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z";
15590
+ var X = "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z";
15591
+ function ShareWidget({
15592
+ url,
15593
+ message = "Join my adventure and let's unlock a lower price together!",
15594
+ layout = "row",
15595
+ title = "Invite friends & lower the price",
15596
+ className
15597
+ }) {
15598
+ const [copied, setCopied] = React29__namespace.useState(false);
15599
+ const [showToast, setShowToast] = React29__namespace.useState(false);
15600
+ const encodedUrl = encodeURIComponent(url);
15601
+ const encodedMsg = encodeURIComponent(`${message} ${url}`);
15602
+ const channels = [
15603
+ {
15604
+ key: "whatsapp",
15605
+ label: "WhatsApp",
15606
+ href: `https://wa.me/?text=${encodedMsg}`,
15607
+ path: WHATSAPP,
15608
+ color: "hover:text-[#25D366] hover:border-[#25D366]"
15609
+ },
15610
+ {
15611
+ key: "facebook",
15612
+ label: "Facebook",
15613
+ href: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
15614
+ path: FACEBOOK,
15615
+ color: "hover:text-[#1877F2] hover:border-[#1877F2]"
15616
+ },
15617
+ {
15618
+ key: "x",
15619
+ label: "X",
15620
+ href: `https://twitter.com/intent/tweet?text=${encodeURIComponent(message)}&url=${encodedUrl}`,
15621
+ path: X,
15622
+ color: "hover:text-foreground hover:border-foreground"
15623
+ }
15624
+ ];
15625
+ const copyLink = async () => {
15626
+ try {
15627
+ await navigator.clipboard.writeText(url);
15628
+ } catch (e) {
15629
+ }
15630
+ setCopied(true);
15631
+ setShowToast(true);
15632
+ setTimeout(() => setCopied(false), 2e3);
15633
+ };
15634
+ const isIcons = layout === "icons";
15635
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
15636
+ title && /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "flex items-center gap-1.5 font-heading text-sm font-bold text-foreground", children: [
15637
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Share2Icon, { className: "size-4 text-primary", "aria-hidden": "true" }),
15638
+ title
15639
+ ] }),
15640
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
15641
+ channels.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
15642
+ "a",
15643
+ {
15644
+ href: c.href,
15645
+ target: "_blank",
15646
+ rel: "noopener noreferrer",
15647
+ "aria-label": `Share on ${c.label}`,
15648
+ className: cn(
15649
+ "inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors",
15650
+ c.color
15651
+ ),
15652
+ children: [
15653
+ /* @__PURE__ */ jsxRuntime.jsx(BrandIcon, { path: c.path }),
15654
+ !isIcons && /* @__PURE__ */ jsxRuntime.jsx("span", { children: c.label })
15655
+ ]
15656
+ },
15657
+ c.key
15658
+ )),
15659
+ /* @__PURE__ */ jsxRuntime.jsxs(
15660
+ "button",
15661
+ {
15662
+ type: "button",
15663
+ onClick: copyLink,
15664
+ "aria-label": "Copy link",
15665
+ className: cn(
15666
+ "inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors hover:border-primary hover:text-primary",
15667
+ copied && "border-success text-success"
15668
+ ),
15669
+ children: [
15670
+ copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyIcon, { className: "size-4" }),
15671
+ !isIcons && /* @__PURE__ */ jsxRuntime.jsx("span", { children: copied ? "Copied!" : "Copy link" })
15672
+ ]
15673
+ }
15674
+ )
15675
+ ] }),
15676
+ showToast && /* @__PURE__ */ jsxRuntime.jsx(
15677
+ Toast,
15678
+ {
15679
+ message: "Link copied to clipboard",
15680
+ variant: "success",
15681
+ onClose: () => setShowToast(false),
15682
+ duration: 2500
15683
+ }
15684
+ )
15685
+ ] });
15686
+ }
15687
+ var MODE_COPY = {
15688
+ joinable: { cta: "Join this adventure", disabled: false },
15689
+ full: { cta: "Join waiting list", disabled: false },
15690
+ closed: { cta: "Booking closed", disabled: true },
15691
+ owner: { cta: "Share your departure", disabled: false }
15692
+ };
15693
+ function StickyBookingCard({
15694
+ currentPrice,
15695
+ deposit,
15696
+ spotsRemaining,
15697
+ mode = "joinable",
15698
+ onPrimary,
15699
+ note,
15700
+ className
15701
+ }) {
15702
+ const { cta, disabled } = MODE_COPY[mode];
15703
+ return /* @__PURE__ */ jsxRuntime.jsxs(
15704
+ "div",
15705
+ {
15706
+ className: cn(
15707
+ "flex flex-col gap-4 rounded-2xl border border-border bg-card p-5 ring-1 ring-foreground/5",
15708
+ className
15709
+ ),
15710
+ children: [
15711
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between", children: [
15712
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
15713
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current price" }),
15714
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-heading text-2xl font-bold text-foreground tabular-nums", children: currentPrice }),
15715
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-sans text-xs text-muted-foreground", children: "per person" })
15716
+ ] }),
15717
+ mode !== "owner" && /* @__PURE__ */ jsxRuntime.jsx(
15718
+ "span",
15719
+ {
15720
+ className: cn(
15721
+ "font-ui text-xs font-semibold",
15722
+ spotsRemaining <= 2 && spotsRemaining > 0 ? "text-warning" : "text-muted-foreground"
15723
+ ),
15724
+ children: spotsRemaining > 0 ? `${spotsRemaining} spots left` : "Full"
15725
+ }
15726
+ )
15727
+ ] }),
15728
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between rounded-lg bg-muted/60 px-3 py-2", children: [
15729
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Deposit today" }),
15730
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-ui text-sm font-bold text-foreground tabular-nums", children: deposit })
15731
+ ] }),
15732
+ /* @__PURE__ */ jsxRuntime.jsx(
15733
+ Button,
15734
+ {
15735
+ variant: "primary",
15736
+ size: "lg",
15737
+ className: "w-full",
15738
+ disabled,
15739
+ onClick: onPrimary,
15740
+ children: cta
15741
+ }
15742
+ ),
15743
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-center font-sans text-xs text-muted-foreground", children: note != null ? note : "A hold is placed on your card \u2014 no charge until approved." })
15744
+ ]
15745
+ }
15746
+ );
15747
+ }
14765
15748
 
14766
15749
  exports.ActivityCard = ActivityCard;
14767
15750
  exports.AgentContactCard = AgentContactCard;
@@ -14780,10 +15763,12 @@ exports.BookingShell = BookingShell;
14780
15763
  exports.BookingSummary = BookingSummary;
14781
15764
  exports.Button = Button;
14782
15765
  exports.COUNTRIES = COUNTRIES;
15766
+ exports.CategoryPage2 = CategoryPage2;
14783
15767
  exports.CounterField = CounterField;
14784
15768
  exports.CountrySearchField = CountrySearchField;
14785
15769
  exports.DEFAULT_HEADER_LINKS = DEFAULT_HEADER_LINKS;
14786
15770
  exports.DEFAULT_LANGUAGES = DEFAULT_LANGUAGES;
15771
+ exports.DEPARTURE_STATUS_MAP = STATUS_MAP;
14787
15772
  exports.DatePickerField = DatePickerField;
14788
15773
  exports.Dialog = Dialog;
14789
15774
  exports.DialogClose = DialogClose;
@@ -14796,6 +15781,8 @@ exports.ExoOrb = ExoOrb;
14796
15781
  exports.FilterPanel = FilterPanel;
14797
15782
  exports.FloatingInput = FloatingInput;
14798
15783
  exports.FloatingSelect = FloatingSelect;
15784
+ exports.GroupProgressBar = GroupProgressBar;
15785
+ exports.GroupStatusBanner = GroupStatusBanner;
14799
15786
  exports.Itinerary = Itinerary;
14800
15787
  exports.ItineraryDay = ItineraryDay;
14801
15788
  exports.LOGO_PLANETAEXO_DATA_URI = LOGO_PLANETAEXO_DATA_URI;
@@ -14804,6 +15791,8 @@ exports.MenuTrip = MenuTrip;
14804
15791
  exports.OTPCodeInput = OTPCodeInput;
14805
15792
  exports.Offer = Offer;
14806
15793
  exports.OfferAdventureCard = OfferAdventureCard;
15794
+ exports.ParticipantCounter = ParticipantCounter;
15795
+ exports.ParticipantList = ParticipantList;
14807
15796
  exports.PartnerBookingCreatedEmail = PartnerBookingCreatedEmail;
14808
15797
  exports.PartnerRegistrationCompleteEmail = PartnerRegistrationCompleteEmail;
14809
15798
  exports.PaymentAmountSelector = PaymentAmountSelector;
@@ -14815,13 +15804,18 @@ exports.PaymentReminderEmail = PaymentReminderEmail;
14815
15804
  exports.PhoneCountrySelect = PhoneCountrySelect;
14816
15805
  exports.PhotoGallery = PhotoGallery;
14817
15806
  exports.Picture = Picture;
15807
+ exports.PriceProgress = PriceProgress;
15808
+ exports.PricingMatrixCard = PricingMatrixCard;
14818
15809
  exports.PricingTrip = PricingTrip;
14819
15810
  exports.RegistrationForm = RegistrationForm;
14820
15811
  exports.RegistrationProgressBar = RegistrationProgressBar;
14821
15812
  exports.RegistrationReminderEmail = RegistrationReminderEmail;
14822
15813
  exports.RegistrationReminderIndividualEmail = RegistrationReminderIndividualEmail;
14823
15814
  exports.RegistrationSuccessCard = RegistrationSuccessCard;
15815
+ exports.ShareWidget = ShareWidget;
14824
15816
  exports.SiteHeader = SiteHeader;
15817
+ exports.StatusBadge = StatusBadge2;
15818
+ exports.StickyBookingCard = StickyBookingCard;
14825
15819
  exports.TERMS_ACCEPT_KEY = TERMS_ACCEPT_KEY;
14826
15820
  exports.TermsSection = TermsSection;
14827
15821
  exports.ThemeToggle = ThemeToggle;