@planetaexo/design-system 0.2.13 → 0.2.15

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 React4 = require('react');
3
+ var React18 = require('react');
4
4
  var dateFns = require('date-fns');
5
5
  var lucideReact = require('lucide-react');
6
6
  var clsx = require('clsx');
@@ -11,6 +11,12 @@ var dialog = require('@base-ui/react/dialog');
11
11
  var button = require('@base-ui/react/button');
12
12
  var classVarianceAuthority = require('class-variance-authority');
13
13
  var reactDayPicker = require('react-day-picker');
14
+ var popover = require('@base-ui/react/popover');
15
+ var checkbox = require('@base-ui/react/checkbox');
16
+ var accordion = require('@base-ui/react/accordion');
17
+ var mergeProps = require('@base-ui/react/merge-props');
18
+ var useRender = require('@base-ui/react/use-render');
19
+ var input = require('@base-ui/react/input');
14
20
 
15
21
  function _interopNamespace(e) {
16
22
  if (e && e.__esModule) return e;
@@ -30,7 +36,7 @@ function _interopNamespace(e) {
30
36
  return Object.freeze(n);
31
37
  }
32
38
 
33
- var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
39
+ var React18__namespace = /*#__PURE__*/_interopNamespace(React18);
34
40
 
35
41
  var __defProp = Object.defineProperty;
36
42
  var __defProps = Object.defineProperties;
@@ -231,6 +237,23 @@ function DialogTitle(_a) {
231
237
  }, props)
232
238
  );
233
239
  }
240
+ function DialogDescription(_a) {
241
+ var _b = _a, {
242
+ className
243
+ } = _b, props = __objRest(_b, [
244
+ "className"
245
+ ]);
246
+ return /* @__PURE__ */ jsxRuntime.jsx(
247
+ dialog.Dialog.Description,
248
+ __spreadValues({
249
+ "data-slot": "dialog-description",
250
+ className: cn(
251
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
252
+ className
253
+ )
254
+ }, props)
255
+ );
256
+ }
234
257
  function Calendar(_a) {
235
258
  var _b = _a, {
236
259
  className,
@@ -399,8 +422,8 @@ function CalendarDayButton(_a) {
399
422
  "locale"
400
423
  ]);
401
424
  const defaultClassNames = reactDayPicker.getDefaultClassNames();
402
- const ref = React4__namespace.useRef(null);
403
- React4__namespace.useEffect(() => {
425
+ const ref = React18__namespace.useRef(null);
426
+ React18__namespace.useEffect(() => {
404
427
  var _a2;
405
428
  if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
406
429
  }, [modifiers.focused]);
@@ -422,10 +445,10 @@ function CalendarDayButton(_a) {
422
445
  }, props)
423
446
  );
424
447
  }
425
- var FloatingInput = React4__namespace.forwardRef(
448
+ var FloatingInput = React18__namespace.forwardRef(
426
449
  (_a, ref) => {
427
450
  var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
428
- const inputId = id != null ? id : React4__namespace.useId();
451
+ const inputId = id != null ? id : React18__namespace.useId();
429
452
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
430
453
  /* @__PURE__ */ jsxRuntime.jsx(
431
454
  "input",
@@ -465,10 +488,10 @@ var FloatingInput = React4__namespace.forwardRef(
465
488
  }
466
489
  );
467
490
  FloatingInput.displayName = "FloatingInput";
468
- var FloatingSelect = React4__namespace.forwardRef(
491
+ var FloatingSelect = React18__namespace.forwardRef(
469
492
  (_a, ref) => {
470
493
  var _b = _a, { label, error, id, className, required, children } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children"]);
471
- const inputId = id != null ? id : React4__namespace.useId();
494
+ const inputId = id != null ? id : React18__namespace.useId();
472
495
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
473
496
  /* @__PURE__ */ jsxRuntime.jsx(
474
497
  "select",
@@ -729,11 +752,11 @@ function PhoneCountrySelect({
729
752
  className
730
753
  }) {
731
754
  var _a;
732
- const [open, setOpen] = React4__namespace.useState(false);
733
- const containerRef = React4__namespace.useRef(null);
734
- const listRef = React4__namespace.useRef(null);
755
+ const [open, setOpen] = React18__namespace.useState(false);
756
+ const containerRef = React18__namespace.useRef(null);
757
+ const listRef = React18__namespace.useRef(null);
735
758
  const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
736
- React4__namespace.useEffect(() => {
759
+ React18__namespace.useEffect(() => {
737
760
  if (!open) return;
738
761
  const handler = (e) => {
739
762
  var _a2;
@@ -744,7 +767,7 @@ function PhoneCountrySelect({
744
767
  document.addEventListener("mousedown", handler);
745
768
  return () => document.removeEventListener("mousedown", handler);
746
769
  }, [open]);
747
- React4__namespace.useEffect(() => {
770
+ React18__namespace.useEffect(() => {
748
771
  if (!open || !listRef.current) return;
749
772
  const activeEl = listRef.current.querySelector("[data-selected=true]");
750
773
  activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
@@ -840,9 +863,214 @@ function PhoneCountrySelect({
840
863
  )
841
864
  ] });
842
865
  }
866
+ var COUNTRIES = [
867
+ { code: "AF", name: "Afghanistan" },
868
+ { code: "AL", name: "Albania" },
869
+ { code: "DZ", name: "Algeria" },
870
+ { code: "AO", name: "Angola" },
871
+ { code: "AR", name: "Argentina" },
872
+ { code: "AM", name: "Armenia" },
873
+ { code: "AU", name: "Australia" },
874
+ { code: "AT", name: "Austria" },
875
+ { code: "AZ", name: "Azerbaijan" },
876
+ { code: "BE", name: "Belgium" },
877
+ { code: "BO", name: "Bolivia" },
878
+ { code: "BA", name: "Bosnia" },
879
+ { code: "BR", name: "Brazil" },
880
+ { code: "BG", name: "Bulgaria" },
881
+ { code: "KH", name: "Cambodia" },
882
+ { code: "CA", name: "Canada" },
883
+ { code: "CL", name: "Chile" },
884
+ { code: "CN", name: "China" },
885
+ { code: "CO", name: "Colombia" },
886
+ { code: "CR", name: "Costa Rica" },
887
+ { code: "HR", name: "Croatia" },
888
+ { code: "CU", name: "Cuba" },
889
+ { code: "CZ", name: "Czech Republic" },
890
+ { code: "DK", name: "Denmark" },
891
+ { code: "DO", name: "Dominican Republic" },
892
+ { code: "EC", name: "Ecuador" },
893
+ { code: "EG", name: "Egypt" },
894
+ { code: "SV", name: "El Salvador" },
895
+ { code: "ET", name: "Ethiopia" },
896
+ { code: "FI", name: "Finland" },
897
+ { code: "FR", name: "France" },
898
+ { code: "GE", name: "Georgia" },
899
+ { code: "DE", name: "Germany" },
900
+ { code: "GH", name: "Ghana" },
901
+ { code: "GR", name: "Greece" },
902
+ { code: "GT", name: "Guatemala" },
903
+ { code: "HN", name: "Honduras" },
904
+ { code: "HK", name: "Hong Kong" },
905
+ { code: "HU", name: "Hungary" },
906
+ { code: "IS", name: "Iceland" },
907
+ { code: "IN", name: "India" },
908
+ { code: "ID", name: "Indonesia" },
909
+ { code: "IR", name: "Iran" },
910
+ { code: "IQ", name: "Iraq" },
911
+ { code: "IE", name: "Ireland" },
912
+ { code: "IL", name: "Israel" },
913
+ { code: "IT", name: "Italy" },
914
+ { code: "JM", name: "Jamaica" },
915
+ { code: "JP", name: "Japan" },
916
+ { code: "JO", name: "Jordan" },
917
+ { code: "KZ", name: "Kazakhstan" },
918
+ { code: "KE", name: "Kenya" },
919
+ { code: "KW", name: "Kuwait" },
920
+ { code: "LB", name: "Lebanon" },
921
+ { code: "LY", name: "Libya" },
922
+ { code: "MY", name: "Malaysia" },
923
+ { code: "MX", name: "Mexico" },
924
+ { code: "MA", name: "Morocco" },
925
+ { code: "MZ", name: "Mozambique" },
926
+ { code: "NP", name: "Nepal" },
927
+ { code: "NL", name: "Netherlands" },
928
+ { code: "NZ", name: "New Zealand" },
929
+ { code: "NI", name: "Nicaragua" },
930
+ { code: "NG", name: "Nigeria" },
931
+ { code: "NO", name: "Norway" },
932
+ { code: "PK", name: "Pakistan" },
933
+ { code: "PA", name: "Panama" },
934
+ { code: "PY", name: "Paraguay" },
935
+ { code: "PE", name: "Peru" },
936
+ { code: "PH", name: "Philippines" },
937
+ { code: "PL", name: "Poland" },
938
+ { code: "PT", name: "Portugal" },
939
+ { code: "QA", name: "Qatar" },
940
+ { code: "RO", name: "Romania" },
941
+ { code: "RU", name: "Russia" },
942
+ { code: "SA", name: "Saudi Arabia" },
943
+ { code: "SN", name: "Senegal" },
944
+ { code: "RS", name: "Serbia" },
945
+ { code: "SG", name: "Singapore" },
946
+ { code: "ZA", name: "South Africa" },
947
+ { code: "KR", name: "South Korea" },
948
+ { code: "ES", name: "Spain" },
949
+ { code: "LK", name: "Sri Lanka" },
950
+ { code: "SE", name: "Sweden" },
951
+ { code: "CH", name: "Switzerland" },
952
+ { code: "TW", name: "Taiwan" },
953
+ { code: "TZ", name: "Tanzania" },
954
+ { code: "TH", name: "Thailand" },
955
+ { code: "TN", name: "Tunisia" },
956
+ { code: "TR", name: "Turkey" },
957
+ { code: "UA", name: "Ukraine" },
958
+ { code: "AE", name: "United Arab Emirates" },
959
+ { code: "GB", name: "United Kingdom" },
960
+ { code: "US", name: "United States" },
961
+ { code: "UY", name: "Uruguay" },
962
+ { code: "UZ", name: "Uzbekistan" },
963
+ { code: "VE", name: "Venezuela" },
964
+ { code: "VN", name: "Vietnam" },
965
+ { code: "YE", name: "Yemen" },
966
+ { code: "ZW", name: "Zimbabwe" }
967
+ ];
968
+ function CountrySearchField({
969
+ value,
970
+ onChange,
971
+ required,
972
+ label = "Country",
973
+ countries,
974
+ placeholder = "Search country\u2026",
975
+ className
976
+ }) {
977
+ var _a;
978
+ const list = countries != null ? countries : COUNTRIES;
979
+ const [query, setQuery] = React18__namespace.useState("");
980
+ const [open, setOpen] = React18__namespace.useState(false);
981
+ const containerRef = React18__namespace.useRef(null);
982
+ const searchRef = React18__namespace.useRef(null);
983
+ const selected = list.find((c) => c.code === value);
984
+ const isFloated = open || !!selected;
985
+ const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
986
+ React18__namespace.useEffect(() => {
987
+ if (!open) return;
988
+ const handler = (e) => {
989
+ var _a2;
990
+ if (!((_a2 = containerRef.current) == null ? void 0 : _a2.contains(e.target))) {
991
+ setOpen(false);
992
+ setQuery("");
993
+ }
994
+ };
995
+ document.addEventListener("mousedown", handler);
996
+ return () => document.removeEventListener("mousedown", handler);
997
+ }, [open]);
998
+ const handleOpen = () => {
999
+ setOpen(true);
1000
+ setQuery("");
1001
+ setTimeout(() => {
1002
+ var _a2;
1003
+ return (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
1004
+ }, 0);
1005
+ };
1006
+ const handleSelect = (code) => {
1007
+ onChange(code);
1008
+ setOpen(false);
1009
+ setQuery("");
1010
+ };
1011
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: cn("relative w-full", className), children: [
1012
+ /* @__PURE__ */ jsxRuntime.jsxs(
1013
+ "button",
1014
+ {
1015
+ type: "button",
1016
+ onClick: handleOpen,
1017
+ className: cn(
1018
+ "relative flex w-full items-center rounded-lg border border-border bg-background h-14 px-3 text-left transition-colors",
1019
+ open && "border-primary ring-1 ring-primary"
1020
+ ),
1021
+ children: [
1022
+ /* @__PURE__ */ jsxRuntime.jsxs(
1023
+ "span",
1024
+ {
1025
+ className: cn(
1026
+ "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
1027
+ isFloated ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
1028
+ ),
1029
+ children: [
1030
+ label,
1031
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
1032
+ ]
1033
+ }
1034
+ ),
1035
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-1 pt-3 text-base font-ui truncate", selected ? "text-foreground" : "invisible"), children: (_a = selected == null ? void 0 : selected.name) != null ? _a : "\u2014" }),
1036
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
1037
+ ]
1038
+ }
1039
+ ),
1040
+ open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-[calc(100%+4px)] left-0 right-0 z-50 rounded-xl border border-border bg-background shadow-lg overflow-hidden", children: [
1041
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
1042
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1043
+ /* @__PURE__ */ jsxRuntime.jsx(
1044
+ "input",
1045
+ {
1046
+ ref: searchRef,
1047
+ type: "text",
1048
+ value: query,
1049
+ onChange: (e) => setQuery(e.target.value),
1050
+ placeholder,
1051
+ className: "flex-1 bg-transparent text-sm font-ui text-foreground placeholder:text-muted-foreground focus:outline-none"
1052
+ }
1053
+ )
1054
+ ] }),
1055
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-52 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 py-2 text-sm font-ui text-muted-foreground", children: "No countries found" }) : filtered.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
1056
+ "button",
1057
+ {
1058
+ type: "button",
1059
+ onClick: () => handleSelect(c.code),
1060
+ className: cn(
1061
+ "flex w-full items-center px-3 py-2 text-sm font-ui text-left transition-colors hover:bg-muted",
1062
+ c.code === value && "bg-primary/10 text-primary font-semibold"
1063
+ ),
1064
+ children: c.name
1065
+ },
1066
+ c.code
1067
+ )) })
1068
+ ] })
1069
+ ] });
1070
+ }
843
1071
  function AdventureCard({ adventure }) {
844
1072
  var _a, _b, _c;
845
- const [checked, setChecked] = React4__namespace.useState(
1073
+ const [checked, setChecked] = React18__namespace.useState(
846
1074
  new Set((_b = (_a = adventure.optionals) == null ? void 0 : _a.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _b : [])
847
1075
  );
848
1076
  const toggleOptional = (id) => setChecked((prev) => {
@@ -1132,220 +1360,20 @@ function OfferSummarySection({
1132
1360
  )
1133
1361
  ] });
1134
1362
  }
1135
- var COUNTRIES = [
1136
- { code: "AF", name: "Afghanistan" },
1137
- { code: "AL", name: "Albania" },
1138
- { code: "DZ", name: "Algeria" },
1139
- { code: "AO", name: "Angola" },
1140
- { code: "AR", name: "Argentina" },
1141
- { code: "AM", name: "Armenia" },
1142
- { code: "AU", name: "Australia" },
1143
- { code: "AT", name: "Austria" },
1144
- { code: "AZ", name: "Azerbaijan" },
1145
- { code: "BE", name: "Belgium" },
1146
- { code: "BO", name: "Bolivia" },
1147
- { code: "BA", name: "Bosnia" },
1148
- { code: "BR", name: "Brazil" },
1149
- { code: "BG", name: "Bulgaria" },
1150
- { code: "KH", name: "Cambodia" },
1151
- { code: "CA", name: "Canada" },
1152
- { code: "CL", name: "Chile" },
1153
- { code: "CN", name: "China" },
1154
- { code: "CO", name: "Colombia" },
1155
- { code: "CR", name: "Costa Rica" },
1156
- { code: "HR", name: "Croatia" },
1157
- { code: "CU", name: "Cuba" },
1158
- { code: "CZ", name: "Czech Republic" },
1159
- { code: "DK", name: "Denmark" },
1160
- { code: "DO", name: "Dominican Republic" },
1161
- { code: "EC", name: "Ecuador" },
1162
- { code: "EG", name: "Egypt" },
1163
- { code: "SV", name: "El Salvador" },
1164
- { code: "ET", name: "Ethiopia" },
1165
- { code: "FI", name: "Finland" },
1166
- { code: "FR", name: "France" },
1167
- { code: "GE", name: "Georgia" },
1168
- { code: "DE", name: "Germany" },
1169
- { code: "GH", name: "Ghana" },
1170
- { code: "GR", name: "Greece" },
1171
- { code: "GT", name: "Guatemala" },
1172
- { code: "HN", name: "Honduras" },
1173
- { code: "HK", name: "Hong Kong" },
1174
- { code: "HU", name: "Hungary" },
1175
- { code: "IS", name: "Iceland" },
1176
- { code: "IN", name: "India" },
1177
- { code: "ID", name: "Indonesia" },
1178
- { code: "IR", name: "Iran" },
1179
- { code: "IQ", name: "Iraq" },
1180
- { code: "IE", name: "Ireland" },
1181
- { code: "IL", name: "Israel" },
1182
- { code: "IT", name: "Italy" },
1183
- { code: "JM", name: "Jamaica" },
1184
- { code: "JP", name: "Japan" },
1185
- { code: "JO", name: "Jordan" },
1186
- { code: "KZ", name: "Kazakhstan" },
1187
- { code: "KE", name: "Kenya" },
1188
- { code: "KW", name: "Kuwait" },
1189
- { code: "LB", name: "Lebanon" },
1190
- { code: "LY", name: "Libya" },
1191
- { code: "MY", name: "Malaysia" },
1192
- { code: "MX", name: "Mexico" },
1193
- { code: "MA", name: "Morocco" },
1194
- { code: "MZ", name: "Mozambique" },
1195
- { code: "NP", name: "Nepal" },
1196
- { code: "NL", name: "Netherlands" },
1197
- { code: "NZ", name: "New Zealand" },
1198
- { code: "NI", name: "Nicaragua" },
1199
- { code: "NG", name: "Nigeria" },
1200
- { code: "NO", name: "Norway" },
1201
- { code: "PK", name: "Pakistan" },
1202
- { code: "PA", name: "Panama" },
1203
- { code: "PY", name: "Paraguay" },
1204
- { code: "PE", name: "Peru" },
1205
- { code: "PH", name: "Philippines" },
1206
- { code: "PL", name: "Poland" },
1207
- { code: "PT", name: "Portugal" },
1208
- { code: "QA", name: "Qatar" },
1209
- { code: "RO", name: "Romania" },
1210
- { code: "RU", name: "Russia" },
1211
- { code: "SA", name: "Saudi Arabia" },
1212
- { code: "SN", name: "Senegal" },
1213
- { code: "RS", name: "Serbia" },
1214
- { code: "SG", name: "Singapore" },
1215
- { code: "ZA", name: "South Africa" },
1216
- { code: "KR", name: "South Korea" },
1217
- { code: "ES", name: "Spain" },
1218
- { code: "LK", name: "Sri Lanka" },
1219
- { code: "SE", name: "Sweden" },
1220
- { code: "CH", name: "Switzerland" },
1221
- { code: "TW", name: "Taiwan" },
1222
- { code: "TZ", name: "Tanzania" },
1223
- { code: "TH", name: "Thailand" },
1224
- { code: "TN", name: "Tunisia" },
1225
- { code: "TR", name: "Turkey" },
1226
- { code: "UA", name: "Ukraine" },
1227
- { code: "AE", name: "United Arab Emirates" },
1228
- { code: "GB", name: "United Kingdom" },
1229
- { code: "US", name: "United States" },
1230
- { code: "UY", name: "Uruguay" },
1231
- { code: "UZ", name: "Uzbekistan" },
1232
- { code: "VE", name: "Venezuela" },
1233
- { code: "VN", name: "Vietnam" },
1234
- { code: "YE", name: "Yemen" },
1235
- { code: "ZW", name: "Zimbabwe" }
1236
- ];
1237
- function CountrySearchField({
1238
- value,
1239
- onChange,
1240
- required
1241
- }) {
1242
- var _a;
1243
- const [query, setQuery] = React4__namespace.useState("");
1244
- const [open, setOpen] = React4__namespace.useState(false);
1245
- const containerRef = React4__namespace.useRef(null);
1246
- const searchRef = React4__namespace.useRef(null);
1247
- const selected = COUNTRIES.find((c) => c.code === value);
1248
- const isFloated = open || !!selected;
1249
- const filtered = query.trim() ? COUNTRIES.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : COUNTRIES;
1250
- React4__namespace.useEffect(() => {
1251
- if (!open) return;
1252
- const handler = (e) => {
1253
- var _a2;
1254
- if (!((_a2 = containerRef.current) == null ? void 0 : _a2.contains(e.target))) {
1255
- setOpen(false);
1256
- setQuery("");
1257
- }
1258
- };
1259
- document.addEventListener("mousedown", handler);
1260
- return () => document.removeEventListener("mousedown", handler);
1261
- }, [open]);
1262
- const handleOpen = () => {
1263
- setOpen(true);
1264
- setQuery("");
1265
- setTimeout(() => {
1266
- var _a2;
1267
- return (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
1268
- }, 0);
1269
- };
1270
- const handleSelect = (code) => {
1271
- onChange(code);
1272
- setOpen(false);
1273
- setQuery("");
1274
- };
1275
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "relative w-full", children: [
1276
- /* @__PURE__ */ jsxRuntime.jsxs(
1277
- "button",
1278
- {
1279
- type: "button",
1280
- onClick: handleOpen,
1281
- className: cn(
1282
- "relative flex w-full items-center rounded-lg border border-border bg-background h-14 px-3 text-left transition-colors",
1283
- open && "border-primary ring-1 ring-primary"
1284
- ),
1285
- children: [
1286
- /* @__PURE__ */ jsxRuntime.jsxs(
1287
- "span",
1288
- {
1289
- className: cn(
1290
- "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
1291
- isFloated ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
1292
- ),
1293
- children: [
1294
- "Country",
1295
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
1296
- ]
1297
- }
1298
- ),
1299
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-1 pt-3 text-base font-ui truncate", selected ? "text-foreground" : "invisible"), children: (_a = selected == null ? void 0 : selected.name) != null ? _a : "\u2014" }),
1300
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
1301
- ]
1302
- }
1303
- ),
1304
- open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-[calc(100%+4px)] left-0 right-0 z-50 rounded-xl border border-border bg-background shadow-lg overflow-hidden", children: [
1305
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
1306
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1307
- /* @__PURE__ */ jsxRuntime.jsx(
1308
- "input",
1309
- {
1310
- ref: searchRef,
1311
- type: "text",
1312
- value: query,
1313
- onChange: (e) => setQuery(e.target.value),
1314
- placeholder: "Search country\u2026",
1315
- className: "flex-1 bg-transparent text-sm font-ui text-foreground placeholder:text-muted-foreground focus:outline-none"
1316
- }
1317
- )
1318
- ] }),
1319
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-52 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 py-2 text-sm font-ui text-muted-foreground", children: "No countries found" }) : filtered.map((c) => /* @__PURE__ */ jsxRuntime.jsx(
1320
- "button",
1321
- {
1322
- type: "button",
1323
- onClick: () => handleSelect(c.code),
1324
- className: cn(
1325
- "flex w-full items-center px-3 py-2 text-sm font-ui text-left transition-colors hover:bg-muted",
1326
- c.code === value && "bg-primary/10 text-primary font-semibold"
1327
- ),
1328
- children: c.name
1329
- },
1330
- c.code
1331
- )) })
1332
- ] })
1333
- ] });
1334
- }
1335
1363
  function BirthDateField({
1336
1364
  label,
1337
1365
  required,
1338
1366
  value,
1339
1367
  onChange
1340
1368
  }) {
1341
- const [open, setOpen] = React4__namespace.useState(false);
1342
- const [text, setText] = React4__namespace.useState(value ? dateFns.format(value, "dd/MM/yyyy") : "");
1343
- const containerRef = React4__namespace.useRef(null);
1344
- const inputId = React4__namespace.useId();
1345
- React4__namespace.useEffect(() => {
1369
+ const [open, setOpen] = React18__namespace.useState(false);
1370
+ const [text, setText] = React18__namespace.useState(value ? dateFns.format(value, "dd/MM/yyyy") : "");
1371
+ const containerRef = React18__namespace.useRef(null);
1372
+ const inputId = React18__namespace.useId();
1373
+ React18__namespace.useEffect(() => {
1346
1374
  setText(value ? dateFns.format(value, "dd/MM/yyyy") : "");
1347
1375
  }, [value]);
1348
- React4__namespace.useEffect(() => {
1376
+ React18__namespace.useEffect(() => {
1349
1377
  if (!open) return;
1350
1378
  const handler = (e) => {
1351
1379
  var _a;
@@ -1446,9 +1474,9 @@ function BookingWizard({
1446
1474
  depositInfo,
1447
1475
  onCancel
1448
1476
  }) {
1449
- const [step, setStep] = React4__namespace.useState("responsible");
1450
- const [error, setError] = React4__namespace.useState(null);
1451
- const [responsible, setResponsible] = React4__namespace.useState({
1477
+ const [step, setStep] = React18__namespace.useState("responsible");
1478
+ const [error, setError] = React18__namespace.useState(null);
1479
+ const [responsible, setResponsible] = React18__namespace.useState({
1452
1480
  firstName: "",
1453
1481
  lastName: "",
1454
1482
  email: "",
@@ -1467,7 +1495,7 @@ function BookingWizard({
1467
1495
  return s + ((_b = (_a = a.slots) == null ? void 0 : _a.children) != null ? _b : 0);
1468
1496
  }, 0);
1469
1497
  const totalPax = totalAdults + totalChildren;
1470
- const [travellers, setTravellers] = React4__namespace.useState(
1498
+ const [travellers, setTravellers] = React18__namespace.useState(
1471
1499
  Array.from({ length: Math.max(totalPax, 1) }, () => ({
1472
1500
  firstName: "",
1473
1501
  lastName: "",
@@ -1475,10 +1503,10 @@ function BookingWizard({
1475
1503
  email: ""
1476
1504
  }))
1477
1505
  );
1478
- const [payAmount, setPayAmount] = React4__namespace.useState("full");
1479
- const [payMethod, setPayMethod] = React4__namespace.useState("stripe");
1480
- const [termsAccepted, setTermsAccepted] = React4__namespace.useState(false);
1481
- const [termsModalOpen, setTermsModalOpen] = React4__namespace.useState(false);
1506
+ const [payAmount, setPayAmount] = React18__namespace.useState("full");
1507
+ const [payMethod, setPayMethod] = React18__namespace.useState("stripe");
1508
+ const [termsAccepted, setTermsAccepted] = React18__namespace.useState(false);
1509
+ const [termsModalOpen, setTermsModalOpen] = React18__namespace.useState(false);
1482
1510
  const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
1483
1511
  const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
1484
1512
  const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
@@ -1550,7 +1578,7 @@ function BookingWizard({
1550
1578
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1551
1579
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1552
1580
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: "Booking details" }),
1553
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: WIZARD_STEPS.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs(React4__namespace.Fragment, { children: [
1581
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: WIZARD_STEPS.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs(React18__namespace.Fragment, { children: [
1554
1582
  /* @__PURE__ */ jsxRuntime.jsx(
1555
1583
  "span",
1556
1584
  {
@@ -1828,7 +1856,7 @@ function Offer({
1828
1856
  continueDisabled,
1829
1857
  className
1830
1858
  }) {
1831
- const [showBooking, setShowBooking] = React4__namespace.useState(false);
1859
+ const [showBooking, setShowBooking] = React18__namespace.useState(false);
1832
1860
  const handleBook = () => {
1833
1861
  if (!externalBookingFlow) setShowBooking(true);
1834
1862
  onContinue == null ? void 0 : onContinue();
@@ -1949,9 +1977,9 @@ function AdventureSection({
1949
1977
  onAddSuggestedTraveller
1950
1978
  }) {
1951
1979
  var _a, _b, _c;
1952
- const [detailsOpen, setDetailsOpen] = React4__namespace.useState(false);
1953
- const [addModalOpen, setAddModalOpen] = React4__namespace.useState(false);
1954
- const [newTraveller, setNewTraveller] = React4__namespace.useState({
1980
+ const [detailsOpen, setDetailsOpen] = React18__namespace.useState(false);
1981
+ const [addModalOpen, setAddModalOpen] = React18__namespace.useState(false);
1982
+ const [newTraveller, setNewTraveller] = React18__namespace.useState({
1955
1983
  firstName: "",
1956
1984
  lastName: "",
1957
1985
  passport: "",
@@ -2628,96 +2656,9 @@ function BookingDetails({
2628
2656
  );
2629
2657
  }
2630
2658
  var DEFAULT_LOGO = "/logo-planetaexo.png";
2631
- function BookingConfirmationEmail({
2632
- recipientName,
2633
- addTravellersUrl,
2634
- logoUrl = DEFAULT_LOGO,
2635
- bookingNumber,
2636
- activity,
2637
- adventure,
2638
- startingDate,
2639
- numberOfPeople,
2640
- host,
2641
- className
2642
- }) {
2643
- const AddTravellersCta = addTravellersUrl ? /* @__PURE__ */ jsxRuntime.jsx(
2644
- "a",
2645
- {
2646
- href: addTravellersUrl,
2647
- className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading hover:bg-primary-800 transition-colors no-underline",
2648
- children: "Add travellers to your booking"
2649
- }
2650
- ) : /* @__PURE__ */ jsxRuntime.jsx(
2651
- "span",
2652
- {
2653
- className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading",
2654
- role: "presentation",
2655
- children: "Add travellers to your booking"
2656
- }
2657
- );
2658
- return /* @__PURE__ */ jsxRuntime.jsxs(
2659
- "div",
2660
- {
2661
- className: cn(
2662
- "max-w-xl mx-auto bg-white text-foreground font-sans text-base leading-relaxed",
2663
- className
2664
- ),
2665
- children: [
2666
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 mb-8 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
2667
- "img",
2668
- {
2669
- src: logoUrl,
2670
- alt: "PlanetaEXO",
2671
- className: "h-[70px] w-auto object-contain"
2672
- }
2673
- ) }),
2674
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mb-4", children: [
2675
- "Hi ",
2676
- recipientName,
2677
- ","
2678
- ] }),
2679
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "Thank you for booking your adventure with PlanetaEXO \u2014 we're really looking forward to your adventure." }),
2680
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "To move forward, the first step is to add all travellers included in your booking. Once you do this, each person \u2014 including you \u2014 will receive an email with a link to complete their individual registration." }),
2681
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-8", children: AddTravellersCta }),
2682
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-t border-border mb-8" }),
2683
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 font-heading font-bold text-foreground", children: "\u{1F4DD} Here's a quick summary of your booking:" }),
2684
- /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm mb-8", children: /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "divide-y divide-border", children: [
2685
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2686
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Booking Number:" }),
2687
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: bookingNumber })
2688
- ] }),
2689
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2690
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Activity:" }),
2691
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: activity })
2692
- ] }),
2693
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2694
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Adventure:" }),
2695
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: adventure })
2696
- ] }),
2697
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2698
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Starting Date:" }),
2699
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: startingDate })
2700
- ] }),
2701
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2702
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Number of People:" }),
2703
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: numberOfPeople })
2704
- ] }),
2705
- /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2706
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Host:" }),
2707
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: host })
2708
- ] })
2709
- ] }) }),
2710
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-t border-border mb-8" }),
2711
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "After adding everyone, you will also receive your own registration email, just like the other travellers. Please make sure everyone completes this step so we can organise everything properly." }),
2712
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "If you have any questions, just reply to this email \u2014 happy to help." })
2713
- ]
2714
- }
2715
- );
2716
- }
2717
- var DEFAULT_LOGO2 = "/logo-planetaexo.png";
2718
2659
  function BookingConfirmation({
2719
2660
  recipientName,
2720
- logoUrl = DEFAULT_LOGO2,
2661
+ logoUrl = DEFAULT_LOGO,
2721
2662
  bookingReference,
2722
2663
  adventures,
2723
2664
  summaryLineItems,
@@ -3044,14 +2985,3686 @@ function BookingConfirmation({
3044
2985
  }
3045
2986
  );
3046
2987
  }
2988
+ var DEFAULT_LOGO2 = "/logo-planetaexo.png";
2989
+ function BookingConfirmationEmail({
2990
+ recipientName,
2991
+ addTravellersUrl,
2992
+ logoUrl = DEFAULT_LOGO2,
2993
+ bookingNumber,
2994
+ activity,
2995
+ adventure,
2996
+ startingDate,
2997
+ numberOfPeople,
2998
+ host,
2999
+ className
3000
+ }) {
3001
+ const AddTravellersCta = addTravellersUrl ? /* @__PURE__ */ jsxRuntime.jsx(
3002
+ "a",
3003
+ {
3004
+ href: addTravellersUrl,
3005
+ className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading hover:bg-primary-800 transition-colors no-underline",
3006
+ children: "Add travellers to your booking"
3007
+ }
3008
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3009
+ "span",
3010
+ {
3011
+ className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading",
3012
+ role: "presentation",
3013
+ children: "Add travellers to your booking"
3014
+ }
3015
+ );
3016
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3017
+ "div",
3018
+ {
3019
+ className: cn(
3020
+ "max-w-xl mx-auto bg-white text-foreground font-sans text-base leading-relaxed",
3021
+ className
3022
+ ),
3023
+ children: [
3024
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 mb-8 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
3025
+ "img",
3026
+ {
3027
+ src: logoUrl,
3028
+ alt: "PlanetaEXO",
3029
+ className: "h-[70px] w-auto object-contain"
3030
+ }
3031
+ ) }),
3032
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mb-4", children: [
3033
+ "Hi ",
3034
+ recipientName,
3035
+ ","
3036
+ ] }),
3037
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "Thank you for booking your adventure with PlanetaEXO \u2014 we're really looking forward to your adventure." }),
3038
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "To move forward, the first step is to add all travellers included in your booking. Once you do this, each person \u2014 including you \u2014 will receive an email with a link to complete their individual registration." }),
3039
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-8", children: AddTravellersCta }),
3040
+ /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-t border-border mb-8" }),
3041
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 font-heading font-bold text-foreground", children: "\u{1F4DD} Here's a quick summary of your booking:" }),
3042
+ /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm mb-8", children: /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "divide-y divide-border", children: [
3043
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3044
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Booking Number:" }),
3045
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: bookingNumber })
3046
+ ] }),
3047
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3048
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Activity:" }),
3049
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: activity })
3050
+ ] }),
3051
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3052
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Adventure:" }),
3053
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: adventure })
3054
+ ] }),
3055
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3056
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Starting Date:" }),
3057
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: startingDate })
3058
+ ] }),
3059
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3060
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Number of People:" }),
3061
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: numberOfPeople })
3062
+ ] }),
3063
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3064
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Host:" }),
3065
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-1 font-medium text-foreground", children: host })
3066
+ ] })
3067
+ ] }) }),
3068
+ /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-t border-border mb-8" }),
3069
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "After adding everyone, you will also receive your own registration email, just like the other travellers. Please make sure everyone completes this step so we can organise everything properly." }),
3070
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "If you have any questions, just reply to this email \u2014 happy to help." })
3071
+ ]
3072
+ }
3073
+ );
3074
+ }
3075
+ function CounterField({
3076
+ label,
3077
+ sublabel,
3078
+ required,
3079
+ value,
3080
+ min = 0,
3081
+ max = 99,
3082
+ onChange,
3083
+ className
3084
+ }) {
3085
+ const decrement = () => {
3086
+ if (value > min) onChange(value - 1);
3087
+ };
3088
+ const increment = () => {
3089
+ if (value < max) onChange(value + 1);
3090
+ };
3091
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
3092
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "text-sm font-ui text-foreground", children: [
3093
+ label,
3094
+ sublabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-normal ml-1", children: sublabel }),
3095
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
3096
+ ] }),
3097
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between rounded-lg border border-border bg-background px-4 py-3 h-14", children: [
3098
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl font-semibold text-foreground tabular-nums w-8 font-ui", children: value }),
3099
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
3100
+ /* @__PURE__ */ jsxRuntime.jsx(
3101
+ "button",
3102
+ {
3103
+ type: "button",
3104
+ onClick: decrement,
3105
+ disabled: value <= min,
3106
+ "aria-label": `Diminuir ${label}`,
3107
+ className: cn(
3108
+ "inline-flex h-8 w-8 items-center justify-center rounded-full border border-border",
3109
+ "text-foreground transition-colors",
3110
+ "hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3111
+ "disabled:pointer-events-none disabled:opacity-30"
3112
+ ),
3113
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusIcon, { className: "h-3.5 w-3.5" })
3114
+ }
3115
+ ),
3116
+ /* @__PURE__ */ jsxRuntime.jsx(
3117
+ "button",
3118
+ {
3119
+ type: "button",
3120
+ onClick: increment,
3121
+ disabled: value >= max,
3122
+ "aria-label": `Aumentar ${label}`,
3123
+ className: cn(
3124
+ "inline-flex h-8 w-8 items-center justify-center rounded-full border border-border",
3125
+ "text-foreground transition-colors",
3126
+ "hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3127
+ "disabled:pointer-events-none disabled:opacity-30"
3128
+ ),
3129
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "h-3.5 w-3.5" })
3130
+ }
3131
+ )
3132
+ ] })
3133
+ ] })
3134
+ ] });
3135
+ }
3136
+ function Popover(_a) {
3137
+ var props = __objRest(_a, []);
3138
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Root, __spreadValues({ "data-slot": "popover" }, props));
3139
+ }
3140
+ function PopoverTrigger(_a) {
3141
+ var props = __objRest(_a, []);
3142
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Trigger, __spreadValues({ "data-slot": "popover-trigger" }, props));
3143
+ }
3144
+ function PopoverContent(_a) {
3145
+ var _b = _a, {
3146
+ className,
3147
+ align = "center",
3148
+ alignOffset = 0,
3149
+ side = "bottom",
3150
+ sideOffset = 4
3151
+ } = _b, props = __objRest(_b, [
3152
+ "className",
3153
+ "align",
3154
+ "alignOffset",
3155
+ "side",
3156
+ "sideOffset"
3157
+ ]);
3158
+ return /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
3159
+ popover.Popover.Positioner,
3160
+ {
3161
+ align,
3162
+ alignOffset,
3163
+ side,
3164
+ sideOffset,
3165
+ className: "isolate z-50",
3166
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3167
+ popover.Popover.Popup,
3168
+ __spreadValues({
3169
+ "data-slot": "popover-content",
3170
+ className: cn(
3171
+ "z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
3172
+ className
3173
+ )
3174
+ }, props)
3175
+ )
3176
+ }
3177
+ ) });
3178
+ }
3179
+ function DatePickerField({
3180
+ label,
3181
+ required,
3182
+ value,
3183
+ onChange,
3184
+ placeholder = "Select a date",
3185
+ disabled,
3186
+ fromDate,
3187
+ className
3188
+ }) {
3189
+ const [open, setOpen] = React18__namespace.useState(false);
3190
+ const containerRef = React18__namespace.useRef(null);
3191
+ const [calendarWidth, setCalendarWidth] = React18__namespace.useState();
3192
+ const hasValue = !!value;
3193
+ React18__namespace.useEffect(() => {
3194
+ if (!containerRef.current) return;
3195
+ const observer = new ResizeObserver(([entry]) => {
3196
+ setCalendarWidth(entry.contentRect.width);
3197
+ });
3198
+ observer.observe(containerRef.current);
3199
+ return () => observer.disconnect();
3200
+ }, []);
3201
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
3202
+ /* @__PURE__ */ jsxRuntime.jsxs(
3203
+ PopoverTrigger,
3204
+ {
3205
+ disabled,
3206
+ className: cn(
3207
+ "relative flex w-full items-center rounded-lg border border-border bg-background",
3208
+ "px-3 text-left text-base font-ui transition-colors h-14",
3209
+ "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
3210
+ "disabled:pointer-events-none disabled:opacity-50",
3211
+ open && "border-primary ring-1 ring-primary"
3212
+ ),
3213
+ children: [
3214
+ /* @__PURE__ */ jsxRuntime.jsxs(
3215
+ "span",
3216
+ {
3217
+ className: cn(
3218
+ "pointer-events-none absolute left-3 transition-all duration-150 font-ui",
3219
+ hasValue || open ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
3220
+ ),
3221
+ children: [
3222
+ label,
3223
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary ml-0.5", children: "*" })
3224
+ ]
3225
+ }
3226
+ ),
3227
+ /* @__PURE__ */ jsxRuntime.jsx(
3228
+ "span",
3229
+ {
3230
+ className: cn(
3231
+ "flex-1 truncate mt-3",
3232
+ hasValue ? "text-foreground" : "invisible"
3233
+ ),
3234
+ children: hasValue ? dateFns.format(value, "dd MMM yyyy") : placeholder
3235
+ }
3236
+ ),
3237
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "ml-2 h-4 w-4 shrink-0 text-muted-foreground" })
3238
+ ]
3239
+ }
3240
+ ),
3241
+ /* @__PURE__ */ jsxRuntime.jsx(
3242
+ PopoverContent,
3243
+ {
3244
+ className: "p-0",
3245
+ align: "start",
3246
+ style: calendarWidth ? { width: calendarWidth } : void 0,
3247
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3248
+ Calendar,
3249
+ {
3250
+ mode: "single",
3251
+ selected: value,
3252
+ onSelect: (date) => {
3253
+ onChange == null ? void 0 : onChange(date);
3254
+ setOpen(false);
3255
+ },
3256
+ fromDate: fromDate != null ? fromDate : /* @__PURE__ */ new Date(),
3257
+ className: "font-ui w-full",
3258
+ autoFocus: true
3259
+ }
3260
+ )
3261
+ }
3262
+ )
3263
+ ] }) });
3264
+ }
3265
+ function FormSection({
3266
+ title,
3267
+ children,
3268
+ className
3269
+ }) {
3270
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
3271
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
3272
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground whitespace-nowrap font-heading", children: title }),
3273
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-border" })
3274
+ ] }),
3275
+ children
3276
+ ] });
3277
+ }
3278
+ var defaultInitial = {
3279
+ adults: 2,
3280
+ children: 0,
3281
+ travelDate: void 0,
3282
+ budget: "",
3283
+ project: "",
3284
+ civility: "",
3285
+ phoneCountry: "BR",
3286
+ lastName: "",
3287
+ firstName: "",
3288
+ country: "France",
3289
+ phone: "",
3290
+ email: ""
3291
+ };
3292
+ function BookingForm({
3293
+ defaultValues,
3294
+ onSubmit,
3295
+ submitLabel = "Send my request",
3296
+ loading = false,
3297
+ showHeader = true,
3298
+ title = "Check availability for your trip",
3299
+ subtitle = "Free enquiry \u2013 no commitment",
3300
+ className
3301
+ }) {
3302
+ const [values, setValues] = React18__namespace.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
3303
+ const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
3304
+ const handleSubmit = (e) => {
3305
+ e.preventDefault();
3306
+ onSubmit == null ? void 0 : onSubmit(values);
3307
+ };
3308
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3309
+ "form",
3310
+ {
3311
+ onSubmit: handleSubmit,
3312
+ className: cn("flex flex-col gap-10", className),
3313
+ noValidate: true,
3314
+ children: [
3315
+ showHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3316
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-black uppercase tracking-wide text-foreground font-heading leading-tight", children: title }),
3317
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-sm text-muted-foreground font-ui", children: subtitle })
3318
+ ] }),
3319
+ /* @__PURE__ */ jsxRuntime.jsx(FormSection, { title: "Who's joining the adventure?", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
3320
+ /* @__PURE__ */ jsxRuntime.jsx(
3321
+ CounterField,
3322
+ {
3323
+ label: "Adults",
3324
+ required: true,
3325
+ value: values.adults,
3326
+ min: 1,
3327
+ onChange: (v) => set("adults", v)
3328
+ }
3329
+ ),
3330
+ /* @__PURE__ */ jsxRuntime.jsx(
3331
+ CounterField,
3332
+ {
3333
+ label: "Children",
3334
+ sublabel: "(under 12)",
3335
+ value: values.children,
3336
+ min: 0,
3337
+ onChange: (v) => set("children", v)
3338
+ }
3339
+ )
3340
+ ] }) }),
3341
+ /* @__PURE__ */ jsxRuntime.jsx(FormSection, { title: "Your next trip", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
3342
+ /* @__PURE__ */ jsxRuntime.jsx(
3343
+ DatePickerField,
3344
+ {
3345
+ label: "Travel date",
3346
+ required: true,
3347
+ value: values.travelDate,
3348
+ onChange: (d) => set("travelDate", d),
3349
+ placeholder: "Pick a date"
3350
+ }
3351
+ ),
3352
+ /* @__PURE__ */ jsxRuntime.jsx(
3353
+ FloatingInput,
3354
+ {
3355
+ label: "Budget (per person)",
3356
+ required: true,
3357
+ type: "number",
3358
+ min: 0,
3359
+ value: values.budget,
3360
+ onChange: (e) => set("budget", e.target.value)
3361
+ }
3362
+ )
3363
+ ] }) }),
3364
+ /* @__PURE__ */ jsxRuntime.jsx(FormSection, { title: "Tell us about your trip", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
3365
+ /* @__PURE__ */ jsxRuntime.jsx(
3366
+ "textarea",
3367
+ {
3368
+ id: "project",
3369
+ placeholder: " ",
3370
+ rows: 5,
3371
+ value: values.project,
3372
+ onChange: (e) => set("project", e.target.value),
3373
+ className: cn(
3374
+ "peer block w-full resize-none rounded-lg border border-border bg-background",
3375
+ "px-3 pt-6 pb-3 text-base text-foreground font-ui",
3376
+ "transition-colors placeholder-transparent",
3377
+ "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
3378
+ )
3379
+ }
3380
+ ),
3381
+ /* @__PURE__ */ jsxRuntime.jsxs(
3382
+ "label",
3383
+ {
3384
+ htmlFor: "project",
3385
+ className: cn(
3386
+ "pointer-events-none absolute left-3 top-4",
3387
+ "text-base text-muted-foreground font-ui transition-all duration-150",
3388
+ "peer-focus:top-2 peer-focus:text-xs peer-focus:text-primary",
3389
+ "peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
3390
+ ),
3391
+ children: [
3392
+ "Your trip in a few words",
3393
+ " ",
3394
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
3395
+ ]
3396
+ }
3397
+ )
3398
+ ] }) }),
3399
+ /* @__PURE__ */ jsxRuntime.jsxs(FormSection, { title: "Contact details", children: [
3400
+ /* @__PURE__ */ jsxRuntime.jsx(
3401
+ "div",
3402
+ {
3403
+ role: "radiogroup",
3404
+ "aria-label": "Title",
3405
+ className: "flex flex-wrap items-center gap-x-6 gap-y-3",
3406
+ children: ["ms", "mr"].map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
3407
+ "label",
3408
+ {
3409
+ className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground",
3410
+ children: [
3411
+ /* @__PURE__ */ jsxRuntime.jsx(
3412
+ "input",
3413
+ {
3414
+ type: "radio",
3415
+ name: "civility",
3416
+ value: c,
3417
+ checked: values.civility === c,
3418
+ onChange: () => set("civility", c),
3419
+ className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
3420
+ }
3421
+ ),
3422
+ c === "ms" ? "Ms." : "Mr."
3423
+ ]
3424
+ },
3425
+ c
3426
+ ))
3427
+ }
3428
+ ),
3429
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 min-w-0", children: [
3430
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3431
+ FloatingInput,
3432
+ {
3433
+ label: "Last name",
3434
+ required: true,
3435
+ value: values.lastName,
3436
+ onChange: (e) => set("lastName", e.target.value)
3437
+ }
3438
+ ) }),
3439
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3440
+ FloatingInput,
3441
+ {
3442
+ label: "First name",
3443
+ required: true,
3444
+ value: values.firstName,
3445
+ onChange: (e) => set("firstName", e.target.value)
3446
+ }
3447
+ ) }),
3448
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 sm:col-span-2 lg:col-span-1", children: /* @__PURE__ */ jsxRuntime.jsxs(
3449
+ FloatingSelect,
3450
+ {
3451
+ label: "Country of residence",
3452
+ required: true,
3453
+ value: values.country,
3454
+ onChange: (e) => set("country", e.target.value),
3455
+ children: [
3456
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, hidden: true }),
3457
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "France", children: "France" }),
3458
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Belgium", children: "Belgium" }),
3459
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Switzerland", children: "Switzerland" }),
3460
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Canada", children: "Canada" }),
3461
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Luxembourg", children: "Luxembourg" }),
3462
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "United Kingdom", children: "United Kingdom" }),
3463
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "United States", children: "United States" }),
3464
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "Other", children: "Other" })
3465
+ ]
3466
+ }
3467
+ ) })
3468
+ ] }),
3469
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-2", children: [
3470
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-w-0", children: [
3471
+ /* @__PURE__ */ jsxRuntime.jsx(
3472
+ PhoneCountrySelect,
3473
+ {
3474
+ value: values.phoneCountry,
3475
+ onChange: (code) => set("phoneCountry", code),
3476
+ className: "shrink-0"
3477
+ }
3478
+ ),
3479
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-w-0 flex-1", children: [
3480
+ /* @__PURE__ */ jsxRuntime.jsx(
3481
+ "input",
3482
+ {
3483
+ id: "phone",
3484
+ type: "tel",
3485
+ placeholder: " ",
3486
+ value: values.phone,
3487
+ onChange: (e) => set("phone", e.target.value),
3488
+ className: cn(
3489
+ "peer block h-14 w-full rounded-r-lg border border-border bg-background",
3490
+ "px-3 pt-5 pb-2 text-base text-foreground font-ui",
3491
+ "transition-colors placeholder-transparent",
3492
+ "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
3493
+ )
3494
+ }
3495
+ ),
3496
+ /* @__PURE__ */ jsxRuntime.jsxs(
3497
+ "label",
3498
+ {
3499
+ htmlFor: "phone",
3500
+ className: cn(
3501
+ "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
3502
+ "text-base text-muted-foreground font-ui transition-all duration-150",
3503
+ "peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
3504
+ "peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
3505
+ ),
3506
+ children: [
3507
+ "Phone ",
3508
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: "*" })
3509
+ ]
3510
+ }
3511
+ )
3512
+ ] })
3513
+ ] }),
3514
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3515
+ FloatingInput,
3516
+ {
3517
+ label: "Email",
3518
+ required: true,
3519
+ type: "email",
3520
+ value: values.email,
3521
+ onChange: (e) => set("email", e.target.value)
3522
+ }
3523
+ ) })
3524
+ ] })
3525
+ ] }),
3526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
3527
+ "button",
3528
+ {
3529
+ type: "submit",
3530
+ disabled: loading,
3531
+ className: cn(
3532
+ "inline-flex items-center justify-center gap-2 rounded-full px-10 py-3.5",
3533
+ "bg-primary text-primary-foreground font-ui font-semibold text-sm",
3534
+ "transition-colors hover:bg-primary/90 focus-visible:outline-none",
3535
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3536
+ "disabled:pointer-events-none disabled:opacity-60"
3537
+ ),
3538
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3539
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
3540
+ /* @__PURE__ */ jsxRuntime.jsx(
3541
+ "circle",
3542
+ {
3543
+ className: "opacity-25",
3544
+ cx: "12",
3545
+ cy: "12",
3546
+ r: "10",
3547
+ stroke: "currentColor",
3548
+ strokeWidth: "4"
3549
+ }
3550
+ ),
3551
+ /* @__PURE__ */ jsxRuntime.jsx(
3552
+ "path",
3553
+ {
3554
+ className: "opacity-75",
3555
+ fill: "currentColor",
3556
+ d: "M4 12a8 8 0 018-8v4l3-3-3-3v4a8 8 0 00-8 8h4z"
3557
+ }
3558
+ )
3559
+ ] }),
3560
+ "Sending\u2026"
3561
+ ] }) : submitLabel
3562
+ }
3563
+ ) })
3564
+ ]
3565
+ }
3566
+ );
3567
+ }
3568
+ function Checkbox(_a) {
3569
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3570
+ return /* @__PURE__ */ jsxRuntime.jsx(
3571
+ checkbox.Checkbox.Root,
3572
+ __spreadProps(__spreadValues({
3573
+ "data-slot": "checkbox",
3574
+ className: cn(
3575
+ "peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
3576
+ className
3577
+ )
3578
+ }, props), {
3579
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3580
+ checkbox.Checkbox.Indicator,
3581
+ {
3582
+ "data-slot": "checkbox-indicator",
3583
+ className: "grid place-content-center text-current transition-none [&>svg]:size-3.5",
3584
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3585
+ lucideReact.CheckIcon,
3586
+ {}
3587
+ )
3588
+ }
3589
+ )
3590
+ })
3591
+ );
3592
+ }
3593
+ var AccordionVariantContext = React18__namespace.createContext("default");
3594
+ function Accordion(_a) {
3595
+ var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
3596
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsxRuntime.jsx(
3597
+ accordion.Accordion.Root,
3598
+ __spreadValues({
3599
+ "data-slot": "accordion",
3600
+ "data-variant": variant,
3601
+ className: cn(
3602
+ "flex w-full flex-col",
3603
+ variant === "faq" && "gap-3",
3604
+ className
3605
+ )
3606
+ }, props)
3607
+ ) });
3608
+ }
3609
+ function AccordionItem(_a) {
3610
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3611
+ const variant = React18__namespace.useContext(AccordionVariantContext);
3612
+ return /* @__PURE__ */ jsxRuntime.jsx(
3613
+ accordion.Accordion.Item,
3614
+ __spreadValues({
3615
+ "data-slot": "accordion-item",
3616
+ className: cn(
3617
+ variant === "default" && "not-last:border-b",
3618
+ variant === "faq" && "rounded-lg border border-border bg-card",
3619
+ className
3620
+ )
3621
+ }, props)
3622
+ );
3623
+ }
3624
+ function AccordionTrigger(_a) {
3625
+ var _b = _a, {
3626
+ className,
3627
+ children
3628
+ } = _b, props = __objRest(_b, [
3629
+ "className",
3630
+ "children"
3631
+ ]);
3632
+ const variant = React18__namespace.useContext(AccordionVariantContext);
3633
+ return /* @__PURE__ */ jsxRuntime.jsx(accordion.Accordion.Header, { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
3634
+ accordion.Accordion.Trigger,
3635
+ __spreadProps(__spreadValues({
3636
+ "data-slot": "accordion-trigger",
3637
+ className: cn(
3638
+ "group/accordion-trigger relative flex flex-1 items-center justify-between text-left transition-all outline-none",
3639
+ "focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
3640
+ variant === "default" && [
3641
+ "rounded-lg border border-transparent py-2.5 text-sm font-medium",
3642
+ "hover:underline focus-visible:border-ring",
3643
+ "**:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground"
3644
+ ],
3645
+ variant === "faq" && [
3646
+ "px-5 py-4 text-base font-bold",
3647
+ "hover:bg-muted/30 rounded-lg"
3648
+ ],
3649
+ className
3650
+ )
3651
+ }, props), {
3652
+ children: [
3653
+ children,
3654
+ variant === "default" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3655
+ /* @__PURE__ */ jsxRuntime.jsx(
3656
+ lucideReact.ChevronDownIcon,
3657
+ {
3658
+ "data-slot": "accordion-trigger-icon",
3659
+ className: "pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
3660
+ }
3661
+ ),
3662
+ /* @__PURE__ */ jsxRuntime.jsx(
3663
+ lucideReact.ChevronUpIcon,
3664
+ {
3665
+ "data-slot": "accordion-trigger-icon",
3666
+ className: "pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
3667
+ }
3668
+ )
3669
+ ] }),
3670
+ variant === "faq" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3671
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "pointer-events-none shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:hidden" }),
3672
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusIcon, { className: "pointer-events-none hidden shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:inline" })
3673
+ ] })
3674
+ ]
3675
+ })
3676
+ ) });
3677
+ }
3678
+ function AccordionContent(_a) {
3679
+ var _b = _a, {
3680
+ className,
3681
+ children
3682
+ } = _b, props = __objRest(_b, [
3683
+ "className",
3684
+ "children"
3685
+ ]);
3686
+ const variant = React18__namespace.useContext(AccordionVariantContext);
3687
+ return /* @__PURE__ */ jsxRuntime.jsx(
3688
+ accordion.Accordion.Panel,
3689
+ __spreadProps(__spreadValues({
3690
+ "data-slot": "accordion-content",
3691
+ className: "overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
3692
+ }, props), {
3693
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3694
+ "div",
3695
+ {
3696
+ className: cn(
3697
+ "h-(--accordion-panel-height) pt-0 data-ending-style:h-0 data-starting-style:h-0",
3698
+ "[&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
3699
+ variant === "default" && "pb-2.5",
3700
+ variant === "faq" && "px-5 pb-5 text-base text-muted-foreground leading-relaxed",
3701
+ className
3702
+ ),
3703
+ children
3704
+ }
3705
+ )
3706
+ })
3707
+ );
3708
+ }
3709
+ function FilterPanel({
3710
+ groups,
3711
+ value,
3712
+ onChange,
3713
+ onClearAll,
3714
+ alwaysShowClear = false,
3715
+ title = "Filters",
3716
+ className
3717
+ }) {
3718
+ const [internalValue, setInternalValue] = React18__namespace.useState(
3719
+ () => Object.fromEntries(groups.map((g) => [g.id, []]))
3720
+ );
3721
+ const selected = value != null ? value : internalValue;
3722
+ const handleToggle = (groupId, itemId) => {
3723
+ var _a;
3724
+ const current = (_a = selected[groupId]) != null ? _a : [];
3725
+ const next = current.includes(itemId) ? current.filter((id) => id !== itemId) : [...current, itemId];
3726
+ const nextValue = __spreadProps(__spreadValues({}, selected), { [groupId]: next });
3727
+ if (onChange) {
3728
+ onChange(nextValue);
3729
+ } else {
3730
+ setInternalValue(nextValue);
3731
+ }
3732
+ };
3733
+ const handleClearAll = () => {
3734
+ const cleared = Object.fromEntries(groups.map((g) => [g.id, []]));
3735
+ if (onChange) {
3736
+ onChange(cleared);
3737
+ } else {
3738
+ setInternalValue(cleared);
3739
+ }
3740
+ onClearAll == null ? void 0 : onClearAll();
3741
+ };
3742
+ const totalSelected = Object.values(selected).flat().length;
3743
+ const showClear = alwaysShowClear || totalSelected > 0;
3744
+ const defaultOpenValues = groups.filter((g) => g.defaultOpen).map((g) => g.id);
3745
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
3746
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
3747
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-ui", children: title }),
3748
+ totalSelected > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-[10px] font-bold text-primary-foreground", children: totalSelected })
3749
+ ] }),
3750
+ /* @__PURE__ */ jsxRuntime.jsx(
3751
+ Accordion,
3752
+ {
3753
+ defaultValue: defaultOpenValues,
3754
+ className: "flex flex-col gap-2",
3755
+ children: groups.map((group) => {
3756
+ var _a;
3757
+ const groupSelected = (_a = selected[group.id]) != null ? _a : [];
3758
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3759
+ AccordionItem,
3760
+ {
3761
+ value: group.id,
3762
+ className: "border-0 border-b border-border last:border-b-0",
3763
+ children: [
3764
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionTrigger, { className: "px-0 py-3.5 hover:no-underline transition-colors", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2.5", children: [
3765
+ group.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary shrink-0", children: group.icon }),
3766
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold text-foreground font-ui", children: group.label }),
3767
+ groupSelected.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-primary-foreground", children: groupSelected.length })
3768
+ ] }) }),
3769
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionContent, { className: "px-4 pb-3 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-0.5", children: group.items.map((item) => {
3770
+ const checked = groupSelected.includes(item.id);
3771
+ const checkboxId = `filter-${group.id}-${item.id}`;
3772
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
3773
+ "label",
3774
+ {
3775
+ htmlFor: checkboxId,
3776
+ className: "flex cursor-pointer items-center gap-3 rounded-md px-1 py-2 transition-colors hover:bg-muted/50",
3777
+ children: [
3778
+ /* @__PURE__ */ jsxRuntime.jsx(
3779
+ Checkbox,
3780
+ {
3781
+ id: checkboxId,
3782
+ checked,
3783
+ onCheckedChange: () => handleToggle(group.id, item.id),
3784
+ className: "shrink-0"
3785
+ }
3786
+ ),
3787
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-foreground font-ui", children: item.label }),
3788
+ item.count !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-primary font-ui", children: [
3789
+ "(",
3790
+ item.count,
3791
+ ")"
3792
+ ] })
3793
+ ]
3794
+ }
3795
+ ) }, item.id);
3796
+ }) }) })
3797
+ ]
3798
+ },
3799
+ group.id
3800
+ );
3801
+ })
3802
+ }
3803
+ ),
3804
+ showClear && /* @__PURE__ */ jsxRuntime.jsx(
3805
+ "button",
3806
+ {
3807
+ onClick: handleClearAll,
3808
+ className: "self-start text-sm text-muted-foreground underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring font-ui",
3809
+ children: "Remove all filters"
3810
+ }
3811
+ )
3812
+ ] });
3813
+ }
3814
+ function ItineraryDayCard({
3815
+ stop,
3816
+ onOpen
3817
+ }) {
3818
+ const hasDescription = !!stop.description;
3819
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3820
+ "div",
3821
+ {
3822
+ onClick: onOpen,
3823
+ className: "group relative flex-none w-56 sm:w-64 h-80 rounded-2xl overflow-hidden cursor-pointer shadow-sm hover:shadow-lg transition-shadow duration-300",
3824
+ children: [
3825
+ /* @__PURE__ */ jsxRuntime.jsx(
3826
+ "img",
3827
+ {
3828
+ src: stop.coverImage,
3829
+ alt: stop.title,
3830
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
3831
+ }
3832
+ ),
3833
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-3 right-3 z-10 rounded-md bg-primary px-2 py-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-primary-foreground font-ui", children: [
3834
+ "Day ",
3835
+ stop.dayNumber
3836
+ ] }) }),
3837
+ /* @__PURE__ */ jsxRuntime.jsxs(
3838
+ "div",
3839
+ {
3840
+ className: cn(
3841
+ "absolute inset-x-0 bottom-0 z-10 bg-gradient-to-t from-black/70 via-black/20 to-transparent p-4 transition-opacity duration-300",
3842
+ hasDescription && "group-hover:opacity-0"
3843
+ ),
3844
+ children: [
3845
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-white leading-tight font-heading", children: stop.title }),
3846
+ stop.location && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-0.5 flex items-center gap-1 text-xs text-white/80 font-ui", children: [
3847
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-3 w-3 shrink-0" }),
3848
+ stop.location
3849
+ ] }),
3850
+ stop.route && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 flex items-center gap-1.5 text-xs text-white/80 font-ui", children: [
3851
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarIcon, { className: "h-3 w-3 shrink-0" }),
3852
+ stop.route.distance,
3853
+ " \xB7 ",
3854
+ stop.route.duration
3855
+ ] })
3856
+ ]
3857
+ }
3858
+ ),
3859
+ hasDescription && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-x-0 bottom-0 z-20 bg-background translate-y-full group-hover:translate-y-0 transition-transform duration-300 ease-out p-4", children: [
3860
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-bold text-foreground font-heading leading-tight", children: stop.title }),
3861
+ stop.location && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-0.5 flex items-center gap-1 text-xs text-muted-foreground font-ui", children: [
3862
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-3 w-3 shrink-0 text-primary" }),
3863
+ stop.location
3864
+ ] }),
3865
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 line-clamp-3 text-xs text-foreground/80 leading-relaxed [&_p]:inline [&_strong]:font-semibold", children: stop.description }),
3866
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-2 inline-block text-xs font-semibold text-primary font-ui", children: "Read more \u2192" })
3867
+ ] })
3868
+ ]
3869
+ }
3870
+ );
3871
+ }
3872
+ function ItineraryModal({
3873
+ stop,
3874
+ allStops,
3875
+ onClose,
3876
+ onPrev,
3877
+ onNext
3878
+ }) {
3879
+ var _a, _b, _c;
3880
+ const [imgIndex, setImgIndex] = React18__namespace.useState(0);
3881
+ const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
3882
+ const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
3883
+ const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
3884
+ React18__namespace.useEffect(() => {
3885
+ setImgIndex(0);
3886
+ }, [stop == null ? void 0 : stop.dayNumber]);
3887
+ if (!stop) return null;
3888
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: !!stop, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(
3889
+ DialogContent,
3890
+ {
3891
+ className: cn(
3892
+ /* Override shadcn defaults: remove padding, gap, grid, max-w-sm */
3893
+ "p-0 gap-0 sm:max-w-2xl max-w-[calc(100%-2rem)] overflow-hidden rounded-2xl",
3894
+ /* Outer flex column: [header+body] / [footer] */
3895
+ "flex flex-col"
3896
+ ),
3897
+ children: [
3898
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "sr-only", children: [
3899
+ stop.title,
3900
+ " \u2014 Day ",
3901
+ stop.dayNumber
3902
+ ] }),
3903
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { className: "sr-only", children: [
3904
+ "Itinerary details for Day ",
3905
+ stop.dayNumber
3906
+ ] }),
3907
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row flex-1 min-h-0", children: [
3908
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1 p-6 sm:p-8 overflow-y-auto max-h-[50vh] sm:max-h-[70vh]", children: [
3909
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading leading-tight", children: stop.title }),
3910
+ stop.location && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1.5 flex items-center gap-1.5 text-sm text-muted-foreground font-ui", children: [
3911
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-4 w-4 shrink-0 text-primary" }),
3912
+ stop.location
3913
+ ] }),
3914
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-4 text-sm font-bold text-foreground font-heading", children: [
3915
+ "Day ",
3916
+ stop.dayNumber
3917
+ ] }),
3918
+ stop.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-sm text-foreground/80 leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2", children: stop.description }),
3919
+ stop.route && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex items-center gap-2 text-sm text-muted-foreground font-ui", children: [
3920
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CarIcon, { className: "h-4 w-4 shrink-0 text-primary" }),
3921
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
3922
+ stop.route.distance,
3923
+ " \xB7 ",
3924
+ stop.route.duration
3925
+ ] })
3926
+ ] })
3927
+ ] }),
3928
+ images.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative sm:w-72 sm:shrink-0 h-52 sm:h-auto bg-muted overflow-hidden", children: [
3929
+ /* @__PURE__ */ jsxRuntime.jsx(
3930
+ "img",
3931
+ {
3932
+ src: images[imgIndex],
3933
+ alt: `${stop.title} ${imgIndex + 1}`,
3934
+ className: "h-full w-full object-cover"
3935
+ },
3936
+ imgIndex
3937
+ ),
3938
+ images.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3939
+ /* @__PURE__ */ jsxRuntime.jsx(
3940
+ "button",
3941
+ {
3942
+ type: "button",
3943
+ onClick: () => setImgIndex((i) => (i - 1 + images.length) % images.length),
3944
+ className: "absolute left-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-background/80 shadow hover:bg-background transition-colors",
3945
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-4 w-4" })
3946
+ }
3947
+ ),
3948
+ /* @__PURE__ */ jsxRuntime.jsx(
3949
+ "button",
3950
+ {
3951
+ type: "button",
3952
+ onClick: () => setImgIndex((i) => (i + 1) % images.length),
3953
+ className: "absolute right-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-background/80 shadow hover:bg-background transition-colors",
3954
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-4 w-4" })
3955
+ }
3956
+ ),
3957
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-3 inset-x-0 flex justify-center gap-1.5", children: images.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
3958
+ "button",
3959
+ {
3960
+ type: "button",
3961
+ onClick: () => setImgIndex(i),
3962
+ className: cn(
3963
+ "h-1.5 rounded-full transition-all",
3964
+ i === imgIndex ? "w-4 bg-white" : "w-1.5 bg-white/50"
3965
+ )
3966
+ },
3967
+ i
3968
+ )) })
3969
+ ] })
3970
+ ] })
3971
+ ] }),
3972
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-t border-border px-6 py-3 bg-background shrink-0", children: [
3973
+ /* @__PURE__ */ jsxRuntime.jsxs(
3974
+ "button",
3975
+ {
3976
+ type: "button",
3977
+ onClick: onPrev,
3978
+ disabled: isFirst,
3979
+ className: cn(
3980
+ "flex items-center gap-1.5 text-sm font-ui transition-colors",
3981
+ isFirst ? "text-muted-foreground/40 pointer-events-none" : "text-foreground hover:text-primary"
3982
+ ),
3983
+ children: [
3984
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full border border-current", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-3.5 w-3.5" }) }),
3985
+ "Last day"
3986
+ ]
3987
+ }
3988
+ ),
3989
+ /* @__PURE__ */ jsxRuntime.jsxs(
3990
+ "button",
3991
+ {
3992
+ type: "button",
3993
+ onClick: onNext,
3994
+ disabled: isLast,
3995
+ className: cn(
3996
+ "flex items-center gap-1.5 text-sm font-ui transition-colors",
3997
+ isLast ? "text-muted-foreground/40 pointer-events-none" : "text-foreground hover:text-primary"
3998
+ ),
3999
+ children: [
4000
+ "Next day",
4001
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full border border-current", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-3.5 w-3.5" }) })
4002
+ ]
4003
+ }
4004
+ )
4005
+ ] })
4006
+ ]
4007
+ }
4008
+ ) });
4009
+ }
4010
+ function Itinerary({ title, subtitle, stops, className }) {
4011
+ const [activeIndex, setActiveIndex] = React18__namespace.useState(null);
4012
+ const scrollRef = React18__namespace.useRef(null);
4013
+ const activeStop = activeIndex !== null ? stops[activeIndex] : null;
4014
+ const scrollBy = (dir) => {
4015
+ if (!scrollRef.current) return;
4016
+ const amount = 280;
4017
+ scrollRef.current.scrollBy({
4018
+ left: dir === "right" ? amount : -amount,
4019
+ behavior: "smooth"
4020
+ });
4021
+ };
4022
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
4023
+ (title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 text-center px-4", children: [
4024
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading", children: title }),
4025
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground max-w-md mx-auto leading-relaxed", children: subtitle })
4026
+ ] }),
4027
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/strip", children: [
4028
+ /* @__PURE__ */ jsxRuntime.jsx(
4029
+ "button",
4030
+ {
4031
+ type: "button",
4032
+ onClick: () => scrollBy("left"),
4033
+ "aria-label": "Scroll left",
4034
+ className: cn(
4035
+ "absolute left-0 top-1/2 -translate-y-1/2 z-20",
4036
+ "-translate-x-1/2 sm:-translate-x-5",
4037
+ "flex h-9 w-9 items-center justify-center rounded-full",
4038
+ "bg-background border border-border shadow-md",
4039
+ "transition-opacity hover:bg-muted",
4040
+ "opacity-0 group-hover/strip:opacity-100"
4041
+ ),
4042
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-4 w-4 text-foreground" })
4043
+ }
4044
+ ),
4045
+ /* @__PURE__ */ jsxRuntime.jsx(
4046
+ "button",
4047
+ {
4048
+ type: "button",
4049
+ onClick: () => scrollBy("right"),
4050
+ "aria-label": "Scroll right",
4051
+ className: cn(
4052
+ "absolute right-0 top-1/2 -translate-y-1/2 z-20",
4053
+ "translate-x-1/2 sm:translate-x-5",
4054
+ "flex h-9 w-9 items-center justify-center rounded-full",
4055
+ "bg-background border border-border shadow-md",
4056
+ "transition-opacity hover:bg-muted",
4057
+ "opacity-0 group-hover/strip:opacity-100"
4058
+ ),
4059
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-4 w-4 text-foreground" })
4060
+ }
4061
+ ),
4062
+ /* @__PURE__ */ jsxRuntime.jsx(
4063
+ "div",
4064
+ {
4065
+ ref: scrollRef,
4066
+ className: cn(
4067
+ "flex gap-3 sm:gap-4 overflow-x-auto pb-4",
4068
+ "snap-x snap-mandatory scroll-smooth",
4069
+ "[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
4070
+ "px-4 sm:px-2"
4071
+ ),
4072
+ children: stops.map((stop, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "snap-start shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(ItineraryDayCard, { stop, onOpen: () => setActiveIndex(i) }) }, stop.dayNumber))
4073
+ }
4074
+ )
4075
+ ] }),
4076
+ /* @__PURE__ */ jsxRuntime.jsx(
4077
+ ItineraryModal,
4078
+ {
4079
+ stop: activeStop,
4080
+ allStops: stops,
4081
+ onClose: () => setActiveIndex(null),
4082
+ onPrev: () => setActiveIndex((i) => i !== null ? Math.max(0, i - 1) : 0),
4083
+ onNext: () => setActiveIndex(
4084
+ (i) => i !== null ? Math.min(stops.length - 1, i + 1) : 0
4085
+ )
4086
+ }
4087
+ )
4088
+ ] });
4089
+ }
4090
+ function MenuTrip({
4091
+ sections,
4092
+ activeSection,
4093
+ onSelect,
4094
+ variant = "pill",
4095
+ bold = true,
4096
+ className
4097
+ }) {
4098
+ const scrollRef = React18__namespace.useRef(null);
4099
+ React18__namespace.useEffect(() => {
4100
+ if (!scrollRef.current || !activeSection) return;
4101
+ const container = scrollRef.current;
4102
+ const btn = container.querySelector(
4103
+ `[data-section="${activeSection}"]`
4104
+ );
4105
+ if (!btn) return;
4106
+ const btnLeft = btn.offsetLeft;
4107
+ const btnRight = btnLeft + btn.offsetWidth;
4108
+ const cLeft = container.scrollLeft;
4109
+ const cRight = cLeft + container.offsetWidth;
4110
+ if (btnLeft < cLeft) {
4111
+ container.scrollTo({ left: btnLeft - 16, behavior: "smooth" });
4112
+ } else if (btnRight > cRight) {
4113
+ container.scrollTo({ left: btnRight - container.offsetWidth + 16, behavior: "smooth" });
4114
+ }
4115
+ }, [activeSection]);
4116
+ if (variant === "underline") {
4117
+ return /* @__PURE__ */ jsxRuntime.jsx(
4118
+ "div",
4119
+ {
4120
+ ref: scrollRef,
4121
+ className: cn(
4122
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
4123
+ "border-b border-border",
4124
+ className
4125
+ ),
4126
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex min-w-max items-end gap-0", children: sections.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
4127
+ "button",
4128
+ {
4129
+ "data-section": s.id,
4130
+ type: "button",
4131
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
4132
+ className: cn(
4133
+ "relative px-4 py-2.5 text-sm font-ui whitespace-nowrap transition-colors duration-150",
4134
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
4135
+ "after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full after:transition-all",
4136
+ bold ? "font-semibold" : "font-normal",
4137
+ activeSection === s.id ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent"
4138
+ ),
4139
+ children: s.label
4140
+ },
4141
+ s.id
4142
+ )) })
4143
+ }
4144
+ );
4145
+ }
4146
+ if (variant === "outlined") {
4147
+ return /* @__PURE__ */ jsxRuntime.jsx(
4148
+ "div",
4149
+ {
4150
+ ref: scrollRef,
4151
+ className: cn(
4152
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
4153
+ className
4154
+ ),
4155
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex min-w-max items-center gap-2", children: sections.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
4156
+ "button",
4157
+ {
4158
+ "data-section": s.id,
4159
+ type: "button",
4160
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
4161
+ className: cn(
4162
+ "rounded-full border px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
4163
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4164
+ bold ? "font-semibold" : "font-normal",
4165
+ activeSection === s.id ? "border-foreground bg-foreground text-background" : "border-border bg-background text-muted-foreground hover:border-foreground/50 hover:text-foreground"
4166
+ ),
4167
+ children: s.label
4168
+ },
4169
+ s.id
4170
+ )) })
4171
+ }
4172
+ );
4173
+ }
4174
+ if (variant === "floating") {
4175
+ return /* @__PURE__ */ jsxRuntime.jsx(
4176
+ "div",
4177
+ {
4178
+ ref: scrollRef,
4179
+ className: cn(
4180
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
4181
+ "py-1 px-0.5",
4182
+ /* padding so shadow isn't clipped by overflow */
4183
+ className
4184
+ ),
4185
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex min-w-max items-center gap-0.5 rounded-full border border-border/40 bg-background/90 backdrop-blur-md shadow-sm px-1.5 py-1.5", children: sections.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
4186
+ "button",
4187
+ {
4188
+ "data-section": s.id,
4189
+ type: "button",
4190
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
4191
+ className: cn(
4192
+ "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
4193
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4194
+ bold ? "font-semibold" : "font-normal",
4195
+ activeSection === s.id ? "bg-foreground text-background shadow-sm" : "text-foreground/60 hover:text-foreground hover:bg-muted/60"
4196
+ ),
4197
+ children: s.label
4198
+ },
4199
+ s.id
4200
+ )) })
4201
+ }
4202
+ );
4203
+ }
4204
+ return /* @__PURE__ */ jsxRuntime.jsx(
4205
+ "div",
4206
+ {
4207
+ ref: scrollRef,
4208
+ className: cn(
4209
+ "overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
4210
+ className
4211
+ ),
4212
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex min-w-max items-center gap-1 p-1", children: sections.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
4213
+ "button",
4214
+ {
4215
+ "data-section": s.id,
4216
+ type: "button",
4217
+ onClick: () => onSelect == null ? void 0 : onSelect(s.id),
4218
+ className: cn(
4219
+ "rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
4220
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4221
+ bold ? "font-semibold" : "font-normal",
4222
+ activeSection === s.id ? "bg-foreground text-background shadow-sm" : "bg-white text-foreground/70 hover:text-foreground shadow-sm"
4223
+ ),
4224
+ children: s.label
4225
+ },
4226
+ s.id
4227
+ )) })
4228
+ }
4229
+ );
4230
+ }
4231
+ function normalise(p) {
4232
+ return typeof p === "string" ? { src: p } : p;
4233
+ }
4234
+ function gridCols(total) {
4235
+ if (total === 1) return "grid-cols-1";
4236
+ if (total === 2) return "grid-cols-2";
4237
+ return "grid-cols-3";
4238
+ }
4239
+ function Lightbox({
4240
+ photos,
4241
+ initialIndex,
4242
+ onClose
4243
+ }) {
4244
+ var _a;
4245
+ const [index, setIndex] = React18__namespace.useState(initialIndex);
4246
+ const total = photos.length;
4247
+ const photo = photos[index];
4248
+ const prev = React18__namespace.useCallback(
4249
+ () => setIndex((i) => (i - 1 + total) % total),
4250
+ [total]
4251
+ );
4252
+ const next = React18__namespace.useCallback(
4253
+ () => setIndex((i) => (i + 1) % total),
4254
+ [total]
4255
+ );
4256
+ React18__namespace.useEffect(() => {
4257
+ const onKey = (e) => {
4258
+ if (e.key === "Escape") onClose();
4259
+ if (e.key === "ArrowLeft") prev();
4260
+ if (e.key === "ArrowRight") next();
4261
+ };
4262
+ document.addEventListener("keydown", onKey);
4263
+ return () => document.removeEventListener("keydown", onKey);
4264
+ }, [onClose, prev, next]);
4265
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4266
+ "div",
4267
+ {
4268
+ className: "fixed inset-0 z-50 bg-black/92 flex flex-col items-center justify-center",
4269
+ onClick: onClose,
4270
+ children: [
4271
+ /* @__PURE__ */ jsxRuntime.jsx(
4272
+ "button",
4273
+ {
4274
+ type: "button",
4275
+ onClick: onClose,
4276
+ className: "absolute top-5 right-5 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors z-10",
4277
+ "aria-label": "Close lightbox",
4278
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "h-5 w-5" })
4279
+ }
4280
+ ),
4281
+ total > 1 && /* @__PURE__ */ jsxRuntime.jsx(
4282
+ "button",
4283
+ {
4284
+ type: "button",
4285
+ onClick: (e) => {
4286
+ e.stopPropagation();
4287
+ prev();
4288
+ },
4289
+ className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
4290
+ "aria-label": "Previous photo",
4291
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-5 w-5" })
4292
+ }
4293
+ ),
4294
+ total > 1 && /* @__PURE__ */ jsxRuntime.jsx(
4295
+ "button",
4296
+ {
4297
+ type: "button",
4298
+ onClick: (e) => {
4299
+ e.stopPropagation();
4300
+ next();
4301
+ },
4302
+ className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
4303
+ "aria-label": "Next photo",
4304
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-5 w-5" })
4305
+ }
4306
+ ),
4307
+ /* @__PURE__ */ jsxRuntime.jsx(
4308
+ "img",
4309
+ {
4310
+ src: photo.src,
4311
+ alt: (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
4312
+ className: "max-w-[calc(100%-6rem)] max-h-[calc(100vh-11rem)] object-contain rounded-lg shadow-2xl",
4313
+ onClick: (e) => e.stopPropagation()
4314
+ }
4315
+ ),
4316
+ (photo.caption || photo.credit) && /* @__PURE__ */ jsxRuntime.jsxs(
4317
+ "div",
4318
+ {
4319
+ className: "mt-4 flex flex-col items-center gap-0.5 px-16 text-center",
4320
+ onClick: (e) => e.stopPropagation(),
4321
+ children: [
4322
+ photo.caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-white/90 font-ui leading-snug max-w-xl", children: photo.caption }),
4323
+ photo.credit && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-white/45 font-ui", children: [
4324
+ "\xA9 ",
4325
+ photo.credit
4326
+ ] })
4327
+ ]
4328
+ }
4329
+ ),
4330
+ total > 1 && /* @__PURE__ */ jsxRuntime.jsxs(
4331
+ "div",
4332
+ {
4333
+ className: "absolute bottom-5 inset-x-0 flex items-center justify-center gap-3 px-5",
4334
+ onClick: (e) => e.stopPropagation(),
4335
+ children: [
4336
+ /* @__PURE__ */ jsxRuntime.jsx(
4337
+ "button",
4338
+ {
4339
+ type: "button",
4340
+ onClick: (e) => {
4341
+ e.stopPropagation();
4342
+ prev();
4343
+ },
4344
+ className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
4345
+ "aria-label": "Previous photo",
4346
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-4 w-4" })
4347
+ }
4348
+ ),
4349
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: photos.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
4350
+ "button",
4351
+ {
4352
+ type: "button",
4353
+ onClick: (e) => {
4354
+ e.stopPropagation();
4355
+ setIndex(i);
4356
+ },
4357
+ "aria-label": `Go to photo ${i + 1}`,
4358
+ className: cn(
4359
+ "h-1.5 rounded-full transition-all duration-300 focus-visible:outline-none",
4360
+ i === index ? "w-6 bg-primary" : "w-1.5 bg-white/40 hover:bg-white/70"
4361
+ )
4362
+ },
4363
+ i
4364
+ )) }),
4365
+ /* @__PURE__ */ jsxRuntime.jsx(
4366
+ "button",
4367
+ {
4368
+ type: "button",
4369
+ onClick: (e) => {
4370
+ e.stopPropagation();
4371
+ next();
4372
+ },
4373
+ className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
4374
+ "aria-label": "Next photo",
4375
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-4 w-4" })
4376
+ }
4377
+ )
4378
+ ]
4379
+ }
4380
+ )
4381
+ ]
4382
+ }
4383
+ );
4384
+ }
4385
+ function PhotoTile({
4386
+ photo,
4387
+ index,
4388
+ className,
4389
+ onClick
4390
+ }) {
4391
+ var _a, _b;
4392
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4393
+ "button",
4394
+ {
4395
+ type: "button",
4396
+ onClick,
4397
+ className: cn(
4398
+ "relative overflow-hidden group block w-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4399
+ className
4400
+ ),
4401
+ "aria-label": (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
4402
+ children: [
4403
+ /* @__PURE__ */ jsxRuntime.jsx(
4404
+ "img",
4405
+ {
4406
+ src: photo.src,
4407
+ alt: (_b = photo.alt) != null ? _b : `Photo ${index + 1}`,
4408
+ className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105",
4409
+ loading: "lazy"
4410
+ }
4411
+ ),
4412
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomInIcon, { className: "h-8 w-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
4413
+ ]
4414
+ }
4415
+ );
4416
+ }
4417
+ function ShowMoreButton({
4418
+ count,
4419
+ expanded,
4420
+ onClick
4421
+ }) {
4422
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
4423
+ "button",
4424
+ {
4425
+ type: "button",
4426
+ onClick,
4427
+ className: cn(
4428
+ "inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
4429
+ "text-sm font-semibold text-foreground shadow-sm",
4430
+ "hover:bg-muted transition-colors duration-150",
4431
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
4432
+ ),
4433
+ children: expanded ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4434
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
4435
+ "Show less"
4436
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4437
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LayoutGridIcon, { className: "h-4 w-4 text-muted-foreground" }),
4438
+ "See more (",
4439
+ count,
4440
+ ")"
4441
+ ] })
4442
+ }
4443
+ ) });
4444
+ }
4445
+ function GridGallery({
4446
+ photos,
4447
+ initialVisible,
4448
+ onOpen
4449
+ }) {
4450
+ const [expanded, setExpanded] = React18__namespace.useState(false);
4451
+ const cols = gridCols(photos.length);
4452
+ const hasMore = photos.length > initialVisible;
4453
+ const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
4454
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4455
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid", cols), children: visible.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
4456
+ PhotoTile,
4457
+ {
4458
+ photo: p,
4459
+ index: i,
4460
+ className: "aspect-[4/3]",
4461
+ onClick: () => onOpen(i)
4462
+ },
4463
+ i
4464
+ )) }),
4465
+ hasMore && /* @__PURE__ */ jsxRuntime.jsx(
4466
+ ShowMoreButton,
4467
+ {
4468
+ count: photos.length - initialVisible,
4469
+ expanded,
4470
+ onClick: () => setExpanded((v) => !v)
4471
+ }
4472
+ )
4473
+ ] });
4474
+ }
4475
+ function MasonryGallery({
4476
+ photos,
4477
+ initialVisible,
4478
+ onOpen
4479
+ }) {
4480
+ const [expanded, setExpanded] = React18__namespace.useState(false);
4481
+ const hasMore = photos.length > initialVisible;
4482
+ const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
4483
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4484
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "columns-2 sm:columns-3 gap-1 [&>*]:break-inside-avoid [&>*]:mb-1", children: visible.map((p, i) => {
4485
+ var _a, _b;
4486
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4487
+ "button",
4488
+ {
4489
+ type: "button",
4490
+ onClick: () => onOpen(i),
4491
+ className: "relative overflow-hidden group block w-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4492
+ "aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 1}`,
4493
+ children: [
4494
+ /* @__PURE__ */ jsxRuntime.jsx(
4495
+ "img",
4496
+ {
4497
+ src: p.src,
4498
+ alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
4499
+ className: "w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105",
4500
+ loading: "lazy"
4501
+ }
4502
+ ),
4503
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
4504
+ ]
4505
+ },
4506
+ i
4507
+ );
4508
+ }) }),
4509
+ hasMore && /* @__PURE__ */ jsxRuntime.jsx(
4510
+ ShowMoreButton,
4511
+ {
4512
+ count: photos.length - initialVisible,
4513
+ expanded,
4514
+ onClick: () => setExpanded((v) => !v)
4515
+ }
4516
+ )
4517
+ ] });
4518
+ }
4519
+ function FilmstripGallery({
4520
+ photos,
4521
+ onOpen
4522
+ }) {
4523
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto flex gap-1 snap-x snap-mandatory pb-1 scrollbar-none", children: photos.map((p, i) => {
4524
+ var _a, _b;
4525
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4526
+ "button",
4527
+ {
4528
+ type: "button",
4529
+ onClick: () => onOpen(i),
4530
+ className: "relative shrink-0 overflow-hidden group h-56 w-auto aspect-[4/3] snap-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4531
+ "aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 1}`,
4532
+ children: [
4533
+ /* @__PURE__ */ jsxRuntime.jsx(
4534
+ "img",
4535
+ {
4536
+ src: p.src,
4537
+ alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
4538
+ className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
4539
+ loading: "lazy"
4540
+ }
4541
+ ),
4542
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
4543
+ ]
4544
+ },
4545
+ i
4546
+ );
4547
+ }) });
4548
+ }
4549
+ function FeaturedGallery({
4550
+ photos,
4551
+ onOpen
4552
+ }) {
4553
+ const [expanded, setExpanded] = React18__namespace.useState(false);
4554
+ const featured = photos.slice(0, 3);
4555
+ const extra = photos.slice(3);
4556
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4557
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-1.5 h-72 sm:h-80 lg:h-96 rounded-xl overflow-hidden", children: [
4558
+ featured[0] && /* @__PURE__ */ jsxRuntime.jsx(
4559
+ PhotoTile,
4560
+ {
4561
+ photo: featured[0],
4562
+ index: 0,
4563
+ className: "col-span-2 h-full",
4564
+ onClick: () => onOpen(0)
4565
+ }
4566
+ ),
4567
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 h-full", children: [
4568
+ featured[1] && /* @__PURE__ */ jsxRuntime.jsx(
4569
+ PhotoTile,
4570
+ {
4571
+ photo: featured[1],
4572
+ index: 1,
4573
+ className: "flex-1 min-h-0",
4574
+ onClick: () => onOpen(1)
4575
+ }
4576
+ ),
4577
+ featured[2] && /* @__PURE__ */ jsxRuntime.jsx(
4578
+ PhotoTile,
4579
+ {
4580
+ photo: featured[2],
4581
+ index: 2,
4582
+ className: "flex-1 min-h-0",
4583
+ onClick: () => onOpen(2)
4584
+ }
4585
+ )
4586
+ ] })
4587
+ ] }),
4588
+ expanded && extra.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5 overflow-x-auto flex gap-1.5 snap-x snap-mandatory scrollbar-none rounded-xl overflow-hidden pb-0", children: extra.map((p, i) => {
4589
+ var _a, _b;
4590
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4591
+ "button",
4592
+ {
4593
+ type: "button",
4594
+ onClick: () => onOpen(i + 3),
4595
+ className: "relative shrink-0 overflow-hidden group h-40 sm:h-48 aspect-[4/3] snap-start rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4596
+ "aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 4}`,
4597
+ children: [
4598
+ /* @__PURE__ */ jsxRuntime.jsx(
4599
+ "img",
4600
+ {
4601
+ src: p.src,
4602
+ alt: (_b = p.alt) != null ? _b : `Photo ${i + 4}`,
4603
+ className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
4604
+ loading: "lazy"
4605
+ }
4606
+ ),
4607
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
4608
+ ]
4609
+ },
4610
+ i + 3
4611
+ );
4612
+ }) }),
4613
+ extra.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
4614
+ ShowMoreButton,
4615
+ {
4616
+ count: extra.length,
4617
+ expanded,
4618
+ onClick: () => setExpanded((v) => !v)
4619
+ }
4620
+ )
4621
+ ] });
4622
+ }
4623
+ function PhotoGallery({
4624
+ photos,
4625
+ variant = "grid",
4626
+ initialVisible = 6,
4627
+ onPhotoClick,
4628
+ className
4629
+ }) {
4630
+ const [lightboxIndex, setLightboxIndex] = React18__namespace.useState(null);
4631
+ const normalised = React18__namespace.useMemo(() => photos.map(normalise), [photos]);
4632
+ const handleOpen = (index) => {
4633
+ setLightboxIndex(index);
4634
+ onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
4635
+ };
4636
+ if (normalised.length === 0) return null;
4637
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
4638
+ variant === "grid" && /* @__PURE__ */ jsxRuntime.jsx(
4639
+ GridGallery,
4640
+ {
4641
+ photos: normalised,
4642
+ initialVisible,
4643
+ onOpen: handleOpen
4644
+ }
4645
+ ),
4646
+ variant === "masonry" && /* @__PURE__ */ jsxRuntime.jsx(
4647
+ MasonryGallery,
4648
+ {
4649
+ photos: normalised,
4650
+ initialVisible,
4651
+ onOpen: handleOpen
4652
+ }
4653
+ ),
4654
+ variant === "filmstrip" && /* @__PURE__ */ jsxRuntime.jsx(FilmstripGallery, { photos: normalised, onOpen: handleOpen }),
4655
+ variant === "featured" && /* @__PURE__ */ jsxRuntime.jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen }),
4656
+ lightboxIndex !== null && /* @__PURE__ */ jsxRuntime.jsx(
4657
+ Lightbox,
4658
+ {
4659
+ photos: normalised,
4660
+ initialIndex: lightboxIndex,
4661
+ onClose: () => setLightboxIndex(null)
4662
+ }
4663
+ )
4664
+ ] });
4665
+ }
4666
+ var badgeVariants = classVarianceAuthority.cva(
4667
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
4668
+ {
4669
+ variants: {
4670
+ variant: {
4671
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
4672
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
4673
+ 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",
4674
+ outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
4675
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
4676
+ link: "text-primary underline-offset-4 hover:underline"
4677
+ }
4678
+ },
4679
+ defaultVariants: {
4680
+ variant: "default"
4681
+ }
4682
+ }
4683
+ );
4684
+ function Badge(_a) {
4685
+ var _b = _a, {
4686
+ className,
4687
+ variant = "default",
4688
+ render
4689
+ } = _b, props = __objRest(_b, [
4690
+ "className",
4691
+ "variant",
4692
+ "render"
4693
+ ]);
4694
+ return useRender.useRender({
4695
+ defaultTagName: "span",
4696
+ props: mergeProps.mergeProps(
4697
+ {
4698
+ className: cn(badgeVariants({ variant }), className)
4699
+ },
4700
+ props
4701
+ ),
4702
+ render,
4703
+ state: {
4704
+ slot: "badge",
4705
+ variant
4706
+ }
4707
+ });
4708
+ }
4709
+ function PricingTrip({
4710
+ priceFrom,
4711
+ currency = "CHF",
4712
+ season,
4713
+ departureTimes,
4714
+ pricingOptions,
4715
+ onBook,
4716
+ bookLabel = "Check availability",
4717
+ variant = "card",
4718
+ className
4719
+ }) {
4720
+ const [showPricing, setShowPricing] = React18__namespace.useState(false);
4721
+ if (variant === "compact") {
4722
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-3", className), children: [
4723
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4724
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
4725
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-lg font-bold text-foreground font-heading leading-none", children: [
4726
+ currency,
4727
+ " ",
4728
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: priceFrom })
4729
+ ] })
4730
+ ] }),
4731
+ /* @__PURE__ */ jsxRuntime.jsx(
4732
+ "button",
4733
+ {
4734
+ type: "button",
4735
+ onClick: onBook,
4736
+ className: cn(
4737
+ "flex-1 rounded-full bg-primary px-4 py-2 text-sm font-semibold",
4738
+ "text-primary-foreground font-ui transition-colors hover:bg-primary/90",
4739
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
4740
+ ),
4741
+ children: bookLabel
4742
+ }
4743
+ )
4744
+ ] });
4745
+ }
4746
+ if (variant === "bar") {
4747
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4748
+ "div",
4749
+ {
4750
+ className: cn(
4751
+ "flex items-center gap-4 rounded-2xl border border-border bg-card px-5 py-3 shadow-sm",
4752
+ className
4753
+ ),
4754
+ children: [
4755
+ season && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden sm:flex items-center gap-1.5 text-sm text-muted-foreground font-ui shrink-0", children: [
4756
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
4757
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[180px]", children: season })
4758
+ ] }),
4759
+ departureTimes && departureTimes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden md:flex items-center gap-1.5 shrink-0", children: [
4760
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClockIcon, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
4761
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", children: departureTimes.map((t) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "font-ui text-xs px-1.5 py-0.5", children: t }, t)) })
4762
+ ] }),
4763
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
4764
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 text-right", children: [
4765
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
4766
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xl font-bold text-foreground font-heading leading-none", children: [
4767
+ currency,
4768
+ " ",
4769
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: priceFrom })
4770
+ ] })
4771
+ ] }),
4772
+ /* @__PURE__ */ jsxRuntime.jsxs(
4773
+ "button",
4774
+ {
4775
+ type: "button",
4776
+ onClick: onBook,
4777
+ className: cn(
4778
+ "shrink-0 flex items-center gap-2 rounded-full bg-primary px-5 py-2.5",
4779
+ "text-sm font-semibold text-primary-foreground font-ui",
4780
+ "transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
4781
+ ),
4782
+ children: [
4783
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "h-4 w-4 shrink-0" }),
4784
+ bookLabel
4785
+ ]
4786
+ }
4787
+ )
4788
+ ]
4789
+ }
4790
+ );
4791
+ }
4792
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
4793
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4794
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide", children: "From" }),
4795
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-3xl font-bold text-foreground font-heading", children: [
4796
+ currency,
4797
+ " ",
4798
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: priceFrom }),
4799
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-normal text-muted-foreground font-ui", children: " / guest" })
4800
+ ] })
4801
+ ] }),
4802
+ season && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 text-sm text-muted-foreground font-ui", children: [
4803
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, { className: "h-4 w-4 shrink-0 text-primary mt-0.5" }),
4804
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: season })
4805
+ ] }),
4806
+ departureTimes && departureTimes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
4807
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-foreground font-ui uppercase tracking-wide", children: "Departure times" }),
4808
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5", children: departureTimes.map((t) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "font-ui text-xs", children: t }, t)) })
4809
+ ] }),
4810
+ pricingOptions && pricingOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
4811
+ /* @__PURE__ */ jsxRuntime.jsx(
4812
+ "button",
4813
+ {
4814
+ type: "button",
4815
+ onClick: () => setShowPricing((v) => !v),
4816
+ className: "flex items-center gap-1 text-xs text-primary font-ui text-left hover:underline underline-offset-2",
4817
+ children: showPricing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4818
+ "Show pricing options ",
4819
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "h-3 w-3" })
4820
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4821
+ "Show pricing options ",
4822
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "h-3 w-3" })
4823
+ ] })
4824
+ }
4825
+ ),
4826
+ showPricing && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border overflow-hidden", children: pricingOptions.map((opt, i) => /* @__PURE__ */ jsxRuntime.jsxs(
4827
+ "div",
4828
+ {
4829
+ className: cn(
4830
+ "flex items-center justify-between px-3 py-2.5 text-sm",
4831
+ i < pricingOptions.length - 1 && "border-b border-border"
4832
+ ),
4833
+ children: [
4834
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-ui", children: opt.label }),
4835
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-right", children: [
4836
+ opt.originalPrice && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground line-through font-ui", children: [
4837
+ currency,
4838
+ " ",
4839
+ opt.originalPrice
4840
+ ] }),
4841
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold text-foreground font-ui", children: [
4842
+ currency,
4843
+ " ",
4844
+ opt.price,
4845
+ opt.unit && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: [
4846
+ " ",
4847
+ "/ ",
4848
+ opt.unit
4849
+ ] })
4850
+ ] })
4851
+ ] })
4852
+ ]
4853
+ },
4854
+ i
4855
+ )) })
4856
+ ] }),
4857
+ /* @__PURE__ */ jsxRuntime.jsx(
4858
+ "button",
4859
+ {
4860
+ type: "button",
4861
+ onClick: onBook,
4862
+ className: cn(
4863
+ "w-full rounded-full bg-primary py-3 text-center text-sm font-semibold",
4864
+ "text-primary-foreground font-ui transition-colors hover:bg-primary/90",
4865
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
4866
+ ),
4867
+ children: bookLabel
4868
+ }
4869
+ )
4870
+ ] });
4871
+ }
4872
+ var VARIANT = {
4873
+ transparent: {
4874
+ header: "",
4875
+ navItem: "text-white hover:text-white/80",
4876
+ navItemOpen: "text-white bg-white/10",
4877
+ chevron: "text-white/50",
4878
+ lang: "text-white/70 hover:text-white",
4879
+ langOpen: "text-white bg-white/10",
4880
+ langChevron: "text-white/40",
4881
+ icon: "text-white/60 hover:text-white hover:bg-white/10",
4882
+ mobileTrigger: "text-white/70 hover:text-primary-400 hover:bg-white/8",
4883
+ mobileDrawer: "bg-primary-900 border-t border-white/10",
4884
+ mobileLink: "text-white hover:text-primary-400 border-b border-white/10",
4885
+ mobileSub: "text-white/70 font-bold hover:text-primary-400 border-b border-white/8",
4886
+ mobileLangActive: "text-primary-400 font-semibold",
4887
+ mobileLangIdle: "text-white/40 hover:text-primary-400",
4888
+ logoBlend: "mix-blend-screen"
4889
+ },
4890
+ white: {
4891
+ header: "bg-white border-b border-border shadow-sm",
4892
+ navItem: "text-foreground/70 hover:text-foreground",
4893
+ navItemOpen: "text-foreground bg-muted",
4894
+ chevron: "text-foreground/35",
4895
+ lang: "text-foreground/60 hover:text-foreground",
4896
+ langOpen: "text-foreground bg-muted",
4897
+ langChevron: "text-foreground/30",
4898
+ icon: "text-foreground/50 hover:text-foreground hover:bg-muted",
4899
+ mobileTrigger: "text-foreground/50 hover:text-foreground hover:bg-muted",
4900
+ mobileDrawer: "bg-white border-t border-border",
4901
+ mobileLink: "text-foreground/80 hover:text-foreground border-b border-border",
4902
+ mobileSub: "text-foreground/50 font-bold hover:text-foreground border-b border-border/40",
4903
+ mobileLangActive: "text-primary font-semibold",
4904
+ mobileLangIdle: "text-muted-foreground hover:text-foreground",
4905
+ logoBlend: "invert mix-blend-multiply"
4906
+ },
4907
+ dark: {
4908
+ header: "bg-neutral-950 border-b border-white/10",
4909
+ navItem: "text-white/70 hover:text-white",
4910
+ navItemOpen: "text-white bg-white/10",
4911
+ chevron: "text-white/40",
4912
+ lang: "text-white/60 hover:text-white",
4913
+ langOpen: "text-white bg-white/10",
4914
+ langChevron: "text-white/30",
4915
+ icon: "text-white/50 hover:text-white hover:bg-white/10",
4916
+ mobileTrigger: "text-white/50 hover:text-white hover:bg-white/10",
4917
+ mobileDrawer: "bg-neutral-950 border-t border-white/10",
4918
+ mobileLink: "text-white/80 hover:text-white border-b border-white/8",
4919
+ mobileSub: "text-white/45 font-bold hover:text-white border-b border-white/5",
4920
+ mobileLangActive: "text-white font-semibold",
4921
+ mobileLangIdle: "text-white/35 hover:text-white/60",
4922
+ logoBlend: "mix-blend-screen"
4923
+ }
4924
+ };
4925
+ var DEFAULT_HEADER_LINKS = [
4926
+ { label: "All trips", href: "#" },
4927
+ {
4928
+ label: "Destinations",
4929
+ items: [
4930
+ { label: "Europe", href: "#" },
4931
+ { label: "South America", href: "#" },
4932
+ { label: "Africa", href: "#" },
4933
+ { label: "Asia", href: "#" },
4934
+ { label: "North America", href: "#" },
4935
+ { label: "Oceania", href: "#" }
4936
+ ]
4937
+ },
4938
+ {
4939
+ label: "Travel themes",
4940
+ items: [
4941
+ { label: "Adventure", href: "#" },
4942
+ { label: "Cultural", href: "#" },
4943
+ { label: "Wildlife", href: "#" },
4944
+ { label: "Beach & Coast", href: "#" },
4945
+ { label: "Trekking", href: "#" }
4946
+ ]
4947
+ },
4948
+ {
4949
+ label: "About",
4950
+ items: [
4951
+ { label: "About us", href: "#" },
4952
+ { label: "Sustainability", href: "#" },
4953
+ { label: "Jobs", href: "#" },
4954
+ { label: "FAQ", href: "#" },
4955
+ { label: "Contact", href: "#" },
4956
+ { label: "Gift Card", href: "#" }
4957
+ ]
4958
+ },
4959
+ { label: "Blog", href: "#" }
4960
+ ];
4961
+ var DEFAULT_LANGUAGES = [
4962
+ { code: "EN", label: "English" },
4963
+ { code: "PT", label: "Portugu\xEAs" },
4964
+ { code: "NL", label: "Nederlands" },
4965
+ { code: "DE", label: "Deutsch" },
4966
+ { code: "FR", label: "Fran\xE7ais" },
4967
+ { code: "ES", label: "Espa\xF1ol" }
4968
+ ];
4969
+ function NavDropdown({
4970
+ items,
4971
+ onClose,
4972
+ onMouseEnter,
4973
+ onMouseLeave
4974
+ }) {
4975
+ return /* @__PURE__ */ jsxRuntime.jsx(
4976
+ "div",
4977
+ {
4978
+ className: "absolute top-[calc(100%+8px)] left-0 min-w-[200px] rounded-xl bg-white shadow-2xl border border-black/8 py-1.5 z-50",
4979
+ onMouseEnter,
4980
+ onMouseLeave,
4981
+ children: items.map((item) => {
4982
+ var _a;
4983
+ return /* @__PURE__ */ jsxRuntime.jsx(
4984
+ "a",
4985
+ {
4986
+ href: (_a = item.href) != null ? _a : "#",
4987
+ onClick: onClose,
4988
+ className: "block px-5 py-2.5 text-sm text-foreground/75 font-ui font-bold hover:text-foreground hover:bg-muted transition-colors whitespace-nowrap",
4989
+ children: item.label
4990
+ },
4991
+ item.label
4992
+ );
4993
+ })
4994
+ }
4995
+ );
4996
+ }
4997
+ function LangDropdown({
4998
+ languages,
4999
+ activeLang,
5000
+ onSelect,
5001
+ onMouseEnter,
5002
+ onMouseLeave
5003
+ }) {
5004
+ return /* @__PURE__ */ jsxRuntime.jsx(
5005
+ "div",
5006
+ {
5007
+ className: "absolute top-[calc(100%+8px)] right-0 min-w-[160px] rounded-xl bg-white shadow-2xl border border-black/8 py-1.5 z-50",
5008
+ onMouseEnter,
5009
+ onMouseLeave,
5010
+ children: languages.map((lang) => /* @__PURE__ */ jsxRuntime.jsxs(
5011
+ "button",
5012
+ {
5013
+ type: "button",
5014
+ onClick: () => onSelect(lang.code),
5015
+ className: cn(
5016
+ "flex items-center gap-3 w-full px-5 py-2.5 text-sm font-ui text-left transition-colors hover:bg-muted",
5017
+ lang.code === activeLang ? "text-primary font-semibold" : "text-foreground"
5018
+ ),
5019
+ children: [
5020
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold w-8 shrink-0", children: lang.code }),
5021
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: lang.label })
5022
+ ]
5023
+ },
5024
+ lang.code
5025
+ ))
5026
+ }
5027
+ );
5028
+ }
5029
+ function SiteHeader({
5030
+ variant = "transparent",
5031
+ links = DEFAULT_HEADER_LINKS,
5032
+ logoSrc = "/logo-planetaexo.png",
5033
+ logoAlt = "Planeta Exo",
5034
+ languages = DEFAULT_LANGUAGES,
5035
+ currentLanguage = "EN",
5036
+ onLanguageChange,
5037
+ onSearch,
5038
+ onAccount,
5039
+ position = variant === "transparent" ? "overlay" : "fixed",
5040
+ className
5041
+ }) {
5042
+ const t = VARIANT[variant];
5043
+ const [openMenu, setOpenMenu] = React18__namespace.useState(null);
5044
+ const [langOpen, setLangOpen] = React18__namespace.useState(false);
5045
+ const [mobileOpen, setMobileOpen] = React18__namespace.useState(false);
5046
+ const [openMobileSection, setOpenMobileSection] = React18__namespace.useState(null);
5047
+ const [activeLang, setActiveLang] = React18__namespace.useState(currentLanguage);
5048
+ const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
5049
+ const menuCloseTimer = React18__namespace.useRef(void 0);
5050
+ const langCloseTimer = React18__namespace.useRef(void 0);
5051
+ const handleMenuEnter = (label) => {
5052
+ clearTimeout(menuCloseTimer.current);
5053
+ setOpenMenu(label);
5054
+ };
5055
+ const handleMenuLeave = () => {
5056
+ menuCloseTimer.current = setTimeout(() => setOpenMenu(null), 120);
5057
+ };
5058
+ const handleLangEnter = () => {
5059
+ clearTimeout(langCloseTimer.current);
5060
+ setLangOpen(true);
5061
+ };
5062
+ const handleLangLeave = () => {
5063
+ langCloseTimer.current = setTimeout(() => setLangOpen(false), 120);
5064
+ };
5065
+ const closeAll = () => {
5066
+ clearTimeout(menuCloseTimer.current);
5067
+ clearTimeout(langCloseTimer.current);
5068
+ setOpenMenu(null);
5069
+ setLangOpen(false);
5070
+ };
5071
+ React18__namespace.useEffect(() => () => {
5072
+ clearTimeout(menuCloseTimer.current);
5073
+ clearTimeout(langCloseTimer.current);
5074
+ }, []);
5075
+ const handleLangSelect = (code) => {
5076
+ setActiveLang(code);
5077
+ onLanguageChange == null ? void 0 : onLanguageChange(code);
5078
+ setLangOpen(false);
5079
+ };
5080
+ const positionClass = position === "overlay" ? "absolute" : position === "fixed" ? "fixed" : "relative";
5081
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5082
+ "header",
5083
+ {
5084
+ className: cn(
5085
+ positionClass,
5086
+ "top-0 left-0 right-0 z-40",
5087
+ t.header,
5088
+ className
5089
+ ),
5090
+ children: [
5091
+ variant === "transparent" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-x-0 top-0 h-52 bg-gradient-to-b from-black/55 via-black/20 to-transparent pointer-events-none" }),
5092
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center gap-2 px-6 sm:px-10 h-[72px]", children: [
5093
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#", className: "shrink-0 flex items-center mr-4", children: /* @__PURE__ */ jsxRuntime.jsx(
5094
+ "img",
5095
+ {
5096
+ src: logoSrc,
5097
+ alt: logoAlt,
5098
+ className: cn("h-11 w-auto select-none", t.logoBlend),
5099
+ draggable: false
5100
+ }
5101
+ ) }),
5102
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "hidden lg:flex items-center gap-0.5 mx-auto", children: links.map((link) => {
5103
+ var _a, _b;
5104
+ const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
5105
+ const isOpen = openMenu === link.label;
5106
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5107
+ "div",
5108
+ {
5109
+ className: "relative",
5110
+ onMouseEnter: () => hasDropdown && handleMenuEnter(link.label),
5111
+ onMouseLeave: handleMenuLeave,
5112
+ children: [
5113
+ /* @__PURE__ */ jsxRuntime.jsxs(
5114
+ "a",
5115
+ {
5116
+ href: (_b = link.href) != null ? _b : "#",
5117
+ onClick: hasDropdown ? (e) => e.preventDefault() : void 0,
5118
+ className: cn(
5119
+ "flex items-center gap-1 px-3.5 py-1.5 rounded-full",
5120
+ "text-base font-ui font-black transition-colors whitespace-nowrap",
5121
+ t.navItem,
5122
+ isOpen && t.navItemOpen
5123
+ ),
5124
+ children: [
5125
+ link.label,
5126
+ hasDropdown && /* @__PURE__ */ jsxRuntime.jsx(
5127
+ lucideReact.ChevronDownIcon,
5128
+ {
5129
+ className: cn(
5130
+ "h-3.5 w-3.5 transition-transform duration-150 shrink-0",
5131
+ t.chevron,
5132
+ isOpen && "rotate-180"
5133
+ )
5134
+ }
5135
+ )
5136
+ ]
5137
+ }
5138
+ ),
5139
+ isOpen && link.items && /* @__PURE__ */ jsxRuntime.jsx(
5140
+ NavDropdown,
5141
+ {
5142
+ items: link.items,
5143
+ onClose: closeAll,
5144
+ onMouseEnter: () => handleMenuEnter(link.label),
5145
+ onMouseLeave: handleMenuLeave
5146
+ }
5147
+ )
5148
+ ]
5149
+ },
5150
+ link.label
5151
+ );
5152
+ }) }),
5153
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-auto lg:ml-0 shrink-0", children: [
5154
+ languages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
5155
+ "div",
5156
+ {
5157
+ className: "relative hidden lg:block",
5158
+ onMouseEnter: handleLangEnter,
5159
+ onMouseLeave: handleLangLeave,
5160
+ children: [
5161
+ /* @__PURE__ */ jsxRuntime.jsxs(
5162
+ "button",
5163
+ {
5164
+ type: "button",
5165
+ "aria-label": "Language",
5166
+ className: cn(
5167
+ "flex items-center gap-0.5 px-2.5 py-1.5 rounded-full",
5168
+ "text-sm font-ui transition-colors",
5169
+ t.lang,
5170
+ langOpen && t.langOpen
5171
+ ),
5172
+ children: [
5173
+ activeLang,
5174
+ /* @__PURE__ */ jsxRuntime.jsx(
5175
+ lucideReact.ChevronDownIcon,
5176
+ {
5177
+ className: cn(
5178
+ "h-3 w-3 transition-transform duration-150",
5179
+ t.langChevron,
5180
+ langOpen && "rotate-180"
5181
+ )
5182
+ }
5183
+ )
5184
+ ]
5185
+ }
5186
+ ),
5187
+ langOpen && /* @__PURE__ */ jsxRuntime.jsx(
5188
+ LangDropdown,
5189
+ {
5190
+ languages,
5191
+ activeLang,
5192
+ onSelect: handleLangSelect,
5193
+ onMouseEnter: handleLangEnter,
5194
+ onMouseLeave: handleLangLeave
5195
+ }
5196
+ )
5197
+ ]
5198
+ }
5199
+ ),
5200
+ /* @__PURE__ */ jsxRuntime.jsx(
5201
+ "button",
5202
+ {
5203
+ type: "button",
5204
+ onClick: onSearch,
5205
+ "aria-label": "Search",
5206
+ className: cn(
5207
+ "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
5208
+ t.icon
5209
+ ),
5210
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "h-[18px] w-[18px]" })
5211
+ }
5212
+ ),
5213
+ /* @__PURE__ */ jsxRuntime.jsx(
5214
+ "button",
5215
+ {
5216
+ type: "button",
5217
+ onClick: onAccount,
5218
+ "aria-label": "Account",
5219
+ className: cn(
5220
+ "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
5221
+ t.icon
5222
+ ),
5223
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "h-[18px] w-[18px]" })
5224
+ }
5225
+ ),
5226
+ /* @__PURE__ */ jsxRuntime.jsx(
5227
+ "button",
5228
+ {
5229
+ type: "button",
5230
+ onClick: () => setMobileOpen(true),
5231
+ "aria-label": "Open menu",
5232
+ className: cn(
5233
+ "flex lg:hidden h-9 w-9 items-center justify-center rounded-full transition-colors ml-0.5",
5234
+ t.mobileTrigger
5235
+ ),
5236
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MenuIcon, { className: "h-[18px] w-[18px]" })
5237
+ }
5238
+ )
5239
+ ] })
5240
+ ] }),
5241
+ mobileOpen && /* @__PURE__ */ jsxRuntime.jsxs(
5242
+ "div",
5243
+ {
5244
+ className: cn(
5245
+ "fixed inset-0 z-50 lg:hidden flex flex-col",
5246
+ variant === "white" ? "bg-white" : "bg-primary-900"
5247
+ ),
5248
+ children: [
5249
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 h-[72px] shrink-0 border-b border-white/8", children: [
5250
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#", className: "shrink-0 flex items-center", onClick: () => setMobileOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(
5251
+ "img",
5252
+ {
5253
+ src: logoSrc,
5254
+ alt: logoAlt,
5255
+ className: cn("h-11 w-auto select-none", t.logoBlend),
5256
+ draggable: false
5257
+ }
5258
+ ) }),
5259
+ /* @__PURE__ */ jsxRuntime.jsx(
5260
+ "button",
5261
+ {
5262
+ type: "button",
5263
+ onClick: () => setMobileOpen(false),
5264
+ "aria-label": "Close menu",
5265
+ className: cn(
5266
+ "flex h-9 w-9 items-center justify-center rounded-full transition-colors",
5267
+ t.mobileTrigger
5268
+ ),
5269
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "h-5 w-5" })
5270
+ }
5271
+ )
5272
+ ] }),
5273
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex-1 overflow-y-auto px-6 py-6 flex flex-col gap-1", children: links.map((link) => {
5274
+ var _a, _b;
5275
+ const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
5276
+ const isExpanded = openMobileSection === link.label;
5277
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5278
+ hasDropdown ? /* @__PURE__ */ jsxRuntime.jsxs(
5279
+ "button",
5280
+ {
5281
+ type: "button",
5282
+ onClick: () => toggleMobileSection(link.label),
5283
+ className: cn(
5284
+ "flex items-center justify-between w-full py-4 text-xl font-ui font-black transition-colors border-b border-white/8",
5285
+ t.mobileLink
5286
+ ),
5287
+ children: [
5288
+ link.label,
5289
+ /* @__PURE__ */ jsxRuntime.jsx(
5290
+ lucideReact.ChevronDownIcon,
5291
+ {
5292
+ className: cn(
5293
+ "h-5 w-5 transition-transform duration-200 opacity-40",
5294
+ isExpanded && "rotate-180"
5295
+ )
5296
+ }
5297
+ )
5298
+ ]
5299
+ }
5300
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
5301
+ "a",
5302
+ {
5303
+ href: (_b = link.href) != null ? _b : "#",
5304
+ onClick: () => setMobileOpen(false),
5305
+ className: cn(
5306
+ "flex items-center py-4 text-xl font-ui font-black transition-colors border-b border-white/8",
5307
+ t.mobileLink
5308
+ ),
5309
+ children: link.label
5310
+ }
5311
+ ),
5312
+ hasDropdown && isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0 pl-4 pb-2", children: link.items.map((item) => {
5313
+ var _a2;
5314
+ return /* @__PURE__ */ jsxRuntime.jsx(
5315
+ "a",
5316
+ {
5317
+ href: (_a2 = item.href) != null ? _a2 : "#",
5318
+ onClick: () => setMobileOpen(false),
5319
+ className: cn(
5320
+ "py-3 text-base font-ui font-bold transition-colors border-b",
5321
+ t.mobileSub
5322
+ ),
5323
+ children: item.label
5324
+ },
5325
+ item.label
5326
+ );
5327
+ }) })
5328
+ ] }, link.label);
5329
+ }) }),
5330
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
5331
+ "shrink-0 px-6 py-5 flex items-center justify-between border-t",
5332
+ variant === "white" ? "border-border" : "border-white/10"
5333
+ ), children: [
5334
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
5335
+ const isActive = lang.code === activeLang;
5336
+ return /* @__PURE__ */ jsxRuntime.jsxs(React18__namespace.Fragment, { children: [
5337
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
5338
+ "text-xs select-none",
5339
+ variant === "white" ? "text-border" : "text-white/15"
5340
+ ), children: "\xB7" }),
5341
+ /* @__PURE__ */ jsxRuntime.jsx(
5342
+ "button",
5343
+ {
5344
+ type: "button",
5345
+ onClick: () => handleLangSelect(lang.code),
5346
+ className: cn(
5347
+ "font-ui font-black transition-all duration-150 rounded-full",
5348
+ isActive ? cn(
5349
+ "text-sm px-3 py-1 border",
5350
+ variant === "white" ? "text-primary border-primary bg-primary/8" : "text-primary-400 border-primary-400/50 bg-primary-400/10"
5351
+ ) : cn(
5352
+ "text-xs px-2 py-1",
5353
+ variant === "white" ? "text-muted-foreground hover:text-foreground" : "text-white/35 hover:text-white/70"
5354
+ )
5355
+ ),
5356
+ children: lang.code
5357
+ }
5358
+ )
5359
+ ] }, lang.code);
5360
+ }) }),
5361
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
5362
+ /* @__PURE__ */ jsxRuntime.jsx(
5363
+ "button",
5364
+ {
5365
+ type: "button",
5366
+ onClick: () => {
5367
+ onSearch == null ? void 0 : onSearch();
5368
+ setMobileOpen(false);
5369
+ },
5370
+ "aria-label": "Search",
5371
+ className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
5372
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "h-[18px] w-[18px]" })
5373
+ }
5374
+ ),
5375
+ /* @__PURE__ */ jsxRuntime.jsx(
5376
+ "button",
5377
+ {
5378
+ type: "button",
5379
+ onClick: () => {
5380
+ onAccount == null ? void 0 : onAccount();
5381
+ setMobileOpen(false);
5382
+ },
5383
+ "aria-label": "Account",
5384
+ className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
5385
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserIcon, { className: "h-[18px] w-[18px]" })
5386
+ }
5387
+ )
5388
+ ] })
5389
+ ] })
5390
+ ]
5391
+ }
5392
+ )
5393
+ ]
5394
+ }
5395
+ );
5396
+ }
5397
+ function ThemeToggle({ className }) {
5398
+ const [dark, setDark] = React18__namespace.useState(false);
5399
+ React18__namespace.useEffect(() => {
5400
+ const saved = localStorage.getItem("theme");
5401
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
5402
+ const isDark = saved === "dark" || !saved && prefersDark;
5403
+ setDark(isDark);
5404
+ document.documentElement.classList.toggle("dark", isDark);
5405
+ }, []);
5406
+ const toggle = () => {
5407
+ const next = !dark;
5408
+ setDark(next);
5409
+ document.documentElement.classList.toggle("dark", next);
5410
+ localStorage.setItem("theme", next ? "dark" : "light");
5411
+ };
5412
+ return /* @__PURE__ */ jsxRuntime.jsx(
5413
+ "button",
5414
+ {
5415
+ type: "button",
5416
+ onClick: toggle,
5417
+ "aria-label": dark ? "Switch to light mode" : "Switch to dark mode",
5418
+ className: cn(
5419
+ "flex h-8 w-8 items-center justify-center rounded-md",
5420
+ "bg-card border border-border text-muted-foreground shadow-sm",
5421
+ "hover:text-foreground hover:bg-muted transition-colors",
5422
+ className
5423
+ ),
5424
+ children: dark ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SunIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoonIcon, { className: "h-4 w-4" })
5425
+ }
5426
+ );
5427
+ }
5428
+ function CalendarIcon5() {
5429
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5430
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
5431
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }),
5432
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }),
5433
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
5434
+ ] });
5435
+ }
5436
+ function TrendingIcon() {
5437
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5438
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "23 6 13.5 15.5 8.5 10.5 1 18" }),
5439
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "17 6 23 6 23 12" })
5440
+ ] });
5441
+ }
5442
+ function ArrowIcon() {
5443
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5444
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
5445
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 5 19 12 12 19" })
5446
+ ] });
5447
+ }
5448
+ var sizeConfig = {
5449
+ sm: {
5450
+ card: "h-72 w-56",
5451
+ title: "text-lg font-bold",
5452
+ meta: "text-xs",
5453
+ description: "text-xs"
5454
+ },
5455
+ md: {
5456
+ card: "h-96 w-72",
5457
+ title: "text-xl font-bold",
5458
+ meta: "text-xs",
5459
+ description: "text-sm"
5460
+ },
5461
+ lg: {
5462
+ card: "h-[28rem] w-96",
5463
+ title: "text-2xl font-bold",
5464
+ meta: "text-sm",
5465
+ description: "text-sm"
5466
+ }
5467
+ };
5468
+ var statusConfig = {
5469
+ "sold-out": {
5470
+ label: "All seats taken",
5471
+ icon: /* @__PURE__ */ jsxRuntime.jsx(CalendarIcon5, {})
5472
+ },
5473
+ trending: {
5474
+ label: "Trending",
5475
+ icon: /* @__PURE__ */ jsxRuntime.jsx(TrendingIcon, {})
5476
+ }
5477
+ };
5478
+ function TripCard({
5479
+ image,
5480
+ imageAlt = "",
5481
+ status,
5482
+ nights,
5483
+ period,
5484
+ title,
5485
+ description,
5486
+ cta,
5487
+ price,
5488
+ size = "md",
5489
+ className
5490
+ }) {
5491
+ const s = sizeConfig[size];
5492
+ const statusInfo = status ? statusConfig[status] : null;
5493
+ const meta = [
5494
+ nights ? `${nights} nights` : null,
5495
+ period != null ? period : null
5496
+ ].filter(Boolean).join(" | ");
5497
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5498
+ "div",
5499
+ {
5500
+ className: cn(
5501
+ "group relative flex flex-col justify-between overflow-hidden rounded-2xl",
5502
+ "shadow-md transition-shadow duration-300 hover:shadow-xl",
5503
+ s.card,
5504
+ className
5505
+ ),
5506
+ children: [
5507
+ /* @__PURE__ */ jsxRuntime.jsx(
5508
+ "img",
5509
+ {
5510
+ src: image,
5511
+ alt: imageAlt,
5512
+ className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
5513
+ }
5514
+ ),
5515
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent" }),
5516
+ statusInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-xl bg-card/90 px-3 py-1.5 backdrop-blur-sm shadow-sm", children: [
5517
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: statusInfo.icon }),
5518
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-foreground font-ui", children: statusInfo.label })
5519
+ ] }) }),
5520
+ !statusInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10" }),
5521
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
5522
+ meta && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-white/70 font-medium font-ui", s.meta), children: meta }),
5523
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-white leading-snug", s.title), children: title }),
5524
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-white/80 leading-relaxed mt-0.5", s.description), children: description }),
5525
+ (cta || price) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex items-center justify-between gap-4", children: [
5526
+ cta && /* @__PURE__ */ jsxRuntime.jsxs(
5527
+ "button",
5528
+ {
5529
+ onClick: cta.onClick,
5530
+ className: cn(
5531
+ "group/cta inline-flex items-center gap-1.5 border-b border-white/70 pb-0.5",
5532
+ "text-sm font-semibold text-white transition-colors hover:border-white hover:text-white",
5533
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50",
5534
+ "font-ui"
5535
+ ),
5536
+ children: [
5537
+ cta.label,
5538
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "transition-transform duration-150 group-hover/cta:translate-x-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(ArrowIcon, {}) })
5539
+ ]
5540
+ }
5541
+ ),
5542
+ price && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-white/90 whitespace-nowrap font-ui", children: price })
5543
+ ] })
5544
+ ] })
5545
+ ]
5546
+ }
5547
+ );
5548
+ }
5549
+ function useHlsVideo(videoRef, src) {
5550
+ React18__namespace.useEffect(() => {
5551
+ if (!src || !videoRef.current) return;
5552
+ const video = videoRef.current;
5553
+ if (!src.includes(".m3u8")) return;
5554
+ let hlsInstance = null;
5555
+ import('hls.js').then(({ default: Hls }) => {
5556
+ if (!Hls.isSupported()) {
5557
+ video.src = src;
5558
+ return;
5559
+ }
5560
+ hlsInstance = new Hls({
5561
+ /* Start with low-quality level to show first frame ASAP */
5562
+ startLevel: 0,
5563
+ /* Limit initial buffer to 10s — faster start */
5564
+ maxBufferLength: 10,
5565
+ maxMaxBufferLength: 30
5566
+ });
5567
+ hlsInstance.loadSource(src);
5568
+ hlsInstance.attachMedia(video);
5569
+ hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {
5570
+ video.play().catch(() => {
5571
+ });
5572
+ });
5573
+ });
5574
+ return () => {
5575
+ hlsInstance == null ? void 0 : hlsInstance.destroy();
5576
+ };
5577
+ }, [src, videoRef]);
5578
+ }
5579
+ function TripHeader({
5580
+ images,
5581
+ videoUrl,
5582
+ title,
5583
+ breadcrumb,
5584
+ destination,
5585
+ duration,
5586
+ tagline,
5587
+ siteHeader,
5588
+ uiVariant = "v1",
5589
+ className
5590
+ }) {
5591
+ var _a;
5592
+ const [heroIndex, setHeroIndex] = React18__namespace.useState(0);
5593
+ const [videoReady, setVideoReady] = React18__namespace.useState(false);
5594
+ const videoRef = React18__namespace.useRef(null);
5595
+ const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
5596
+ const validImages = React18__namespace.useMemo(
5597
+ () => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
5598
+ [images]
5599
+ );
5600
+ const hasHeroImage = validImages.length > 0;
5601
+ const heroSrc = (i) => {
5602
+ var _a2;
5603
+ return (_a2 = validImages[i]) != null ? _a2 : "";
5604
+ };
5605
+ const safeIndex = Math.min(heroIndex, Math.max(0, validImages.length - 1));
5606
+ const currentSrc = heroSrc(safeIndex);
5607
+ const showCarousel = !videoUrl && validImages.length > 1;
5608
+ const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
5609
+ const hasMeta = !!(destination || duration);
5610
+ useHlsVideo(videoRef, isHls ? videoUrl : void 0);
5611
+ React18__namespace.useEffect(() => {
5612
+ if (!videoUrl) return;
5613
+ const el = videoRef.current;
5614
+ if (!el) return;
5615
+ const observer = new IntersectionObserver(
5616
+ ([entry]) => {
5617
+ if (entry.isIntersecting) {
5618
+ el.play().catch(() => {
5619
+ });
5620
+ } else {
5621
+ el.pause();
5622
+ }
5623
+ },
5624
+ { threshold: 0.1 }
5625
+ );
5626
+ observer.observe(el);
5627
+ return () => observer.disconnect();
5628
+ }, [videoUrl]);
5629
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5630
+ "div",
5631
+ {
5632
+ className: cn("w-full", className),
5633
+ "data-trip-header-variant": uiVariant,
5634
+ children: [
5635
+ /* @__PURE__ */ jsxRuntime.jsxs(
5636
+ "div",
5637
+ {
5638
+ className: cn(
5639
+ "relative w-full overflow-hidden",
5640
+ hasHeroImage ? "bg-muted" : "bg-zinc-900",
5641
+ siteHeader ? "h-[80vh] min-h-[520px]" : "h-[70vh] min-h-[420px]"
5642
+ ),
5643
+ children: [
5644
+ !videoUrl && !hasHeroImage && /* @__PURE__ */ jsxRuntime.jsx(
5645
+ "div",
5646
+ {
5647
+ className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950",
5648
+ "aria-hidden": true
5649
+ }
5650
+ ),
5651
+ videoUrl ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5652
+ hasHeroImage ? /* @__PURE__ */ jsxRuntime.jsx(
5653
+ "img",
5654
+ {
5655
+ src: validImages[0],
5656
+ alt: "",
5657
+ "aria-hidden": true,
5658
+ fetchPriority: "high",
5659
+ className: cn(
5660
+ "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
5661
+ videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
5662
+ )
5663
+ }
5664
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
5665
+ "div",
5666
+ {
5667
+ className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950 transition-opacity duration-700",
5668
+ "aria-hidden": true
5669
+ }
5670
+ ),
5671
+ /* @__PURE__ */ jsxRuntime.jsx(
5672
+ "video",
5673
+ {
5674
+ ref: videoRef,
5675
+ src: isHls ? void 0 : videoUrl,
5676
+ autoPlay: true,
5677
+ muted: true,
5678
+ loop: true,
5679
+ playsInline: true,
5680
+ preload: "auto",
5681
+ poster: hasHeroImage ? validImages[0] : void 0,
5682
+ onCanPlay: () => setVideoReady(true),
5683
+ className: cn(
5684
+ "absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
5685
+ videoReady ? "opacity-100" : "opacity-0"
5686
+ )
5687
+ }
5688
+ )
5689
+ ] }) : hasHeroImage ? /* @__PURE__ */ jsxRuntime.jsx(
5690
+ "img",
5691
+ {
5692
+ src: currentSrc,
5693
+ alt: title,
5694
+ fetchPriority: safeIndex === 0 ? "high" : "auto",
5695
+ className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
5696
+ }
5697
+ ) : null,
5698
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/85 via-black/20 to-transparent" }),
5699
+ siteHeader && /* @__PURE__ */ jsxRuntime.jsx(
5700
+ SiteHeader,
5701
+ {
5702
+ links: Array.isArray(siteHeader) ? siteHeader : void 0,
5703
+ position: "overlay"
5704
+ }
5705
+ ),
5706
+ !videoUrl && showCarousel && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5707
+ /* @__PURE__ */ jsxRuntime.jsx(
5708
+ "button",
5709
+ {
5710
+ type: "button",
5711
+ onClick: () => setHeroIndex(
5712
+ (i) => (i - 1 + validImages.length) % validImages.length
5713
+ ),
5714
+ className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
5715
+ "aria-label": "Imagem anterior",
5716
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "h-5 w-5" })
5717
+ }
5718
+ ),
5719
+ /* @__PURE__ */ jsxRuntime.jsx(
5720
+ "button",
5721
+ {
5722
+ type: "button",
5723
+ onClick: () => setHeroIndex((i) => (i + 1) % validImages.length),
5724
+ className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
5725
+ "aria-label": "Pr\xF3xima imagem",
5726
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-5 w-5" })
5727
+ }
5728
+ ),
5729
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-5 right-5 flex gap-1.5", children: validImages.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
5730
+ "button",
5731
+ {
5732
+ type: "button",
5733
+ onClick: () => setHeroIndex(i),
5734
+ className: cn(
5735
+ "h-1.5 rounded-full transition-all",
5736
+ i === safeIndex ? "w-5 bg-white" : "w-1.5 bg-white/50"
5737
+ )
5738
+ },
5739
+ i
5740
+ )) })
5741
+ ] })
5742
+ ]
5743
+ }
5744
+ ),
5745
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6", children: /* @__PURE__ */ jsxRuntime.jsxs(
5746
+ "div",
5747
+ {
5748
+ className: cn(
5749
+ "relative z-10 pb-10",
5750
+ siteHeader ? "-mt-44" : "-mt-36"
5751
+ ),
5752
+ children: [
5753
+ 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(React18__namespace.Fragment, { children: [
5754
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
5755
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
5756
+ ] }, i)) }),
5757
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight", children: title }),
5758
+ hasMeta ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex items-center gap-5 flex-wrap", children: [
5759
+ destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-white/85", children: [
5760
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
5761
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-ui font-semibold", children: destination })
5762
+ ] }),
5763
+ duration && nights !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-white/85", children: [
5764
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoonIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
5765
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-ui font-semibold", children: [
5766
+ nights,
5767
+ " ",
5768
+ nights === 1 ? "noite" : "noites"
5769
+ ] }),
5770
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white/40", children: "\xB7" }),
5771
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SunIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
5772
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-ui font-semibold", children: [
5773
+ duration.days,
5774
+ " ",
5775
+ duration.days === 1 ? "dia" : "dias"
5776
+ ] })
5777
+ ] })
5778
+ ] }) : tagline ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm sm:text-base text-white/80 font-ui", children: tagline }) : null
5779
+ ]
5780
+ }
5781
+ ) })
5782
+ ]
5783
+ }
5784
+ );
5785
+ }
5786
+ function Stars({ count = 5 }) {
5787
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex gap-0.5", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
5788
+ lucideReact.StarIcon,
5789
+ {
5790
+ className: cn(
5791
+ "h-3.5 w-3.5",
5792
+ i < count ? "fill-primary text-primary" : "fill-muted text-muted"
5793
+ )
5794
+ },
5795
+ i
5796
+ )) });
5797
+ }
5798
+ function ItineraryTimeline({ steps }) {
5799
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "relative flex flex-col gap-0", children: steps.map((step, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "relative flex gap-4 pb-8 last:pb-0", children: [
5800
+ i < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3.5 top-7 bottom-0 w-px bg-border" }),
5801
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border-2 border-primary bg-background", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold text-primary font-ui", children: i + 1 }) }),
5802
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 pt-0.5 flex-1", children: [
5803
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
5804
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-bold text-foreground font-heading", children: step.label }),
5805
+ step.duration && /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "outline", className: "text-xs font-ui h-5 px-2", children: [
5806
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClockIcon, { className: "h-3 w-3 mr-1" }),
5807
+ step.duration
5808
+ ] }),
5809
+ step.isTransfer && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-ui h-5 px-2", children: "Transfer" })
5810
+ ] }),
5811
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground leading-relaxed [&_p:not(:last-child)]:mb-2 [&_strong]:text-foreground [&_strong]:font-semibold", children: step.description })
5812
+ ] })
5813
+ ] }, i)) });
5814
+ }
5815
+ function Checklist({ items, icon }) {
5816
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "flex flex-col gap-2", children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
5817
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 shrink-0 text-primary", children: icon != null ? icon : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "h-4 w-4" }) }),
5818
+ item
5819
+ ] }, i)) });
5820
+ }
5821
+ function TripPage({
5822
+ title,
5823
+ tagline,
5824
+ destination,
5825
+ duration,
5826
+ images,
5827
+ videoUrl,
5828
+ breadcrumb,
5829
+ highlights,
5830
+ infoGroups,
5831
+ recommendedFor,
5832
+ overview,
5833
+ itinerary,
5834
+ gallery,
5835
+ included,
5836
+ whatToBring,
5837
+ weather,
5838
+ meetingPoints,
5839
+ faqs,
5840
+ reviews,
5841
+ priceFrom,
5842
+ currency = "CHF",
5843
+ season,
5844
+ departureTimes,
5845
+ pricingOptions,
5846
+ onBook,
5847
+ bookLabel,
5848
+ siteHeader,
5849
+ uiVariant = "v1",
5850
+ features,
5851
+ className
5852
+ }) {
5853
+ const [activeSection, setActiveSection] = React18__namespace.useState("");
5854
+ const [navFloating, setNavFloating] = React18__namespace.useState(false);
5855
+ const [navHidden, setNavHidden] = React18__namespace.useState(false);
5856
+ const [isFloating, setIsFloating] = React18__namespace.useState(false);
5857
+ const [sidebarPos, setSidebarPos] = React18__namespace.useState(null);
5858
+ const [pricingBarVisible, setPricingBarVisible] = React18__namespace.useState(false);
5859
+ const navRef = React18__namespace.useRef(null);
5860
+ const navSentinelRef = React18__namespace.useRef(null);
5861
+ const sentinelRef = React18__namespace.useRef(null);
5862
+ const sidebarPlaceholderRef = React18__namespace.useRef(null);
5863
+ const pricingBarRef = React18__namespace.useRef(null);
5864
+ const galleryRef = React18__namespace.useRef(null);
5865
+ const sections = React18__namespace.useMemo(
5866
+ () => [
5867
+ { id: "key-info", label: "Key info", show: !!(infoGroups == null ? void 0 : infoGroups.length) },
5868
+ { id: "overview", label: "Overview", show: !!overview },
5869
+ { id: "itinerary", label: "Itinerary", show: !!(itinerary == null ? void 0 : itinerary.length) },
5870
+ { id: "included", label: "Included", show: !!((included == null ? void 0 : included.length) || (whatToBring == null ? void 0 : whatToBring.length)) },
5871
+ { id: "what-to-bring", label: "What to bring", show: !!(whatToBring == null ? void 0 : whatToBring.length) },
5872
+ { id: "weather", label: "Weather", show: !!weather },
5873
+ { id: "meeting", label: "Meeting point", show: !!(meetingPoints == null ? void 0 : meetingPoints.length) },
5874
+ { id: "faq", label: "FAQ", show: !!(faqs == null ? void 0 : faqs.length) },
5875
+ { id: "gallery", label: "Photos", show: !!(gallery == null ? void 0 : gallery.length) }
5876
+ ].filter((s) => s.show),
5877
+ // eslint-disable-next-line react-hooks/exhaustive-deps
5878
+ []
5879
+ );
5880
+ React18__namespace.useEffect(() => {
5881
+ const sentinel = navSentinelRef.current;
5882
+ if (!sentinel) return;
5883
+ const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
5884
+ document.addEventListener("scroll", update, { passive: true, capture: true });
5885
+ update();
5886
+ return () => document.removeEventListener("scroll", update, { capture: true });
5887
+ }, []);
5888
+ React18__namespace.useEffect(() => {
5889
+ const sentinel = sentinelRef.current;
5890
+ if (!sentinel) return;
5891
+ const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
5892
+ document.addEventListener("scroll", update, { passive: true, capture: true });
5893
+ update();
5894
+ return () => document.removeEventListener("scroll", update, { capture: true });
5895
+ }, []);
5896
+ React18__namespace.useEffect(() => {
5897
+ const measure = () => {
5898
+ if (!sidebarPlaceholderRef.current) return;
5899
+ const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
5900
+ setSidebarPos({ left: rect.left, width: rect.width });
5901
+ };
5902
+ measure();
5903
+ window.addEventListener("resize", measure);
5904
+ return () => window.removeEventListener("resize", measure);
5905
+ }, [isFloating]);
5906
+ React18__namespace.useEffect(() => {
5907
+ const check = () => {
5908
+ var _a;
5909
+ const target = (_a = galleryRef.current) != null ? _a : pricingBarRef.current;
5910
+ if (!target) return;
5911
+ setPricingBarVisible(target.getBoundingClientRect().top < window.innerHeight * 0.75);
5912
+ };
5913
+ document.addEventListener("scroll", check, { passive: true, capture: true });
5914
+ check();
5915
+ return () => document.removeEventListener("scroll", check, { capture: true });
5916
+ }, []);
5917
+ React18__namespace.useEffect(() => {
5918
+ const check = () => {
5919
+ if (!pricingBarRef.current) return;
5920
+ setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
5921
+ };
5922
+ document.addEventListener("scroll", check, { passive: true, capture: true });
5923
+ check();
5924
+ return () => document.removeEventListener("scroll", check, { capture: true });
5925
+ }, []);
5926
+ React18__namespace.useEffect(() => {
5927
+ if (sections.length === 0) return;
5928
+ setActiveSection(sections[0].id);
5929
+ const update = () => {
5930
+ var _a, _b;
5931
+ const navH = ((_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56) + 20;
5932
+ for (const { id } of [...sections].reverse()) {
5933
+ const el = document.getElementById(`trip-section-${id}`);
5934
+ if (el && el.getBoundingClientRect().top <= navH) {
5935
+ setActiveSection(id);
5936
+ return;
5937
+ }
5938
+ }
5939
+ setActiveSection(sections[0].id);
5940
+ };
5941
+ document.addEventListener("scroll", update, { passive: true, capture: true });
5942
+ return () => document.removeEventListener("scroll", update, { capture: true });
5943
+ }, [sections]);
5944
+ const scrollToBookingForm = () => {
5945
+ var _a, _b, _c;
5946
+ const el = document.getElementById("trip-booking-form");
5947
+ if (!el) return;
5948
+ const navHeight = ((_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56) + 16;
5949
+ const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
5950
+ const elTop = el.getBoundingClientRect().top;
5951
+ const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
5952
+ const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
5953
+ const target = currentScroll + (elTop - containerTop) - navHeight;
5954
+ if (scrollEl) {
5955
+ scrollEl.scrollTo({ top: target, behavior: "smooth" });
5956
+ } else {
5957
+ window.scrollTo({ top: target, behavior: "smooth" });
5958
+ }
5959
+ };
5960
+ const scrollToSection = (id) => {
5961
+ var _a, _b, _c;
5962
+ const el = document.getElementById(`trip-section-${id}`);
5963
+ if (!el) return;
5964
+ const navHeight = (_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56;
5965
+ const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
5966
+ const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
5967
+ const elTop = el.getBoundingClientRect().top;
5968
+ const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
5969
+ const target = currentScroll + (elTop - containerTop) - navHeight - 12;
5970
+ if (scrollEl) {
5971
+ scrollEl.scrollTo({ top: target, behavior: "smooth" });
5972
+ } else {
5973
+ window.scrollTo({ top: target, behavior: "smooth" });
5974
+ }
5975
+ };
5976
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5977
+ "div",
5978
+ {
5979
+ className: cn("w-full overflow-x-hidden", className),
5980
+ "data-ui-variant": uiVariant,
5981
+ "data-features": features ? JSON.stringify(features) : void 0,
5982
+ children: [
5983
+ /* @__PURE__ */ jsxRuntime.jsx(
5984
+ TripHeader,
5985
+ {
5986
+ images,
5987
+ videoUrl,
5988
+ title,
5989
+ breadcrumb,
5990
+ destination,
5991
+ duration,
5992
+ tagline,
5993
+ siteHeader,
5994
+ uiVariant
5995
+ }
5996
+ ),
5997
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6", children: [
5998
+ highlights && highlights.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-6 flex flex-wrap justify-center gap-6 py-2", children: highlights.map((h, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
5999
+ h.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full border-2 border-border text-foreground", children: h.icon }),
6000
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-foreground font-ui", children: h.label })
6001
+ ] }, i)) }),
6002
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: navSentinelRef, className: "h-px", "aria-hidden": true }),
6003
+ sections.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
6004
+ "div",
6005
+ {
6006
+ className: cn(
6007
+ "py-2 flex justify-center transition-opacity duration-150",
6008
+ navFloating ? "opacity-0 pointer-events-none" : "opacity-100"
6009
+ ),
6010
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6011
+ MenuTrip,
6012
+ {
6013
+ sections,
6014
+ activeSection,
6015
+ onSelect: scrollToSection,
6016
+ variant: "floating"
6017
+ }
6018
+ )
6019
+ }
6020
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-6" }),
6021
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: sentinelRef, className: "h-px -mt-px", "aria-hidden": true }),
6022
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col lg:flex-row gap-8 mt-4", children: [
6023
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0 space-y-12 pb-12", children: [
6024
+ infoGroups && infoGroups.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-key-info", className: "scroll-mt-20", children: [
6025
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Key info" }),
6026
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: infoGroups.map((group, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6027
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
6028
+ group.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: group.icon }),
6029
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-heading", children: group.title })
6030
+ ] }),
6031
+ /* @__PURE__ */ jsxRuntime.jsx(Checklist, { items: group.items }),
6032
+ i < infoGroups.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "mt-6" })
6033
+ ] }, i)) })
6034
+ ] }),
6035
+ overview && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
6036
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-4", children: "Overview" }),
6037
+ recommendedFor && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2.5 rounded-xl bg-primary/8 border border-primary/20 p-4 mb-4", children: [
6038
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "h-4 w-4 text-primary mt-0.5 shrink-0" }),
6039
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-foreground font-ui", children: [
6040
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold", children: "Recommended for: " }),
6041
+ recommendedFor
6042
+ ] })
6043
+ ] }),
6044
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview })
6045
+ ] }),
6046
+ itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
6047
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Itinerary" }),
6048
+ /* @__PURE__ */ jsxRuntime.jsx(ItineraryTimeline, { steps: itinerary })
6049
+ ] }),
6050
+ included && included.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
6051
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
6052
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, { className: "h-5 w-5 text-primary" }),
6053
+ "Included"
6054
+ ] }),
6055
+ /* @__PURE__ */ jsxRuntime.jsx(Checklist, { items: included })
6056
+ ] }),
6057
+ whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-what-to-bring", className: "scroll-mt-20", children: [
6058
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
6059
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PackageIcon, { className: "h-5 w-5 text-primary" }),
6060
+ "What to bring"
6061
+ ] }),
6062
+ /* @__PURE__ */ jsxRuntime.jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, { className: "h-4 w-4" }) })
6063
+ ] }),
6064
+ weather && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-weather", className: "scroll-mt-20", children: [
6065
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
6066
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SunIcon, { className: "h-5 w-5 text-primary" }),
6067
+ "Weather"
6068
+ ] }),
6069
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start gap-3 rounded-xl bg-muted/60 border border-border p-5", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-2 [&_strong]:font-semibold", children: weather }) })
6070
+ ] }),
6071
+ meetingPoints && meetingPoints.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-meeting", className: "scroll-mt-20", children: [
6072
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
6073
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-5 w-5 text-primary" }),
6074
+ "Meeting point"
6075
+ ] }),
6076
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
6077
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPinIcon, { className: "h-4 w-4 text-primary" }) }),
6078
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6079
+ mp.type && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? "Activity location" : mp.type === "alternative" ? "Alternative meeting point" : "Meeting point" }),
6080
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
6081
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
6082
+ ] })
6083
+ ] }, i)) })
6084
+ ] }),
6085
+ faqs && faqs.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
6086
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "FAQ" }),
6087
+ /* @__PURE__ */ jsxRuntime.jsx(Accordion, { variant: "faq", children: faqs.map((faq, i) => /* @__PURE__ */ jsxRuntime.jsxs(AccordionItem, { value: `faq-${i}`, children: [
6088
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionTrigger, { children: faq.question }),
6089
+ /* @__PURE__ */ jsxRuntime.jsx(AccordionContent, { children: faq.answer })
6090
+ ] }, i)) })
6091
+ ] }),
6092
+ reviews && reviews.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6093
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "mb-10" }),
6094
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: "What our guests think" }),
6095
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: reviews.map((r, i) => {
6096
+ var _a;
6097
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border p-5", children: [
6098
+ /* @__PURE__ */ jsxRuntime.jsx(Stars, { count: (_a = r.rating) != null ? _a : 5 }),
6099
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-foreground leading-relaxed line-clamp-4", children: [
6100
+ "\u201C",
6101
+ r.text,
6102
+ "\u201D"
6103
+ ] }),
6104
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-semibold text-muted-foreground font-ui mt-auto", children: [
6105
+ "\u2014 ",
6106
+ r.author
6107
+ ] })
6108
+ ] }, i);
6109
+ }) })
6110
+ ] })
6111
+ ] }),
6112
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: sidebarPlaceholderRef, className: "hidden lg:block lg:w-72 xl:w-80 shrink-0", children: !isFloating && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-20 rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
6113
+ PricingTrip,
6114
+ {
6115
+ priceFrom,
6116
+ currency,
6117
+ season,
6118
+ departureTimes,
6119
+ pricingOptions,
6120
+ onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
6121
+ bookLabel: bookLabel != null ? bookLabel : "Check availability",
6122
+ variant: "card"
6123
+ }
6124
+ ) }) })
6125
+ ] })
6126
+ ] }),
6127
+ sections.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
6128
+ "div",
6129
+ {
6130
+ ref: navRef,
6131
+ className: cn(
6132
+ "fixed top-0 left-0 right-0 z-20 py-3 transition-all duration-200",
6133
+ navFloating && !navHidden ? "translate-y-0 opacity-100" : "-translate-y-full opacity-0 pointer-events-none"
6134
+ ),
6135
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
6136
+ MenuTrip,
6137
+ {
6138
+ sections,
6139
+ activeSection,
6140
+ onSelect: scrollToSection,
6141
+ variant: "floating"
6142
+ }
6143
+ ) })
6144
+ }
6145
+ ),
6146
+ isFloating && !pricingBarVisible && sidebarPos && /* @__PURE__ */ jsxRuntime.jsx(
6147
+ "div",
6148
+ {
6149
+ className: "hidden lg:block fixed z-20",
6150
+ style: { top: "5rem", left: sidebarPos.left, width: sidebarPos.width },
6151
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
6152
+ PricingTrip,
6153
+ {
6154
+ priceFrom,
6155
+ currency,
6156
+ season,
6157
+ departureTimes,
6158
+ pricingOptions,
6159
+ onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
6160
+ bookLabel: bookLabel != null ? bookLabel : "Check availability",
6161
+ variant: "card"
6162
+ }
6163
+ ) })
6164
+ }
6165
+ ),
6166
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("section", { ref: galleryRef, id: "trip-section-gallery", className: "scroll-mt-20", children: /* @__PURE__ */ jsxRuntime.jsx(
6167
+ PhotoGallery,
6168
+ {
6169
+ photos: gallery,
6170
+ variant: "grid",
6171
+ initialVisible: 6
6172
+ }
6173
+ ) }),
6174
+ gallery && gallery.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-5xl px-4 sm:px-6 py-12", children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(BookingForm, { onSubmit: onBook ? (values) => onBook() : void 0 }) }) }),
6175
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed bottom-0 inset-x-0 z-30 lg:hidden border-t border-border bg-background/95 backdrop-blur-sm px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(
6176
+ PricingTrip,
6177
+ {
6178
+ priceFrom,
6179
+ currency,
6180
+ onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
6181
+ bookLabel: bookLabel != null ? bookLabel : "Book now",
6182
+ variant: "compact"
6183
+ }
6184
+ ) }),
6185
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-20 lg:hidden" })
6186
+ ]
6187
+ }
6188
+ );
6189
+ }
6190
+ var sizeConfig2 = {
6191
+ sm: {
6192
+ card: "w-56",
6193
+ image: "h-36",
6194
+ title: "text-sm font-bold",
6195
+ description: "text-xs",
6196
+ price: "text-xs py-2"
6197
+ },
6198
+ md: {
6199
+ card: "w-72",
6200
+ image: "h-52",
6201
+ title: "text-base font-bold",
6202
+ description: "text-sm",
6203
+ price: "text-sm py-2.5"
6204
+ },
6205
+ lg: {
6206
+ card: "w-96",
6207
+ image: "h-64",
6208
+ title: "text-lg font-bold",
6209
+ description: "text-sm",
6210
+ price: "text-sm py-3"
6211
+ }
6212
+ };
6213
+ function ActivityCard({
6214
+ image,
6215
+ imageAlt = "",
6216
+ badge,
6217
+ icon,
6218
+ title,
6219
+ description,
6220
+ price,
6221
+ onClick,
6222
+ size = "md",
6223
+ className
6224
+ }) {
6225
+ const s = sizeConfig2[size];
6226
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6227
+ "div",
6228
+ {
6229
+ role: onClick ? "button" : void 0,
6230
+ tabIndex: onClick ? 0 : void 0,
6231
+ onClick,
6232
+ onKeyDown: onClick ? (e) => (e.key === "Enter" || e.key === " ") && onClick() : void 0,
6233
+ className: cn(
6234
+ "group flex flex-col overflow-hidden rounded-[1.25rem] bg-card",
6235
+ "border border-border shadow-md transition-shadow duration-200",
6236
+ onClick && "cursor-pointer hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6237
+ s.card,
6238
+ className
6239
+ ),
6240
+ children: [
6241
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative w-full shrink-0 overflow-hidden", s.image), children: [
6242
+ /* @__PURE__ */ jsxRuntime.jsx(
6243
+ "img",
6244
+ {
6245
+ src: image,
6246
+ alt: imageAlt,
6247
+ className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
6248
+ }
6249
+ ),
6250
+ icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm", children: icon }),
6251
+ badge && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-3", children: /* @__PURE__ */ jsxRuntime.jsx(
6252
+ Badge,
6253
+ {
6254
+ variant: "secondary",
6255
+ className: "rounded-full bg-card/90 text-foreground backdrop-blur-sm shadow-sm border-0 font-medium font-ui",
6256
+ children: badge
6257
+ }
6258
+ ) })
6259
+ ] }),
6260
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
6261
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-foreground leading-snug font-ui", s.title), children: title }),
6262
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground leading-relaxed", s.description), children: description }),
6263
+ price && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
6264
+ "div",
6265
+ {
6266
+ className: cn(
6267
+ "w-full rounded-full bg-muted text-center font-semibold text-foreground font-ui",
6268
+ s.price
6269
+ ),
6270
+ children: price
6271
+ }
6272
+ ) })
6273
+ ] })
6274
+ ]
6275
+ }
6276
+ );
6277
+ }
6278
+ function Input(_a) {
6279
+ var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
6280
+ return /* @__PURE__ */ jsxRuntime.jsx(
6281
+ input.Input,
6282
+ __spreadValues({
6283
+ type,
6284
+ "data-slot": "input",
6285
+ className: cn(
6286
+ "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
6287
+ className
6288
+ )
6289
+ }, props)
6290
+ );
6291
+ }
6292
+ function Label(_a) {
6293
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
6294
+ return /* @__PURE__ */ jsxRuntime.jsx(
6295
+ "label",
6296
+ __spreadValues({
6297
+ "data-slot": "label",
6298
+ className: cn(
6299
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
6300
+ className
6301
+ )
6302
+ }, props)
6303
+ );
6304
+ }
6305
+ var DEFAULTS = {
6306
+ heading: "Where will your next adventure take you?",
6307
+ subtitle: "Tell us about your dream trip and our travel experts will craft the perfect itinerary for you.",
6308
+ nameLabel: "Your name",
6309
+ namePlaceholder: "e.g. Maria Silva",
6310
+ emailLabel: "Email",
6311
+ emailPlaceholder: "you@example.com",
6312
+ travelDateLabel: "When are you planning to travel?",
6313
+ travelDateOptions: [
6314
+ "In the next 30 days",
6315
+ "1 \u2013 3 months from now",
6316
+ "3 \u2013 6 months from now",
6317
+ "6 \u2013 12 months from now",
6318
+ "I'm just exploring"
6319
+ ],
6320
+ submitLabel: "Send my request",
6321
+ successHeading: "Thank you!",
6322
+ successMessage: "One of our travel experts will reach out soon to help plan your perfect trip.",
6323
+ privacyText: 'By submitting you agree to our <a href="/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>.',
6324
+ trigger: "delay",
6325
+ delaySeconds: 5,
6326
+ scrollPercent: 50,
6327
+ dismissDays: 7,
6328
+ overlayOpacity: 40,
6329
+ position: "center"
6330
+ };
6331
+ var COOKIE_NAME = "pexo_lead_popup_dismissed";
6332
+ function isDismissed() {
6333
+ return document.cookie.includes(`${COOKIE_NAME}=1`);
6334
+ }
6335
+ function setDismissed(days) {
6336
+ const expires = new Date(Date.now() + days * 864e5).toUTCString();
6337
+ document.cookie = `${COOKIE_NAME}=1; expires=${expires}; path=/; SameSite=Lax`;
6338
+ }
6339
+ function LeadCapturePopup({
6340
+ config: _config
6341
+ }) {
6342
+ var _a;
6343
+ const config = __spreadValues(__spreadValues({}, DEFAULTS), _config);
6344
+ const [open, setOpen] = React18.useState(false);
6345
+ const [closing, setClosing] = React18.useState(false);
6346
+ const [submitted, setSubmitted] = React18.useState(false);
6347
+ const [submitting, setSubmitting] = React18.useState(false);
6348
+ const [error, setError] = React18.useState(null);
6349
+ const [name, setName] = React18.useState("");
6350
+ const [email, setEmail] = React18.useState("");
6351
+ const [travelDate, setTravelDate] = React18.useState("");
6352
+ const panelRef = React18.useRef(null);
6353
+ const nameRef = React18.useRef(null);
6354
+ const show = React18.useCallback(() => {
6355
+ if (isDismissed()) return;
6356
+ setOpen(true);
6357
+ }, []);
6358
+ React18.useEffect(() => {
6359
+ var _a2;
6360
+ if (isDismissed()) return;
6361
+ if (config.trigger === "delay") {
6362
+ const t = setTimeout(show, ((_a2 = config.delaySeconds) != null ? _a2 : 5) * 1e3);
6363
+ return () => clearTimeout(t);
6364
+ }
6365
+ if (config.trigger === "exit_intent") {
6366
+ const handler = (e) => {
6367
+ if (e.clientY <= 5) show();
6368
+ };
6369
+ document.addEventListener("mouseout", handler);
6370
+ return () => document.removeEventListener("mouseout", handler);
6371
+ }
6372
+ if (config.trigger === "scroll") {
6373
+ const handler = () => {
6374
+ var _a3;
6375
+ const pct = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
6376
+ if (pct >= ((_a3 = config.scrollPercent) != null ? _a3 : 50)) {
6377
+ show();
6378
+ window.removeEventListener("scroll", handler);
6379
+ }
6380
+ };
6381
+ window.addEventListener("scroll", handler, { passive: true });
6382
+ return () => window.removeEventListener("scroll", handler);
6383
+ }
6384
+ }, [config.trigger, config.delaySeconds, config.scrollPercent, show]);
6385
+ React18.useEffect(() => {
6386
+ if (open && !submitted) {
6387
+ requestAnimationFrame(() => {
6388
+ var _a2;
6389
+ return (_a2 = nameRef.current) == null ? void 0 : _a2.focus();
6390
+ });
6391
+ }
6392
+ }, [open, submitted]);
6393
+ const close = React18.useCallback(() => {
6394
+ setClosing(true);
6395
+ setDismissed(config.dismissDays);
6396
+ setTimeout(() => {
6397
+ setOpen(false);
6398
+ setClosing(false);
6399
+ }, 250);
6400
+ }, [config.dismissDays]);
6401
+ React18.useEffect(() => {
6402
+ if (!open) return;
6403
+ const handler = (e) => {
6404
+ if (e.key === "Escape") close();
6405
+ };
6406
+ document.addEventListener("keydown", handler);
6407
+ return () => document.removeEventListener("keydown", handler);
6408
+ }, [open, close]);
6409
+ const onOverlayClick = React18.useCallback(
6410
+ (e) => {
6411
+ if (panelRef.current && !panelRef.current.contains(e.target)) {
6412
+ close();
6413
+ }
6414
+ },
6415
+ [close]
6416
+ );
6417
+ const handleSubmit = async (e) => {
6418
+ var _a2;
6419
+ e.preventDefault();
6420
+ setError(null);
6421
+ if (!name.trim() || !email.trim() || !travelDate) {
6422
+ setError("Please fill in all fields.");
6423
+ return;
6424
+ }
6425
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
6426
+ setError("Please enter a valid email address.");
6427
+ return;
6428
+ }
6429
+ setSubmitting(true);
6430
+ try {
6431
+ if (config.ajaxUrl) {
6432
+ const res = await fetch(config.ajaxUrl, {
6433
+ method: "POST",
6434
+ headers: { "Content-Type": "application/json" },
6435
+ body: JSON.stringify({
6436
+ name: name.trim(),
6437
+ email: email.trim(),
6438
+ travel_date: travelDate,
6439
+ nonce: (_a2 = config.nonce) != null ? _a2 : ""
6440
+ })
6441
+ });
6442
+ if (!res.ok) throw new Error("Server error");
6443
+ }
6444
+ setSubmitted(true);
6445
+ setDismissed(config.dismissDays);
6446
+ } catch (e2) {
6447
+ setError("Something went wrong. Please try again.");
6448
+ } finally {
6449
+ setSubmitting(false);
6450
+ }
6451
+ };
6452
+ if (!open) return null;
6453
+ const accentStyle = config.accentColor ? { "--popup-accent": config.accentColor } : void 0;
6454
+ const isCenter = config.position === "center";
6455
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6456
+ "div",
6457
+ {
6458
+ className: cn(
6459
+ "pexo-lead-popup fixed inset-0 z-[99999] flex",
6460
+ isCenter ? "items-center justify-center" : "items-end justify-end",
6461
+ closing ? "animate-fade-out" : "animate-fade-in"
6462
+ ),
6463
+ style: {
6464
+ backgroundColor: `rgba(0,0,0,${((_a = config.overlayOpacity) != null ? _a : 40) / 100})`,
6465
+ backdropFilter: "blur(4px)",
6466
+ WebkitBackdropFilter: "blur(4px)"
6467
+ },
6468
+ onClick: onOverlayClick,
6469
+ role: "dialog",
6470
+ "aria-modal": "true",
6471
+ "aria-label": config.heading,
6472
+ children: [
6473
+ /* @__PURE__ */ jsxRuntime.jsxs(
6474
+ "div",
6475
+ {
6476
+ ref: panelRef,
6477
+ className: cn(
6478
+ "relative flex flex-col overflow-hidden bg-background text-foreground shadow-2xl ring-1 ring-foreground/5",
6479
+ isCenter ? "m-4 w-full max-w-md rounded-2xl sm:max-w-lg" : "m-4 w-full max-w-sm rounded-2xl sm:m-6",
6480
+ closing ? isCenter ? "animate-zoom-out" : "animate-slide-out-right" : isCenter ? "animate-zoom-in" : "animate-slide-in-right"
6481
+ ),
6482
+ style: accentStyle,
6483
+ children: [
6484
+ /* @__PURE__ */ jsxRuntime.jsx(
6485
+ "button",
6486
+ {
6487
+ onClick: close,
6488
+ className: "absolute top-3 right-3 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm transition-colors hover:bg-black/50",
6489
+ "aria-label": "Close",
6490
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "h-4 w-4" })
6491
+ }
6492
+ ),
6493
+ config.imageUrl && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-44 w-full shrink-0 overflow-hidden sm:h-52", children: [
6494
+ /* @__PURE__ */ jsxRuntime.jsx(
6495
+ "img",
6496
+ {
6497
+ src: config.imageUrl,
6498
+ alt: "",
6499
+ className: "h-full w-full object-cover",
6500
+ loading: "eager"
6501
+ }
6502
+ ),
6503
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" })
6504
+ ] }),
6505
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col gap-5 p-5 sm:p-6", children: !submitted ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6506
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6507
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-heading text-lg font-bold leading-tight tracking-tight text-foreground sm:text-xl", children: config.heading }),
6508
+ config.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: config.subtitle })
6509
+ ] }),
6510
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [
6511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6512
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "pexo-lead-name", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.nameLabel }),
6513
+ /* @__PURE__ */ jsxRuntime.jsx(
6514
+ Input,
6515
+ {
6516
+ ref: nameRef,
6517
+ id: "pexo-lead-name",
6518
+ type: "text",
6519
+ placeholder: config.namePlaceholder,
6520
+ value: name,
6521
+ onChange: (e) => setName(e.target.value),
6522
+ autoComplete: "name",
6523
+ className: "h-10 rounded-lg border-border/60 bg-muted/30 px-3 text-sm focus-visible:border-primary focus-visible:ring-primary/30"
6524
+ }
6525
+ )
6526
+ ] }),
6527
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6528
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "pexo-lead-email", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.emailLabel }),
6529
+ /* @__PURE__ */ jsxRuntime.jsx(
6530
+ Input,
6531
+ {
6532
+ id: "pexo-lead-email",
6533
+ type: "email",
6534
+ placeholder: config.emailPlaceholder,
6535
+ value: email,
6536
+ onChange: (e) => setEmail(e.target.value),
6537
+ autoComplete: "email",
6538
+ className: "h-10 rounded-lg border-border/60 bg-muted/30 px-3 text-sm focus-visible:border-primary focus-visible:ring-primary/30"
6539
+ }
6540
+ )
6541
+ ] }),
6542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6543
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "pexo-lead-travel", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.travelDateLabel }),
6544
+ /* @__PURE__ */ jsxRuntime.jsxs(
6545
+ "select",
6546
+ {
6547
+ id: "pexo-lead-travel",
6548
+ value: travelDate,
6549
+ onChange: (e) => setTravelDate(e.target.value),
6550
+ className: cn(
6551
+ "h-10 w-full appearance-none rounded-lg border border-border/60 bg-muted/30 px-3 text-sm text-foreground outline-none transition-colors",
6552
+ "focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/30",
6553
+ !travelDate && "text-muted-foreground"
6554
+ ),
6555
+ style: {
6556
+ backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")`,
6557
+ backgroundRepeat: "no-repeat",
6558
+ backgroundPosition: "right 0.75rem center",
6559
+ paddingRight: "2.5rem"
6560
+ },
6561
+ children: [
6562
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: "Select a timeframe\u2026" }),
6563
+ config.travelDateOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: opt }, opt))
6564
+ ]
6565
+ }
6566
+ )
6567
+ ] }),
6568
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-destructive", role: "alert", children: error }),
6569
+ /* @__PURE__ */ jsxRuntime.jsxs(
6570
+ Button,
6571
+ {
6572
+ type: "submit",
6573
+ disabled: submitting,
6574
+ className: cn(
6575
+ "h-11 w-full gap-2 rounded-lg text-sm font-bold tracking-wide",
6576
+ config.accentColor ? "border-transparent text-white" : "bg-primary text-primary-foreground hover:bg-primary/90"
6577
+ ),
6578
+ style: config.accentColor ? { backgroundColor: config.accentColor } : void 0,
6579
+ children: [
6580
+ submitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SendIcon, { className: "h-4 w-4" }),
6581
+ submitting ? "Sending\u2026" : config.submitLabel
6582
+ ]
6583
+ }
6584
+ ),
6585
+ config.privacyText && /* @__PURE__ */ jsxRuntime.jsx(
6586
+ "p",
6587
+ {
6588
+ className: "text-center text-[11px] leading-relaxed text-muted-foreground [&_a]:underline [&_a]:underline-offset-2 [&_a]:hover:text-foreground",
6589
+ dangerouslySetInnerHTML: { __html: config.privacyText }
6590
+ }
6591
+ )
6592
+ ] })
6593
+ ] }) : (
6594
+ /* ---- Success state ---- */
6595
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 py-8 text-center", children: [
6596
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircleIcon, { className: "h-8 w-8 text-primary" }) }),
6597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6598
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-heading text-lg font-bold text-foreground", children: config.successHeading }),
6599
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: config.successMessage })
6600
+ ] }),
6601
+ /* @__PURE__ */ jsxRuntime.jsx(
6602
+ Button,
6603
+ {
6604
+ onClick: close,
6605
+ variant: "outline",
6606
+ className: "mt-2 h-10 px-6 text-sm",
6607
+ children: "Close"
6608
+ }
6609
+ )
6610
+ ] })
6611
+ ) })
6612
+ ]
6613
+ }
6614
+ ),
6615
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
6616
+ @keyframes pexo-fade-in { from { opacity: 0 } to { opacity: 1 } }
6617
+ @keyframes pexo-fade-out { from { opacity: 1 } to { opacity: 0 } }
6618
+ @keyframes pexo-zoom-in { from { opacity: 0; transform: scale(0.92) } to { opacity: 1; transform: scale(1) } }
6619
+ @keyframes pexo-zoom-out { from { opacity: 1; transform: scale(1) } to { opacity: 0; transform: scale(0.92) } }
6620
+ @keyframes pexo-slide-in-right { from { opacity: 0; transform: translateX(100%) } to { opacity: 1; transform: translateX(0) } }
6621
+ @keyframes pexo-slide-out-right { from { opacity: 1; transform: translateX(0) } to { opacity: 0; transform: translateX(100%) } }
6622
+
6623
+ .pexo-lead-popup .animate-fade-in { animation: pexo-fade-in 0.3s ease-out both }
6624
+ .pexo-lead-popup .animate-fade-out { animation: pexo-fade-out 0.25s ease-in both }
6625
+ .pexo-lead-popup .animate-zoom-in { animation: pexo-zoom-in 0.35s cubic-bezier(0.16,1,0.3,1) both }
6626
+ .pexo-lead-popup .animate-zoom-out { animation: pexo-zoom-out 0.25s ease-in both }
6627
+ .pexo-lead-popup .animate-slide-in-right { animation: pexo-slide-in-right 0.4s cubic-bezier(0.16,1,0.3,1) both }
6628
+ .pexo-lead-popup .animate-slide-out-right { animation: pexo-slide-out-right 0.3s ease-in both }
6629
+
6630
+ /* Ensure popup fonts inherit from design system */
6631
+ .pexo-lead-popup { font-family: var(--font-sans, "Literata", Georgia, serif); }
6632
+ .pexo-lead-popup h1, .pexo-lead-popup h2, .pexo-lead-popup h3 { font-family: var(--font-heading, "ArcaMajora3", sans-serif); }
6633
+ .pexo-lead-popup button, .pexo-lead-popup label { font-family: var(--font-ui, "ArcaMajora3", sans-serif); }
6634
+ .pexo-lead-popup select { font-family: var(--font-sans, "Literata", Georgia, serif); }
6635
+ ` })
6636
+ ]
6637
+ }
6638
+ );
6639
+ }
3047
6640
 
6641
+ exports.ActivityCard = ActivityCard;
3048
6642
  exports.BookingConfirmation = BookingConfirmation;
3049
6643
  exports.BookingConfirmationEmail = BookingConfirmationEmail;
3050
6644
  exports.BookingDetails = BookingDetails;
6645
+ exports.BookingForm = BookingForm;
6646
+ exports.COUNTRIES = COUNTRIES;
6647
+ exports.CounterField = CounterField;
6648
+ exports.CountrySearchField = CountrySearchField;
6649
+ exports.DEFAULT_HEADER_LINKS = DEFAULT_HEADER_LINKS;
6650
+ exports.DEFAULT_LANGUAGES = DEFAULT_LANGUAGES;
6651
+ exports.DatePickerField = DatePickerField;
6652
+ exports.FilterPanel = FilterPanel;
3051
6653
  exports.FloatingInput = FloatingInput;
3052
6654
  exports.FloatingSelect = FloatingSelect;
6655
+ exports.Itinerary = Itinerary;
6656
+ exports.LeadCapturePopup = LeadCapturePopup;
6657
+ exports.MenuTrip = MenuTrip;
3053
6658
  exports.Offer = Offer;
3054
6659
  exports.OfferAdventureCard = OfferAdventureCard;
6660
+ exports.PhoneCountrySelect = PhoneCountrySelect;
6661
+ exports.PhotoGallery = PhotoGallery;
6662
+ exports.PricingTrip = PricingTrip;
6663
+ exports.SiteHeader = SiteHeader;
6664
+ exports.ThemeToggle = ThemeToggle;
6665
+ exports.TripCard = TripCard;
6666
+ exports.TripHeader = TripHeader;
6667
+ exports.TripPage = TripPage;
3055
6668
  exports.cn = cn;
3056
6669
  //# sourceMappingURL=index.cjs.map
3057
6670
  //# sourceMappingURL=index.cjs.map